diff --git a/.github/workflows/acvm-publish-acvm-js.yml b/.github/workflows/acvm-publish-acvm-js.yml new file mode 100644 index 00000000000..b2145085a02 --- /dev/null +++ b/.github/workflows/acvm-publish-acvm-js.yml @@ -0,0 +1,54 @@ +name: Publish acvm_js + +on: + workflow_dispatch: + inputs: + acvm-ref: + description: The acvm reference to checkout + required: true + +jobs: + publish-acvm-js-package: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + with: + ref: ${{ inputs.acvm-ref }} + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + registry-url: "https://registry.npmjs.org" + node-version: 18.15 + + - uses: cachix/install-nix-action@v22 + with: + nix_path: nixpkgs=channel:nixos-23.05 + github_access_token: ${{ secrets.GITHUB_TOKEN }} + + - uses: cachix/cachix-action@v12 + with: + name: barretenberg + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Build acvm-js + working-directory: acvm-repo + run: | + nix build .# + + - name: Discover Build Output Path + working-directory: acvm-repo + run: echo "BUILD_OUTPUT_PATH=$(readlink -f ./result)" >> $GITHUB_ENV + + - name: Copy Build Output to Temporary Directory + working-directory: acvm-repo + run: | + mkdir temp_publish_dir + cp -r ${{ env.BUILD_OUTPUT_PATH }}/* temp_publish_dir/ + + - name: Publish to NPM + working-directory: ./acvm-repo/temp_publish_dir + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/acvm-publish.yml b/.github/workflows/acvm-publish.yml new file mode 100644 index 00000000000..931bc7d5a2b --- /dev/null +++ b/.github/workflows/acvm-publish.yml @@ -0,0 +1,80 @@ +name: Publish ACVM crates + +on: + workflow_dispatch: + inputs: + acvm-ref: + description: The acvm reference to checkout + required: true + +jobs: + publish: + name: Publish in order + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + with: + ref: ${{ inputs.acvm-ref }} + + - name: Setup toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.66.0 + + # These steps are in a specific order so crate dependencies are updated first + - name: Publish acir_field + working-directory: acvm-repo + run: | + cargo publish --package acir_field + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.ACVM_CRATES_IO_TOKEN }} + + - name: Publish brillig + working-directory: acvm-repo + run: | + cargo publish --package brillig + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.ACVM_CRATES_IO_TOKEN }} + + - name: Publish acir + working-directory: acvm-repo + run: | + cargo publish --package acir + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.ACVM_CRATES_IO_TOKEN }} + + - name: Publish acvm_blackbox_solver + working-directory: acvm-repo + run: | + cargo publish --package acvm_blackbox_solver + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.ACVM_CRATES_IO_TOKEN }} + + - name: Publish barretenberg_blackbox_solver + working-directory: acvm-repo + run: | + cargo publish --package barretenberg_blackbox_solver + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.ACVM_CRATES_IO_TOKEN }} + + - name: Publish acvm_stdlib + working-directory: acvm-repo + run: | + cargo publish --package acvm_stdlib + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.ACVM_CRATES_IO_TOKEN }} + + - name: Publish brillig_vm + working-directory: acvm-repo + run: | + cargo publish --package brillig_vm + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.ACVM_CRATES_IO_TOKEN }} + + - name: Publish acvm + working-directory: acvm-repo + run: | + cargo publish --package acvm + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.ACVM_CRATES_IO_TOKEN }} diff --git a/.github/workflows/acvm-release.yml b/.github/workflows/acvm-release.yml new file mode 100644 index 00000000000..b086e9e7d0f --- /dev/null +++ b/.github/workflows/acvm-release.yml @@ -0,0 +1,47 @@ +name: ACVM Release + +on: + push: + branches: + - master + +jobs: + release-please: + name: Create Release + outputs: + release-pr: ${{ steps.release.outputs.pr }} + tag-name: ${{ steps.release.outputs.tag_name }} + runs-on: ubuntu-latest + steps: + - name: Run release-please + id: release + uses: google-github-actions/release-please-action@v3 + with: + token: ${{ secrets.ACVM_RELEASE_TOKEN }} + command: manifest + + publish: + name: Publish crates + needs: [release-please] + if: ${{ needs.release-please.outputs.tag-name }} + runs-on: ubuntu-latest + steps: + - name: Dispatch to publish workflow + uses: benc-uk/workflow-dispatch@v1 + with: + workflow: acvm-publish.yml + ref: master + inputs: '{ "acvm-ref": "${{ needs.release-please.outputs.tag-name }}" }' + + dispatch-publish-acvm-js: + name: Dispatch to publish-acvm-js workflow + needs: [release-please] + if: ${{ needs.release-please.outputs.tag-name }} + runs-on: ubuntu-latest + steps: + - name: Trigger publish-acvm-js.yml workflow + uses: benc-uk/workflow-dispatch@v1 + with: + workflow: acvm-publish-acvm-js.yml + ref: master + inputs: '{ "acvm-ref": "${{ needs.release-please.outputs.tag-name }}" }' diff --git a/.github/workflows/acvm-rust.yml b/.github/workflows/acvm-rust.yml new file mode 100644 index 00000000000..0394c306fff --- /dev/null +++ b/.github/workflows/acvm-rust.yml @@ -0,0 +1,58 @@ +name: ACVM Rust + +on: [push, pull_request] + +jobs: + clippy-n-test: + name: Test on ${{ matrix.os }} + runs-on: ${{ matrix.runner }} + timeout-minutes: 30 + + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu + runner: ubuntu-latest + target: x86_64-linux + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - uses: cachix/install-nix-action@v22 + with: + nix_path: nixpkgs=channel:nixos-22.11 + github_access_token: ${{ secrets.GITHUB_TOKEN }} + + - uses: cachix/cachix-action@v12 + with: + name: barretenberg + + - name: Restore nix store cache + id: nix-store-cache + uses: actions/cache@v3 + with: + path: /tmp/nix-cache + key: ${{ runner.os }}-flake-${{ hashFiles('*.lock') }} + + # Based on https://github.com/marigold-dev/deku/blob/b5016f0cf4bf6ac48db9111b70dd7fb49b969dfd/.github/workflows/build.yml#L26 + - name: Copy cache into nix store + if: steps.nix-store-cache.outputs.cache-hit == 'true' + # We don't check the signature because we're the one that created the cache + run: | + for narinfo in /tmp/nix-cache/*.narinfo; do + path=$(head -n 1 "$narinfo" | awk '{print $2}') + nix copy --no-check-sigs --from "file:///tmp/nix-cache" "$path" + done + + - name: Run `nix flake check` + working-directory: acvm-repo + run: | + nix flake check -L + + - name: Export cache from nix store + if: steps.nix-store-cache.outputs.cache-hit != 'true' + working-directory: acvm-repo + run: | + nix copy --to "file:///tmp/nix-cache?compression=zstd¶llel-compression=true" .#cargo-artifacts \ No newline at end of file diff --git a/.github/workflows/acvm-test.yml b/.github/workflows/acvm-test.yml new file mode 100644 index 00000000000..ea46fcb2007 --- /dev/null +++ b/.github/workflows/acvm-test.yml @@ -0,0 +1,120 @@ +name: Test acvm_js + +on: [push, pull_request] + +# This will cancel previous runs when a branch or PR is updated +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + build-acvm-js-package: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - uses: cachix/install-nix-action@v20 + with: + nix_path: nixpkgs=channel:nixos-22.11 + github_access_token: ${{ secrets.GITHUB_TOKEN }} + + - uses: cachix/cachix-action@v12 + with: + name: barretenberg + authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}" + + - name: Build acvm-js + working-directory: acvm-repo + run: | + nix build .# + + - name: Dereference symlink + working-directory: acvm-repo + run: echo "UPLOAD_PATH=$(readlink -f result)" >> $GITHUB_ENV + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: acvm-js + path: ${{ env.UPLOAD_PATH }} + retention-days: 3 + + test-acvm_js-node: + needs: [build-acvm-js-package] + name: Node.js Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: acvm-js + path: ./acvm-repo/result + + - name: Set up test environment + uses: ./.github/actions/setup + with: + working-directory: ./acvm-repo/acvm_js + + - name: Run node tests + working-directory: ./acvm-repo/acvm_js + run: | + yarn + yarn test + + test-acvm_js-browser: + needs: [build-acvm-js-package] + name: Browser Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: acvm-js + path: ./acvm-repo/result + + - name: Set up test environment + uses: ./.github/actions/setup + with: + working-directory: ./acvm-repo/acvm_js + + - name: Install playwright deps + working-directory: ./acvm-repo/acvm_js + run: | + npx playwright install + npx playwright install-deps + + - name: Run browser tests + working-directory: ./acvm-repo/acvm_js + run: | + yarn + yarn test:browser + + test-acvm_js-rust: + name: Rust Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Setup toolchain + uses: dtolnay/rust-toolchain@1.66.0 + with: + targets: wasm32-unknown-unknown + + - uses: taiki-e/install-action@v2 + with: + tool: wasm-bindgen-cli@0.2.87 + + - name: Run rust tests + working-directory: acvm-repo + run: cargo test diff --git a/.github/workflows/acvm-typescript.yml b/.github/workflows/acvm-typescript.yml new file mode 100644 index 00000000000..a35f031fea7 --- /dev/null +++ b/.github/workflows/acvm-typescript.yml @@ -0,0 +1,28 @@ +name: Typescript + +on: [push, pull_request] + +# This will cancel previous runs when a branch or PR is updated +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + eslint: + name: Eslint + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Install dependencies + uses: ./.github/actions/setup + with: + working-directory: ./acvm-repo/acvm_js + + - name: Run eslint + working-directory: ./acvm-repo/acvm_js + run: | + yarn + yarn lint diff --git a/acvm-repo/.envrc b/acvm-repo/.envrc new file mode 100644 index 00000000000..494e7adf16c --- /dev/null +++ b/acvm-repo/.envrc @@ -0,0 +1,20 @@ +# Based on https://github.com/direnv/direnv-vscode/blob/158e8302c2594cc0eaa5f8b4f0cafedd4e1c0315/.envrc + +# You can define your system-specific logic (like Git settings or GH tokens) in .envrc.local +# If that logic is usable by other people and might improve development environment, consider +# contributing it to this file! + +source_env_if_exists .envrc.local + +if [[ -z "${SKIP_NIX:-}" ]] && has nix; then + + if nix flake metadata &>/dev/null && has use_flake; then + # use flakes if possible + use flake + + else + # Otherwise fall back to pure nix + use nix + fi + +fi \ No newline at end of file diff --git a/acvm-repo/.github/actions/setup/action.yml b/acvm-repo/.github/actions/setup/action.yml new file mode 100644 index 00000000000..aaffe2f5a3f --- /dev/null +++ b/acvm-repo/.github/actions/setup/action.yml @@ -0,0 +1,22 @@ +name: Yarn Cache and Install +description: Installs dependencies and caches them + +inputs: + working-directory: + default: ./ + required: false + +runs: + using: composite + steps: + - name: Cache + uses: actions/cache@v3 + id: cache + with: + path: "**/node_modules" + key: yarn-v1-${{ hashFiles('**/yarn.lock') }} + - name: Install + working-directory: ${{ inputs.working-directory }} + run: yarn --immutable + shell: bash + if: steps.cache.outputs.cache-hit != 'true' diff --git a/acvm-repo/.github/workflows/deny.yml b/acvm-repo/.github/workflows/deny.yml new file mode 100644 index 00000000000..1a6af18e7c5 --- /dev/null +++ b/acvm-repo/.github/workflows/deny.yml @@ -0,0 +1,26 @@ +name: deny + +on: + push: + branches: [master] + paths: [Cargo.lock, deny.toml] + pull_request: + branches: [master] + paths: [Cargo.lock, deny.toml] + merge_group: + +env: + RUSTFLAGS: -D warnings + CARGO_TERM_COLOR: always + +concurrency: deny-${{ github.head_ref || github.run_id }} + +jobs: + deny: + name: deny + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: EmbarkStudios/cargo-deny-action@v1 + with: + command: check all diff --git a/acvm-repo/.github/workflows/pull-request.yml b/acvm-repo/.github/workflows/pull-request.yml new file mode 100644 index 00000000000..4b8a626a94e --- /dev/null +++ b/acvm-repo/.github/workflows/pull-request.yml @@ -0,0 +1,29 @@ +name: Pull Request + +on: + merge_group: + pull_request_target: + types: + - opened + - reopened + - edited + - synchronize + +permissions: + pull-requests: read + +jobs: + conventional-title: + name: Validate PR title is Conventional Commit + runs-on: ubuntu-latest + steps: + - name: Check title + if: github.event_name == 'pull_request_target' + uses: amannn/action-semantic-pull-request@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + types: | + fix + feat + chore diff --git a/acvm-repo/.github/workflows/spellcheck.yml b/acvm-repo/.github/workflows/spellcheck.yml new file mode 100644 index 00000000000..6df9b22b850 --- /dev/null +++ b/acvm-repo/.github/workflows/spellcheck.yml @@ -0,0 +1,13 @@ +name: Spellcheck + +on: [push] + +# This will cancel previous runs when a branch or PR is updated +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + spellcheck: + name: Spellcheck + uses: noir-lang/.github/.github/workflows/spellcheck.yml@main diff --git a/acvm-repo/.github/workflows/typescript.yml b/acvm-repo/.github/workflows/typescript.yml new file mode 100644 index 00000000000..147bd356351 --- /dev/null +++ b/acvm-repo/.github/workflows/typescript.yml @@ -0,0 +1,26 @@ +name: Typescript + +on: [push, pull_request] + +# This will cancel previous runs when a branch or PR is updated +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }} + cancel-in-progress: true + +jobs: + eslint: + name: Eslint + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Install dependencies + uses: ./.github/actions/setup + with: + working-directory: ./acvm_js + + - name: Run eslint + working-directory: ./acvm_js + run: yarn lint diff --git a/acvm-repo/.gitignore b/acvm-repo/.gitignore new file mode 100644 index 00000000000..54178440f50 --- /dev/null +++ b/acvm-repo/.gitignore @@ -0,0 +1,7 @@ +/target +.DS_Store +.vscode +# Cargo.lock +result +outputs/ +.direnv \ No newline at end of file diff --git a/acvm-repo/.release-please-manifest.json b/acvm-repo/.release-please-manifest.json new file mode 100644 index 00000000000..1a52d4cb55a --- /dev/null +++ b/acvm-repo/.release-please-manifest.json @@ -0,0 +1,12 @@ +{ + ".": "0.27.0", + "acir": "0.27.0", + "acir_field": "0.27.0", + "acvm": "0.27.0", + "acvm_js": "0.27.0", + "stdlib": "0.27.0", + "brillig": "0.27.0", + "brillig_vm": "0.27.0", + "blackbox_solver": "0.27.0", + "barretenberg_blackbox_solver": "0.27.0" +} diff --git a/acvm-repo/.rustfmt.toml b/acvm-repo/.rustfmt.toml new file mode 100644 index 00000000000..c13d3e328d4 --- /dev/null +++ b/acvm-repo/.rustfmt.toml @@ -0,0 +1,2 @@ +edition = "2018" +use_small_heuristics = "Max" diff --git a/acvm-repo/CHANGELOG.md b/acvm-repo/CHANGELOG.md new file mode 100644 index 00000000000..0833a3c1310 --- /dev/null +++ b/acvm-repo/CHANGELOG.md @@ -0,0 +1,736 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.27.0](https://github.com/noir-lang/acvm/compare/root-v0.26.1...root-v0.27.0) (2023-09-19) + + +### ⚠ BREAKING CHANGES + +* Separate barretenberg solver from generic blackbox solver code ([#554](https://github.com/noir-lang/acvm/issues/554)) + +### Features + +* **acir:** add method on `Circuit` to return assert message ([#551](https://github.com/noir-lang/acvm/issues/551)) ([ee18cde](https://github.com/noir-lang/acvm/commit/ee18cde3537b2be6714061af0bc9ef3793929f7f)) + + +### Bug Fixes + +* bump brillig_vm version in release please ([#556](https://github.com/noir-lang/acvm/issues/556)) ([f6c7823](https://github.com/noir-lang/acvm/commit/f6c7823b3be2b85a6ce8dc4af7a3b57ee7a577db)) +* use the exact version for the hex crate ([#546](https://github.com/noir-lang/acvm/issues/546)) ([2a546e5](https://github.com/noir-lang/acvm/commit/2a546e5b5cc9f39737ad81f8e96d58313a74eced)) + + +### Miscellaneous Chores + +* Separate barretenberg solver from generic blackbox solver code ([#554](https://github.com/noir-lang/acvm/issues/554)) ([a4b9772](https://github.com/noir-lang/acvm/commit/a4b97722a0892fe379ff075e6080675adafdce0e)) + +## [0.26.1](https://github.com/noir-lang/acvm/compare/root-v0.26.0...root-v0.26.1) (2023-09-12) + + +### Bug Fixes + +* Implements handling of the high limb during fixed base scalar multiplication ([#535](https://github.com/noir-lang/acvm/issues/535)) ([551504a](https://github.com/noir-lang/acvm/commit/551504aa572d3f9d56b5576d25ce1211296ee488)) + +## [0.26.0](https://github.com/noir-lang/acvm/compare/root-v0.25.0...root-v0.26.0) (2023-09-07) + + +### ⚠ BREAKING CHANGES + +* Add a low and high limb to scalar mul opcode ([#532](https://github.com/noir-lang/acvm/issues/532)) + +### Miscellaneous Chores + +* Add a low and high limb to scalar mul opcode ([#532](https://github.com/noir-lang/acvm/issues/532)) ([b054f66](https://github.com/noir-lang/acvm/commit/b054f66be9c73d4e02dbecdab80874a907f19242)) + +## [0.25.0](https://github.com/noir-lang/acvm/compare/root-v0.24.1...root-v0.25.0) (2023-09-04) + + +### ⚠ BREAKING CHANGES + +* Provide runtime callstacks for brillig failures and return errors in acvm_js ([#523](https://github.com/noir-lang/acvm/issues/523)) + +### Features + +* Provide runtime callstacks for brillig failures and return errors in acvm_js ([#523](https://github.com/noir-lang/acvm/issues/523)) ([7ab7cff](https://github.com/noir-lang/acvm/commit/7ab7cff48a9aba61a97fad2a759fc8e55740b098)) + + +### Bug Fixes + +* initialize recursive proof output to zero ([#524](https://github.com/noir-lang/acvm/issues/524)) ([5453074](https://github.com/noir-lang/acvm/commit/545307457dd7634b20ea3977e2d2cc751eba06d2)) + +## [0.24.1](https://github.com/noir-lang/acvm/compare/root-v0.24.0...root-v0.24.1) (2023-09-03) + + +### Bug Fixes + +* Add WASI 20 `_initialize` call to `acvm_backend.wasm` binary ([#518](https://github.com/noir-lang/acvm/issues/518)) ([ec6ab0c](https://github.com/noir-lang/acvm/commit/ec6ab0c6fb2753209abe1e03a449873e255ffd76)) + +## [0.24.0](https://github.com/noir-lang/acvm/compare/root-v0.23.0...root-v0.24.0) (2023-08-31) + + +### ⚠ BREAKING CHANGES + +* **acvm:** Remove the `Backend` trait ([#514](https://github.com/noir-lang/acvm/issues/514)) +* **acir:** Remove unused `Directive` opcodes ([#510](https://github.com/noir-lang/acvm/issues/510)) +* **acir:** Add predicate to MemoryOp ([#503](https://github.com/noir-lang/acvm/issues/503)) +* **acvm:** Remove unused arguments from `Backend` trait ([#511](https://github.com/noir-lang/acvm/issues/511)) +* Assertion messages embedded in the circuit ([#484](https://github.com/noir-lang/acvm/issues/484)) + +### Features + +* **acir:** Add predicate to MemoryOp ([#503](https://github.com/noir-lang/acvm/issues/503)) ([ca9eebe](https://github.com/noir-lang/acvm/commit/ca9eebe34e61adabf97318c8ccaf60c8a424aafd)) +* Assertion messages embedded in the circuit ([#484](https://github.com/noir-lang/acvm/issues/484)) ([06b97c5](https://github.com/noir-lang/acvm/commit/06b97c51041e16651cf8b2be8bc18214e276c6c9)) + + +### Miscellaneous Chores + +* **acir:** Remove unused `Directive` opcodes ([#510](https://github.com/noir-lang/acvm/issues/510)) ([cfd8cbf](https://github.com/noir-lang/acvm/commit/cfd8cbf58307511ac0cc9106c299695c2ca779de)) +* **acvm:** Remove the `Backend` trait ([#514](https://github.com/noir-lang/acvm/issues/514)) ([681535d](https://github.com/noir-lang/acvm/commit/681535da52815a4a164ee4f48f7b48329664af98)) +* **acvm:** Remove unused arguments from `Backend` trait ([#511](https://github.com/noir-lang/acvm/issues/511)) ([ae65355](https://github.com/noir-lang/acvm/commit/ae65355afb7df98c71f81d5a54e89f39f9333920)) + +## [0.23.0](https://github.com/noir-lang/acvm/compare/root-v0.22.0...root-v0.23.0) (2023-08-30) + + +### ⚠ BREAKING CHANGES + +* Return an iterator from `new_locations()` instead of collecting ([#507](https://github.com/noir-lang/acvm/issues/507)) +* **acvm:** remove `CommonReferenceString` trait and preprocess method ([#508](https://github.com/noir-lang/acvm/issues/508)) +* **acvm:** Remove `BlackBoxFunctionSolver` from `Backend` trait ([#494](https://github.com/noir-lang/acvm/issues/494)) +* **acvm:** Pass `BlackBoxFunctionSolver` to `ACVM` by reference + +### Features + +* **acvm_js:** Add `execute_circuit_with_black_box_solver` to prevent reinitialization of `BlackBoxFunctionSolver` ([3877e0e](https://github.com/noir-lang/acvm/commit/3877e0e438a8d0e5545a4da7210767dec05c342f)) +* Expose a `BlackBoxFunctionSolver` containing a barretenberg wasm from `blackbox_solver` ([#494](https://github.com/noir-lang/acvm/issues/494)) ([a1d4b71](https://github.com/noir-lang/acvm/commit/a1d4b71256dfbf1e883e770dd9c45479235aa860)) + + +### Miscellaneous Chores + +* **acvm:** Pass `BlackBoxFunctionSolver` to `ACVM` by reference ([3877e0e](https://github.com/noir-lang/acvm/commit/3877e0e438a8d0e5545a4da7210767dec05c342f)) +* **acvm:** Remove `BlackBoxFunctionSolver` from `Backend` trait ([#494](https://github.com/noir-lang/acvm/issues/494)) ([a1d4b71](https://github.com/noir-lang/acvm/commit/a1d4b71256dfbf1e883e770dd9c45479235aa860)) +* **acvm:** remove `CommonReferenceString` trait and preprocess method ([#508](https://github.com/noir-lang/acvm/issues/508)) ([3827dd3](https://github.com/noir-lang/acvm/commit/3827dd3ce487650843ba4df8337b423e39f97edf)) +* Return an iterator from `new_locations()` instead of collecting ([#507](https://github.com/noir-lang/acvm/issues/507)) ([8d49a5c](https://github.com/noir-lang/acvm/commit/8d49a5c15b1e962cd59252467a20a922edadc2f2)) + +## [0.22.0](https://github.com/noir-lang/acvm/compare/root-v0.21.0...root-v0.22.0) (2023-08-18) + + +### ⚠ BREAKING CHANGES + +* Switched from OpcodeLabel to OpcodeLocation and ErrorLocation ([#493](https://github.com/noir-lang/acvm/issues/493)) +* **acvm:** check for index out-of-bounds on memory operations ([#468](https://github.com/noir-lang/acvm/issues/468)) + +### Features + +* **acvm:** check for index out-of-bounds on memory operations ([#468](https://github.com/noir-lang/acvm/issues/468)) ([740468c](https://github.com/noir-lang/acvm/commit/740468c0a144f7179c38f615cfda31b2fcc77359)) +* print error location with fmt ([#497](https://github.com/noir-lang/acvm/issues/497)) ([575a9e5](https://github.com/noir-lang/acvm/commit/575a9e50e97afb04a7b91799e06752cec3093f0b)) +* Switched from OpcodeLabel to OpcodeLocation and ErrorLocation ([#493](https://github.com/noir-lang/acvm/issues/493)) ([27a5a93](https://github.com/noir-lang/acvm/commit/27a5a935849f8904e10056b08089f532a06962b8)) + + +### Bug Fixes + +* add opcode label to unsatisfied constrain string ([#482](https://github.com/noir-lang/acvm/issues/482)) ([cbbbe67](https://github.com/noir-lang/acvm/commit/cbbbe67b9a19a4a560b2dfa8f27ea1c6ebd61f28)) + +## [0.21.0](https://github.com/noir-lang/acvm/compare/root-v0.20.1...root-v0.21.0) (2023-07-26) + + +### ⚠ BREAKING CHANGES + +* **acir:** Remove `Block`, `RAM` and `ROM` opcodes ([#457](https://github.com/noir-lang/acvm/issues/457)) +* **acvm:** Remove `OpcodeResolution` enum ([#400](https://github.com/noir-lang/acvm/issues/400)) +* **acvm:** Support stepwise execution of ACIR ([#399](https://github.com/noir-lang/acvm/issues/399)) + +### Features + +* **acvm:** Remove `OpcodeResolution` enum ([#400](https://github.com/noir-lang/acvm/issues/400)) ([d0ce48c](https://github.com/noir-lang/acvm/commit/d0ce48c506619a5560412ef6693bfa11036b501e)) +* **acvm:** Support stepwise execution of ACIR ([#399](https://github.com/noir-lang/acvm/issues/399)) ([6a03950](https://github.com/noir-lang/acvm/commit/6a0395021779a2711353c2fe2948e09b5b538fc0)) + + +### Miscellaneous Chores + +* **acir:** Remove `Block`, `RAM` and `ROM` opcodes ([#457](https://github.com/noir-lang/acvm/issues/457)) ([8dd220a](https://github.com/noir-lang/acvm/commit/8dd220ae127baf6cc5a31d8ab7ffdeeb161f6109)) + +## [0.20.1](https://github.com/noir-lang/acvm/compare/root-v0.20.0...root-v0.20.1) (2023-07-26) + + +### Features + +* add optimisations to fallback black box functions on booleans ([#446](https://github.com/noir-lang/acvm/issues/446)) ([2cfb2a8](https://github.com/noir-lang/acvm/commit/2cfb2a8cf911a81eedbd9da13ab2c616abd67f83)) +* **stdlib:** Add fallback implementation of `Keccak256` black box function ([#445](https://github.com/noir-lang/acvm/issues/445)) ([f7ebb03](https://github.com/noir-lang/acvm/commit/f7ebb03653c971f119700ff8126d9eb5ff01be0f)) + +## [0.20.0](https://github.com/noir-lang/acvm/compare/root-v0.19.1...root-v0.20.0) (2023-07-20) + + +### ⚠ BREAKING CHANGES + +* atomic memory opcodes ([#447](https://github.com/noir-lang/acvm/issues/447)) + +### Features + +* atomic memory opcodes ([#447](https://github.com/noir-lang/acvm/issues/447)) ([3261c7a](https://github.com/noir-lang/acvm/commit/3261c7a2fd4f3a300bc5f39ef4febccd8a853560)) +* **brillig:** Support integers which fit inside a `FieldElement` ([#403](https://github.com/noir-lang/acvm/issues/403)) ([f992412](https://github.com/noir-lang/acvm/commit/f992412617ade875fa26fe3a2cc3c06dbcad503b)) +* **stdlib:** Add fallback implementation of `HashToField128Security` black box function ([#435](https://github.com/noir-lang/acvm/issues/435)) ([ed40f22](https://github.com/noir-lang/acvm/commit/ed40f228529e888d1960bfa70cb92b277e24b37f)) + +## [0.19.1](https://github.com/noir-lang/acvm/compare/root-v0.19.0...root-v0.19.1) (2023-07-17) + + +### Bug Fixes + +* Remove panic when we divide 0/0 in quotient directive ([#437](https://github.com/noir-lang/acvm/issues/437)) ([9c8ff64](https://github.com/noir-lang/acvm/commit/9c8ff64ebf27a86787ae184e10ed9581041ec0ff)) + +## [0.19.0](https://github.com/noir-lang/acvm/compare/root-v0.18.2...root-v0.19.0) (2023-07-15) + + +### ⚠ BREAKING CHANGES + +* move to bincode and GzEncoding for artifacts ([#436](https://github.com/noir-lang/acvm/issues/436)) + +### Features + +* move to bincode and GzEncoding for artifacts ([#436](https://github.com/noir-lang/acvm/issues/436)) ([4683240](https://github.com/noir-lang/acvm/commit/46832400a8bc20135a8a895ab9477b14449734d9)) + +## [0.18.2](https://github.com/noir-lang/acvm/compare/root-v0.18.1...root-v0.18.2) (2023-07-12) + + +### Features + +* **acvm:** reexport `blackbox_solver` crate from `acvm` ([#431](https://github.com/noir-lang/acvm/issues/431)) ([517e942](https://github.com/noir-lang/acvm/commit/517e942b732d7107f6e064c6791917d1508229b3)) +* **stdlib:** Add fallback implementation of `Blake2s` black box function ([#424](https://github.com/noir-lang/acvm/issues/424)) ([982d940](https://github.com/noir-lang/acvm/commit/982d94087d46092ce7a5e94dbd7e732195f58e42)) + +## [0.18.1](https://github.com/noir-lang/acvm/compare/root-v0.18.0...root-v0.18.1) (2023-07-12) + + +### Bug Fixes + +* Crate publishing order ([#428](https://github.com/noir-lang/acvm/issues/428)) ([4f69cb5](https://github.com/noir-lang/acvm/commit/4f69cb5782435a2fcf45bb0985e1bb0eb944b194)) + +## [0.18.0](https://github.com/noir-lang/acvm/compare/root-v0.17.0...root-v0.18.0) (2023-07-12) + + +### ⚠ BREAKING CHANGES + +* add backend-solvable blackboxes to brillig & unify implementations ([#422](https://github.com/noir-lang/acvm/issues/422)) +* **acvm:** Remove `CircuitSimplifer` ([#421](https://github.com/noir-lang/acvm/issues/421)) +* **acvm:** Add `circuit: &Circuit` to `eth_contract_from_vk` function signature ([#420](https://github.com/noir-lang/acvm/issues/420)) +* Returns index of failing opcode and transformation mapping ([#412](https://github.com/noir-lang/acvm/issues/412)) + +### Features + +* **acvm:** Add `circuit: &Circuit` to `eth_contract_from_vk` function signature ([#420](https://github.com/noir-lang/acvm/issues/420)) ([744e9da](https://github.com/noir-lang/acvm/commit/744e9da71f7ca477a5390a63f47211dd4dffb8b3)) +* add backend-solvable blackboxes to brillig & unify implementations ([#422](https://github.com/noir-lang/acvm/issues/422)) ([093342e](https://github.com/noir-lang/acvm/commit/093342ea9481a311fa71343b8b7a22774788838a)) +* derive PartialOrd, Ord, and Hash on RegisterIndex ([#425](https://github.com/noir-lang/acvm/issues/425)) ([7f6b0dc](https://github.com/noir-lang/acvm/commit/7f6b0dc138c4e11d2b5847f0c9603979cc43493a)) +* Returns index of failing opcode and transformation mapping ([#412](https://github.com/noir-lang/acvm/issues/412)) ([79950e9](https://github.com/noir-lang/acvm/commit/79950e943f60e4082e1cf5ec4442aa67ea91aade)) +* **stdlib:** Add fallback implementation of `SHA256` black box function ([#407](https://github.com/noir-lang/acvm/issues/407)) ([040369a](https://github.com/noir-lang/acvm/commit/040369adc8749fa5ec2edd255ff54c105c3140f5)) + + +### Miscellaneous Chores + +* **acvm:** Remove `CircuitSimplifer` ([#421](https://github.com/noir-lang/acvm/issues/421)) ([e07a56d](https://github.com/noir-lang/acvm/commit/e07a56d9c542a7f03ce156761054cd403de0bd23)) + +## [0.17.0](https://github.com/noir-lang/acvm/compare/root-v0.16.0...root-v0.17.0) (2023-07-07) + + +### ⚠ BREAKING CHANGES + +* **acir:** add `EcdsaSecp256r1` blackbox function ([#408](https://github.com/noir-lang/acvm/issues/408)) + +### Features + +* **acir:** add `EcdsaSecp256r1` blackbox function ([#408](https://github.com/noir-lang/acvm/issues/408)) ([9895817](https://github.com/noir-lang/acvm/commit/98958170c9fa9b4731e33b31cb494a72bb90549e)) + +## [0.16.0](https://github.com/noir-lang/acvm/compare/root-v0.15.1...root-v0.16.0) (2023-07-06) + + +### ⚠ BREAKING CHANGES + +* **acvm:** replace `PartialWitnessGeneratorStatus` with `ACVMStatus` ([#410](https://github.com/noir-lang/acvm/issues/410)) +* **acir:** revert changes to `SchnorrVerify` opcode ([#409](https://github.com/noir-lang/acvm/issues/409)) +* **acvm:** Replace `PartialWitnessGenerator` trait with `BlackBoxFunctionSolver` ([#378](https://github.com/noir-lang/acvm/issues/378)) +* **acvm:** Encapsulate internal state of ACVM within a struct ([#384](https://github.com/noir-lang/acvm/issues/384)) +* remove unused `OpcodeResolutionError::IncorrectNumFunctionArguments` variant ([#397](https://github.com/noir-lang/acvm/issues/397)) +* **acir:** Remove `Oracle` opcode ([#368](https://github.com/noir-lang/acvm/issues/368)) +* **acir:** Use fixed length data structures in black box function inputs/outputs where possible. ([#386](https://github.com/noir-lang/acvm/issues/386)) +* **acir:** Implement `Add` trait for `Witness` & make output of `Mul` on `Expression` optional ([#393](https://github.com/noir-lang/acvm/issues/393)) + +### Features + +* **acir:** Implement `Add` trait for `Witness` & make output of `Mul` on `Expression` optional ([#393](https://github.com/noir-lang/acvm/issues/393)) ([5bcdfc6](https://github.com/noir-lang/acvm/commit/5bcdfc62e4936922135add171d60a948922581ff)) +* **acir:** Remove `Oracle` opcode ([#368](https://github.com/noir-lang/acvm/issues/368)) ([63354df](https://github.com/noir-lang/acvm/commit/63354df1fe47a4f1128b91641d1b66dfc1281794)) +* **acir:** Use fixed length data structures in black box function inputs/outputs where possible. ([#386](https://github.com/noir-lang/acvm/issues/386)) ([b139d4d](https://github.com/noir-lang/acvm/commit/b139d4d566c715009465a430aab0fb819aacab4f)) +* **acvm:** Derive `Copy` for `Language` ([#406](https://github.com/noir-lang/acvm/issues/406)) ([69a6c22](https://github.com/noir-lang/acvm/commit/69a6c224d80be556ac5388ffeb7a02424df22031)) +* **acvm:** Encapsulate internal state of ACVM within a struct ([#384](https://github.com/noir-lang/acvm/issues/384)) ([84d4867](https://github.com/noir-lang/acvm/commit/84d4867b2d97097d451d59174781555dafd2591f)) +* **acvm:** Replace `PartialWitnessGenerator` trait with `BlackBoxFunctionSolver` ([#378](https://github.com/noir-lang/acvm/issues/378)) ([73fbc95](https://github.com/noir-lang/acvm/commit/73fbc95942b0039565c93719809975f66dc9ec53)) +* **acvm:** replace `PartialWitnessGeneratorStatus` with `ACVMStatus` ([#410](https://github.com/noir-lang/acvm/issues/410)) ([fc3240d](https://github.com/noir-lang/acvm/commit/fc3240d456d0128f6eb42096beb8b7a586ea48da)) +* **brillig:** implemented first blackbox functions ([#401](https://github.com/noir-lang/acvm/issues/401)) ([62d40f7](https://github.com/noir-lang/acvm/commit/62d40f7c03cd1102f615b8d565f82496962db637)) + + +### Bug Fixes + +* **acir:** revert changes to `SchnorrVerify` opcode ([#409](https://github.com/noir-lang/acvm/issues/409)) ([f1c7940](https://github.com/noir-lang/acvm/commit/f1c7940f4ac618c7b440b6ed30199f85cbe72cca)) + + +### Miscellaneous Chores + +* remove unused `OpcodeResolutionError::IncorrectNumFunctionArguments` variant ([#397](https://github.com/noir-lang/acvm/issues/397)) ([d1368d0](https://github.com/noir-lang/acvm/commit/d1368d041eb42d265a4ef385e066b82bc36d0743)) + +## [0.15.1](https://github.com/noir-lang/acvm/compare/root-v0.15.0...root-v0.15.1) (2023-06-20) + + +### Features + +* **brillig:** Allow dynamic-size foreign calls ([#370](https://github.com/noir-lang/acvm/issues/370)) ([5ba0349](https://github.com/noir-lang/acvm/commit/5ba0349420cc1b20113cb5e96490a0808a769757)) + + +### Bug Fixes + +* **brillig:** remove register initialization check ([#392](https://github.com/noir-lang/acvm/issues/392)) ([1a53143](https://github.com/noir-lang/acvm/commit/1a531438b5c1ab7ce8c4bd599dda3515bdd5cfcd)) + +## [0.15.0](https://github.com/noir-lang/acvm/compare/root-v0.14.2...root-v0.15.0) (2023-06-15) + + +### ⚠ BREAKING CHANGES + +* **brillig:** Accept multiple inputs/outputs for foreign calls ([#367](https://github.com/noir-lang/acvm/issues/367)) +* **acvm:** Make internals of ACVM private ([#353](https://github.com/noir-lang/acvm/issues/353)) + +### Features + +* Add method to generate updated `Brillig` opcode from `UnresolvedBrilligCall` ([#363](https://github.com/noir-lang/acvm/issues/363)) ([fda5dbe](https://github.com/noir-lang/acvm/commit/fda5dbe57c28dc4bc28dfd8fe0a4a8ba29635393)) +* **brillig:** Accept multiple inputs/outputs for foreign calls ([#367](https://github.com/noir-lang/acvm/issues/367)) ([78d62b2](https://github.com/noir-lang/acvm/commit/78d62b2d7c1c8b884e1f3fe7983e6e5029700e70)) +* **brillig:** Set `VMStatus` to `Failure` rather than panicking on invalid foreign call response ([#375](https://github.com/noir-lang/acvm/issues/375)) ([c49d82c](https://github.com/noir-lang/acvm/commit/c49d82c99c73c60e264585ed201af2b6a2b7ee0f)) + + +### Bug Fixes + +* **brillig:** Correct signed division implementation ([#356](https://github.com/noir-lang/acvm/issues/356)) ([4eefda0](https://github.com/noir-lang/acvm/commit/4eefda01e7b371035314f77631df4687608b4782)) +* **brillig:** Explicitly wrap on arithmetic operations ([#365](https://github.com/noir-lang/acvm/issues/365)) ([c0544a9](https://github.com/noir-lang/acvm/commit/c0544a99930d3c8d534376c8f8a91645a39aecf8)) + + +### Miscellaneous Chores + +* **acvm:** Make internals of ACVM private ([#353](https://github.com/noir-lang/acvm/issues/353)) ([c902a01](https://github.com/noir-lang/acvm/commit/c902a01639033665d106e2d9f4e5c7070af8c0bb)) + +## [0.14.2](https://github.com/noir-lang/acvm/compare/root-v0.14.1...root-v0.14.2) (2023-06-08) + + +### Bug Fixes + +* **brillig:** expand memory with zeroes on store ([#350](https://github.com/noir-lang/acvm/issues/350)) ([4d2dadd](https://github.com/noir-lang/acvm/commit/4d2dadd3acd9dc25f0feae865b74cbaea7250f3d)) + +## [0.14.1](https://github.com/noir-lang/acvm/compare/root-v0.14.0...root-v0.14.1) (2023-06-07) + + +### Features + +* Re-use intermediate variables created during width reduction, with proper scale. ([#343](https://github.com/noir-lang/acvm/issues/343)) ([6bd0baa](https://github.com/noir-lang/acvm/commit/6bd0baa4bc9ac204e7710ec6d17d1752d2e924c0)) + +## [0.14.0](https://github.com/noir-lang/acvm/compare/root-v0.13.3...root-v0.14.0) (2023-06-06) + + +### ⚠ BREAKING CHANGES + +* **acir:** Verify Proof ([#291](https://github.com/noir-lang/acvm/issues/291)) + +### Features + +* **acir:** Verify Proof ([#291](https://github.com/noir-lang/acvm/issues/291)) ([9f34428](https://github.com/noir-lang/acvm/commit/9f34428b7084c7c38de401a16ca76e748d8b1d77)) + +## [0.13.3](https://github.com/noir-lang/acvm/compare/root-v0.13.2...root-v0.13.3) (2023-06-05) + + +### Bug Fixes + +* Empty commit to trigger release-please ([e8f0748](https://github.com/noir-lang/acvm/commit/e8f0748042ef505d59ab63266d3c36c5358ee30d)) + +## [0.13.2](https://github.com/noir-lang/acvm/compare/root-v0.13.1...root-v0.13.2) (2023-06-02) + + +### Bug Fixes + +* re-use intermediate vars during width reduction ([#278](https://github.com/noir-lang/acvm/issues/278)) ([5b32920](https://github.com/noir-lang/acvm/commit/5b32920263c4481c60faf0b84f0031aa8149b6b2)) + +## [0.13.1](https://github.com/noir-lang/acvm/compare/root-v0.13.0...root-v0.13.1) (2023-06-01) + + +### Bug Fixes + +* **brillig:** Proper error handling for Brillig failures ([#329](https://github.com/noir-lang/acvm/issues/329)) ([cffa110](https://github.com/noir-lang/acvm/commit/cffa110c8df30ee3dd8b635d38b17b1fcd54b03e)) +* **ci:** Add brillig_vm to release-please & link versions ([#332](https://github.com/noir-lang/acvm/issues/332)) ([84bd22e](https://github.com/noir-lang/acvm/commit/84bd22eea46cdfef3a5dbf534b878e819d44f755)) +* **ci:** Correct typo to avoid `undefined` in changelogs ([#333](https://github.com/noir-lang/acvm/issues/333)) ([d3424c0](https://github.com/noir-lang/acvm/commit/d3424c04fd303c9cbe25d03118d8b358cbb84b83)) + +## [0.13.0](https://github.com/noir-lang/acvm/compare/root-v0.12.0...root-v0.13.0) (2023-06-01) + + +### ⚠ BREAKING CHANGES + +* added hash index to pedersen ([#281](https://github.com/noir-lang/acvm/issues/281)) +* Add variable length keccak opcode ([#314](https://github.com/noir-lang/acvm/issues/314)) +* Remove AES opcode ([#302](https://github.com/noir-lang/acvm/issues/302)) +* **acir, acvm:** Remove ComputeMerkleRoot opcode #296 +* Remove manual serialization of `Opcode`s in favour of `serde` ([#286](https://github.com/noir-lang/acvm/issues/286)) +* Remove backend solvable methods from the interface and solve them in ACVM ([#264](https://github.com/noir-lang/acvm/issues/264)) +* Reorganize code related to `PartialWitnessGenerator` ([#287](https://github.com/noir-lang/acvm/issues/287)) + +### Features + +* **acir, acvm:** Remove ComputeMerkleRoot opcode [#296](https://github.com/noir-lang/acvm/issues/296) ([8b3923e](https://github.com/noir-lang/acvm/commit/8b3923e191e4ac399400025496e8bb4453734040)) +* Add `Brillig` opcode to introduce custom non-determinism to ACVM ([#152](https://github.com/noir-lang/acvm/issues/152)) ([3c6740a](https://github.com/noir-lang/acvm/commit/3c6740af75125afc8ebb4379f781f8274015e2e2)) +* Add variable length keccak opcode ([#314](https://github.com/noir-lang/acvm/issues/314)) ([7bfd169](https://github.com/noir-lang/acvm/commit/7bfd1695b6f119cd70fce4866314c9bb4991eaab)) +* added hash index to pedersen ([#281](https://github.com/noir-lang/acvm/issues/281)) ([61820b6](https://github.com/noir-lang/acvm/commit/61820b651900aac8d9557b4b9477ed0e1763c124)) +* Remove backend solvable methods from the interface and solve them in ACVM ([#264](https://github.com/noir-lang/acvm/issues/264)) ([69916cb](https://github.com/noir-lang/acvm/commit/69916cbdd928875b2e8fe4775f2251f71c3f3c92)) + + +### Bug Fixes + +* Allow async functions without send on async trait ([#292](https://github.com/noir-lang/acvm/issues/292)) ([9f9fc21](https://github.com/noir-lang/acvm/commit/9f9fc216a6d09ca97352ffd365bfd347e94ad8eb)) + + +### Miscellaneous Chores + +* Remove AES opcode ([#302](https://github.com/noir-lang/acvm/issues/302)) ([a429a54](https://github.com/noir-lang/acvm/commit/a429a5422d6f001b6db0d0a0f30c79ec0f96de89)) +* Remove manual serialization of `Opcode`s in favour of `serde` ([#286](https://github.com/noir-lang/acvm/issues/286)) ([8a3812f](https://github.com/noir-lang/acvm/commit/8a3812fe6ed3b267692284bdcd909d9dd32b9747)) +* Reorganize code related to `PartialWitnessGenerator` ([#287](https://github.com/noir-lang/acvm/issues/287)) ([b9d61a1](https://github.com/noir-lang/acvm/commit/b9d61a16210d70e350a7e953951362c94f497f89)) + +## [0.12.0](https://github.com/noir-lang/acvm/compare/root-v0.11.0...root-v0.12.0) (2023-05-17) + + +### ⚠ BREAKING CHANGES + +* remove deprecated circuit hash functions ([#288](https://github.com/noir-lang/acvm/issues/288)) +* allow backends to specify support for all opcode variants ([#273](https://github.com/noir-lang/acvm/issues/273)) +* **acvm:** Add CommonReferenceString backend trait ([#231](https://github.com/noir-lang/acvm/issues/231)) +* Introduce WitnessMap data structure to avoid leaking internal structure ([#252](https://github.com/noir-lang/acvm/issues/252)) +* use struct variants for blackbox function calls ([#269](https://github.com/noir-lang/acvm/issues/269)) +* **acvm:** Backend trait must implement Debug ([#275](https://github.com/noir-lang/acvm/issues/275)) +* remove `OpcodeResolutionError::UnexpectedOpcode` ([#274](https://github.com/noir-lang/acvm/issues/274)) +* **acvm:** rename `hash_to_field128_security` to `hash_to_field_128_security` ([#271](https://github.com/noir-lang/acvm/issues/271)) +* **acvm:** update black box solver interfaces to match `pwg:black_box::solve` ([#268](https://github.com/noir-lang/acvm/issues/268)) +* **acvm:** expose separate solvers for AND and XOR opcodes ([#266](https://github.com/noir-lang/acvm/issues/266)) +* **acvm:** Simplification pass for ACIR ([#151](https://github.com/noir-lang/acvm/issues/151)) +* Remove `solve` from PWG trait & introduce separate solvers for each blackbox ([#257](https://github.com/noir-lang/acvm/issues/257)) + +### Features + +* **acvm:** Add CommonReferenceString backend trait ([#231](https://github.com/noir-lang/acvm/issues/231)) ([eeddcf1](https://github.com/noir-lang/acvm/commit/eeddcf179880f246383f7f67a11e589269c4e3ff)) +* **acvm:** Simplification pass for ACIR ([#151](https://github.com/noir-lang/acvm/issues/151)) ([7bc42c6](https://github.com/noir-lang/acvm/commit/7bc42c62b6e095f838b781c87cbb1ecd2af5f179)) +* **acvm:** update black box solver interfaces to match `pwg:black_box::solve` ([#268](https://github.com/noir-lang/acvm/issues/268)) ([0098b7d](https://github.com/noir-lang/acvm/commit/0098b7d9640076d970e6c15d5fd6f368eb1513ff)) +* Introduce WitnessMap data structure to avoid leaking internal structure ([#252](https://github.com/noir-lang/acvm/issues/252)) ([b248e60](https://github.com/noir-lang/acvm/commit/b248e606dd69c25d33ae77c5c5c0541adbf80cd6)) +* Remove `solve` from PWG trait & introduce separate solvers for each blackbox ([#257](https://github.com/noir-lang/acvm/issues/257)) ([3f3dd74](https://github.com/noir-lang/acvm/commit/3f3dd7460b27ab06b55dfc3fe5dd733f08e30a9f)) +* use struct variants for blackbox function calls ([#269](https://github.com/noir-lang/acvm/issues/269)) ([a83333b](https://github.com/noir-lang/acvm/commit/a83333b9e270dfcfd40a36271896840ec0201bc4)) + + +### Bug Fixes + +* **acir:** Hide variants of WitnessMapError and export it from package ([#283](https://github.com/noir-lang/acvm/issues/283)) ([bbd9ab7](https://github.com/noir-lang/acvm/commit/bbd9ab7ca5be3fb31f3e141fee2522704852f5de)) + + +### Miscellaneous Chores + +* **acvm:** Backend trait must implement Debug ([#275](https://github.com/noir-lang/acvm/issues/275)) ([3288b4c](https://github.com/noir-lang/acvm/commit/3288b4c7eb01f5621e577d5ff9e7c92c7757e021)) +* **acvm:** expose separate solvers for AND and XOR opcodes ([#266](https://github.com/noir-lang/acvm/issues/266)) ([84b5d18](https://github.com/noir-lang/acvm/commit/84b5d18d29a111a42bfc1c3d122129c8f062c3db)) +* **acvm:** rename `hash_to_field128_security` to `hash_to_field_128_security` ([#271](https://github.com/noir-lang/acvm/issues/271)) ([fad9af2](https://github.com/noir-lang/acvm/commit/fad9af27fb102fa34bf7511f8ed7b16b3ec2d115)) +* allow backends to specify support for all opcode variants ([#273](https://github.com/noir-lang/acvm/issues/273)) ([efd37fe](https://github.com/noir-lang/acvm/commit/efd37fedcbbabb3fac810e662731439e07fef49a)) +* remove `OpcodeResolutionError::UnexpectedOpcode` ([#274](https://github.com/noir-lang/acvm/issues/274)) ([0e71aac](https://github.com/noir-lang/acvm/commit/0e71aac7aa85b3e9142972a26ba122c2c7c51d9b)) +* remove deprecated circuit hash functions ([#288](https://github.com/noir-lang/acvm/issues/288)) ([1a22c75](https://github.com/noir-lang/acvm/commit/1a22c752de3354a2a6d34892331ab6623b24c0b0)) + +## [0.11.0](https://github.com/noir-lang/acvm/compare/root-v0.10.3...root-v0.11.0) (2023-05-04) + + +### ⚠ BREAKING CHANGES + +* **acvm:** Introduce Error type for fallible Backend traits ([#248](https://github.com/noir-lang/acvm/issues/248)) + +### Features + +* **acvm:** Add generic error for failing to solve an opcode ([#251](https://github.com/noir-lang/acvm/issues/251)) ([bc89528](https://github.com/noir-lang/acvm/commit/bc8952820de610e585d505decfac6e590bbb1a35)) +* **acvm:** Introduce Error type for fallible Backend traits ([#248](https://github.com/noir-lang/acvm/issues/248)) ([45c45f7](https://github.com/noir-lang/acvm/commit/45c45f7cdb79c3ccb0373ca0e698b282d4dabc39)) +* Add Keccak Hash function ([#259](https://github.com/noir-lang/acvm/issues/259)) ([443c734](https://github.com/noir-lang/acvm/commit/443c73482eeef6cc42a1a254bf0d7706698ee353)) + + +### Bug Fixes + +* **acir:** Fix `Expression` multiplication to correctly handle degree 1 terms ([#255](https://github.com/noir-lang/acvm/issues/255)) ([e399396](https://github.com/noir-lang/acvm/commit/e399396f7e06deb6b831517af17018607df3f252)) + +## [0.10.3](https://github.com/noir-lang/acvm/compare/root-v0.10.2...root-v0.10.3) (2023-04-28) + + +### Bug Fixes + +* add default feature flag to ACVM crate ([#245](https://github.com/noir-lang/acvm/issues/245)) ([455fddb](https://github.com/noir-lang/acvm/commit/455fddbc19af81cb01d54e29cad199691e1a1d98)) + +## [0.10.2](https://github.com/noir-lang/acvm/compare/root-v0.10.1...root-v0.10.2) (2023-04-28) + + +### Bug Fixes + +* add default flag to `acvm_stdlib` ([#242](https://github.com/noir-lang/acvm/issues/242)) ([83b6fa8](https://github.com/noir-lang/acvm/commit/83b6fa8302569add7e3ac8481b2fd2a6a1ff3576)) + +## [0.10.1](https://github.com/noir-lang/acvm/compare/root-v0.10.0...root-v0.10.1) (2023-04-28) + + +### Bug Fixes + +* **acir:** add `bn254` as default feature flag ([#240](https://github.com/noir-lang/acvm/issues/240)) ([e56973d](https://github.com/noir-lang/acvm/commit/e56973d8dc1745fe9bb844ec8347acd4d836d42f)) + +## [0.10.0](https://github.com/noir-lang/acvm/compare/root-v0.9.0...root-v0.10.0) (2023-04-26) + + +### ⚠ BREAKING CHANGES + +* return `Result` from `solve_range_opcode` ([#238](https://github.com/noir-lang/acvm/issues/238)) +* **acvm:** have all black box functions return `Result` ([#237](https://github.com/noir-lang/acvm/issues/237)) +* **acvm:** implement `hash_to_field_128_security` ([#230](https://github.com/noir-lang/acvm/issues/230)) +* replace `MerkleMembership` opcode with `ComputeMerkleRoot` ([#233](https://github.com/noir-lang/acvm/issues/233)) +* require `Backend` to implement `Default` trait ([#223](https://github.com/noir-lang/acvm/issues/223)) +* Make GeneralOptimizer crate visible ([#220](https://github.com/noir-lang/acvm/issues/220)) +* return `PartialWitnessGeneratorStatus` from `PartialWitnessGenerator.solve` ([#213](https://github.com/noir-lang/acvm/issues/213)) +* organise operator implementations for Expression ([#190](https://github.com/noir-lang/acvm/issues/190)) + +### Features + +* **acvm:** have all black box functions return `Result<OpcodeResolution, OpcodeResolutionError>` ([#237](https://github.com/noir-lang/acvm/issues/237)) ([e8e93fd](https://github.com/noir-lang/acvm/commit/e8e93fda0db18f0d266dd1aacbb53ec787992dc9)) +* **acvm:** implement `hash_to_field_128_security` ([#230](https://github.com/noir-lang/acvm/issues/230)) ([198fb69](https://github.com/noir-lang/acvm/commit/198fb69e90a5ed3c0a8716d888b4dc6c2f9b18aa)) +* Add range opcode optimization ([#219](https://github.com/noir-lang/acvm/issues/219)) ([7abe6e5](https://github.com/noir-lang/acvm/commit/7abe6e5f6d6fea379c3748a910afd00db066eb45)) +* implement `add_mul` on `Expression` ([#207](https://github.com/noir-lang/acvm/issues/207)) ([f156e18](https://github.com/noir-lang/acvm/commit/f156e18cf7a0f1a99bbe1683b8e75fec8325e6dd)) +* implement `FieldElement::from<bool>()` ([#203](https://github.com/noir-lang/acvm/issues/203)) ([476cfa2](https://github.com/noir-lang/acvm/commit/476cfa247fddb515c64c2801c6868357c9375294)) +* replace `MerkleMembership` opcode with `ComputeMerkleRoot` ([#233](https://github.com/noir-lang/acvm/issues/233)) ([74bfee8](https://github.com/noir-lang/acvm/commit/74bfee80e0ff0d205aee1eea548c97ade8bd0e41)) +* require `Backend` to implement `Default` trait ([#223](https://github.com/noir-lang/acvm/issues/223)) ([00282dc](https://github.com/noir-lang/acvm/commit/00282dc5e2b03947bf709a088d829f3e0ba80eed)) +* return `PartialWitnessGeneratorStatus` from `PartialWitnessGenerator.solve` ([#213](https://github.com/noir-lang/acvm/issues/213)) ([e877bed](https://github.com/noir-lang/acvm/commit/e877bed2cca76bd486e9bed66b4230e65a01f0a2)) +* return `Result<OpcodeResolution, OpcodeResolutionError>` from `solve_range_opcode` ([#238](https://github.com/noir-lang/acvm/issues/238)) ([15d3c5a](https://github.com/noir-lang/acvm/commit/15d3c5a9be2dd92f266fcb7e672da17cada9fec5)) + + +### Bug Fixes + +* prevent `bn254` feature flag always being enabled ([#225](https://github.com/noir-lang/acvm/issues/225)) ([82eee6a](https://github.com/noir-lang/acvm/commit/82eee6ab08ae480f04904ca8571fd88f4466c000)) + + +### Miscellaneous Chores + +* Make GeneralOptimizer crate visible ([#220](https://github.com/noir-lang/acvm/issues/220)) ([64bb346](https://github.com/noir-lang/acvm/commit/64bb346524428a0ce196826ea1e5ccde08ad6201)) +* organise operator implementations for Expression ([#190](https://github.com/noir-lang/acvm/issues/190)) ([a619df6](https://github.com/noir-lang/acvm/commit/a619df614bbb9b2518b788b42a7553b069823a0f)) + +## [0.9.0](https://github.com/noir-lang/acvm/compare/root-v0.8.1...root-v0.9.0) (2023-04-07) + + +### ⚠ BREAKING CHANGES + +* **acvm:** Remove deprecated eth_contract_from_cs from SmartContract trait ([#185](https://github.com/noir-lang/acvm/issues/185)) +* **acvm:** make `Backend` trait object safe ([#180](https://github.com/noir-lang/acvm/issues/180)) + +### Features + +* **acvm:** make `Backend` trait object safe ([#180](https://github.com/noir-lang/acvm/issues/180)) ([fd28657](https://github.com/noir-lang/acvm/commit/fd28657426260ce3c53517b75a27eb5c4a74e234)) + + +### Bug Fixes + +* Add test for Out of Memory ([#188](https://github.com/noir-lang/acvm/issues/188)) ([c3db985](https://github.com/noir-lang/acvm/commit/c3db985893e7e59ea04005bb3a57eda5c6ce28c7)) + + +### Miscellaneous Chores + +* **acvm:** Remove deprecated eth_contract_from_cs from SmartContract trait ([#185](https://github.com/noir-lang/acvm/issues/185)) ([ee59c9e](https://github.com/noir-lang/acvm/commit/ee59c9efe9a54ff6b97e4daaebf64f3e327e97d9)) + +## [0.8.1](https://github.com/noir-lang/acvm/compare/root-v0.8.0...root-v0.8.1) (2023-03-30) + + +### Bug Fixes + +* unwraps if inputs is zero ([#171](https://github.com/noir-lang/acvm/issues/171)) ([10a3bb2](https://github.com/noir-lang/acvm/commit/10a3bb2a9930ccf422b3f08227aae07775686860)) + +## [0.8.0](https://github.com/noir-lang/acvm/compare/root-v0.7.1...root-v0.8.0) (2023-03-28) + + +### ⚠ BREAKING CHANGES + +* **acir:** Read Log Directive ([#156](https://github.com/noir-lang/acvm/issues/156)) + +### Bug Fixes + +* **acir:** Read Log Directive ([#156](https://github.com/noir-lang/acvm/issues/156)) ([1cc2b7f](https://github.com/noir-lang/acvm/commit/1cc2b7f2179cecc338fe0def72bb2dd17eaed0cd)) + +## [0.7.1](https://github.com/noir-lang/acvm/compare/root-v0.7.0...root-v0.7.1) (2023-03-27) + + +### Bug Fixes + +* **pwg:** stall instead of fail for unassigned black box ([#154](https://github.com/noir-lang/acvm/issues/154)) ([412a1a6](https://github.com/noir-lang/acvm/commit/412a1a60b434bef53e12d37c3b2bb3d51a317994)) + +## [0.7.0](https://github.com/noir-lang/acvm/compare/root-v0.6.0...root-v0.7.0) (2023-03-23) + + +### ⚠ BREAKING CHANGES + +* Add initial oracle opcode ([#149](https://github.com/noir-lang/acvm/issues/149)) +* **acir:** Add RAM and ROM opcodes +* **acir:** Add a public outputs field ([#56](https://github.com/noir-lang/acvm/issues/56)) +* **acir:** remove `Linear` struct ([#145](https://github.com/noir-lang/acvm/issues/145)) +* **acvm:** remove `prove_with_meta` and `verify_from_cs` from `ProofSystemCompiler` ([#140](https://github.com/noir-lang/acvm/issues/140)) +* **acvm:** Remove truncate and oddrange directives ([#142](https://github.com/noir-lang/acvm/issues/142)) + +### Features + +* **acir:** Add a public outputs field ([#56](https://github.com/noir-lang/acvm/issues/56)) ([5f358a9](https://github.com/noir-lang/acvm/commit/5f358a97aaa81d87956e182cd8a6d60de75f9752)) +* **acir:** Add RAM and ROM opcodes ([73e9f25](https://github.com/noir-lang/acvm/commit/73e9f25dd87b2ca91245e93d2445eadc0f522fac)) +* Add initial oracle opcode ([#149](https://github.com/noir-lang/acvm/issues/149)) ([88ee2f8](https://github.com/noir-lang/acvm/commit/88ee2f89f37abf5dd1d9f91b4d2eed44dc651348)) + + +### Miscellaneous Chores + +* **acir:** remove `Linear` struct ([#145](https://github.com/noir-lang/acvm/issues/145)) ([bbb6d92](https://github.com/noir-lang/acvm/commit/bbb6d92e25c43dd33b12f5fcd639fc9ad2a9c9d8)) +* **acvm:** remove `prove_with_meta` and `verify_from_cs` from `ProofSystemCompiler` ([#140](https://github.com/noir-lang/acvm/issues/140)) ([35dd181](https://github.com/noir-lang/acvm/commit/35dd181102203df17eef510666b327ef41f4b036)) +* **acvm:** Remove truncate and oddrange directives ([#142](https://github.com/noir-lang/acvm/issues/142)) ([85dd6e8](https://github.com/noir-lang/acvm/commit/85dd6e85bfba85bfb97651f7e30e1f75deb986d5)) + +## [0.6.0](https://github.com/noir-lang/acvm/compare/root-v0.5.0...root-v0.6.0) (2023-03-03) + + +### ⚠ BREAKING CHANGES + +* **acir:** rename `term_addition` to `push_addition_term` +* **acir:** rename `term_multiplication` to `push_multiplication_term` ([#122](https://github.com/noir-lang/acvm/issues/122)) +* **acir:** remove `UnknownWitness` ([#123](https://github.com/noir-lang/acvm/issues/123)) +* add block opcode ([#114](https://github.com/noir-lang/acvm/issues/114)) + +### Features + +* **acir:** add useful methods from `noirc_evaluator` onto `Expression` ([#125](https://github.com/noir-lang/acvm/issues/125)) ([d3d5f89](https://github.com/noir-lang/acvm/commit/d3d5f8917482ce5649602695829862a5df4ea712)) +* add block opcode ([#114](https://github.com/noir-lang/acvm/issues/114)) ([097cfb0](https://github.com/noir-lang/acvm/commit/097cfb069291705ddb4bf1fca77ddcef21dbbd08)) + + +### Bug Fixes + +* **acir:** correctly display expressions with non-unit coefficients ([d3d5f89](https://github.com/noir-lang/acvm/commit/d3d5f8917482ce5649602695829862a5df4ea712)) +* **ci:** publish acvm_stdlib before acvm ([#117](https://github.com/noir-lang/acvm/issues/117)) ([ca6defc](https://github.com/noir-lang/acvm/commit/ca6defc9bb5f51241b2fc4d9cd732f9678b4688f)) + + +### Miscellaneous Chores + +* **acir:** remove `UnknownWitness` ([#123](https://github.com/noir-lang/acvm/issues/123)) ([9f002c7](https://github.com/noir-lang/acvm/commit/9f002c7b49a5cf222d4a01732cc4917a47690863)) +* **acir:** rename `term_addition` to `push_addition_term` ([d389385](https://github.com/noir-lang/acvm/commit/d38938542851a97dc01727438391e6a65e44c689)) +* **acir:** rename `term_multiplication` to `push_multiplication_term` ([#122](https://github.com/noir-lang/acvm/issues/122)) ([d389385](https://github.com/noir-lang/acvm/commit/d38938542851a97dc01727438391e6a65e44c689)) + +## [0.5.0](https://github.com/noir-lang/acvm/compare/root-v0.4.1...root-v0.5.0) (2023-02-22) + + +### ⚠ BREAKING CHANGES + +* **acvm:** switch to accepting public inputs as a map ([#96](https://github.com/noir-lang/acvm/issues/96)) +* **acvm:** add `eth_contract_from_vk` to `SmartContract +* update `ProofSystemCompiler` to not take ownership of keys ([#111](https://github.com/noir-lang/acvm/issues/111)) +* update `ProofSystemCompiler` methods to take `&Circuit` ([#108](https://github.com/noir-lang/acvm/issues/108)) +* **acir:** make PublicInputs use a BTreeSet rather than Vec ([#99](https://github.com/noir-lang/acvm/issues/99)) +* refactor ToRadix to ToRadixLe and ToRadixBe ([#58](https://github.com/noir-lang/acvm/issues/58)) +* **acir:** Add keccak256 Opcode ([#91](https://github.com/noir-lang/acvm/issues/91)) +* reorganise compiler in terms of optimisers and transformers ([#88](https://github.com/noir-lang/acvm/issues/88)) + +### Features + +* **acir:** Add keccak256 Opcode ([#91](https://github.com/noir-lang/acvm/issues/91)) ([b909146](https://github.com/noir-lang/acvm/commit/b9091461e199bacdd073cc9b31f03dade0b4fb2d)) +* **acir:** make PublicInputs use a BTreeSet rather than Vec ([#99](https://github.com/noir-lang/acvm/issues/99)) ([53666b7](https://github.com/noir-lang/acvm/commit/53666b782d89c65cd755f9e4ded2c9cf5a141e46)) +* **acvm:** add `eth_contract_from_vk` to `SmartContract ([#113](https://github.com/noir-lang/acvm/issues/113)) ([373c18f](https://github.com/noir-lang/acvm/commit/373c18fc05edf673cfec9e8bbb78bd7d7514999e)) +* **acvm:** switch to accepting public inputs as a map ([#96](https://github.com/noir-lang/acvm/issues/96)) ([f57ba57](https://github.com/noir-lang/acvm/commit/f57ba57c2bb2597edf2b02fb1321c69cf11993ee)) +* **ci:** Add release workflow ([#89](https://github.com/noir-lang/acvm/issues/89)) ([db8e828](https://github.com/noir-lang/acvm/commit/db8e828341f59241ef7f437c908277fb8fbca9e3)) +* **ci:** Publish crates upon release ([#104](https://github.com/noir-lang/acvm/issues/104)) ([b265920](https://github.com/noir-lang/acvm/commit/b265920bc1b0c776d20326a0b74fc635c22af4b9)) +* update `ProofSystemCompiler` methods to take `&Circuit` ([#108](https://github.com/noir-lang/acvm/issues/108)) ([af56ca9](https://github.com/noir-lang/acvm/commit/af56ca9da06068c650c66e76bfd09e65eb0ec213)) +* update `ProofSystemCompiler` to not take ownership of keys ([#111](https://github.com/noir-lang/acvm/issues/111)) ([39b8a41](https://github.com/noir-lang/acvm/commit/39b8a41293e567971f700f61103852cb987a8d16)) +* Update Arkworks' dependencies on `acir_field` ([#69](https://github.com/noir-lang/acvm/issues/69)) ([65d6130](https://github.com/noir-lang/acvm/commit/65d61307a12f25e04afad2d50e4c4db5ce97dd8c)) + + +### Bug Fixes + +* **ci:** Update dependency versions in the workspace file ([#103](https://github.com/noir-lang/acvm/issues/103)) ([9acc266](https://github.com/noir-lang/acvm/commit/9acc266c7dc5a6ad2fa9c466cc82cb81d984b7ed)) +* Clean up Log Directive hex output ([#97](https://github.com/noir-lang/acvm/issues/97)) ([d23c735](https://github.com/noir-lang/acvm/commit/d23c7352523ffb42f3e8f4229b61f9803ab78a7e)) + + +### Miscellaneous Chores + +* refactor ToRadix to ToRadixLe and ToRadixBe ([#58](https://github.com/noir-lang/acvm/issues/58)) ([2427a27](https://github.com/noir-lang/acvm/commit/2427a275048e598c6d651cce8348a4c55148f235)) +* reorganise compiler in terms of optimisers and transformers ([#88](https://github.com/noir-lang/acvm/issues/88)) ([9329307](https://github.com/noir-lang/acvm/commit/9329307e054de202cfc55207162ad952b70d515e)) + +## [0.4.1] - 2023-02-08 + +### Added + +### Fixed + +- Removed duplicated logic in match branch + +### Changed + +### Removed + +## [0.4.0] - 2023-02-08 + +### Added + +- Add log directive +- Expose `acir_field` through `acir` crate +- Add permutation directive +- Add preprocess methods to ACVM interface + +### Fixed + +### Changed + +- Changed spellings of many functions to be correct using spellchecker + +### Removed + +## [0.3.1] - 2023-01-18 + +### Added + +### Fixed + +### Changed + +- ACVM compile method now returns an Error for when a function cannot be reduced to arithmetic gates + +- Backtrack changes from noir-lang/noir/587 + +### Removed + +## [0.3.0] - 2022-12-31 + +### Added + +- Added stdlib module to hold all of the standard opcodes +- added `read` , `write` methods for circuit + +### Fixed + +### Changed + +- XOR, Range and AND gates are no longer special case. They are now another opcode in the GadgetCall +- Move fallback module to `stdlib` +- Optimizer code and any other passes will live in acvm. acir is solely for defining the IR now. +- ACIR passes now live under the compiler parent module +- Moved opcode module in acir crate to circuit/opcode +- Rename GadgetCall to BlackBoxFuncCall +- Rename opcode file to blackbox_functions . Similarly OPCODE is now BlackBoxFunc +- Renamed GateResolution::UnsupportedOpcode to GateResolution::UnsupportedBlackBoxFunc +- Renamed GadgetDefinition to FuncDefinition +- Rename GadgetInput to FunctionInput +- Rename Gate -> Opcode . Similarly gate.rs is now opcodes.rs +- Rename CustomGate::supports_gate -> CustomGate::supports_opcode +- Rename GateResolution to OpcodeResolution +- Rename Split directive to ToBits +- Field element printing function was modified to uses ascii superscript numbers and ascii multiplication +- Refactor the way we print ACIR (This is a first draft and will change with more feedback) +- Rename `solve_gadget_call` trait method on ProofSystemCompile to `solve_blackbox_function_call` +- API for `compile` now requires a function pointer which tells us whether a blackbox function is supported +- Renamed Directive::Oddrange to Directive::OddRange +- Renamed FieldElement::to_bytes to FieldElement::to_be_bytes + +### Removed + +- Selector struct has been removed as it is no longer being used. It is also not being used by Noir. +- CustomGate trait -- There is a method in the ProofSystemCompiler Trait that backends can use to indicate whether +they support a particular black box function +- Remove OpcodeResolution enum from pwg. The happy case is strictly when the witness has been solved + +## [0.2.1] - 2022-12-23 + +- Removed ToBits and ToBytes opcode diff --git a/acvm-repo/Cargo.lock b/acvm-repo/Cargo.lock new file mode 100644 index 00000000000..72cd8eced47 --- /dev/null +++ b/acvm-repo/Cargo.lock @@ -0,0 +1,3215 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "acir" +version = "0.27.0" +dependencies = [ + "acir_field", + "bincode", + "brillig", + "flate2", + "rmp-serde", + "serde", + "serde_json", + "strum", + "strum_macros", + "thiserror", +] + +[[package]] +name = "acir_field" +version = "0.27.0" +dependencies = [ + "ark-bls12-381", + "ark-bn254", + "ark-ff", + "cfg-if", + "hex", + "num-bigint", + "serde", +] + +[[package]] +name = "acvm" +version = "0.27.0" +dependencies = [ + "acir", + "acvm_blackbox_solver", + "acvm_stdlib", + "brillig_vm", + "indexmap", + "num-bigint", + "num-traits", + "paste", + "proptest", + "rand", + "thiserror", +] + +[[package]] +name = "acvm_blackbox_solver" +version = "0.27.0" +dependencies = [ + "acir", + "blake2", + "k256", + "p256", + "sha2", + "sha3", + "thiserror", +] + +[[package]] +name = "acvm_js" +version = "0.27.0" +dependencies = [ + "acvm", + "barretenberg_blackbox_solver", + "build-data", + "cfg-if", + "console_error_panic_hook", + "const-str", + "gloo-utils", + "js-sys", + "log", + "pkg-config", + "serde", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "wasm-logger", +] + +[[package]] +name = "acvm_stdlib" +version = "0.27.0" +dependencies = [ + "acir", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli 0.28.0", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2135563fb5c609d2b2b87c1e8ce7bc41b0b45430fa9661f457981503dd5bf0" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "barretenberg_blackbox_solver" +version = "0.27.0" +dependencies = [ + "acir", + "acvm_blackbox_solver", + "flate2", + "getrandom", + "hex", + "js-sys", + "num-bigint", + "pkg-config", + "reqwest", + "rust-embed", + "tar", + "thiserror", + "wasm-bindgen-futures", + "wasmer", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brillig" +version = "0.27.0" +dependencies = [ + "acir_field", + "serde", +] + +[[package]] +name = "brillig_vm" +version = "0.27.0" +dependencies = [ + "acir", + "acvm_blackbox_solver", + "num-bigint", + "num-traits", +] + +[[package]] +name = "bstr" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "build-data" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac83c47416b2db78a5a8a45d7d229a730b62806fa41ac6b4dbde6d016798776" +dependencies = [ + "chrono", + "safe-lock", + "safe-regex", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytecheck" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "const-str" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6" + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "corosensei" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "scopeguard", + "windows-sys 0.33.0", +] + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" +dependencies = [ + "arrayvec", + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-egraph", + "cranelift-entity", + "cranelift-isle", + "gimli 0.26.2", + "log", + "regalloc2", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] + +[[package]] +name = "cranelift-entity" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" + +[[package]] +name = "cranelift-frontend" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.9.0", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.0", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-iterator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "enumset" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "errno" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "filetime" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "windows-sys 0.48.0", +] + +[[package]] +name = "flate2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "globset" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" + +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + +[[package]] +name = "linux-raw-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "more-asserts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa", + "elliptic-curve", + "sha2", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.3.5", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" +dependencies = [ + "bit-set", + "bitflags 1.3.2", + "byteorder", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax 0.6.29", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "regalloc2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" +dependencies = [ + "fxhash", + "log", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "regex" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-automata" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "region" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" +dependencies = [ + "bitflags 1.3.2", + "libc", + "mach", + "winapi", +] + +[[package]] +name = "rend" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.11.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rkyv" +version = "0.7.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" +dependencies = [ + "bitvec", + "bytecheck", + "hashbrown 0.12.3", + "indexmap", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rmp" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "rust-embed" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "shellexpand", + "syn 2.0.32", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "7.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" +dependencies = [ + "globset", + "sha2", + "walkdir", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "safe-lock" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "077d73db7973cccf63eb4aff1e5a34dc2459baa867512088269ea5f2f4253c90" + +[[package]] +name = "safe-proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "814c536dcd27acf03296c618dab7ad62d28e70abd7ba41d3f34a2ce707a2c666" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "safe-quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e530f7831f3feafcd5f1aae406ac205dd998436b4007c8e80f03eca78a88f7" +dependencies = [ + "safe-proc-macro2", +] + +[[package]] +name = "safe-regex" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15289bf322e0673d52756a18194167f2378ec1a15fe884af6e2d2cb934822b0" +dependencies = [ + "safe-regex-macro", +] + +[[package]] +name = "safe-regex-compiler" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba76fae590a2aa665279deb1f57b5098cbace01a0c5e60e262fcf55f7c51542" +dependencies = [ + "safe-proc-macro2", + "safe-quote", +] + +[[package]] +name = "safe-regex-macro" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c2e96b5c03f158d1b16ba79af515137795f4ad4e8de3f790518aae91f1d127" +dependencies = [ + "safe-proc-macro2", + "safe-regex-compiler", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "serde_json" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shellexpand" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" +dependencies = [ + "dirs", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tar" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" + +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "thiserror" +version = "1.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.4", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "serde", + "serde_json", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.32", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "wasm-encoder" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba64e81215916eaeb48fee292f29401d69235d62d8b8fd92a7b2844ec5ae5f7" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-logger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074649a66bb306c8f2068c9016395fa65d8e08d2affcbf95acf3c24c3ab19718" +dependencies = [ + "log", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasmer" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78caedecd8cb71ed47ccca03b68d69414a3d278bb031e6f93f15759344efdd52" +dependencies = [ + "bytes", + "cfg-if", + "derivative", + "indexmap", + "js-sys", + "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", + "target-lexicon", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-downcast", + "wasmer-compiler", + "wasmer-compiler-cranelift", + "wasmer-derive", + "wasmer-types", + "wasmer-vm", + "wasmparser 0.83.0", + "wasmparser 0.95.0", + "wat", + "winapi", +] + +[[package]] +name = "wasmer-compiler" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "726a8450541af4a57c34af7b6973fdbfc79f896cc7e733429577dfd1d1687180" +dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", + "enumset", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", + "smallvec", + "thiserror", + "wasmer-types", + "wasmer-vm", + "wasmparser 0.95.0", + "winapi", +] + +[[package]] +name = "wasmer-compiler-cranelift" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e5633f90f372563ebbdf3f9799c7b29ba11c90e56cf9b54017112d2e656c95" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "gimli 0.26.2", + "more-asserts", + "rayon", + "smallvec", + "target-lexicon", + "tracing", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-derive" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97901fdbaae383dbb90ea162cc3a76a9fa58ac39aec7948b4c0b9bbef9307738" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "wasmer-types" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67f1f2839f4f61509550e4ddcd0e658e19f3af862b51c79fda15549d735d659b" +dependencies = [ + "bytecheck", + "enum-iterator", + "enumset", + "indexmap", + "more-asserts", + "rkyv", + "target-lexicon", + "thiserror", +] + +[[package]] +name = "wasmer-vm" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043118ec4f16d1714fed3aab758b502b864bd865e1d5188626c9ad290100563f" +dependencies = [ + "backtrace", + "cc", + "cfg-if", + "corosensei", + "dashmap", + "derivative", + "enum-iterator", + "fnv", + "indexmap", + "lazy_static", + "libc", + "mach", + "memoffset 0.8.0", + "more-asserts", + "region", + "scopeguard", + "thiserror", + "wasmer-types", + "winapi", +] + +[[package]] +name = "wasmparser" +version = "0.83.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" + +[[package]] +name = "wasmparser" +version = "0.95.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" +dependencies = [ + "indexmap", + "url", +] + +[[package]] +name = "wast" +version = "64.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a259b226fd6910225aa7baeba82f9d9933b6d00f2ce1b49b80fa4214328237cc" +dependencies = [ + "leb128", + "memchr", + "unicode-width", + "wasm-encoder", +] + +[[package]] +name = "wat" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53253d920ab413fca1c7dc2161d601c79b4fdf631d0ba51dd4343bf9b556c3f6" +dependencies = [ + "wast", +] + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" +dependencies = [ + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "xattr" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" +dependencies = [ + "libc", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] diff --git a/acvm-repo/Cargo.toml b/acvm-repo/Cargo.toml new file mode 100644 index 00000000000..344d8be1504 --- /dev/null +++ b/acvm-repo/Cargo.toml @@ -0,0 +1,36 @@ +[workspace] + +members = ["acir_field", "acir", "acvm", "acvm_js", "stdlib", "brillig", "brillig_vm", "blackbox_solver", "barretenberg_blackbox_solver"] +resolver = "2" + +[workspace.package] +authors = ["The Noir Team "] +edition = "2021" +license = "MIT" +rust-version = "1.66" +repository = "https://github.com/noir-lang/acvm/" + +[workspace.dependencies] +acir = { version = "0.27.0", path = "acir", default-features = false } +acir_field = { version = "0.27.0", path = "acir_field", default-features = false } +stdlib = { package = "acvm_stdlib", version = "0.27.0", path = "stdlib", default-features = false } +brillig = { version = "0.27.0", path = "brillig", default-features = false } +brillig_vm = { version = "0.27.0", path = "brillig_vm", default-features = false } +acvm_blackbox_solver = { version = "0.27.0", path = "blackbox_solver", default-features = false } +barretenberg_blackbox_solver = { version = "0.26.1", path = "barretenberg_blackbox_solver", default-features = false } + +bincode = "1.3.3" + +hex = "0.4.2" +num-bigint = "0.4" +num-traits = "0.2" + +thiserror = "1.0.21" + + +serde = { version = "1.0.136", features = ["derive"] } + +[profile.dev] +# This is required to be able to run `cargo test` in acvm_js due to the `locals exceeds maximum` error. +# See https://ritik-mishra.medium.com/resolving-the-wasm-pack-error-locals-exceed-maximum-ec3a9d96685b +opt-level = 1 diff --git a/acvm-repo/LICENSE-APACHE b/acvm-repo/LICENSE-APACHE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/acvm-repo/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/acvm-repo/LICENSE-MIT b/acvm-repo/LICENSE-MIT new file mode 100644 index 00000000000..61cc2f7f5e6 --- /dev/null +++ b/acvm-repo/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + + Copyright (c) 2023 noir-lang + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. \ No newline at end of file diff --git a/acvm-repo/README.md b/acvm-repo/README.md new file mode 100644 index 00000000000..96353252f27 --- /dev/null +++ b/acvm-repo/README.md @@ -0,0 +1,20 @@ +# ACIR - Abstract Circuit Intermediate Representation + +ACIR is an NP complete language that generalizes R1CS and arithmetic circuits while not losing proving system specific optimizations through the use of black box functions. + +# ACVM - Abstract Circuit Virtual Machine + +This can be seen as the ACIR compiler. It will take an ACIR instance and convert it to the format required +by a particular proving system to create a proof. + +# How to add a new crate to the workspace + +- Create the new crate with the current version of the other crates. +- In root `Cargo.toml`, add the new crate to the workspace members list. +- If you want to import it from multiple packages, you can add it as a dependency in the root `Cargo.toml`. +- In `release-please-config.json`: + - Add a package entry + - Add the crate name to the `linked-versions` plugin list + - If you added the new crate as a dependency in the root `Cargo.toml`, add it to the extra-files of the root package. +- In `.release-please-manifest.json`, add the new crate with the same version of the others. +- In [publish.yml](.github/workflows/publish.yml), add the new crate to the `publish` job after its dependencies. diff --git a/acvm-repo/acir/CHANGELOG.md b/acvm-repo/acir/CHANGELOG.md new file mode 100644 index 00000000000..e31ee66379a --- /dev/null +++ b/acvm-repo/acir/CHANGELOG.md @@ -0,0 +1,521 @@ +# Changelog + +## [0.27.0](https://github.com/noir-lang/acvm/compare/acir-v0.26.1...acir-v0.27.0) (2023-09-19) + + +### Features + +* **acir:** add method on `Circuit` to return assert message ([#551](https://github.com/noir-lang/acvm/issues/551)) ([ee18cde](https://github.com/noir-lang/acvm/commit/ee18cde3537b2be6714061af0bc9ef3793929f7f)) + +## [0.26.1](https://github.com/noir-lang/acvm/compare/acir-v0.26.0...acir-v0.26.1) (2023-09-12) + + +### Bug Fixes + +* Implements handling of the high limb during fixed base scalar multiplication ([#535](https://github.com/noir-lang/acvm/issues/535)) ([551504a](https://github.com/noir-lang/acvm/commit/551504aa572d3f9d56b5576d25ce1211296ee488)) + +## [0.26.0](https://github.com/noir-lang/acvm/compare/acir-v0.25.0...acir-v0.26.0) (2023-09-07) + + +### ⚠ BREAKING CHANGES + +* Add a low and high limb to scalar mul opcode ([#532](https://github.com/noir-lang/acvm/issues/532)) + +### Miscellaneous Chores + +* Add a low and high limb to scalar mul opcode ([#532](https://github.com/noir-lang/acvm/issues/532)) ([b054f66](https://github.com/noir-lang/acvm/commit/b054f66be9c73d4e02dbecdab80874a907f19242)) + +## [0.25.0](https://github.com/noir-lang/acvm/compare/acir-v0.24.1...acir-v0.25.0) (2023-09-04) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.24.1](https://github.com/noir-lang/acvm/compare/acir-v0.24.0...acir-v0.24.1) (2023-09-03) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.24.0](https://github.com/noir-lang/acvm/compare/acir-v0.23.0...acir-v0.24.0) (2023-08-31) + + +### ⚠ BREAKING CHANGES + +* **acir:** Remove unused `Directive` opcodes ([#510](https://github.com/noir-lang/acvm/issues/510)) +* **acir:** Add predicate to MemoryOp ([#503](https://github.com/noir-lang/acvm/issues/503)) +* Assertion messages embedded in the circuit ([#484](https://github.com/noir-lang/acvm/issues/484)) + +### Features + +* **acir:** Add predicate to MemoryOp ([#503](https://github.com/noir-lang/acvm/issues/503)) ([ca9eebe](https://github.com/noir-lang/acvm/commit/ca9eebe34e61adabf97318c8ccaf60c8a424aafd)) +* Assertion messages embedded in the circuit ([#484](https://github.com/noir-lang/acvm/issues/484)) ([06b97c5](https://github.com/noir-lang/acvm/commit/06b97c51041e16651cf8b2be8bc18214e276c6c9)) + + +### Miscellaneous Chores + +* **acir:** Remove unused `Directive` opcodes ([#510](https://github.com/noir-lang/acvm/issues/510)) ([cfd8cbf](https://github.com/noir-lang/acvm/commit/cfd8cbf58307511ac0cc9106c299695c2ca779de)) + +## [0.23.0](https://github.com/noir-lang/acvm/compare/acir-v0.22.0...acir-v0.23.0) (2023-08-30) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.22.0](https://github.com/noir-lang/acvm/compare/acir-v0.21.0...acir-v0.22.0) (2023-08-18) + + +### ⚠ BREAKING CHANGES + +* Switched from OpcodeLabel to OpcodeLocation and ErrorLocation ([#493](https://github.com/noir-lang/acvm/issues/493)) + +### Features + +* Switched from OpcodeLabel to OpcodeLocation and ErrorLocation ([#493](https://github.com/noir-lang/acvm/issues/493)) ([27a5a93](https://github.com/noir-lang/acvm/commit/27a5a935849f8904e10056b08089f532a06962b8)) + +## [0.21.0](https://github.com/noir-lang/acvm/compare/acir-v0.20.1...acir-v0.21.0) (2023-07-26) + + +### ⚠ BREAKING CHANGES + +* **acir:** Remove `Block`, `RAM` and `ROM` opcodes ([#457](https://github.com/noir-lang/acvm/issues/457)) +* **acvm:** Support stepwise execution of ACIR ([#399](https://github.com/noir-lang/acvm/issues/399)) + +### Features + +* **acvm:** Support stepwise execution of ACIR ([#399](https://github.com/noir-lang/acvm/issues/399)) ([6a03950](https://github.com/noir-lang/acvm/commit/6a0395021779a2711353c2fe2948e09b5b538fc0)) + + +### Miscellaneous Chores + +* **acir:** Remove `Block`, `RAM` and `ROM` opcodes ([#457](https://github.com/noir-lang/acvm/issues/457)) ([8dd220a](https://github.com/noir-lang/acvm/commit/8dd220ae127baf6cc5a31d8ab7ffdeeb161f6109)) + +## [0.20.1](https://github.com/noir-lang/acvm/compare/acir-v0.20.0...acir-v0.20.1) (2023-07-26) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.20.0](https://github.com/noir-lang/acvm/compare/acir-v0.19.1...acir-v0.20.0) (2023-07-20) + + +### ⚠ BREAKING CHANGES + +* atomic memory opcodes ([#447](https://github.com/noir-lang/acvm/issues/447)) + +### Features + +* atomic memory opcodes ([#447](https://github.com/noir-lang/acvm/issues/447)) ([3261c7a](https://github.com/noir-lang/acvm/commit/3261c7a2fd4f3a300bc5f39ef4febccd8a853560)) + +## [0.19.1](https://github.com/noir-lang/acvm/compare/acir-v0.19.0...acir-v0.19.1) (2023-07-17) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.19.0](https://github.com/noir-lang/acvm/compare/acir-v0.18.2...acir-v0.19.0) (2023-07-15) + + +### ⚠ BREAKING CHANGES + +* move to bincode and GzEncoding for artifacts ([#436](https://github.com/noir-lang/acvm/issues/436)) + +### Features + +* move to bincode and GzEncoding for artifacts ([#436](https://github.com/noir-lang/acvm/issues/436)) ([4683240](https://github.com/noir-lang/acvm/commit/46832400a8bc20135a8a895ab9477b14449734d9)) + +## [0.18.2](https://github.com/noir-lang/acvm/compare/acir-v0.18.1...acir-v0.18.2) (2023-07-12) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.18.1](https://github.com/noir-lang/acvm/compare/acir-v0.18.0...acir-v0.18.1) (2023-07-12) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.18.0](https://github.com/noir-lang/acvm/compare/acir-v0.17.0...acir-v0.18.0) (2023-07-12) + + +### ⚠ BREAKING CHANGES + +* add backend-solvable blackboxes to brillig & unify implementations ([#422](https://github.com/noir-lang/acvm/issues/422)) +* Returns index of failing opcode and transformation mapping ([#412](https://github.com/noir-lang/acvm/issues/412)) + +### Features + +* add backend-solvable blackboxes to brillig & unify implementations ([#422](https://github.com/noir-lang/acvm/issues/422)) ([093342e](https://github.com/noir-lang/acvm/commit/093342ea9481a311fa71343b8b7a22774788838a)) +* Returns index of failing opcode and transformation mapping ([#412](https://github.com/noir-lang/acvm/issues/412)) ([79950e9](https://github.com/noir-lang/acvm/commit/79950e943f60e4082e1cf5ec4442aa67ea91aade)) + +## [0.17.0](https://github.com/noir-lang/acvm/compare/acir-v0.16.0...acir-v0.17.0) (2023-07-07) + + +### ⚠ BREAKING CHANGES + +* **acir:** add `EcdsaSecp256r1` blackbox function ([#408](https://github.com/noir-lang/acvm/issues/408)) + +### Features + +* **acir:** add `EcdsaSecp256r1` blackbox function ([#408](https://github.com/noir-lang/acvm/issues/408)) ([9895817](https://github.com/noir-lang/acvm/commit/98958170c9fa9b4731e33b31cb494a72bb90549e)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.16.0 to 0.17.0 + +## [0.16.0](https://github.com/noir-lang/acvm/compare/acir-v0.15.1...acir-v0.16.0) (2023-07-06) + + +### ⚠ BREAKING CHANGES + +* **acir:** revert changes to `SchnorrVerify` opcode ([#409](https://github.com/noir-lang/acvm/issues/409)) +* **acir:** Remove `Oracle` opcode ([#368](https://github.com/noir-lang/acvm/issues/368)) +* **acir:** Use fixed length data structures in black box function inputs/outputs where possible. ([#386](https://github.com/noir-lang/acvm/issues/386)) +* **acir:** Implement `Add` trait for `Witness` & make output of `Mul` on `Expression` optional ([#393](https://github.com/noir-lang/acvm/issues/393)) + +### Features + +* **acir:** Implement `Add` trait for `Witness` & make output of `Mul` on `Expression` optional ([#393](https://github.com/noir-lang/acvm/issues/393)) ([5bcdfc6](https://github.com/noir-lang/acvm/commit/5bcdfc62e4936922135add171d60a948922581ff)) +* **acir:** Remove `Oracle` opcode ([#368](https://github.com/noir-lang/acvm/issues/368)) ([63354df](https://github.com/noir-lang/acvm/commit/63354df1fe47a4f1128b91641d1b66dfc1281794)) +* **acir:** Use fixed length data structures in black box function inputs/outputs where possible. ([#386](https://github.com/noir-lang/acvm/issues/386)) ([b139d4d](https://github.com/noir-lang/acvm/commit/b139d4d566c715009465a430aab0fb819aacab4f)) + + +### Bug Fixes + +* **acir:** revert changes to `SchnorrVerify` opcode ([#409](https://github.com/noir-lang/acvm/issues/409)) ([f1c7940](https://github.com/noir-lang/acvm/commit/f1c7940f4ac618c7b440b6ed30199f85cbe72cca)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.15.1 to 0.16.0 + +## [0.15.1](https://github.com/noir-lang/acvm/compare/acir-v0.15.0...acir-v0.15.1) (2023-06-20) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.15.0 to 0.15.1 + +## [0.15.0](https://github.com/noir-lang/acvm/compare/acir-v0.14.2...acir-v0.15.0) (2023-06-15) + + +### Features + +* Add method to generate updated `Brillig` opcode from `UnresolvedBrilligCall` ([#363](https://github.com/noir-lang/acvm/issues/363)) ([fda5dbe](https://github.com/noir-lang/acvm/commit/fda5dbe57c28dc4bc28dfd8fe0a4a8ba29635393)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.14.2 to 0.15.0 + +## [0.14.2](https://github.com/noir-lang/acvm/compare/acir-v0.14.1...acir-v0.14.2) (2023-06-08) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.14.1 to 0.14.2 + +## [0.14.1](https://github.com/noir-lang/acvm/compare/acir-v0.14.0...acir-v0.14.1) (2023-06-07) + + +### Features + +* Re-use intermediate variables created during width reduction, with proper scale. ([#343](https://github.com/noir-lang/acvm/issues/343)) ([6bd0baa](https://github.com/noir-lang/acvm/commit/6bd0baa4bc9ac204e7710ec6d17d1752d2e924c0)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.14.0 to 0.14.1 + +## [0.14.0](https://github.com/noir-lang/acvm/compare/acir-v0.13.3...acir-v0.14.0) (2023-06-06) + + +### ⚠ BREAKING CHANGES + +* **acir:** Verify Proof ([#291](https://github.com/noir-lang/acvm/issues/291)) + +### Features + +* **acir:** Verify Proof ([#291](https://github.com/noir-lang/acvm/issues/291)) ([9f34428](https://github.com/noir-lang/acvm/commit/9f34428b7084c7c38de401a16ca76e748d8b1d77)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.13.3 to 0.14.0 + +## [0.13.3](https://github.com/noir-lang/acvm/compare/acir-v0.13.2...acir-v0.13.3) (2023-06-05) + + +### Bug Fixes + +* Empty commit to trigger release-please ([e8f0748](https://github.com/noir-lang/acvm/commit/e8f0748042ef505d59ab63266d3c36c5358ee30d)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.13.2 to 0.13.3 + +## [0.13.2](https://github.com/noir-lang/acvm/compare/acir-v0.13.1...acir-v0.13.2) (2023-06-02) + + +### Bug Fixes + +* re-use intermediate vars during width reduction ([#278](https://github.com/noir-lang/acvm/issues/278)) ([5b32920](https://github.com/noir-lang/acvm/commit/5b32920263c4481c60faf0b84f0031aa8149b6b2)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.13.1 to 0.13.2 + +## [0.13.1](https://github.com/noir-lang/acvm/compare/acir-v0.13.0...acir-v0.13.1) (2023-06-01) + + +### Bug Fixes + +* **ci:** Correct typo to avoid `undefined` in changelogs ([#333](https://github.com/noir-lang/acvm/issues/333)) ([d3424c0](https://github.com/noir-lang/acvm/commit/d3424c04fd303c9cbe25d03118d8b358cbb84b83)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.1.1 to 0.13.1 + +## [0.13.0](https://github.com/noir-lang/acvm/compare/acir-v0.12.0...acir-v0.13.0) (2023-06-01) + + +### ⚠ BREAKING CHANGES + +* added hash index to pedersen ([#281](https://github.com/noir-lang/acvm/issues/281)) +* Add variable length keccak opcode ([#314](https://github.com/noir-lang/acvm/issues/314)) +* Remove AES opcode ([#302](https://github.com/noir-lang/acvm/issues/302)) +* **acir, acvm:** Remove ComputeMerkleRoot opcode #296 +* Remove manual serialization of `Opcode`s in favour of `serde` ([#286](https://github.com/noir-lang/acvm/issues/286)) + +### Features + +* **acir, acvm:** Remove ComputeMerkleRoot opcode [#296](https://github.com/noir-lang/acvm/issues/296) ([8b3923e](https://github.com/noir-lang/acvm/commit/8b3923e191e4ac399400025496e8bb4453734040)) +* Add `Brillig` opcode to introduce custom non-determinism to ACVM ([#152](https://github.com/noir-lang/acvm/issues/152)) ([3c6740a](https://github.com/noir-lang/acvm/commit/3c6740af75125afc8ebb4379f781f8274015e2e2)) +* Add variable length keccak opcode ([#314](https://github.com/noir-lang/acvm/issues/314)) ([7bfd169](https://github.com/noir-lang/acvm/commit/7bfd1695b6f119cd70fce4866314c9bb4991eaab)) +* added hash index to pedersen ([#281](https://github.com/noir-lang/acvm/issues/281)) ([61820b6](https://github.com/noir-lang/acvm/commit/61820b651900aac8d9557b4b9477ed0e1763c124)) + + +### Miscellaneous Chores + +* Remove AES opcode ([#302](https://github.com/noir-lang/acvm/issues/302)) ([a429a54](https://github.com/noir-lang/acvm/commit/a429a5422d6f001b6db0d0a0f30c79ec0f96de89)) +* Remove manual serialization of `Opcode`s in favour of `serde` ([#286](https://github.com/noir-lang/acvm/issues/286)) ([8a3812f](https://github.com/noir-lang/acvm/commit/8a3812fe6ed3b267692284bdcd909d9dd32b9747)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.1.0 to 0.1.1 + +## [0.12.0](https://github.com/noir-lang/acvm/compare/acir-v0.11.0...acir-v0.12.0) (2023-05-17) + + +### ⚠ BREAKING CHANGES + +* Introduce WitnessMap data structure to avoid leaking internal structure ([#252](https://github.com/noir-lang/acvm/issues/252)) +* use struct variants for blackbox function calls ([#269](https://github.com/noir-lang/acvm/issues/269)) +* **acvm:** Simplification pass for ACIR ([#151](https://github.com/noir-lang/acvm/issues/151)) + +### Features + +* **acvm:** Simplification pass for ACIR ([#151](https://github.com/noir-lang/acvm/issues/151)) ([7bc42c6](https://github.com/noir-lang/acvm/commit/7bc42c62b6e095f838b781c87cbb1ecd2af5f179)) +* Introduce WitnessMap data structure to avoid leaking internal structure ([#252](https://github.com/noir-lang/acvm/issues/252)) ([b248e60](https://github.com/noir-lang/acvm/commit/b248e606dd69c25d33ae77c5c5c0541adbf80cd6)) +* use struct variants for blackbox function calls ([#269](https://github.com/noir-lang/acvm/issues/269)) ([a83333b](https://github.com/noir-lang/acvm/commit/a83333b9e270dfcfd40a36271896840ec0201bc4)) + + +### Bug Fixes + +* **acir:** Hide variants of WitnessMapError and export it from package ([#283](https://github.com/noir-lang/acvm/issues/283)) ([bbd9ab7](https://github.com/noir-lang/acvm/commit/bbd9ab7ca5be3fb31f3e141fee2522704852f5de)) + +## [0.11.0](https://github.com/noir-lang/acvm/compare/acir-v0.10.3...acir-v0.11.0) (2023-05-04) + + +### Bug Fixes + +* **acir:** Fix `Expression` multiplication to correctly handle degree 1 terms ([#255](https://github.com/noir-lang/acvm/issues/255)) ([e399396](https://github.com/noir-lang/acvm/commit/e399396f7e06deb6b831517af17018607df3f252)) + +## [0.10.3](https://github.com/noir-lang/acvm/compare/acir-v0.10.2...acir-v0.10.3) (2023-04-28) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.10.2](https://github.com/noir-lang/acvm/compare/acir-v0.10.1...acir-v0.10.2) (2023-04-28) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.10.1](https://github.com/noir-lang/acvm/compare/acir-v0.10.0...acir-v0.10.1) (2023-04-28) + + +### Bug Fixes + +* **acir:** add `bn254` as default feature flag ([#240](https://github.com/noir-lang/acvm/issues/240)) ([e56973d](https://github.com/noir-lang/acvm/commit/e56973d8dc1745fe9bb844ec8347acd4d836d42f)) + +## [0.10.0](https://github.com/noir-lang/acvm/compare/acir-v0.9.0...acir-v0.10.0) (2023-04-26) + + +### ⚠ BREAKING CHANGES + +* replace `MerkleMembership` opcode with `ComputeMerkleRoot` ([#233](https://github.com/noir-lang/acvm/issues/233)) +* return `PartialWitnessGeneratorStatus` from `PartialWitnessGenerator.solve` ([#213](https://github.com/noir-lang/acvm/issues/213)) +* organise operator implementations for Expression ([#190](https://github.com/noir-lang/acvm/issues/190)) + +### Features + +* implement `add_mul` on `Expression` ([#207](https://github.com/noir-lang/acvm/issues/207)) ([f156e18](https://github.com/noir-lang/acvm/commit/f156e18cf7a0f1a99bbe1683b8e75fec8325e6dd)) +* replace `MerkleMembership` opcode with `ComputeMerkleRoot` ([#233](https://github.com/noir-lang/acvm/issues/233)) ([74bfee8](https://github.com/noir-lang/acvm/commit/74bfee80e0ff0d205aee1eea548c97ade8bd0e41)) +* return `PartialWitnessGeneratorStatus` from `PartialWitnessGenerator.solve` ([#213](https://github.com/noir-lang/acvm/issues/213)) ([e877bed](https://github.com/noir-lang/acvm/commit/e877bed2cca76bd486e9bed66b4230e65a01f0a2)) + + +### Miscellaneous Chores + +* organise operator implementations for Expression ([#190](https://github.com/noir-lang/acvm/issues/190)) ([a619df6](https://github.com/noir-lang/acvm/commit/a619df614bbb9b2518b788b42a7553b069823a0f)) + +## [0.9.0](https://github.com/noir-lang/acvm/compare/acir-v0.8.1...acir-v0.9.0) (2023-04-07) + + +### Bug Fixes + +* Add test for Out of Memory ([#188](https://github.com/noir-lang/acvm/issues/188)) ([c3db985](https://github.com/noir-lang/acvm/commit/c3db985893e7e59ea04005bb3a57eda5c6ce28c7)) + +## [0.8.1](https://github.com/noir-lang/acvm/compare/acir-v0.8.0...acir-v0.8.1) (2023-03-30) + + +### Bug Fixes + +* unwraps if inputs is zero ([#171](https://github.com/noir-lang/acvm/issues/171)) ([10a3bb2](https://github.com/noir-lang/acvm/commit/10a3bb2a9930ccf422b3f08227aae07775686860)) + +## [0.8.0](https://github.com/noir-lang/acvm/compare/acir-v0.7.1...acir-v0.8.0) (2023-03-28) + + +### ⚠ BREAKING CHANGES + +* **acir:** Read Log Directive ([#156](https://github.com/noir-lang/acvm/issues/156)) + +### Bug Fixes + +* **acir:** Read Log Directive ([#156](https://github.com/noir-lang/acvm/issues/156)) ([1cc2b7f](https://github.com/noir-lang/acvm/commit/1cc2b7f2179cecc338fe0def72bb2dd17eaed0cd)) + +## [0.7.1](https://github.com/noir-lang/acvm/compare/acir-v0.7.0...acir-v0.7.1) (2023-03-27) + + +### Miscellaneous Chores + +* **acir:** Synchronize acvm versions + +## [0.7.0](https://github.com/noir-lang/acvm/compare/acir-v0.6.0...acir-v0.7.0) (2023-03-23) + + +### ⚠ BREAKING CHANGES + +* Add initial oracle opcode ([#149](https://github.com/noir-lang/acvm/issues/149)) +* **acir:** Add RAM and ROM opcodes +* **acir:** Add a public outputs field ([#56](https://github.com/noir-lang/acvm/issues/56)) +* **acir:** remove `Linear` struct ([#145](https://github.com/noir-lang/acvm/issues/145)) +* **acvm:** Remove truncate and oddrange directives ([#142](https://github.com/noir-lang/acvm/issues/142)) + +### Features + +* **acir:** Add a public outputs field ([#56](https://github.com/noir-lang/acvm/issues/56)) ([5f358a9](https://github.com/noir-lang/acvm/commit/5f358a97aaa81d87956e182cd8a6d60de75f9752)) +* **acir:** Add RAM and ROM opcodes ([73e9f25](https://github.com/noir-lang/acvm/commit/73e9f25dd87b2ca91245e93d2445eadc0f522fac)) +* Add initial oracle opcode ([#149](https://github.com/noir-lang/acvm/issues/149)) ([88ee2f8](https://github.com/noir-lang/acvm/commit/88ee2f89f37abf5dd1d9f91b4d2eed44dc651348)) + + +### Miscellaneous Chores + +* **acir:** remove `Linear` struct ([#145](https://github.com/noir-lang/acvm/issues/145)) ([bbb6d92](https://github.com/noir-lang/acvm/commit/bbb6d92e25c43dd33b12f5fcd639fc9ad2a9c9d8)) +* **acvm:** Remove truncate and oddrange directives ([#142](https://github.com/noir-lang/acvm/issues/142)) ([85dd6e8](https://github.com/noir-lang/acvm/commit/85dd6e85bfba85bfb97651f7e30e1f75deb986d5)) + +## [0.6.0](https://github.com/noir-lang/acvm/compare/acir-v0.5.0...acir-v0.6.0) (2023-03-03) + + +### ⚠ BREAKING CHANGES + +* **acir:** rename `term_addition` to `push_addition_term` +* **acir:** rename `term_multiplication` to `push_multiplication_term` ([#122](https://github.com/noir-lang/acvm/issues/122)) +* **acir:** remove `UnknownWitness` ([#123](https://github.com/noir-lang/acvm/issues/123)) +* add block opcode ([#114](https://github.com/noir-lang/acvm/issues/114)) + +### Features + +* **acir:** add useful methods from `noirc_evaluator` onto `Expression` ([#125](https://github.com/noir-lang/acvm/issues/125)) ([d3d5f89](https://github.com/noir-lang/acvm/commit/d3d5f8917482ce5649602695829862a5df4ea712)) +* add block opcode ([#114](https://github.com/noir-lang/acvm/issues/114)) ([097cfb0](https://github.com/noir-lang/acvm/commit/097cfb069291705ddb4bf1fca77ddcef21dbbd08)) + + +### Bug Fixes + +* **acir:** correctly display expressions with non-unit coefficients ([d3d5f89](https://github.com/noir-lang/acvm/commit/d3d5f8917482ce5649602695829862a5df4ea712)) + + +### Miscellaneous Chores + +* **acir:** remove `UnknownWitness` ([#123](https://github.com/noir-lang/acvm/issues/123)) ([9f002c7](https://github.com/noir-lang/acvm/commit/9f002c7b49a5cf222d4a01732cc4917a47690863)) +* **acir:** rename `term_addition` to `push_addition_term` ([d389385](https://github.com/noir-lang/acvm/commit/d38938542851a97dc01727438391e6a65e44c689)) +* **acir:** rename `term_multiplication` to `push_multiplication_term` ([#122](https://github.com/noir-lang/acvm/issues/122)) ([d389385](https://github.com/noir-lang/acvm/commit/d38938542851a97dc01727438391e6a65e44c689)) + +## [0.5.0](https://github.com/noir-lang/acvm/compare/acir-v0.4.1...acir-v0.5.0) (2023-02-22) + + +### ⚠ BREAKING CHANGES + +* **acir:** make PublicInputs use a BTreeSet rather than Vec ([#99](https://github.com/noir-lang/acvm/issues/99)) +* refactor ToRadix to ToRadixLe and ToRadixBe ([#58](https://github.com/noir-lang/acvm/issues/58)) +* **acir:** Add keccak256 Opcode ([#91](https://github.com/noir-lang/acvm/issues/91)) +* reorganise compiler in terms of optimisers and transformers ([#88](https://github.com/noir-lang/acvm/issues/88)) + +### Features + +* **acir:** Add keccak256 Opcode ([#91](https://github.com/noir-lang/acvm/issues/91)) ([b909146](https://github.com/noir-lang/acvm/commit/b9091461e199bacdd073cc9b31f03dade0b4fb2d)) +* **acir:** make PublicInputs use a BTreeSet rather than Vec ([#99](https://github.com/noir-lang/acvm/issues/99)) ([53666b7](https://github.com/noir-lang/acvm/commit/53666b782d89c65cd755f9e4ded2c9cf5a141e46)) + + +### Miscellaneous Chores + +* refactor ToRadix to ToRadixLe and ToRadixBe ([#58](https://github.com/noir-lang/acvm/issues/58)) ([2427a27](https://github.com/noir-lang/acvm/commit/2427a275048e598c6d651cce8348a4c55148f235)) +* reorganise compiler in terms of optimisers and transformers ([#88](https://github.com/noir-lang/acvm/issues/88)) ([9329307](https://github.com/noir-lang/acvm/commit/9329307e054de202cfc55207162ad952b70d515e)) diff --git a/acvm-repo/acir/Cargo.toml b/acvm-repo/acir/Cargo.toml new file mode 100644 index 00000000000..5da8b279429 --- /dev/null +++ b/acvm-repo/acir/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "acir" +description = "ACIR is the IR that the VM processes, it is analogous to LLVM IR" +version = "0.27.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true +repository.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +acir_field.workspace = true +brillig.workspace = true +serde.workspace = true +thiserror.workspace = true +rmp-serde = { version = "1.1.0", optional = true } +flate2 = "1.0.24" +bincode.workspace = true + +[dev-dependencies] +serde_json = "1.0" +strum = "0.24" +strum_macros = "0.24" + +[features] +default = ["bn254"] +bn254 = ["acir_field/bn254", "brillig/bn254"] +bls12_381 = ["acir_field/bls12_381", "brillig/bls12_381"] +serialize-messagepack = ["rmp-serde"] diff --git a/acvm-repo/acir/src/circuit/black_box_functions.rs b/acvm-repo/acir/src/circuit/black_box_functions.rs new file mode 100644 index 00000000000..17c990c7670 --- /dev/null +++ b/acvm-repo/acir/src/circuit/black_box_functions.rs @@ -0,0 +1,118 @@ +//! Black box functions are ACIR opcodes which rely on backends implementing support for specialized constraints. +//! This makes certain zk-snark unfriendly computations cheaper than if they were implemented in more basic constraints. +//! +//! It is possible to fallback to less efficient implementations written in ACIR in some cases. +//! These are implemented inside the ACVM stdlib. + +use serde::{Deserialize, Serialize}; +#[cfg(test)] +use strum_macros::EnumIter; + +#[allow(clippy::upper_case_acronyms)] +#[derive(Clone, Debug, Hash, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(test, derive(EnumIter))] +pub enum BlackBoxFunc { + /// Bitwise AND. + AND, + /// Bitwise XOR. + XOR, + /// Range constraint to ensure that a [`FieldElement`][acir_field::FieldElement] can be represented in a specified number of bits. + RANGE, + /// Calculates the SHA256 hash of the inputs. + SHA256, + /// Calculates the Blake2s hash of the inputs. + Blake2s, + /// Verifies a Schnorr signature over a curve which is "pairing friendly" with the curve on which the ACIR circuit is defined. + /// + /// The exact curve which this signature uses will vary based on the curve being used by ACIR. + /// For example, the BN254 curve supports Schnorr signatures over the [Grumpkin][grumpkin] curve. + /// + /// [grumpkin]: https://hackmd.io/@aztec-network/ByzgNxBfd#2-Grumpkin---A-curve-on-top-of-BN-254-for-SNARK-efficient-group-operations + SchnorrVerify, + /// Calculates a Pedersen commitment to the inputs. + Pedersen, + /// Hashes a set of inputs and applies the field modulus to the result + /// to return a value which can be represented as a [`FieldElement`][acir_field::FieldElement] + /// + /// This is implemented using the `Blake2s` hash function. + /// The "128" in the name specifies that this function should have 128 bits of security. + HashToField128Security, + /// Verifies a ECDSA signature over the secp256k1 curve. + EcdsaSecp256k1, + /// Verifies a ECDSA signature over the secp256r1 curve. + EcdsaSecp256r1, + /// Performs scalar multiplication over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined. + FixedBaseScalarMul, + /// Calculates the Keccak256 hash of the inputs. + Keccak256, + /// Compute a recursive aggregation object when verifying a proof inside another circuit. + /// This outputted aggregation object will then be either checked in a top-level verifier or aggregated upon again. + RecursiveAggregation, +} + +impl std::fmt::Display for BlackBoxFunc { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.name()) + } +} + +impl BlackBoxFunc { + pub fn name(&self) -> &'static str { + match self { + BlackBoxFunc::SHA256 => "sha256", + BlackBoxFunc::SchnorrVerify => "schnorr_verify", + BlackBoxFunc::Blake2s => "blake2s", + BlackBoxFunc::Pedersen => "pedersen", + BlackBoxFunc::HashToField128Security => "hash_to_field_128_security", + BlackBoxFunc::EcdsaSecp256k1 => "ecdsa_secp256k1", + BlackBoxFunc::FixedBaseScalarMul => "fixed_base_scalar_mul", + BlackBoxFunc::AND => "and", + BlackBoxFunc::XOR => "xor", + BlackBoxFunc::RANGE => "range", + BlackBoxFunc::Keccak256 => "keccak256", + BlackBoxFunc::RecursiveAggregation => "recursive_aggregation", + BlackBoxFunc::EcdsaSecp256r1 => "ecdsa_secp256r1", + } + } + pub fn lookup(op_name: &str) -> Option { + match op_name { + "sha256" => Some(BlackBoxFunc::SHA256), + "schnorr_verify" => Some(BlackBoxFunc::SchnorrVerify), + "blake2s" => Some(BlackBoxFunc::Blake2s), + "pedersen" => Some(BlackBoxFunc::Pedersen), + "hash_to_field_128_security" => Some(BlackBoxFunc::HashToField128Security), + "ecdsa_secp256k1" => Some(BlackBoxFunc::EcdsaSecp256k1), + "ecdsa_secp256r1" => Some(BlackBoxFunc::EcdsaSecp256r1), + "fixed_base_scalar_mul" => Some(BlackBoxFunc::FixedBaseScalarMul), + "and" => Some(BlackBoxFunc::AND), + "xor" => Some(BlackBoxFunc::XOR), + "range" => Some(BlackBoxFunc::RANGE), + "keccak256" => Some(BlackBoxFunc::Keccak256), + "recursive_aggregation" => Some(BlackBoxFunc::RecursiveAggregation), + _ => None, + } + } + pub fn is_valid_black_box_func_name(op_name: &str) -> bool { + BlackBoxFunc::lookup(op_name).is_some() + } +} + +#[cfg(test)] +mod tests { + use strum::IntoEnumIterator; + + use crate::BlackBoxFunc; + + #[test] + fn consistent_function_names() { + for bb_func in BlackBoxFunc::iter() { + let resolved_func = BlackBoxFunc::lookup(bb_func.name()).unwrap_or_else(|| { + panic!("BlackBoxFunc::lookup couldn't find black box function {}", bb_func) + }); + assert_eq!( + resolved_func, bb_func, + "BlackBoxFunc::lookup returns unexpected BlackBoxFunc" + ) + } + } +} diff --git a/acvm-repo/acir/src/circuit/brillig.rs b/acvm-repo/acir/src/circuit/brillig.rs new file mode 100644 index 00000000000..5b1ec9d032a --- /dev/null +++ b/acvm-repo/acir/src/circuit/brillig.rs @@ -0,0 +1,33 @@ +use crate::native_types::{Expression, Witness}; +use brillig::ForeignCallResult; +use brillig::Opcode as BrilligOpcode; +use serde::{Deserialize, Serialize}; + +/// Inputs for the Brillig VM. These are the initial inputs +/// that the Brillig VM will use to start. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub enum BrilligInputs { + Single(Expression), + Array(Vec), +} + +/// Outputs for the Brillig VM. Once the VM has completed +/// execution, this will be the object that is returned. +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub enum BrilligOutputs { + Simple(Witness), + Array(Vec), +} + +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct Brillig { + pub inputs: Vec, + pub outputs: Vec, + /// Results of oracles/functions external to brillig like a database read. + // Each element of this vector corresponds to a single foreign call but may contain several values. + pub foreign_call_results: Vec, + /// The Brillig VM bytecode to be executed by this ACIR opcode. + pub bytecode: Vec, + /// Predicate of the Brillig execution - indicates if it should be skipped + pub predicate: Option, +} diff --git a/acvm-repo/acir/src/circuit/directives.rs b/acvm-repo/acir/src/circuit/directives.rs new file mode 100644 index 00000000000..32c0bd6337a --- /dev/null +++ b/acvm-repo/acir/src/circuit/directives.rs @@ -0,0 +1,46 @@ +use crate::native_types::{Expression, Witness}; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct QuotientDirective { + pub a: Expression, + pub b: Expression, + pub q: Witness, + pub r: Witness, + pub predicate: Option, +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +/// Directives do not apply any constraints. +/// You can think of them as opcodes that allow one to use non-determinism +/// In the future, this can be replaced with asm non-determinism blocks +pub enum Directive { + //Performs euclidian division of a / b (as integers) and stores the quotient in q and the rest in r + Quotient(QuotientDirective), + + //decomposition of a: a=\sum b[i]*radix^i where b is an array of witnesses < radix in little endian form + ToLeRadix { + a: Expression, + b: Vec, + radix: u32, + }, + + // Sort directive, using a sorting network + // This directive is used to generate the values of the control bits for the sorting network such that its outputs are properly sorted according to sort_by + PermutationSort { + inputs: Vec>, // Array of tuples to sort + tuple: u32, // tuple size; if 1 then inputs is a single array [a0,a1,..], if 2 then inputs=[(a0,b0),..] is [a0,b0,a1,b1,..], etc.. + bits: Vec, // control bits of the network which permutes the inputs into its sorted version + sort_by: Vec, // specify primary index to sort by, then the secondary,... For instance, if tuple is 2 and sort_by is [1,0], then a=[(a0,b0),..] is sorted by bi and then ai. + }, +} + +impl Directive { + pub fn name(&self) -> &str { + match self { + Directive::Quotient(_) => "quotient", + Directive::ToLeRadix { .. } => "to_le_radix", + Directive::PermutationSort { .. } => "permutation_sort", + } + } +} diff --git a/acvm-repo/acir/src/circuit/mod.rs b/acvm-repo/acir/src/circuit/mod.rs new file mode 100644 index 00000000000..d03240af2c3 --- /dev/null +++ b/acvm-repo/acir/src/circuit/mod.rs @@ -0,0 +1,285 @@ +pub mod black_box_functions; +pub mod brillig; +pub mod directives; +pub mod opcodes; + +use crate::native_types::Witness; +pub use opcodes::Opcode; +use thiserror::Error; + +use std::{io::prelude::*, num::ParseIntError, str::FromStr}; + +use flate2::Compression; + +use serde::{Deserialize, Serialize}; +use std::collections::BTreeSet; + +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +pub struct Circuit { + // current_witness_index is the highest witness index in the circuit. The next witness to be added to this circuit + // will take on this value. (The value is cached here as an optimization.) + pub current_witness_index: u32, + pub opcodes: Vec, + + /// The set of private inputs to the circuit. + pub private_parameters: BTreeSet, + // ACIR distinguishes between the public inputs which are provided externally or calculated within the circuit and returned. + // The elements of these sets may not be mutually exclusive, i.e. a parameter may be returned from the circuit. + // All public inputs (parameters and return values) must be provided to the verifier at verification time. + /// The set of public inputs provided by the prover. + pub public_parameters: PublicInputs, + /// The set of public inputs calculated within the circuit. + pub return_values: PublicInputs, + /// Maps opcode locations to failed assertion messages. + /// These messages are embedded in the circuit to provide useful feedback to users + /// when a constraint in the circuit is not satisfied. + /// + // Note: This should be a BTreeMap, but serde-reflect is creating invalid + // c++ code at the moment when it is, due to OpcodeLocation needing a comparison + // implementation which is never generated. + pub assert_messages: Vec<(OpcodeLocation, String)>, +} + +impl Circuit { + /// Returns the assert message associated with the provided [`OpcodeLocation`]. + /// Returns `None` if no such assert message exists. + pub fn get_assert_message(&self, opcode_location: OpcodeLocation) -> Option<&str> { + self.assert_messages + .iter() + .find(|(loc, _)| *loc == opcode_location) + .map(|(_, message)| message.as_str()) + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +/// Opcodes are locatable so that callers can +/// map opcodes to debug information related to their context. +pub enum OpcodeLocation { + Acir(usize), + Brillig { acir_index: usize, brillig_index: usize }, +} + +impl std::fmt::Display for OpcodeLocation { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + OpcodeLocation::Acir(index) => write!(f, "{index}"), + OpcodeLocation::Brillig { acir_index, brillig_index } => { + write!(f, "{acir_index}.{brillig_index}") + } + } + } +} + +#[derive(Error, Debug)] +pub enum OpcodeLocationFromStrError { + #[error("Invalid opcode location string: {0}")] + InvalidOpcodeLocationString(String), +} + +/// The implementation of display and FromStr allows serializing and deserializing a OpcodeLocation to a string. +/// This is useful when used as key in a map that has to be serialized to JSON/TOML, for example when mapping an opcode to its metadata. +impl FromStr for OpcodeLocation { + type Err = OpcodeLocationFromStrError; + fn from_str(s: &str) -> Result { + let parts: Vec<_> = s.split('.').collect(); + + if parts.is_empty() || parts.len() > 2 { + return Err(OpcodeLocationFromStrError::InvalidOpcodeLocationString(s.to_string())); + } + + fn parse_components(parts: Vec<&str>) -> Result { + match parts.len() { + 1 => { + let index = parts[0].parse()?; + Ok(OpcodeLocation::Acir(index)) + } + 2 => { + let acir_index = parts[0].parse()?; + let brillig_index = parts[1].parse()?; + Ok(OpcodeLocation::Brillig { acir_index, brillig_index }) + } + _ => unreachable!(), + } + } + + parse_components(parts) + .map_err(|_| OpcodeLocationFromStrError::InvalidOpcodeLocationString(s.to_string())) + } +} + +impl Circuit { + pub fn num_vars(&self) -> u32 { + self.current_witness_index + 1 + } + + /// Returns all witnesses which are required to execute the circuit successfully. + pub fn circuit_arguments(&self) -> BTreeSet { + self.private_parameters.union(&self.public_parameters.0).cloned().collect() + } + + /// Returns all public inputs. This includes those provided as parameters to the circuit and those + /// computed as return values. + pub fn public_inputs(&self) -> PublicInputs { + let public_inputs = + self.public_parameters.0.union(&self.return_values.0).cloned().collect(); + PublicInputs(public_inputs) + } + + #[cfg(feature = "serialize-messagepack")] + pub fn write(&self, writer: W) -> std::io::Result<()> { + let buf = rmp_serde::to_vec(&self).unwrap(); + let mut deflater = flate2::write::DeflateEncoder::new(writer, Compression::best()); + deflater.write_all(&buf).unwrap(); + + Ok(()) + } + #[cfg(feature = "serialize-messagepack")] + pub fn read(reader: R) -> std::io::Result { + let mut deflater = flate2::read::DeflateDecoder::new(reader); + let mut buf_d = Vec::new(); + deflater.read_to_end(&mut buf_d).unwrap(); + let circuit = rmp_serde::from_slice(buf_d.as_slice()).unwrap(); + Ok(circuit) + } + + #[cfg(not(feature = "serialize-messagepack"))] + pub fn write(&self, writer: W) -> std::io::Result<()> { + let buf = bincode::serialize(&self).unwrap(); + let mut encoder = flate2::write::GzEncoder::new(writer, Compression::default()); + encoder.write_all(&buf).unwrap(); + encoder.finish().unwrap(); + Ok(()) + } + + #[cfg(not(feature = "serialize-messagepack"))] + pub fn read(reader: R) -> std::io::Result { + let mut gz_decoder = flate2::read::GzDecoder::new(reader); + let mut buf_d = Vec::new(); + gz_decoder.read_to_end(&mut buf_d).unwrap(); + let circuit = bincode::deserialize(&buf_d).unwrap(); + Ok(circuit) + } +} + +impl std::fmt::Display for Circuit { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "current witness index : {}", self.current_witness_index)?; + + let write_public_inputs = |f: &mut std::fmt::Formatter<'_>, + public_inputs: &PublicInputs| + -> Result<(), std::fmt::Error> { + write!(f, "[")?; + let public_input_indices = public_inputs.indices(); + for (index, public_input) in public_input_indices.iter().enumerate() { + write!(f, "{public_input}")?; + if index != public_input_indices.len() - 1 { + write!(f, ", ")?; + } + } + writeln!(f, "]") + }; + + write!(f, "public parameters indices : ")?; + write_public_inputs(f, &self.public_parameters)?; + + write!(f, "return value indices : ")?; + write_public_inputs(f, &self.return_values)?; + + for opcode in &self.opcodes { + writeln!(f, "{opcode}")? + } + Ok(()) + } +} + +impl std::fmt::Debug for Circuit { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self, f) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] +pub struct PublicInputs(pub BTreeSet); + +impl PublicInputs { + /// Returns the witness index of each public input + pub fn indices(&self) -> Vec { + self.0.iter().map(|witness| witness.witness_index()).collect() + } + + pub fn contains(&self, index: usize) -> bool { + self.0.contains(&Witness(index as u32)) + } +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeSet; + + use super::{ + opcodes::{BlackBoxFuncCall, FunctionInput}, + Circuit, Opcode, PublicInputs, + }; + use crate::native_types::Witness; + use acir_field::FieldElement; + + fn and_opcode() -> Opcode { + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::AND { + lhs: FunctionInput { witness: Witness(1), num_bits: 4 }, + rhs: FunctionInput { witness: Witness(2), num_bits: 4 }, + output: Witness(3), + }) + } + fn range_opcode() -> Opcode { + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { + input: FunctionInput { witness: Witness(1), num_bits: 8 }, + }) + } + + #[test] + fn serialization_roundtrip() { + let circuit = Circuit { + current_witness_index: 5, + opcodes: vec![and_opcode(), range_opcode()], + private_parameters: BTreeSet::new(), + public_parameters: PublicInputs(BTreeSet::from_iter(vec![Witness(2), Witness(12)])), + return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(4), Witness(12)])), + assert_messages: Default::default(), + }; + + fn read_write(circuit: Circuit) -> (Circuit, Circuit) { + let mut bytes = Vec::new(); + circuit.write(&mut bytes).unwrap(); + let got_circuit = Circuit::read(&*bytes).unwrap(); + (circuit, got_circuit) + } + + let (circ, got_circ) = read_write(circuit); + assert_eq!(circ, got_circ) + } + + #[test] + fn test_serialize() { + let circuit = Circuit { + current_witness_index: 0, + opcodes: vec![ + Opcode::Arithmetic(crate::native_types::Expression { + mul_terms: vec![], + linear_combinations: vec![], + q_c: FieldElement::from(8u128), + }), + range_opcode(), + and_opcode(), + ], + private_parameters: BTreeSet::new(), + public_parameters: PublicInputs(BTreeSet::from_iter(vec![Witness(2)])), + return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(2)])), + assert_messages: Default::default(), + }; + + let json = serde_json::to_string_pretty(&circuit).unwrap(); + + let deserialized = serde_json::from_str(&json).unwrap(); + assert_eq!(circuit, deserialized); + } +} diff --git a/acvm-repo/acir/src/circuit/opcodes.rs b/acvm-repo/acir/src/circuit/opcodes.rs new file mode 100644 index 00000000000..dc7f73b47e5 --- /dev/null +++ b/acvm-repo/acir/src/circuit/opcodes.rs @@ -0,0 +1,179 @@ +use super::{ + brillig::Brillig, + directives::{Directive, QuotientDirective}, +}; +use crate::native_types::{Expression, Witness}; +use serde::{Deserialize, Serialize}; + +mod black_box_function_call; +mod memory_operation; + +pub use black_box_function_call::{BlackBoxFuncCall, FunctionInput}; +pub use memory_operation::{BlockId, MemOp}; + +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum Opcode { + Arithmetic(Expression), + /// Calls to "gadgets" which rely on backends implementing support for specialized constraints. + /// + /// Often used for exposing more efficient implementations of SNARK-unfriendly computations. + BlackBoxFuncCall(BlackBoxFuncCall), + Directive(Directive), + Brillig(Brillig), + /// Atomic operation on a block of memory + MemoryOp { + block_id: BlockId, + op: MemOp, + /// Predicate of the memory operation - indicates if it should be skipped + predicate: Option, + }, + MemoryInit { + block_id: BlockId, + init: Vec, + }, +} + +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum UnsupportedMemoryOpcode { + MemoryOp, + MemoryInit, +} + +impl std::fmt::Display for UnsupportedMemoryOpcode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + UnsupportedMemoryOpcode::MemoryOp => write!(f, "MemoryOp"), + UnsupportedMemoryOpcode::MemoryInit => write!(f, "MemoryInit"), + } + } +} + +impl Opcode { + // TODO We can add a domain separator by doing something like: + // TODO concat!("directive:", directive.name) + pub fn name(&self) -> &str { + match self { + Opcode::Arithmetic(_) => "arithmetic", + Opcode::Directive(directive) => directive.name(), + Opcode::BlackBoxFuncCall(g) => g.name(), + Opcode::Brillig(_) => "brillig", + Opcode::MemoryOp { .. } => "mem", + Opcode::MemoryInit { .. } => "init memory block", + } + } + + pub fn unsupported_opcode(&self) -> UnsupportedMemoryOpcode { + match self { + Opcode::MemoryOp { .. } => UnsupportedMemoryOpcode::MemoryOp, + Opcode::MemoryInit { .. } => UnsupportedMemoryOpcode::MemoryInit, + Opcode::BlackBoxFuncCall(_) => { + unreachable!("Unsupported Blackbox function should not be reported here") + } + _ => unreachable!("Opcode is supported"), + } + } + + pub fn is_arithmetic(&self) -> bool { + matches!(self, Opcode::Arithmetic(_)) + } + + pub fn arithmetic(self) -> Option { + match self { + Opcode::Arithmetic(expr) => Some(expr), + _ => None, + } + } +} + +impl std::fmt::Display for Opcode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Opcode::Arithmetic(expr) => { + write!(f, "EXPR [ ")?; + for i in &expr.mul_terms { + write!(f, "({}, _{}, _{}) ", i.0, i.1.witness_index(), i.2.witness_index())?; + } + for i in &expr.linear_combinations { + write!(f, "({}, _{}) ", i.0, i.1.witness_index())?; + } + write!(f, "{}", expr.q_c)?; + + write!(f, " ]") + } + Opcode::Directive(Directive::Quotient(QuotientDirective { a, b, q, r, predicate })) => { + write!(f, "DIR::QUOTIENT ")?; + if let Some(pred) = predicate { + writeln!(f, "PREDICATE = {pred}")?; + } + + write!( + f, + "(out : _{}, (_{}, {}), _{})", + a, + q.witness_index(), + b, + r.witness_index() + ) + } + Opcode::BlackBoxFuncCall(g) => write!(f, "{g}"), + Opcode::Directive(Directive::ToLeRadix { a, b, radix: _ }) => { + write!(f, "DIR::TORADIX ")?; + write!( + f, + // TODO (Note): this assumes that the decomposed bits have contiguous witness indices + // This should be the case, however, we can also have a function which checks this + "(_{}, [_{}..._{}] )", + a, + b.first().unwrap().witness_index(), + b.last().unwrap().witness_index(), + ) + } + Opcode::Directive(Directive::PermutationSort { inputs: a, tuple, bits, sort_by }) => { + write!(f, "DIR::PERMUTATIONSORT ")?; + write!( + f, + "(permutation size: {} {}-tuples, sort_by: {:#?}, bits: [_{}..._{}]))", + a.len(), + tuple, + sort_by, + // (Note): the bits do not have contiguous index but there are too many for display + bits.first().unwrap().witness_index(), + bits.last().unwrap().witness_index(), + ) + } + + Opcode::Brillig(brillig) => { + write!(f, "BRILLIG: ")?; + writeln!(f, "inputs: {:?}", brillig.inputs)?; + writeln!(f, "outputs: {:?}", brillig.outputs)?; + writeln!(f, "{:?}", brillig.bytecode) + } + Opcode::MemoryOp { block_id, op, predicate } => { + write!(f, "MEM ")?; + if let Some(pred) = predicate { + writeln!(f, "PREDICATE = {pred}")?; + } + + let is_read = op.operation.is_zero(); + let is_write = op.operation == Expression::one(); + if is_read { + write!(f, "(id: {}, read at: {}, value: {}) ", block_id.0, op.index, op.value) + } else if is_write { + write!(f, "(id: {}, write {} at: {}) ", block_id.0, op.value, op.index) + } else { + write!(f, "(id: {}, op {} at: {}) ", block_id.0, op.operation, op.index) + } + } + Opcode::MemoryInit { block_id, init } => { + write!(f, "INIT ")?; + write!(f, "(id: {}, len: {}) ", block_id.0, init.len()) + } + } + } +} + +impl std::fmt::Debug for Opcode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self, f) + } +} diff --git a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs new file mode 100644 index 00000000000..b2ca0440b59 --- /dev/null +++ b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -0,0 +1,410 @@ +use crate::native_types::Witness; +use crate::BlackBoxFunc; +use serde::{Deserialize, Serialize}; + +// Note: Some functions will not use all of the witness +// So we need to supply how many bits of the witness is needed +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct FunctionInput { + pub witness: Witness, + pub num_bits: u32, +} + +impl FunctionInput { + pub fn dummy() -> Self { + Self { witness: Witness(0), num_bits: 0 } + } +} + +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum BlackBoxFuncCall { + AND { + lhs: FunctionInput, + rhs: FunctionInput, + output: Witness, + }, + XOR { + lhs: FunctionInput, + rhs: FunctionInput, + output: Witness, + }, + RANGE { + input: FunctionInput, + }, + SHA256 { + inputs: Vec, + outputs: Vec, + }, + Blake2s { + inputs: Vec, + outputs: Vec, + }, + SchnorrVerify { + public_key_x: FunctionInput, + public_key_y: FunctionInput, + signature: Vec, + message: Vec, + output: Witness, + }, + Pedersen { + inputs: Vec, + domain_separator: u32, + outputs: (Witness, Witness), + }, + // 128 here specifies that this function + // should have 128 bits of security + HashToField128Security { + inputs: Vec, + output: Witness, + }, + EcdsaSecp256k1 { + public_key_x: Vec, + public_key_y: Vec, + signature: Vec, + hashed_message: Vec, + output: Witness, + }, + EcdsaSecp256r1 { + public_key_x: Vec, + public_key_y: Vec, + signature: Vec, + hashed_message: Vec, + output: Witness, + }, + FixedBaseScalarMul { + low: FunctionInput, + high: FunctionInput, + outputs: (Witness, Witness), + }, + Keccak256 { + inputs: Vec, + outputs: Vec, + }, + Keccak256VariableLength { + inputs: Vec, + /// This is the number of bytes to take + /// from the input. Note: if `var_message_size` + /// is more than the number of bytes in the input, + /// then an error is returned. + var_message_size: FunctionInput, + outputs: Vec, + }, + RecursiveAggregation { + verification_key: Vec, + proof: Vec, + /// These represent the public inputs of the proof we are verifying + /// They should be checked against in the circuit after construction + /// of a new aggregation state + public_inputs: Vec, + /// A key hash is used to check the validity of the verification key. + /// The circuit implementing this opcode can use this hash to ensure that the + /// key provided to the circuit matches the key produced by the circuit creator + key_hash: FunctionInput, + /// An aggregation object is blob of data that the top-level verifier must run some proof system specific + /// algorithm on to complete verification. The size is proof system specific and will be set by the backend integrating this opcode. + /// The input aggregation object is only not `None` when we are verifying a previous recursive aggregation in + /// the current circuit. If this is the first recursive aggregation there is no input aggregation object. + /// It is left to the backend to determine how to handle when there is no input aggregation object. + input_aggregation_object: Option>, + /// This is the result of a recursive aggregation and is what will be fed into the next verifier. + /// The next verifier can either perform a final verification (returning true or false) + /// or perform another recursive aggregation where this output aggregation object + /// will be the input aggregation object of the next recursive aggregation. + output_aggregation_object: Vec, + }, +} + +impl BlackBoxFuncCall { + #[deprecated = "BlackBoxFuncCall::dummy() is unnecessary and will be removed in ACVM 0.24.0"] + pub fn dummy(bb_func: BlackBoxFunc) -> Self { + match bb_func { + BlackBoxFunc::AND => BlackBoxFuncCall::AND { + lhs: FunctionInput::dummy(), + rhs: FunctionInput::dummy(), + output: Witness(0), + }, + BlackBoxFunc::XOR => BlackBoxFuncCall::XOR { + lhs: FunctionInput::dummy(), + rhs: FunctionInput::dummy(), + output: Witness(0), + }, + BlackBoxFunc::RANGE => BlackBoxFuncCall::RANGE { input: FunctionInput::dummy() }, + BlackBoxFunc::SHA256 => BlackBoxFuncCall::SHA256 { inputs: vec![], outputs: vec![] }, + BlackBoxFunc::Blake2s => BlackBoxFuncCall::Blake2s { inputs: vec![], outputs: vec![] }, + BlackBoxFunc::SchnorrVerify => BlackBoxFuncCall::SchnorrVerify { + public_key_x: FunctionInput::dummy(), + public_key_y: FunctionInput::dummy(), + signature: vec![], + message: vec![], + output: Witness(0), + }, + BlackBoxFunc::Pedersen => BlackBoxFuncCall::Pedersen { + inputs: vec![], + domain_separator: 0, + outputs: (Witness(0), Witness(0)), + }, + BlackBoxFunc::HashToField128Security => { + BlackBoxFuncCall::HashToField128Security { inputs: vec![], output: Witness(0) } + } + BlackBoxFunc::EcdsaSecp256k1 => BlackBoxFuncCall::EcdsaSecp256k1 { + public_key_x: vec![], + public_key_y: vec![], + signature: vec![], + hashed_message: vec![], + output: Witness(0), + }, + BlackBoxFunc::EcdsaSecp256r1 => BlackBoxFuncCall::EcdsaSecp256r1 { + public_key_x: vec![], + public_key_y: vec![], + signature: vec![], + hashed_message: vec![], + output: Witness(0), + }, + BlackBoxFunc::FixedBaseScalarMul => BlackBoxFuncCall::FixedBaseScalarMul { + low: FunctionInput::dummy(), + high: FunctionInput::dummy(), + outputs: (Witness(0), Witness(0)), + }, + BlackBoxFunc::Keccak256 => { + BlackBoxFuncCall::Keccak256 { inputs: vec![], outputs: vec![] } + } + BlackBoxFunc::RecursiveAggregation => BlackBoxFuncCall::RecursiveAggregation { + verification_key: vec![], + proof: vec![], + public_inputs: vec![], + key_hash: FunctionInput::dummy(), + input_aggregation_object: None, + output_aggregation_object: vec![], + }, + } + } + + pub fn get_black_box_func(&self) -> BlackBoxFunc { + match self { + BlackBoxFuncCall::AND { .. } => BlackBoxFunc::AND, + BlackBoxFuncCall::XOR { .. } => BlackBoxFunc::XOR, + BlackBoxFuncCall::RANGE { .. } => BlackBoxFunc::RANGE, + BlackBoxFuncCall::SHA256 { .. } => BlackBoxFunc::SHA256, + BlackBoxFuncCall::Blake2s { .. } => BlackBoxFunc::Blake2s, + BlackBoxFuncCall::SchnorrVerify { .. } => BlackBoxFunc::SchnorrVerify, + BlackBoxFuncCall::Pedersen { .. } => BlackBoxFunc::Pedersen, + BlackBoxFuncCall::HashToField128Security { .. } => BlackBoxFunc::HashToField128Security, + BlackBoxFuncCall::EcdsaSecp256k1 { .. } => BlackBoxFunc::EcdsaSecp256k1, + BlackBoxFuncCall::EcdsaSecp256r1 { .. } => BlackBoxFunc::EcdsaSecp256r1, + BlackBoxFuncCall::FixedBaseScalarMul { .. } => BlackBoxFunc::FixedBaseScalarMul, + BlackBoxFuncCall::Keccak256 { .. } => BlackBoxFunc::Keccak256, + BlackBoxFuncCall::Keccak256VariableLength { .. } => BlackBoxFunc::Keccak256, + BlackBoxFuncCall::RecursiveAggregation { .. } => BlackBoxFunc::RecursiveAggregation, + } + } + + pub fn name(&self) -> &str { + self.get_black_box_func().name() + } + + pub fn get_inputs_vec(&self) -> Vec { + match self { + BlackBoxFuncCall::SHA256 { inputs, .. } + | BlackBoxFuncCall::Blake2s { inputs, .. } + | BlackBoxFuncCall::Keccak256 { inputs, .. } + | BlackBoxFuncCall::Pedersen { inputs, .. } + | BlackBoxFuncCall::HashToField128Security { inputs, .. } => inputs.to_vec(), + BlackBoxFuncCall::AND { lhs, rhs, .. } | BlackBoxFuncCall::XOR { lhs, rhs, .. } => { + vec![*lhs, *rhs] + } + BlackBoxFuncCall::FixedBaseScalarMul { low, high, .. } => vec![*low, *high], + BlackBoxFuncCall::RANGE { input } => vec![*input], + BlackBoxFuncCall::SchnorrVerify { + public_key_x, + public_key_y, + signature, + message, + .. + } => { + let mut inputs = Vec::with_capacity(2 + signature.len() + message.len()); + inputs.push(*public_key_x); + inputs.push(*public_key_y); + inputs.extend(signature.iter().copied()); + inputs.extend(message.iter().copied()); + inputs + } + BlackBoxFuncCall::EcdsaSecp256k1 { + public_key_x, + public_key_y, + signature, + hashed_message, + .. + } => { + let mut inputs = Vec::with_capacity( + public_key_x.len() + + public_key_y.len() + + signature.len() + + hashed_message.len(), + ); + inputs.extend(public_key_x.iter().copied()); + inputs.extend(public_key_y.iter().copied()); + inputs.extend(signature.iter().copied()); + inputs.extend(hashed_message.iter().copied()); + inputs + } + BlackBoxFuncCall::EcdsaSecp256r1 { + public_key_x, + public_key_y, + signature, + hashed_message, + .. + } => { + let mut inputs = Vec::with_capacity( + public_key_x.len() + + public_key_y.len() + + signature.len() + + hashed_message.len(), + ); + inputs.extend(public_key_x.iter().copied()); + inputs.extend(public_key_y.iter().copied()); + inputs.extend(signature.iter().copied()); + inputs.extend(hashed_message.iter().copied()); + inputs + } + BlackBoxFuncCall::Keccak256VariableLength { inputs, var_message_size, .. } => { + let mut inputs = inputs.clone(); + inputs.push(*var_message_size); + inputs + } + BlackBoxFuncCall::RecursiveAggregation { + verification_key: key, + proof, + public_inputs, + key_hash, + .. + } => { + let mut inputs = Vec::new(); + inputs.extend(key.iter().copied()); + inputs.extend(proof.iter().copied()); + inputs.extend(public_inputs.iter().copied()); + inputs.push(*key_hash); + // NOTE: we do not return an input aggregation object as it will either be non-existent for the first recursive aggregation + // or the output aggregation object of a previous recursive aggregation. We do not simulate recursive aggregation + // thus the input aggregation object will always be unassigned until proving + inputs + } + } + } + + pub fn get_outputs_vec(&self) -> Vec { + match self { + BlackBoxFuncCall::SHA256 { outputs, .. } + | BlackBoxFuncCall::Blake2s { outputs, .. } + | BlackBoxFuncCall::Keccak256 { outputs, .. } + | BlackBoxFuncCall::RecursiveAggregation { + output_aggregation_object: outputs, .. + } => outputs.to_vec(), + BlackBoxFuncCall::AND { output, .. } + | BlackBoxFuncCall::XOR { output, .. } + | BlackBoxFuncCall::HashToField128Security { output, .. } + | BlackBoxFuncCall::SchnorrVerify { output, .. } + | BlackBoxFuncCall::EcdsaSecp256k1 { output, .. } + | BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output], + BlackBoxFuncCall::FixedBaseScalarMul { outputs, .. } + | BlackBoxFuncCall::Pedersen { outputs, .. } => vec![outputs.0, outputs.1], + BlackBoxFuncCall::RANGE { .. } => vec![], + BlackBoxFuncCall::Keccak256VariableLength { outputs, .. } => outputs.to_vec(), + } + } +} + +const ABBREVIATION_LIMIT: usize = 5; + +fn get_inputs_string(inputs: &[FunctionInput]) -> String { + // Once a vectors length gets above this limit, + // instead of listing all of their elements, we use ellipses + // to abbreviate them + let should_abbreviate_inputs = inputs.len() <= ABBREVIATION_LIMIT; + + if should_abbreviate_inputs { + let mut result = String::new(); + for (index, inp) in inputs.iter().enumerate() { + result += &format!("(_{}, num_bits: {})", inp.witness.witness_index(), inp.num_bits); + // Add a comma, unless it is the last entry + if index != inputs.len() - 1 { + result += ", " + } + } + result + } else { + let first = inputs.first().unwrap(); + let last = inputs.last().unwrap(); + + let mut result = String::new(); + + result += &format!( + "(_{}, num_bits: {})...(_{}, num_bits: {})", + first.witness.witness_index(), + first.num_bits, + last.witness.witness_index(), + last.num_bits, + ); + + result + } +} + +fn get_outputs_string(outputs: &[Witness]) -> String { + let should_abbreviate_outputs = outputs.len() <= ABBREVIATION_LIMIT; + + if should_abbreviate_outputs { + let mut result = String::new(); + for (index, output) in outputs.iter().enumerate() { + result += &format!("_{}", output.witness_index()); + // Add a comma, unless it is the last entry + if index != outputs.len() - 1 { + result += ", " + } + } + result + } else { + let first = outputs.first().unwrap(); + let last = outputs.last().unwrap(); + + let mut result = String::new(); + result += &format!("(_{},...,_{})", first.witness_index(), last.witness_index()); + result + } +} + +impl std::fmt::Display for BlackBoxFuncCall { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let uppercase_name = self.name().to_uppercase(); + write!(f, "BLACKBOX::{uppercase_name} ")?; + // INPUTS + write!(f, "[")?; + + let inputs_str = get_inputs_string(&self.get_inputs_vec()); + + write!(f, "{inputs_str}")?; + write!(f, "] ")?; + + // OUTPUTS + write!(f, "[ ")?; + + let outputs_str = get_outputs_string(&self.get_outputs_vec()); + + write!(f, "{outputs_str}")?; + + write!(f, "]")?; + + // SPECIFIC PARAMETERS + match self { + BlackBoxFuncCall::Pedersen { domain_separator, .. } => { + write!(f, " domain_separator: {domain_separator}") + } + _ => write!(f, ""), + } + } +} + +impl std::fmt::Debug for BlackBoxFuncCall { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self, f) + } +} diff --git a/acvm-repo/acir/src/circuit/opcodes/memory_operation.rs b/acvm-repo/acir/src/circuit/opcodes/memory_operation.rs new file mode 100644 index 00000000000..9e45dc4ee8c --- /dev/null +++ b/acvm-repo/acir/src/circuit/opcodes/memory_operation.rs @@ -0,0 +1,28 @@ +use crate::native_types::{Expression, Witness}; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Hash, Copy, Default)] +pub struct BlockId(pub u32); + +/// Operation on a block of memory +/// We can either write or read at an index in memory +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub struct MemOp { + /// Can be 0 (read) or 1 (write) + pub operation: Expression, + pub index: Expression, + pub value: Expression, +} + +impl MemOp { + /// Creates a `MemOp` which reads from memory at `index` and inserts the read value + /// into the [`WitnessMap`][crate::native_types::WitnessMap] at `witness` + pub fn read_at_mem_index(index: Expression, witness: Witness) -> Self { + MemOp { operation: Expression::zero(), index, value: witness.into() } + } + + /// Creates a `MemOp` which writes the [`Expression`] `value` into memory at `index`. + pub fn write_to_mem_index(index: Expression, value: Expression) -> Self { + MemOp { operation: Expression::one(), index, value } + } +} diff --git a/acvm-repo/acir/src/lib.rs b/acvm-repo/acir/src/lib.rs new file mode 100644 index 00000000000..96ac444b6d9 --- /dev/null +++ b/acvm-repo/acir/src/lib.rs @@ -0,0 +1,12 @@ +#![warn(unused_crate_dependencies)] +#![warn(unreachable_pub)] + +// Arbitrary Circuit Intermediate Representation + +pub mod circuit; +pub mod native_types; + +pub use acir_field; +pub use acir_field::FieldElement; +pub use brillig; +pub use circuit::black_box_functions::BlackBoxFunc; diff --git a/acvm-repo/acir/src/native_types/expression/mod.rs b/acvm-repo/acir/src/native_types/expression/mod.rs new file mode 100644 index 00000000000..368630c2e06 --- /dev/null +++ b/acvm-repo/acir/src/native_types/expression/mod.rs @@ -0,0 +1,398 @@ +use crate::native_types::Witness; +use acir_field::FieldElement; +use serde::{Deserialize, Serialize}; +use std::cmp::Ordering; + +mod operators; +mod ordering; + +// In the addition polynomial +// We can have arbitrary fan-in/out, so we need more than wL,wR and wO +// When looking at the arithmetic opcode for the quotient polynomial in standard plonk +// You can think of it as fan-in 2 and fan out-1 , or you can think of it as fan-in 1 and fan-out 2 +// +// In the multiplication polynomial +// XXX: If we allow the degree of the quotient polynomial to be arbitrary, then we will need a vector of wire values +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] +pub struct Expression { + // To avoid having to create intermediate variables pre-optimization + // We collect all of the multiplication terms in the arithmetic opcode + // A multiplication term if of the form q_M * wL * wR + // Hence this vector represents the following sum: q_M1 * wL1 * wR1 + q_M2 * wL2 * wR2 + .. + + pub mul_terms: Vec<(FieldElement, Witness, Witness)>, + + pub linear_combinations: Vec<(FieldElement, Witness)>, + // TODO: rename q_c to `constant` moreover q_X is not clear to those who + // TODO are not familiar with PLONK + pub q_c: FieldElement, +} + +impl Default for Expression { + fn default() -> Expression { + Expression { + mul_terms: Vec::new(), + linear_combinations: Vec::new(), + q_c: FieldElement::zero(), + } + } +} + +impl std::fmt::Display for Expression { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + if let Some(witness) = self.to_witness() { + write!(f, "x{}", witness.witness_index()) + } else { + write!(f, "%{:?}%", crate::circuit::opcodes::Opcode::Arithmetic(self.clone())) + } + } +} + +impl Expression { + // TODO: possibly remove, and move to noir repo. + pub const fn can_defer_constraint(&self) -> bool { + false + } + + /// Returns the number of multiplication terms + pub fn num_mul_terms(&self) -> usize { + self.mul_terms.len() + } + + pub fn from_field(q_c: FieldElement) -> Expression { + Self { q_c, ..Default::default() } + } + + pub fn one() -> Expression { + Self::from_field(FieldElement::one()) + } + + pub fn zero() -> Expression { + Self::default() + } + + /// Adds a new linear term to the `Expression`. + pub fn push_addition_term(&mut self, coefficient: FieldElement, variable: Witness) { + self.linear_combinations.push((coefficient, variable)) + } + + /// Adds a new quadratic term to the `Expression`. + pub fn push_multiplication_term( + &mut self, + coefficient: FieldElement, + lhs: Witness, + rhs: Witness, + ) { + self.mul_terms.push((coefficient, lhs, rhs)) + } + + /// Returns `true` if the expression represents a constant polynomial. + /// + /// Examples: + /// - f(x,y) = x + y would return false + /// - f(x,y) = xy would return false, the degree here is 2 + /// - f(x,y) = 5 would return true, the degree is 0 + pub fn is_const(&self) -> bool { + self.mul_terms.is_empty() && self.linear_combinations.is_empty() + } + + /// Returns `true` if highest degree term in the expression is one or less. + /// + /// - `mul_term` in an expression contains degree-2 terms + /// - `linear_combinations` contains degree-1 terms + /// Hence, it is sufficient to check that there are no `mul_terms` + /// + /// Examples: + /// - f(x,y) = x + y would return true + /// - f(x,y) = xy would return false, the degree here is 2 + /// - f(x,y) = 0 would return true, the degree is 0 + pub fn is_linear(&self) -> bool { + self.mul_terms.is_empty() + } + + /// Returns `true` if the expression can be seen as a degree-1 univariate polynomial + /// + /// - `mul_terms` in an expression can be univariate, however unless the coefficient + /// is zero, it is always degree-2. + /// - `linear_combinations` contains the sum of degree-1 terms, these terms do not + /// need to contain the same variable and so it can be multivariate. However, we + /// have thus far only checked if `linear_combinations` contains one term, so this + /// method will return false, if the `Expression` has not been simplified. + /// + /// Hence, we check in the simplest case if an expression is a degree-1 univariate, + /// by checking if it contains no `mul_terms` and it contains one `linear_combination` term. + /// + /// Examples: + /// - f(x,y) = x would return true + /// - f(x,y) = x + 6 would return true + /// - f(x,y) = 2*y + 6 would return true + /// - f(x,y) = x + y would return false + /// - f(x,y) = x + x should return true, but we return false *** (we do not simplify) + /// - f(x,y) = 5 would return false + pub fn is_degree_one_univariate(&self) -> bool { + self.is_linear() && self.linear_combinations.len() == 1 + } + + pub fn is_zero(&self) -> bool { + *self == Self::zero() + } + + /// Returns a `FieldElement` if the expression represents a constant polynomial. + /// Otherwise returns `None`. + /// + /// Examples: + /// - f(x,y) = x would return `None` + /// - f(x,y) = x + 6 would return `None` + /// - f(x,y) = 2*y + 6 would return `None` + /// - f(x,y) = x + y would return `None` + /// - f(x,y) = 5 would return `FieldElement(5)` + pub fn to_const(&self) -> Option { + self.is_const().then_some(self.q_c) + } + + /// Returns a `Witness` if the `Expression` can be represented as a degree-1 + /// univariate polynomial. Otherwise returns `None`. + /// + /// Note that `Witness` is only capable of expressing polynomials of the form + /// f(x) = x and not polynomials of the form f(x) = mx+c , so this method has + /// extra checks to ensure that m=1 and c=0 + pub fn to_witness(&self) -> Option { + if self.is_degree_one_univariate() { + // If we get here, we know that our expression is of the form `f(x) = mx+c` + // We want to now restrict ourselves to expressions of the form f(x) = x + // ie where the constant term is 0 and the coefficient in front of the variable is + // one. + let (coefficient, variable) = self.linear_combinations[0]; + let constant = self.q_c; + + if coefficient.is_one() && constant.is_zero() { + return Some(variable); + } + } + None + } + + /// Sorts opcode in a deterministic order + /// XXX: We can probably make this more efficient by sorting on each phase. We only care if it is deterministic + pub fn sort(&mut self) { + self.mul_terms.sort_by(|a, b| a.1.cmp(&b.1).then(a.2.cmp(&b.2))); + self.linear_combinations.sort_by(|a, b| a.1.cmp(&b.1)); + } + + /// Checks if this polynomial can fit into one arithmetic identity + pub fn fits_in_one_identity(&self, width: usize) -> bool { + // A Polynomial with more than one mul term cannot fit into one opcode + if self.mul_terms.len() > 1 { + return false; + }; + // A Polynomial with more terms than fan-in cannot fit within a single opcode + if self.linear_combinations.len() > width { + return false; + } + + // A polynomial with no mul term and a fan-in that fits inside of the width can fit into a single opcode + if self.mul_terms.is_empty() { + return true; + } + + // A polynomial with width-2 fan-in terms and a single non-zero mul term can fit into one opcode + // Example: Axy + Dz . Notice, that the mul term places a constraint on the first two terms, but not the last term + // XXX: This would change if our arithmetic polynomial equation was changed to Axyz for example, but for now it is not. + if self.linear_combinations.len() <= (width - 2) { + return true; + } + + // We now know that we have a single mul term. We also know that the mul term must match up with two other terms + // A polynomial whose mul terms are non zero which do not match up with two terms in the fan-in cannot fit into one opcode + // An example of this is: Axy + Bx + Cy + ... + // Notice how the bivariate monomial xy has two univariate monomials with their respective coefficients + // XXX: note that if x or y is zero, then we could apply a further optimization, but this would be done in another algorithm. + // It would be the same as when we have zero coefficients - Can only work if wire is constrained to be zero publicly + let mul_term = &self.mul_terms[0]; + + // The coefficient should be non-zero, as this method is ran after the compiler removes all zero coefficient terms + assert_ne!(mul_term.0, FieldElement::zero()); + + let mut found_x = false; + let mut found_y = false; + + for term in self.linear_combinations.iter() { + let witness = &term.1; + let x = &mul_term.1; + let y = &mul_term.2; + if witness == x { + found_x = true; + }; + if witness == y { + found_y = true; + }; + if found_x & found_y { + break; + } + } + + found_x & found_y + } + + /// Returns `self + k*b` + pub fn add_mul(&self, k: FieldElement, b: &Expression) -> Expression { + if k.is_zero() { + return self.clone(); + } else if self.is_const() { + return self.q_c + (k * b); + } else if b.is_const() { + return self.clone() + (k * b.q_c); + } + + let mut mul_terms: Vec<(FieldElement, Witness, Witness)> = + Vec::with_capacity(self.mul_terms.len() + b.mul_terms.len()); + let mut linear_combinations: Vec<(FieldElement, Witness)> = + Vec::with_capacity(self.linear_combinations.len() + b.linear_combinations.len()); + let q_c = self.q_c + k * b.q_c; + + //linear combinations + let mut i1 = 0; //a + let mut i2 = 0; //b + while i1 < self.linear_combinations.len() && i2 < b.linear_combinations.len() { + let (a_c, a_w) = self.linear_combinations[i1]; + let (b_c, b_w) = b.linear_combinations[i2]; + + let (coeff, witness) = match a_w.cmp(&b_w) { + Ordering::Greater => { + i2 += 1; + (k * b_c, b_w) + } + Ordering::Less => { + i1 += 1; + (a_c, a_w) + } + Ordering::Equal => { + // Here we're taking both witnesses as the witness indices are equal. + // We then advance both `i1` and `i2`. + i1 += 1; + i2 += 1; + (a_c + k * b_c, a_w) + } + }; + + if !coeff.is_zero() { + linear_combinations.push((coeff, witness)); + } + } + + // Finally process all the remaining terms which we didn't handle in the above loop. + while i1 < self.linear_combinations.len() { + linear_combinations.push(self.linear_combinations[i1]); + i1 += 1; + } + while i2 < b.linear_combinations.len() { + let (b_c, b_w) = b.linear_combinations[i2]; + let coeff = b_c * k; + if !coeff.is_zero() { + linear_combinations.push((coeff, b_w)); + } + i2 += 1; + } + + //mul terms + + i1 = 0; //a + i2 = 0; //b + while i1 < self.mul_terms.len() && i2 < b.mul_terms.len() { + let (a_c, a_wl, a_wr) = self.mul_terms[i1]; + let (b_c, b_wl, b_wr) = b.mul_terms[i2]; + + let (coeff, wl, wr) = match (a_wl, a_wr).cmp(&(b_wl, b_wr)) { + Ordering::Greater => { + i2 += 1; + (k * b_c, b_wl, b_wr) + } + Ordering::Less => { + i1 += 1; + (a_c, a_wl, a_wr) + } + Ordering::Equal => { + // Here we're taking both terms as the witness indices are equal. + // We then advance both `i1` and `i2`. + i2 += 1; + i1 += 1; + (a_c + k * b_c, a_wl, a_wr) + } + }; + + if !coeff.is_zero() { + mul_terms.push((coeff, wl, wr)); + } + } + + // Finally process all the remaining terms which we didn't handle in the above loop. + while i1 < self.mul_terms.len() { + mul_terms.push(self.mul_terms[i1]); + i1 += 1; + } + while i2 < b.mul_terms.len() { + let (b_c, b_wl, b_wr) = b.mul_terms[i2]; + let coeff = b_c * k; + if coeff != FieldElement::zero() { + mul_terms.push((coeff, b_wl, b_wr)); + } + i2 += 1; + } + + Expression { mul_terms, linear_combinations, q_c } + } +} + +impl From for Expression { + fn from(constant: FieldElement) -> Expression { + Expression { q_c: constant, linear_combinations: Vec::new(), mul_terms: Vec::new() } + } +} + +impl From for Expression { + /// Creates an Expression from a Witness. + /// + /// This is infallible since an `Expression` is + /// a multi-variate polynomial and a `Witness` + /// can be seen as a univariate polynomial + fn from(wit: Witness) -> Expression { + Expression { + q_c: FieldElement::zero(), + linear_combinations: vec![(FieldElement::one(), wit)], + mul_terms: Vec::new(), + } + } +} + +#[test] +fn add_mul_smoketest() { + let a = Expression { + mul_terms: vec![(FieldElement::from(2u128), Witness(1), Witness(2))], + ..Default::default() + }; + + let k = FieldElement::from(10u128); + + let b = Expression { + mul_terms: vec![ + (FieldElement::from(3u128), Witness(0), Witness(2)), + (FieldElement::from(3u128), Witness(1), Witness(2)), + (FieldElement::from(4u128), Witness(4), Witness(5)), + ], + linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], + q_c: FieldElement::one(), + }; + + let result = a.add_mul(k, &b); + assert_eq!( + result, + Expression { + mul_terms: vec![ + (FieldElement::from(30u128), Witness(0), Witness(2)), + (FieldElement::from(32u128), Witness(1), Witness(2)), + (FieldElement::from(40u128), Witness(4), Witness(5)), + ], + linear_combinations: vec![(FieldElement::from(40u128), Witness(4))], + q_c: FieldElement::from(10u128) + } + ) +} diff --git a/acvm-repo/acir/src/native_types/expression/operators.rs b/acvm-repo/acir/src/native_types/expression/operators.rs new file mode 100644 index 00000000000..35a548a2e3f --- /dev/null +++ b/acvm-repo/acir/src/native_types/expression/operators.rs @@ -0,0 +1,290 @@ +use crate::native_types::Witness; +use acir_field::FieldElement; +use std::{ + cmp::Ordering, + ops::{Add, Mul, Neg, Sub}, +}; + +use super::Expression; + +// Negation + +impl Neg for &Expression { + type Output = Expression; + fn neg(self) -> Self::Output { + // XXX(med) : Implement an efficient way to do this + + let mul_terms: Vec<_> = + self.mul_terms.iter().map(|(q_m, w_l, w_r)| (-*q_m, *w_l, *w_r)).collect(); + + let linear_combinations: Vec<_> = + self.linear_combinations.iter().map(|(q_k, w_k)| (-*q_k, *w_k)).collect(); + let q_c = -self.q_c; + + Expression { mul_terms, linear_combinations, q_c } + } +} + +// FieldElement + +impl Add for Expression { + type Output = Expression; + fn add(self, rhs: FieldElement) -> Self::Output { + // Increase the constant + let q_c = self.q_c + rhs; + + Expression { mul_terms: self.mul_terms, q_c, linear_combinations: self.linear_combinations } + } +} + +impl Add for FieldElement { + type Output = Expression; + #[inline] + fn add(self, rhs: Expression) -> Self::Output { + rhs + self + } +} + +impl Sub for Expression { + type Output = Expression; + fn sub(self, rhs: FieldElement) -> Self::Output { + // Increase the constant + let q_c = self.q_c - rhs; + + Expression { mul_terms: self.mul_terms, q_c, linear_combinations: self.linear_combinations } + } +} + +impl Sub for FieldElement { + type Output = Expression; + #[inline] + fn sub(self, rhs: Expression) -> Self::Output { + rhs - self + } +} + +impl Mul for &Expression { + type Output = Expression; + fn mul(self, rhs: FieldElement) -> Self::Output { + // Scale the mul terms + let mul_terms: Vec<_> = + self.mul_terms.iter().map(|(q_m, w_l, w_r)| (*q_m * rhs, *w_l, *w_r)).collect(); + + // Scale the linear combinations terms + let lin_combinations: Vec<_> = + self.linear_combinations.iter().map(|(q_l, w_l)| (*q_l * rhs, *w_l)).collect(); + + // Scale the constant + let q_c = self.q_c * rhs; + + Expression { mul_terms, q_c, linear_combinations: lin_combinations } + } +} + +impl Mul<&Expression> for FieldElement { + type Output = Expression; + #[inline] + fn mul(self, rhs: &Expression) -> Self::Output { + rhs * self + } +} + +// Witness + +impl Add for &Expression { + type Output = Expression; + fn add(self, rhs: Witness) -> Expression { + self + &Expression::from(rhs) + } +} + +impl Add<&Expression> for Witness { + type Output = Expression; + #[inline] + fn add(self, rhs: &Expression) -> Expression { + rhs + self + } +} + +impl Sub for &Expression { + type Output = Expression; + fn sub(self, rhs: Witness) -> Expression { + self - &Expression::from(rhs) + } +} + +impl Sub<&Expression> for Witness { + type Output = Expression; + #[inline] + fn sub(self, rhs: &Expression) -> Expression { + rhs - self + } +} + +// Mul is not implemented as this could result in degree 3 terms. + +// Expression + +impl Add<&Expression> for &Expression { + type Output = Expression; + fn add(self, rhs: &Expression) -> Expression { + self.add_mul(FieldElement::one(), rhs) + } +} + +impl Sub<&Expression> for &Expression { + type Output = Expression; + fn sub(self, rhs: &Expression) -> Expression { + self.add_mul(-FieldElement::one(), rhs) + } +} + +impl Mul<&Expression> for &Expression { + type Output = Option; + fn mul(self, rhs: &Expression) -> Option { + if self.is_const() { + return Some(self.q_c * rhs); + } else if rhs.is_const() { + return Some(self * rhs.q_c); + } else if !(self.is_linear() && rhs.is_linear()) { + // `Expression`s can only represent terms which are up to degree 2. + // We then disallow multiplication of `Expression`s which have degree 2 terms. + return None; + } + + let mut output = Expression::from_field(self.q_c * rhs.q_c); + + //TODO to optimize... + for lc in &self.linear_combinations { + let single = single_mul(lc.1, rhs); + output = output.add_mul(lc.0, &single); + } + + //linear terms + let mut i1 = 0; //a + let mut i2 = 0; //b + while i1 < self.linear_combinations.len() && i2 < rhs.linear_combinations.len() { + let (a_c, a_w) = self.linear_combinations[i1]; + let (b_c, b_w) = rhs.linear_combinations[i2]; + + // Apply scaling from multiplication + let a_c = rhs.q_c * a_c; + let b_c = self.q_c * b_c; + + let (coeff, witness) = match a_w.cmp(&b_w) { + Ordering::Greater => { + i2 += 1; + (b_c, b_w) + } + Ordering::Less => { + i1 += 1; + (a_c, a_w) + } + Ordering::Equal => { + // Here we're taking both terms as the witness indices are equal. + // We then advance both `i1` and `i2`. + i1 += 1; + i2 += 1; + (a_c + b_c, a_w) + } + }; + + if !coeff.is_zero() { + output.linear_combinations.push((coeff, witness)); + } + } + while i1 < self.linear_combinations.len() { + let (a_c, a_w) = self.linear_combinations[i1]; + let coeff = rhs.q_c * a_c; + if !coeff.is_zero() { + output.linear_combinations.push((coeff, a_w)); + } + i1 += 1; + } + while i2 < rhs.linear_combinations.len() { + let (b_c, b_w) = rhs.linear_combinations[i2]; + let coeff = self.q_c * b_c; + if !coeff.is_zero() { + output.linear_combinations.push((coeff, b_w)); + } + i2 += 1; + } + + Some(output) + } +} + +/// Returns `w*b.linear_combinations` +fn single_mul(w: Witness, b: &Expression) -> Expression { + Expression { + mul_terms: b + .linear_combinations + .iter() + .map(|(a, wit)| { + let (wl, wr) = if w < *wit { (w, *wit) } else { (*wit, w) }; + (*a, wl, wr) + }) + .collect(), + ..Default::default() + } +} + +#[test] +fn add_smoketest() { + let a = Expression { + mul_terms: vec![], + linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], + q_c: FieldElement::from(2u128), + }; + + let b = Expression { + mul_terms: vec![], + linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], + q_c: FieldElement::one(), + }; + + assert_eq!( + &a + &b, + Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::from(2u128), Witness(2)), + (FieldElement::from(4u128), Witness(4)) + ], + q_c: FieldElement::from(3u128) + } + ); + + // Enforce commutativity + assert_eq!(&a + &b, &b + &a); +} + +#[test] +fn mul_smoketest() { + let a = Expression { + mul_terms: vec![], + linear_combinations: vec![(FieldElement::from(2u128), Witness(2))], + q_c: FieldElement::from(2u128), + }; + + let b = Expression { + mul_terms: vec![], + linear_combinations: vec![(FieldElement::from(4u128), Witness(4))], + q_c: FieldElement::one(), + }; + + assert_eq!( + (&a * &b).unwrap(), + Expression { + mul_terms: vec![(FieldElement::from(8u128), Witness(2), Witness(4)),], + linear_combinations: vec![ + (FieldElement::from(2u128), Witness(2)), + (FieldElement::from(8u128), Witness(4)) + ], + q_c: FieldElement::from(2u128) + } + ); + + // Enforce commutativity + assert_eq!(&a * &b, &b * &a); +} diff --git a/acvm-repo/acir/src/native_types/expression/ordering.rs b/acvm-repo/acir/src/native_types/expression/ordering.rs new file mode 100644 index 00000000000..e24a25ec3af --- /dev/null +++ b/acvm-repo/acir/src/native_types/expression/ordering.rs @@ -0,0 +1,99 @@ +use crate::native_types::Witness; +use std::cmp::Ordering; + +use super::Expression; + +// TODO: It's undecided whether `Expression` should implement `Ord/PartialOrd`. +// This is currently used in ACVM in the compiler. + +impl Ord for Expression { + fn cmp(&self, other: &Self) -> Ordering { + let mut i1 = self.get_max_idx(); + let mut i2 = other.get_max_idx(); + let mut result = Ordering::Equal; + while result == Ordering::Equal { + let m1 = self.get_max_term(&mut i1); + let m2 = other.get_max_term(&mut i2); + if m1.is_none() && m2.is_none() { + return Ordering::Equal; + } + result = Expression::cmp_max(m1, m2); + } + result + } +} + +impl PartialOrd for Expression { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +struct WitnessIdx { + linear: usize, + mul: usize, + second_term: bool, +} + +impl Expression { + fn get_max_idx(&self) -> WitnessIdx { + WitnessIdx { + linear: self.linear_combinations.len(), + mul: self.mul_terms.len(), + second_term: true, + } + } + + /// Returns the maximum witness at the provided position, and decrement the position. + /// + /// This function assumes the gate is sorted + fn get_max_term(&self, idx: &mut WitnessIdx) -> Option { + if idx.linear > 0 { + if idx.mul > 0 { + let mul_term = if idx.second_term { + self.mul_terms[idx.mul - 1].2 + } else { + self.mul_terms[idx.mul - 1].1 + }; + if self.linear_combinations[idx.linear - 1].1 > mul_term { + idx.linear -= 1; + Some(self.linear_combinations[idx.linear].1) + } else { + if idx.second_term { + idx.second_term = false; + } else { + idx.mul -= 1; + } + Some(mul_term) + } + } else { + idx.linear -= 1; + Some(self.linear_combinations[idx.linear].1) + } + } else if idx.mul > 0 { + if idx.second_term { + idx.second_term = false; + Some(self.mul_terms[idx.mul - 1].2) + } else { + idx.mul -= 1; + Some(self.mul_terms[idx.mul].1) + } + } else { + None + } + } + + fn cmp_max(m1: Option, m2: Option) -> Ordering { + if let Some(m1) = m1 { + if let Some(m2) = m2 { + m1.cmp(&m2) + } else { + Ordering::Greater + } + } else if m2.is_some() { + Ordering::Less + } else { + Ordering::Equal + } + } +} diff --git a/acvm-repo/acir/src/native_types/mod.rs b/acvm-repo/acir/src/native_types/mod.rs new file mode 100644 index 00000000000..66c822bfff8 --- /dev/null +++ b/acvm-repo/acir/src/native_types/mod.rs @@ -0,0 +1,8 @@ +mod expression; +mod witness; +mod witness_map; + +pub use expression::Expression; +pub use witness::Witness; +pub use witness_map::WitnessMap; +pub use witness_map::WitnessMapError; diff --git a/acvm-repo/acir/src/native_types/witness.rs b/acvm-repo/acir/src/native_types/witness.rs new file mode 100644 index 00000000000..740d10d2951 --- /dev/null +++ b/acvm-repo/acir/src/native_types/witness.rs @@ -0,0 +1,43 @@ +use std::ops::Add; + +use acir_field::FieldElement; +use serde::{Deserialize, Serialize}; + +use super::Expression; + +// Witness might be a misnomer. This is an index that represents the position a witness will take +#[derive( + Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize, +)] +pub struct Witness(pub u32); + +impl Witness { + pub fn new(witness_index: u32) -> Witness { + Witness(witness_index) + } + pub fn witness_index(&self) -> u32 { + self.0 + } + pub fn as_usize(&self) -> usize { + // This is safe as long as the architecture is 32bits minimum + self.0 as usize + } + + pub const fn can_defer_constraint(&self) -> bool { + true + } +} + +impl From for Witness { + fn from(value: u32) -> Self { + Self(value) + } +} + +impl Add for Witness { + type Output = Expression; + + fn add(self, rhs: Witness) -> Self::Output { + Expression::from(self).add_mul(FieldElement::one(), &Expression::from(rhs)) + } +} diff --git a/acvm-repo/acir/src/native_types/witness_map.rs b/acvm-repo/acir/src/native_types/witness_map.rs new file mode 100644 index 00000000000..400e0a8ca1a --- /dev/null +++ b/acvm-repo/acir/src/native_types/witness_map.rs @@ -0,0 +1,146 @@ +use std::{ + collections::{btree_map, BTreeMap}, + io::Read, + ops::Index, +}; + +use acir_field::FieldElement; +use flate2::bufread::GzDecoder; +use flate2::bufread::GzEncoder; +use flate2::Compression; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +use crate::native_types::Witness; + +#[cfg(feature = "serialize-messagepack")] +#[derive(Debug, Error)] +enum SerializationError { + #[error(transparent)] + MsgpackEncode(#[from] rmp_serde::encode::Error), + + #[error(transparent)] + MsgpackDecode(#[from] rmp_serde::decode::Error), + + #[error(transparent)] + Deflate(#[from] std::io::Error), +} + +#[cfg(not(feature = "serialize-messagepack"))] +#[derive(Debug, Error)] +enum SerializationError { + #[error(transparent)] + Deflate(#[from] std::io::Error), +} + +#[derive(Debug, Error)] +#[error(transparent)] +pub struct WitnessMapError(#[from] SerializationError); + +/// A map from the witnesses in a constraint system to the field element values +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Serialize, Deserialize)] +pub struct WitnessMap(BTreeMap); + +impl WitnessMap { + pub fn new() -> Self { + Self(BTreeMap::new()) + } + pub fn get(&self, witness: &Witness) -> Option<&FieldElement> { + self.0.get(witness) + } + pub fn get_index(&self, index: u32) -> Option<&FieldElement> { + self.0.get(&index.into()) + } + pub fn contains_key(&self, key: &Witness) -> bool { + self.0.contains_key(key) + } + pub fn insert(&mut self, key: Witness, value: FieldElement) -> Option { + self.0.insert(key, value) + } +} + +impl Index<&Witness> for WitnessMap { + type Output = FieldElement; + + fn index(&self, index: &Witness) -> &Self::Output { + &self.0[index] + } +} + +pub struct IntoIter(btree_map::IntoIter); + +impl Iterator for IntoIter { + type Item = (Witness, FieldElement); + + fn next(&mut self) -> Option { + self.0.next() + } +} + +impl IntoIterator for WitnessMap { + type Item = (Witness, FieldElement); + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntoIter(self.0.into_iter()) + } +} + +impl From> for WitnessMap { + fn from(value: BTreeMap) -> Self { + Self(value) + } +} + +#[cfg(feature = "serialize-messagepack")] +impl TryFrom for Vec { + type Error = WitnessMapError; + + fn try_from(val: WitnessMap) -> Result { + let buf = rmp_serde::to_vec(&val).map_err(|err| WitnessMapError(err.into()))?; + let mut deflater = flate2::write::DeflateEncoder::new(buf.as_slice(), Compression::best()); + let mut buf_c = Vec::new(); + deflater.read_to_end(&mut buf_c).map_err(|err| WitnessMapError(err.into()))?; + Ok(buf_c) + } +} + +#[cfg(not(feature = "serialize-messagepack"))] +impl TryFrom for Vec { + type Error = WitnessMapError; + + fn try_from(val: WitnessMap) -> Result { + let buf = bincode::serialize(&val).unwrap(); + let mut deflater = GzEncoder::new(buf.as_slice(), Compression::best()); + let mut buf_c = Vec::new(); + deflater.read_to_end(&mut buf_c).map_err(|err| WitnessMapError(err.into()))?; + Ok(buf_c) + } +} + +#[cfg(feature = "serialize-messagepack")] +impl TryFrom<&[u8]> for WitnessMap { + type Error = WitnessMapError; + + fn try_from(bytes: &[u8]) -> Result { + let mut deflater = flate2::bufread::DeflateDecoder::new(bytes); + let mut buf_d = Vec::new(); + deflater.read_to_end(&mut buf_d).map_err(|err| WitnessMapError(err.into()))?; + let witness_map = + rmp_serde::from_slice(buf_d.as_slice()).map_err(|err| WitnessMapError(err.into()))?; + Ok(Self(witness_map)) + } +} + +#[cfg(not(feature = "serialize-messagepack"))] +impl TryFrom<&[u8]> for WitnessMap { + type Error = WitnessMapError; + + fn try_from(bytes: &[u8]) -> Result { + let mut deflater = GzDecoder::new(bytes); + let mut buf_d = Vec::new(); + deflater.read_to_end(&mut buf_d).map_err(|err| WitnessMapError(err.into()))?; + let witness_map = bincode::deserialize(buf_d.as_slice()).unwrap(); + Ok(Self(witness_map)) + } +} diff --git a/acvm-repo/acir/tests/test_program_serialization.rs b/acvm-repo/acir/tests/test_program_serialization.rs new file mode 100644 index 00000000000..5aa51237dd9 --- /dev/null +++ b/acvm-repo/acir/tests/test_program_serialization.rs @@ -0,0 +1,330 @@ +//! This integration test defines a set of circuits which are used in order to test the acvm_js package. +//! +//! The acvm_js test suite contains serialized [circuits][`Circuit`] which must be kept in sync with the format +//! outputted from the [ACIR crate][acir]. +//! Breaking changes to the serialization format then require refreshing acvm_js's test suite. +//! This file contains Rust definitions of these circuits and outputs the updated serialized format. +//! +//! These tests also check this circuit serialization against an expected value, erroring if the serialization changes. +//! Generally in this situation we just need to refresh the `expected_serialization` variables to match the +//! actual output, **HOWEVER** note that this results in a breaking change to the ACIR format. + +use std::collections::BTreeSet; + +use acir::{ + circuit::{ + brillig::{Brillig, BrilligInputs, BrilligOutputs}, + opcodes::{BlackBoxFuncCall, BlockId, FunctionInput, MemOp}, + Circuit, Opcode, PublicInputs, + }, + native_types::{Expression, Witness}, +}; +use acir_field::FieldElement; +use brillig::{HeapArray, RegisterIndex, RegisterOrMemory}; + +#[test] +fn addition_circuit() { + let addition = Opcode::Arithmetic(Expression { + mul_terms: Vec::new(), + linear_combinations: vec![ + (FieldElement::one(), Witness(1)), + (FieldElement::one(), Witness(2)), + (-FieldElement::one(), Witness(3)), + ], + q_c: FieldElement::zero(), + }); + + let circuit = Circuit { + current_witness_index: 4, + opcodes: vec![addition], + private_parameters: BTreeSet::from([Witness(1), Witness(2)]), + return_values: PublicInputs([Witness(3)].into()), + ..Circuit::default() + }; + + let mut bytes = Vec::new(); + circuit.write(&mut bytes).unwrap(); + + let expected_serialization: Vec = vec![ + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 187, 13, 192, 32, 12, 68, 249, 100, 32, 27, + 219, 96, 119, 89, 37, 40, 176, 255, 8, 17, 18, 5, 74, 202, 240, 154, 235, 158, 238, 238, + 112, 206, 121, 247, 37, 206, 60, 103, 194, 63, 208, 111, 116, 133, 197, 69, 144, 153, 91, + 73, 13, 9, 47, 72, 86, 85, 128, 165, 102, 69, 69, 81, 185, 147, 18, 53, 101, 45, 86, 173, + 128, 33, 83, 195, 46, 70, 125, 202, 226, 190, 94, 16, 166, 103, 108, 13, 203, 151, 254, + 245, 233, 224, 1, 1, 52, 166, 127, 120, 1, 0, 0, + ]; + + assert_eq!(bytes, expected_serialization) +} + +#[test] +fn fixed_base_scalar_mul_circuit() { + let fixed_base_scalar_mul = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::FixedBaseScalarMul { + low: FunctionInput { witness: Witness(1), num_bits: 128 }, + high: FunctionInput { witness: Witness(2), num_bits: 128 }, + outputs: (Witness(3), Witness(4)), + }); + + let circuit = Circuit { + current_witness_index: 5, + opcodes: vec![fixed_base_scalar_mul], + private_parameters: BTreeSet::from([Witness(1), Witness(2)]), + return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(3), Witness(4)])), + ..Circuit::default() + }; + + let mut bytes = Vec::new(); + circuit.write(&mut bytes).unwrap(); + + let expected_serialization: Vec = vec![ + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 138, 91, 10, 0, 48, 12, 194, 178, 215, 207, 78, 189, + 163, 175, 165, 10, 21, 36, 10, 57, 192, 160, 146, 188, 226, 139, 78, 113, 69, 183, 190, 61, + 111, 218, 182, 231, 124, 68, 185, 243, 207, 92, 0, 0, 0, + ]; + + assert_eq!(bytes, expected_serialization) +} + +#[test] +fn pedersen_circuit() { + let pedersen = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Pedersen { + inputs: vec![FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }], + outputs: (Witness(2), Witness(3)), + domain_separator: 0, + }); + + let circuit = Circuit { + current_witness_index: 4, + opcodes: vec![pedersen], + private_parameters: BTreeSet::from([Witness(1)]), + return_values: PublicInputs(BTreeSet::from_iter(vec![Witness(2), Witness(3)])), + ..Circuit::default() + }; + + let mut bytes = Vec::new(); + circuit.write(&mut bytes).unwrap(); + + let expected_serialization: Vec = vec![ + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 138, 9, 10, 0, 64, 8, 2, 103, 15, 250, 255, 139, + 163, 162, 130, 72, 16, 149, 241, 3, 135, 84, 164, 172, 173, 213, 175, 251, 45, 198, 96, + 243, 211, 50, 152, 67, 220, 211, 92, 0, 0, 0, + ]; + + assert_eq!(bytes, expected_serialization) +} + +#[test] +fn schnorr_verify_circuit() { + let public_key_x = + FunctionInput { witness: Witness(1), num_bits: FieldElement::max_num_bits() }; + let public_key_y = + FunctionInput { witness: Witness(2), num_bits: FieldElement::max_num_bits() }; + let signature = + (3..(3 + 64)).map(|i| FunctionInput { witness: Witness(i), num_bits: 8 }).collect(); + let message = ((3 + 64)..(3 + 64 + 10)) + .map(|i| FunctionInput { witness: Witness(i), num_bits: 8 }) + .collect(); + let output = Witness(3 + 64 + 10); + let last_input = output.witness_index() - 1; + + let schnorr = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::SchnorrVerify { + public_key_x, + public_key_y, + signature, + message, + output, + }); + + let circuit = Circuit { + current_witness_index: 100, + opcodes: vec![schnorr], + private_parameters: BTreeSet::from_iter((1..=last_input).map(Witness)), + return_values: PublicInputs(BTreeSet::from([output])), + ..Circuit::default() + }; + + let mut bytes = Vec::new(); + circuit.write(&mut bytes).unwrap(); + + let expected_serialization: Vec = vec![ + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 210, 87, 78, 2, 1, 20, 134, 209, 177, 247, 222, 123, + 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 221, 133, 251, 95, 130, 145, 27, 206, 36, 78, 50, + 57, 16, 94, 200, 253, 191, 159, 36, 73, 134, 146, 193, 19, 142, 241, 183, 255, 14, 179, + 233, 247, 145, 254, 59, 217, 127, 71, 57, 198, 113, 78, 48, 125, 167, 56, 205, 25, 206, + 114, 142, 243, 92, 224, 34, 151, 184, 204, 21, 174, 114, 141, 235, 220, 224, 38, 183, 184, + 205, 29, 238, 114, 143, 251, 60, 224, 33, 143, 120, 204, 19, 158, 242, 140, 25, 158, 51, + 203, 11, 230, 120, 201, 60, 175, 88, 224, 53, 139, 188, 97, 137, 183, 44, 243, 142, 21, + 222, 179, 202, 7, 214, 248, 200, 58, 159, 216, 224, 51, 155, 124, 97, 235, 223, 142, 241, + 188, 250, 222, 230, 27, 59, 124, 103, 151, 31, 236, 241, 147, 95, 252, 246, 57, 158, 104, + 47, 186, 139, 214, 162, 179, 104, 44, 250, 74, 219, 154, 242, 63, 162, 165, 232, 40, 26, + 138, 126, 162, 157, 232, 38, 154, 137, 94, 162, 149, 232, 36, 26, 137, 62, 162, 141, 232, + 34, 154, 136, 30, 162, 133, 232, 32, 26, 136, 253, 99, 251, 195, 100, 176, 121, 236, 29, + 91, 159, 218, 56, 99, 219, 172, 77, 115, 182, 204, 219, 176, 96, 187, 162, 205, 74, 182, + 42, 219, 168, 98, 155, 170, 77, 106, 182, 168, 219, 160, 225, 246, 77, 55, 111, 185, 113, + 219, 109, 59, 110, 218, 117, 203, 158, 27, 166, 55, 75, 239, 150, 184, 101, 250, 252, 1, + 19, 89, 159, 101, 220, 3, 0, 0, + ]; + + assert_eq!(bytes, expected_serialization) +} + +#[test] +fn simple_brillig_foreign_call() { + let w_input = Witness(1); + let w_inverted = Witness(2); + + let brillig_data = Brillig { + inputs: vec![ + BrilligInputs::Single(w_input.into()), // Input Register 0, + ], + // This tells the BrilligSolver which witnesses its output registers correspond to + outputs: vec![ + BrilligOutputs::Simple(w_inverted), // Output Register 1 + ], + // stack of foreign call/oracle resolutions, starts empty + foreign_call_results: vec![], + bytecode: vec![brillig::Opcode::ForeignCall { + function: "invert".into(), + destinations: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(0))], + inputs: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(0))], + }], + predicate: None, + }; + + let opcodes = vec![Opcode::Brillig(brillig_data)]; + let circuit = Circuit { + current_witness_index: 8, + opcodes, + private_parameters: BTreeSet::from([Witness(1), Witness(2)]), + ..Circuit::default() + }; + + let mut bytes = Vec::new(); + circuit.write(&mut bytes).unwrap(); + + let expected_serialization: Vec = vec![ + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 143, 81, 10, 0, 16, 16, 68, 199, 42, 57, 14, 55, + 112, 25, 31, 126, 124, 72, 206, 79, 161, 86, 225, 135, 87, 219, 78, 187, 53, 205, 104, 0, + 2, 29, 201, 52, 103, 222, 220, 216, 230, 13, 43, 254, 121, 25, 158, 151, 54, 153, 117, 27, + 53, 116, 136, 197, 167, 124, 107, 184, 64, 236, 73, 56, 83, 1, 18, 139, 122, 157, 67, 1, 0, + 0, + ]; + + assert_eq!(bytes, expected_serialization) +} + +#[test] +fn complex_brillig_foreign_call() { + let fe_0 = FieldElement::zero(); + let fe_1 = FieldElement::one(); + let a = Witness(1); + let b = Witness(2); + let c = Witness(3); + + let a_times_2 = Witness(4); + let b_times_3 = Witness(5); + let c_times_4 = Witness(6); + let a_plus_b_plus_c = Witness(7); + let a_plus_b_plus_c_times_2 = Witness(8); + + let brillig_data = Brillig { + inputs: vec![ + // Input Register 0 + BrilligInputs::Array(vec![ + Expression::from(a), + Expression::from(b), + Expression::from(c), + ]), + // Input Register 1 + BrilligInputs::Single(Expression { + mul_terms: vec![], + linear_combinations: vec![(fe_1, a), (fe_1, b), (fe_1, c)], + q_c: fe_0, + }), + ], + // This tells the BrilligSolver which witnesses its output registers correspond to + outputs: vec![ + BrilligOutputs::Array(vec![a_times_2, b_times_3, c_times_4]), // Output Register 0 + BrilligOutputs::Simple(a_plus_b_plus_c), // Output Register 1 + BrilligOutputs::Simple(a_plus_b_plus_c_times_2), // Output Register 2 + ], + // stack of foreign call/oracle resolutions, starts empty + foreign_call_results: vec![], + bytecode: vec![ + // Oracles are named 'foreign calls' in brillig + brillig::Opcode::ForeignCall { + function: "complex".into(), + inputs: vec![ + RegisterOrMemory::HeapArray(HeapArray { pointer: 0.into(), size: 3 }), + RegisterOrMemory::RegisterIndex(RegisterIndex::from(1)), + ], + destinations: vec![ + RegisterOrMemory::HeapArray(HeapArray { pointer: 0.into(), size: 3 }), + RegisterOrMemory::RegisterIndex(RegisterIndex::from(1)), + RegisterOrMemory::RegisterIndex(RegisterIndex::from(2)), + ], + }, + ], + predicate: None, + }; + + let opcodes = vec![Opcode::Brillig(brillig_data)]; + let circuit = Circuit { + current_witness_index: 8, + opcodes, + private_parameters: BTreeSet::from([Witness(1), Witness(2), Witness(3)]), + ..Circuit::default() + }; + + let mut bytes = Vec::new(); + circuit.write(&mut bytes).unwrap(); + + let expected_serialization: Vec = vec![ + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 219, 10, 128, 48, 8, 245, 210, 101, 159, 179, + 254, 160, 127, 137, 222, 138, 122, 236, 243, 27, 228, 64, 44, 232, 33, 7, 237, 128, 56, + 157, 147, 131, 103, 6, 0, 64, 184, 192, 201, 72, 206, 40, 177, 70, 174, 27, 197, 199, 111, + 24, 208, 175, 87, 44, 197, 145, 42, 224, 200, 5, 56, 230, 255, 240, 83, 189, 61, 117, 113, + 157, 31, 63, 236, 79, 147, 172, 77, 214, 73, 220, 139, 15, 106, 214, 168, 114, 249, 126, + 218, 214, 125, 153, 15, 54, 37, 90, 26, 155, 39, 227, 95, 223, 232, 230, 4, 247, 157, 215, + 56, 1, 153, 86, 63, 138, 44, 4, 0, 0, + ]; + + assert_eq!(bytes, expected_serialization) +} + +#[test] +fn memory_op_circuit() { + let init = vec![Witness(1), Witness(2)]; + + let memory_init = Opcode::MemoryInit { block_id: BlockId(0), init }; + let write = Opcode::MemoryOp { + block_id: BlockId(0), + op: MemOp::write_to_mem_index(FieldElement::from(1u128).into(), Witness(3).into()), + predicate: None, + }; + let read = Opcode::MemoryOp { + block_id: BlockId(0), + op: MemOp::read_at_mem_index(FieldElement::one().into(), Witness(4)), + predicate: None, + }; + + let circuit = Circuit { + current_witness_index: 5, + opcodes: vec![memory_init, write, read], + private_parameters: BTreeSet::from([Witness(1), Witness(2), Witness(3)]), + return_values: PublicInputs([Witness(4)].into()), + ..Circuit::default() + }; + let mut bytes = Vec::new(); + circuit.write(&mut bytes).unwrap(); + + let expected_serialization: Vec = vec![ + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 146, 49, 14, 0, 32, 8, 3, 139, 192, 127, 240, 7, + 254, 255, 85, 198, 136, 9, 131, 155, 48, 216, 165, 76, 77, 57, 80, 0, 140, 45, 117, 111, + 238, 228, 179, 224, 174, 225, 110, 111, 234, 213, 185, 148, 156, 203, 121, 89, 86, 13, 215, + 126, 131, 43, 153, 187, 115, 40, 185, 62, 153, 3, 136, 83, 60, 30, 96, 2, 12, 235, 225, + 124, 14, 3, 0, 0, + ]; + + assert_eq!(bytes, expected_serialization) +} diff --git a/acvm-repo/acir_field/.gitignore b/acvm-repo/acir_field/.gitignore new file mode 100644 index 00000000000..c41cc9e35e3 --- /dev/null +++ b/acvm-repo/acir_field/.gitignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/acvm-repo/acir_field/CHANGELOG.md b/acvm-repo/acir_field/CHANGELOG.md new file mode 100644 index 00000000000..1d80bfd6a20 --- /dev/null +++ b/acvm-repo/acir_field/CHANGELOG.md @@ -0,0 +1,296 @@ +# Changelog + +## [0.27.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.26.1...acir_field-v0.27.0) (2023-09-19) + + +### ⚠ BREAKING CHANGES + +* Separate barretenberg solver from generic blackbox solver code ([#554](https://github.com/noir-lang/acvm/issues/554)) + +### Miscellaneous Chores + +* Separate barretenberg solver from generic blackbox solver code ([#554](https://github.com/noir-lang/acvm/issues/554)) ([a4b9772](https://github.com/noir-lang/acvm/commit/a4b97722a0892fe379ff075e6080675adafdce0e)) + +## [0.26.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.26.0...acir_field-v0.26.1) (2023-09-12) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.26.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.25.0...acir_field-v0.26.0) (2023-09-07) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.25.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.24.1...acir_field-v0.25.0) (2023-09-04) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.24.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.24.0...acir_field-v0.24.1) (2023-09-03) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.24.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.23.0...acir_field-v0.24.0) (2023-08-31) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.23.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.22.0...acir_field-v0.23.0) (2023-08-30) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.22.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.21.0...acir_field-v0.22.0) (2023-08-18) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.21.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.20.1...acir_field-v0.21.0) (2023-07-26) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.20.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.20.0...acir_field-v0.20.1) (2023-07-26) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.20.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.19.1...acir_field-v0.20.0) (2023-07-20) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.19.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.19.0...acir_field-v0.19.1) (2023-07-17) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.19.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.18.2...acir_field-v0.19.0) (2023-07-15) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.18.2](https://github.com/noir-lang/acvm/compare/acir_field-v0.18.1...acir_field-v0.18.2) (2023-07-12) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.18.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.18.0...acir_field-v0.18.1) (2023-07-12) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.18.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.17.0...acir_field-v0.18.0) (2023-07-12) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.17.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.16.0...acir_field-v0.17.0) (2023-07-07) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.16.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.15.1...acir_field-v0.16.0) (2023-07-06) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.15.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.15.0...acir_field-v0.15.1) (2023-06-20) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.15.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.14.2...acir_field-v0.15.0) (2023-06-15) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.14.2](https://github.com/noir-lang/acvm/compare/acir_field-v0.14.1...acir_field-v0.14.2) (2023-06-08) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.14.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.14.0...acir_field-v0.14.1) (2023-06-07) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.14.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.13.3...acir_field-v0.14.0) (2023-06-06) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.13.3](https://github.com/noir-lang/acvm/compare/acir_field-v0.13.2...acir_field-v0.13.3) (2023-06-05) + + +### Bug Fixes + +* Empty commit to trigger release-please ([e8f0748](https://github.com/noir-lang/acvm/commit/e8f0748042ef505d59ab63266d3c36c5358ee30d)) + +## [0.13.2](https://github.com/noir-lang/acvm/compare/acir_field-v0.13.1...acir_field-v0.13.2) (2023-06-02) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.13.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.13.0...acir_field-v0.13.1) (2023-06-01) + + +### Bug Fixes + +* **ci:** Correct typo to avoid `undefined` in changelogs ([#333](https://github.com/noir-lang/acvm/issues/333)) ([d3424c0](https://github.com/noir-lang/acvm/commit/d3424c04fd303c9cbe25d03118d8b358cbb84b83)) + +## [0.13.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.12.0...acir_field-v0.13.0) (2023-06-01) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.12.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.11.0...acir_field-v0.12.0) (2023-05-17) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.11.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.10.3...acir_field-v0.11.0) (2023-05-04) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.10.3](https://github.com/noir-lang/acvm/compare/acir_field-v0.10.2...acir_field-v0.10.3) (2023-04-28) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.10.2](https://github.com/noir-lang/acvm/compare/acir_field-v0.10.1...acir_field-v0.10.2) (2023-04-28) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.10.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.10.0...acir_field-v0.10.1) (2023-04-28) + + +### Features + +* implement `FieldElement::from<bool>()` ([#203](https://github.com/noir-lang/acvm/issues/203)) ([476cfa2](https://github.com/noir-lang/acvm/commit/476cfa247fddb515c64c2801c6868357c9375294)) +* Update Arkworks' dependencies on `acir_field` ([#69](https://github.com/noir-lang/acvm/issues/69)) ([65d6130](https://github.com/noir-lang/acvm/commit/65d61307a12f25e04afad2d50e4c4db5ce97dd8c)) + + +### Bug Fixes + +* prevent `bn254` feature flag always being enabled ([#225](https://github.com/noir-lang/acvm/issues/225)) ([82eee6a](https://github.com/noir-lang/acvm/commit/82eee6ab08ae480f04904ca8571fd88f4466c000)) + +## [0.10.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.9.0...acir_field-v0.10.0) (2023-04-26) + + +### Features + +* implement `FieldElement::from<bool>()` ([#203](https://github.com/noir-lang/acvm/issues/203)) ([476cfa2](https://github.com/noir-lang/acvm/commit/476cfa247fddb515c64c2801c6868357c9375294)) + + +### Bug Fixes + +* prevent `bn254` feature flag always being enabled ([#225](https://github.com/noir-lang/acvm/issues/225)) ([82eee6a](https://github.com/noir-lang/acvm/commit/82eee6ab08ae480f04904ca8571fd88f4466c000)) + +## [0.9.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.8.1...acir_field-v0.9.0) (2023-04-07) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.8.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.8.0...acir_field-v0.8.1) (2023-03-30) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.8.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.7.1...acir_field-v0.8.0) (2023-03-28) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.7.1](https://github.com/noir-lang/acvm/compare/acir_field-v0.7.0...acir_field-v0.7.1) (2023-03-27) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.7.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.6.0...acir_field-v0.7.0) (2023-03-23) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.6.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.5.0...acir_field-v0.6.0) (2023-03-03) + + +### Miscellaneous Chores + +* **acir_field:** Synchronize acvm versions + +## [0.5.0](https://github.com/noir-lang/acvm/compare/acir_field-v0.4.1...acir_field-v0.5.0) (2023-02-22) + + +### Features + +* Update Arkworks' dependencies on `acir_field` ([#69](https://github.com/noir-lang/acvm/issues/69)) ([65d6130](https://github.com/noir-lang/acvm/commit/65d61307a12f25e04afad2d50e4c4db5ce97dd8c)) diff --git a/acvm-repo/acir_field/Cargo.toml b/acvm-repo/acir_field/Cargo.toml new file mode 100644 index 00000000000..3d9da848a0d --- /dev/null +++ b/acvm-repo/acir_field/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "acir_field" +description = "The field implementation being used by ACIR." +version = "0.27.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true +repository.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +hex.workspace = true +num-bigint.workspace = true +serde.workspace = true + +ark-bn254 = { version = "^0.4.0", optional = true, default-features = false, features = [ + "curve", +] } +ark-bls12-381 = { version = "^0.4.0", optional = true, default-features = false, features = [ + "curve", +] } +ark-ff = { version = "^0.4.0", optional = true, default-features = false } + +cfg-if = "1.0.0" + +[features] +default = ["bn254"] +bn254 = ["dep:ark-bn254", "dep:ark-ff"] +bls12_381 = ["dep:ark-bls12-381", "dep:ark-ff"] diff --git a/acvm-repo/acir_field/src/generic_ark.rs b/acvm-repo/acir_field/src/generic_ark.rs new file mode 100644 index 00000000000..59600549f32 --- /dev/null +++ b/acvm-repo/acir_field/src/generic_ark.rs @@ -0,0 +1,502 @@ +use ark_ff::PrimeField; +use ark_ff::Zero; +use num_bigint::BigUint; +use serde::{Deserialize, Serialize}; + +// XXX: Switch out for a trait and proper implementations +// This implementation is in-efficient, can definitely remove hex usage and Iterator instances for trivial functionality +#[derive(Clone, Copy, Eq, PartialOrd, Ord)] +pub struct FieldElement(F); + +impl std::fmt::Display for FieldElement { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + // First check if the number is zero + // + let number = BigUint::from_bytes_be(&self.to_be_bytes()); + if number == BigUint::zero() { + return write!(f, "0"); + } + // Check if the negative version is smaller to represent + // + let minus_number = BigUint::from_bytes_be(&(self.neg()).to_be_bytes()); + let (smaller_repr, is_negative) = + if minus_number.to_string().len() < number.to_string().len() { + (minus_number, true) + } else { + (number, false) + }; + if is_negative { + write!(f, "-")?; + } + + // Number of bits needed to represent the smaller representation + let num_bits = smaller_repr.bits(); + + // Check if the number represents a power of 2 + if smaller_repr.count_ones() == 1 { + let mut bit_index = 0; + for i in 0..num_bits { + if smaller_repr.bit(i) { + bit_index = i; + break; + } + } + return match bit_index { + 0 => write!(f, "1"), + 1 => write!(f, "2"), + 2 => write!(f, "4"), + 3 => write!(f, "8"), + _ => write!(f, "2{}", superscript(bit_index)), + }; + } + + // Check if number is a multiple of a power of 2. + // This is used because when computing the quotient + // we usually have numbers in the form 2^t * q + r + // We focus on 2^64, 2^32, 2^16, 2^8, 2^4 because + // they are common. We could extend this to a more + // general factorization strategy, but we pay in terms of CPU time + let mul_sign = "×"; + for power in [64, 32, 16, 8, 4] { + let power_of_two = BigUint::from(2_u128).pow(power); + if &smaller_repr % &power_of_two == BigUint::zero() { + return write!( + f, + "2{}{}{}", + superscript(power as u64), + mul_sign, + smaller_repr / &power_of_two, + ); + } + } + write!(f, "{smaller_repr}") + } +} + +impl std::fmt::Debug for FieldElement { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self, f) + } +} + +impl std::hash::Hash for FieldElement { + fn hash(&self, state: &mut H) { + state.write(&self.to_be_bytes()) + } +} + +impl PartialEq for FieldElement { + fn eq(&self, other: &Self) -> bool { + self.to_be_bytes() == other.to_be_bytes() + } +} + +impl From for FieldElement { + fn from(mut a: i128) -> FieldElement { + let mut negative = false; + if a < 0 { + a = -a; + negative = true; + } + + let mut result = match F::from_str(&a.to_string()) { + Ok(result) => result, + Err(_) => panic!("Cannot convert i128 as a string to a field element"), + }; + + if negative { + result = -result; + } + FieldElement(result) + } +} + +impl Serialize for FieldElement { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.to_hex().serialize(serializer) + } +} + +impl<'de, T: ark_ff::PrimeField> Deserialize<'de> for FieldElement { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = <&str>::deserialize(deserializer)?; + match Self::from_hex(s) { + Some(value) => Ok(value), + None => Err(serde::de::Error::custom(format!("Invalid hex for FieldElement: {s}",))), + } + } +} + +impl From for FieldElement { + fn from(a: u128) -> FieldElement { + let result = match F::from_str(&a.to_string()) { + Ok(result) => result, + Err(_) => panic!("Cannot convert u128 as a string to a field element"), + }; + FieldElement(result) + } +} + +impl From for FieldElement { + fn from(boolean: bool) -> FieldElement { + if boolean { + FieldElement::one() + } else { + FieldElement::zero() + } + } +} + +impl FieldElement { + pub fn one() -> FieldElement { + FieldElement(F::one()) + } + pub fn zero() -> FieldElement { + FieldElement(F::zero()) + } + + pub fn is_zero(&self) -> bool { + self == &Self::zero() + } + pub fn is_one(&self) -> bool { + self == &Self::one() + } + + pub fn pow(&self, exponent: &Self) -> Self { + FieldElement(self.0.pow(exponent.0.into_bigint())) + } + + /// Maximum number of bits needed to represent a field element + /// This is not the amount of bits being used to represent a field element + /// Example, you only need 254 bits to represent a field element in BN256 + /// But the representation uses 256 bits, so the top two bits are always zero + /// This method would return 254 + pub const fn max_num_bits() -> u32 { + F::MODULUS_BIT_SIZE + } + + /// Maximum numbers of bytes needed to represent a field element + /// We are not guaranteed that the number of bits being used to represent a field element + /// will always be divisible by 8. If the case that it is not, we add one to the max number of bytes + /// For example, a max bit size of 254 would give a max byte size of 32. + pub const fn max_num_bytes() -> u32 { + let num_bytes = Self::max_num_bits() / 8; + if Self::max_num_bits() % 8 == 0 { + num_bytes + } else { + num_bytes + 1 + } + } + + pub fn modulus() -> BigUint { + F::MODULUS.into() + } + /// Returns None, if the string is not a canonical + /// representation of a field element; less than the order + /// or if the hex string is invalid. + /// This method can be used for both hex and decimal representations. + pub fn try_from_str(input: &str) -> Option> { + if input.contains('x') { + return FieldElement::from_hex(input); + } + + let fr = F::from_str(input).ok()?; + Some(FieldElement(fr)) + } + + /// This is the number of bits required to represent this specific field element + pub fn num_bits(&self) -> u32 { + let bits = self.bits(); + // Iterate the number of bits and pop off all leading zeroes + let iter = bits.iter().skip_while(|x| !(**x)); + // Note: count will panic if it goes over usize::MAX. + // This may not be suitable for devices whose usize < u16 + iter.count() as u32 + } + + pub fn fits_in_u128(&self) -> bool { + self.num_bits() <= 128 + } + + pub fn to_u128(self) -> u128 { + let bytes = self.to_be_bytes(); + u128::from_be_bytes(bytes[16..32].try_into().unwrap()) + } + + pub fn try_into_u128(self) -> Option { + self.fits_in_u128().then(|| self.to_u128()) + } + + pub fn try_to_u64(&self) -> Option { + (self.num_bits() <= 64).then(|| self.to_u128() as u64) + } + + /// Computes the inverse or returns zero if the inverse does not exist + /// Before using this FieldElement, please ensure that this behavior is necessary + pub fn inverse(&self) -> FieldElement { + let inv = self.0.inverse().unwrap_or_else(F::zero); + FieldElement(inv) + } + + pub fn try_inverse(mut self) -> Option { + self.0.inverse_in_place().map(|f| FieldElement(*f)) + } + + // XXX: This method is used while this field element + // implementation is not generic. + pub fn into_repr(self) -> F { + self.0 + } + + pub fn to_hex(self) -> String { + let mut bytes = Vec::new(); + self.0.serialize_uncompressed(&mut bytes).unwrap(); + bytes.reverse(); + hex::encode(bytes) + } + pub fn from_hex(hex_str: &str) -> Option> { + let value = hex_str.strip_prefix("0x").unwrap_or(hex_str); + let hex_as_bytes = hex::decode(value).ok()?; + Some(FieldElement::from_be_bytes_reduce(&hex_as_bytes)) + } + + pub fn to_be_bytes(self) -> Vec { + // to_be_bytes! uses little endian which is why we reverse the output + // TODO: Add a little endian equivalent, so the caller can use whichever one + // TODO they desire + let mut bytes = Vec::new(); + self.0.serialize_uncompressed(&mut bytes).unwrap(); + bytes.reverse(); + bytes + } + + /// Converts bytes into a FieldElement and applies a + /// reduction if needed. + pub fn from_be_bytes_reduce(bytes: &[u8]) -> FieldElement { + FieldElement(F::from_be_bytes_mod_order(bytes)) + } + + pub fn bits(&self) -> Vec { + let bytes = self.to_be_bytes(); + let mut bits = Vec::with_capacity(bytes.len() * 8); + for byte in bytes { + let _bits = FieldElement::::byte_to_bit(byte); + bits.extend(_bits); + } + bits + } + + fn byte_to_bit(byte: u8) -> Vec { + let mut bits = Vec::with_capacity(8); + for index in (0..=7).rev() { + bits.push((byte & (1 << index)) >> index == 1) + } + bits + } + + /// Returns the closest number of bytes to the bits specified + /// This method truncates + pub fn fetch_nearest_bytes(&self, num_bits: usize) -> Vec { + fn nearest_bytes(num_bits: usize) -> usize { + ((num_bits + 7) / 8) * 8 + } + + let num_bytes = nearest_bytes(num_bits); + let num_elements = num_bytes / 8; + + let mut bytes = self.to_be_bytes(); + bytes.reverse(); // put it in big endian format. XXX(next refactor): we should be explicit about endianness. + + bytes[0..num_elements].to_vec() + } + + // mask_to methods will not remove any bytes from the field + // they are simply zeroed out + // Whereas truncate_to will remove those bits and make the byte array smaller + fn mask_to_be_bytes(&self, num_bits: u32) -> Vec { + let mut bytes = self.to_be_bytes(); + mask_vector_le(&mut bytes, num_bits as usize); + bytes + } + + fn and_xor(&self, rhs: &FieldElement, num_bits: u32, is_xor: bool) -> FieldElement { + // XXX: Gadgets like SHA256 need to have their input be a multiple of 8 + // This is not a restriction caused by SHA256, as it works on bits + // but most backends assume bytes. + // We could implicitly pad, however this may not be intuitive for users. + // assert!( + // num_bits % 8 == 0, + // "num_bits is not a multiple of 8, it is {}", + // num_bits + // ); + + let lhs_bytes = self.mask_to_be_bytes(num_bits); + let rhs_bytes = rhs.mask_to_be_bytes(num_bits); + + let and_byte_arr: Vec<_> = lhs_bytes + .into_iter() + .zip(rhs_bytes.into_iter()) + .map(|(lhs, rhs)| if is_xor { lhs ^ rhs } else { lhs & rhs }) + .collect(); + + FieldElement::from_be_bytes_reduce(&and_byte_arr) + } + pub fn and(&self, rhs: &FieldElement, num_bits: u32) -> FieldElement { + self.and_xor(rhs, num_bits, false) + } + pub fn xor(&self, rhs: &FieldElement, num_bits: u32) -> FieldElement { + self.and_xor(rhs, num_bits, true) + } +} + +use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; + +impl Neg for FieldElement { + type Output = FieldElement; + + fn neg(self) -> Self::Output { + FieldElement(-self.0) + } +} + +impl Mul for FieldElement { + type Output = FieldElement; + fn mul(mut self, rhs: FieldElement) -> Self::Output { + self.0.mul_assign(&rhs.0); + FieldElement(self.0) + } +} +impl Div for FieldElement { + type Output = FieldElement; + #[allow(clippy::suspicious_arithmetic_impl)] + fn div(self, rhs: FieldElement) -> Self::Output { + self * rhs.inverse() + } +} +impl Add for FieldElement { + type Output = FieldElement; + fn add(mut self, rhs: FieldElement) -> Self::Output { + self.0.add_assign(&rhs.0); + FieldElement(self.0) + } +} +impl AddAssign for FieldElement { + fn add_assign(&mut self, rhs: FieldElement) { + self.0.add_assign(&rhs.0); + } +} + +impl Sub for FieldElement { + type Output = FieldElement; + fn sub(mut self, rhs: FieldElement) -> Self::Output { + self.0.sub_assign(&rhs.0); + FieldElement(self.0) + } +} +impl SubAssign for FieldElement { + fn sub_assign(&mut self, rhs: FieldElement) { + self.0.sub_assign(&rhs.0); + } +} + +#[cfg(test)] +mod tests { + #[test] + fn and() { + let max = 10_000u32; + + let num_bits = (std::mem::size_of::() * 8) as u32 - max.leading_zeros(); + + for x in 0..max { + let x = crate::generic_ark::FieldElement::::from(x as i128); + let res = x.and(&x, num_bits); + assert_eq!(res.to_be_bytes(), x.to_be_bytes()); + } + } + + #[test] + fn serialize_fixed_test_vectors() { + // Serialized field elements from of 0, -1, -2, -3 + let hex_strings = vec![ + "0000000000000000000000000000000000000000000000000000000000000000", + "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffffff", + "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593effffffe", + ]; + + for (i, string) in hex_strings.into_iter().enumerate() { + let minus_i_field_element = + -crate::generic_ark::FieldElement::::from(i as i128); + assert_eq!(minus_i_field_element.to_hex(), string) + } + } + #[test] + fn max_num_bits_smoke() { + let max_num_bits_bn254 = crate::generic_ark::FieldElement::::max_num_bits(); + assert_eq!(max_num_bits_bn254, 254) + } +} + +fn mask_vector_le(bytes: &mut [u8], num_bits: usize) { + // reverse to big endian format + bytes.reverse(); + + let mask_power = num_bits % 8; + let array_mask_index = num_bits / 8; + + for (index, byte) in bytes.iter_mut().enumerate() { + match index.cmp(&array_mask_index) { + std::cmp::Ordering::Less => { + // do nothing if the current index is less than + // the array index. + } + std::cmp::Ordering::Equal => { + let mask = 2u8.pow(mask_power as u32) - 1; + // mask the byte + *byte &= mask; + } + std::cmp::Ordering::Greater => { + // Anything greater than the array index + // will be set to zero + *byte = 0; + } + } + } + // reverse back to little endian + bytes.reverse(); +} + +// For pretty printing powers +fn superscript(n: u64) -> String { + if n == 0 { + "⁰".to_owned() + } else if n == 1 { + "¹".to_owned() + } else if n == 2 { + "²".to_owned() + } else if n == 3 { + "³".to_owned() + } else if n == 4 { + "⁴".to_owned() + } else if n == 5 { + "⁵".to_owned() + } else if n == 6 { + "⁶".to_owned() + } else if n == 7 { + "⁷".to_owned() + } else if n == 8 { + "⁸".to_owned() + } else if n == 9 { + "⁹".to_owned() + } else if n >= 10 { + superscript(n / 10) + &superscript(n % 10) + } else { + panic!("{}", n.to_string() + " can't be converted to superscript."); + } +} diff --git a/acvm-repo/acir_field/src/lib.rs b/acvm-repo/acir_field/src/lib.rs new file mode 100644 index 00000000000..97cd8c66c71 --- /dev/null +++ b/acvm-repo/acir_field/src/lib.rs @@ -0,0 +1,40 @@ +#![warn(unused_crate_dependencies)] +#![warn(unreachable_pub)] + +cfg_if::cfg_if! { + if #[cfg(feature = "bn254")] { + mod generic_ark; + pub type FieldElement = generic_ark::FieldElement; + pub const CHOSEN_FIELD : FieldOptions = FieldOptions::BN254; + + } else if #[cfg(feature = "bls12_381")] { + mod generic_ark; + pub type FieldElement = generic_ark::FieldElement; + pub const CHOSEN_FIELD : FieldOptions = FieldOptions::BLS12_381; + } else { + compile_error!("please specify a field to compile with"); + } +} + +#[derive(Debug)] +pub enum FieldOptions { + BN254, + BLS12_381, +} + +// This is needed because features are additive through the dependency graph; if a dependency turns on the bn254, then it +// will be turned on in all crates that depend on it +#[macro_export] +macro_rules! assert_unique_feature { + () => {}; + ($first:tt $(,$rest:tt)*) => { + $( + #[cfg(all(feature = $first, feature = $rest))] + compile_error!(concat!("features \"", $first, "\" and \"", $rest, "\" cannot be used together")); + )* + assert_unique_feature!($($rest),*); + } +} +// https://internals.rust-lang.org/t/mutually-exclusive-feature-flags/8601/7 +// If another field/feature is added, we add it here too +assert_unique_feature!("bn254", "bls12_381"); diff --git a/acvm-repo/acvm/CHANGELOG.md b/acvm-repo/acvm/CHANGELOG.md new file mode 100644 index 00000000000..29a4aa93adc --- /dev/null +++ b/acvm-repo/acvm/CHANGELOG.md @@ -0,0 +1,662 @@ +# Changelog + +## [0.27.0](https://github.com/noir-lang/acvm/compare/acvm-v0.26.1...acvm-v0.27.0) (2023-09-19) + + +### ⚠ BREAKING CHANGES + +* Separate barretenberg solver from generic blackbox solver code ([#554](https://github.com/noir-lang/acvm/issues/554)) + +### Miscellaneous Chores + +* Separate barretenberg solver from generic blackbox solver code ([#554](https://github.com/noir-lang/acvm/issues/554)) ([a4b9772](https://github.com/noir-lang/acvm/commit/a4b97722a0892fe379ff075e6080675adafdce0e)) + +## [0.26.1](https://github.com/noir-lang/acvm/compare/acvm-v0.26.0...acvm-v0.26.1) (2023-09-12) + + +### Miscellaneous Chores + +* **acvm:** Synchronize acvm versions + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.26.0 to 0.26.1 + +## [0.26.0](https://github.com/noir-lang/acvm/compare/acvm-v0.25.0...acvm-v0.26.0) (2023-09-07) + + +### ⚠ BREAKING CHANGES + +* Add a low and high limb to scalar mul opcode ([#532](https://github.com/noir-lang/acvm/issues/532)) + +### Miscellaneous Chores + +* Add a low and high limb to scalar mul opcode ([#532](https://github.com/noir-lang/acvm/issues/532)) ([b054f66](https://github.com/noir-lang/acvm/commit/b054f66be9c73d4e02dbecdab80874a907f19242)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.25.0 to 0.26.0 + +## [0.25.0](https://github.com/noir-lang/acvm/compare/acvm-v0.24.1...acvm-v0.25.0) (2023-09-04) + + +### ⚠ BREAKING CHANGES + +* Provide runtime callstacks for brillig failures and return errors in acvm_js ([#523](https://github.com/noir-lang/acvm/issues/523)) + +### Features + +* Provide runtime callstacks for brillig failures and return errors in acvm_js ([#523](https://github.com/noir-lang/acvm/issues/523)) ([7ab7cff](https://github.com/noir-lang/acvm/commit/7ab7cff48a9aba61a97fad2a759fc8e55740b098)) + + +### Bug Fixes + +* initialize recursive proof output to zero ([#524](https://github.com/noir-lang/acvm/issues/524)) ([5453074](https://github.com/noir-lang/acvm/commit/545307457dd7634b20ea3977e2d2cc751eba06d2)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.24.1 to 0.25.0 + +## [0.24.1](https://github.com/noir-lang/acvm/compare/acvm-v0.24.0...acvm-v0.24.1) (2023-09-03) + + +### Miscellaneous Chores + +* **acvm:** Synchronize acvm versions + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.24.0 to 0.24.1 + +## [0.24.0](https://github.com/noir-lang/acvm/compare/acvm-v0.23.0...acvm-v0.24.0) (2023-08-31) + + +### ⚠ BREAKING CHANGES + +* **acvm:** Remove the `Backend` trait ([#514](https://github.com/noir-lang/acvm/issues/514)) +* **acir:** Remove unused `Directive` opcodes ([#510](https://github.com/noir-lang/acvm/issues/510)) +* **acir:** Add predicate to MemoryOp ([#503](https://github.com/noir-lang/acvm/issues/503)) +* **acvm:** Remove unused arguments from `Backend` trait ([#511](https://github.com/noir-lang/acvm/issues/511)) +* Assertion messages embedded in the circuit ([#484](https://github.com/noir-lang/acvm/issues/484)) + +### Features + +* **acir:** Add predicate to MemoryOp ([#503](https://github.com/noir-lang/acvm/issues/503)) ([ca9eebe](https://github.com/noir-lang/acvm/commit/ca9eebe34e61adabf97318c8ccaf60c8a424aafd)) +* Assertion messages embedded in the circuit ([#484](https://github.com/noir-lang/acvm/issues/484)) ([06b97c5](https://github.com/noir-lang/acvm/commit/06b97c51041e16651cf8b2be8bc18214e276c6c9)) + + +### Miscellaneous Chores + +* **acir:** Remove unused `Directive` opcodes ([#510](https://github.com/noir-lang/acvm/issues/510)) ([cfd8cbf](https://github.com/noir-lang/acvm/commit/cfd8cbf58307511ac0cc9106c299695c2ca779de)) +* **acvm:** Remove the `Backend` trait ([#514](https://github.com/noir-lang/acvm/issues/514)) ([681535d](https://github.com/noir-lang/acvm/commit/681535da52815a4a164ee4f48f7b48329664af98)) +* **acvm:** Remove unused arguments from `Backend` trait ([#511](https://github.com/noir-lang/acvm/issues/511)) ([ae65355](https://github.com/noir-lang/acvm/commit/ae65355afb7df98c71f81d5a54e89f39f9333920)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.23.0 to 0.24.0 + +## [0.23.0](https://github.com/noir-lang/acvm/compare/acvm-v0.22.0...acvm-v0.23.0) (2023-08-30) + + +### ⚠ BREAKING CHANGES + +* Return an iterator from `new_locations()` instead of collecting ([#507](https://github.com/noir-lang/acvm/issues/507)) +* **acvm:** remove `CommonReferenceString` trait and preprocess method ([#508](https://github.com/noir-lang/acvm/issues/508)) +* **acvm:** Pass `BlackBoxFunctionSolver` to `ACVM` by reference + +### Features + +* **acvm_js:** Add `execute_circuit_with_black_box_solver` to prevent reinitialization of `BlackBoxFunctionSolver` ([3877e0e](https://github.com/noir-lang/acvm/commit/3877e0e438a8d0e5545a4da7210767dec05c342f)) + + +### Miscellaneous Chores + +* **acvm:** Pass `BlackBoxFunctionSolver` to `ACVM` by reference ([3877e0e](https://github.com/noir-lang/acvm/commit/3877e0e438a8d0e5545a4da7210767dec05c342f)) +* **acvm:** remove `CommonReferenceString` trait and preprocess method ([#508](https://github.com/noir-lang/acvm/issues/508)) ([3827dd3](https://github.com/noir-lang/acvm/commit/3827dd3ce487650843ba4df8337b423e39f97edf)) +* Return an iterator from `new_locations()` instead of collecting ([#507](https://github.com/noir-lang/acvm/issues/507)) ([8d49a5c](https://github.com/noir-lang/acvm/commit/8d49a5c15b1e962cd59252467a20a922edadc2f2)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.22.0 to 0.23.0 + +## [0.22.0](https://github.com/noir-lang/acvm/compare/acvm-v0.21.0...acvm-v0.22.0) (2023-08-18) + + +### ⚠ BREAKING CHANGES + +* Switched from OpcodeLabel to OpcodeLocation and ErrorLocation ([#493](https://github.com/noir-lang/acvm/issues/493)) +* **acvm:** check for index out-of-bounds on memory operations ([#468](https://github.com/noir-lang/acvm/issues/468)) + +### Features + +* **acvm:** check for index out-of-bounds on memory operations ([#468](https://github.com/noir-lang/acvm/issues/468)) ([740468c](https://github.com/noir-lang/acvm/commit/740468c0a144f7179c38f615cfda31b2fcc77359)) +* print error location with fmt ([#497](https://github.com/noir-lang/acvm/issues/497)) ([575a9e5](https://github.com/noir-lang/acvm/commit/575a9e50e97afb04a7b91799e06752cec3093f0b)) +* Switched from OpcodeLabel to OpcodeLocation and ErrorLocation ([#493](https://github.com/noir-lang/acvm/issues/493)) ([27a5a93](https://github.com/noir-lang/acvm/commit/27a5a935849f8904e10056b08089f532a06962b8)) + + +### Bug Fixes + +* add opcode label to unsatisfied constrain string ([#482](https://github.com/noir-lang/acvm/issues/482)) ([cbbbe67](https://github.com/noir-lang/acvm/commit/cbbbe67b9a19a4a560b2dfa8f27ea1c6ebd61f28)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.21.0 to 0.22.0 + +## [0.21.0](https://github.com/noir-lang/acvm/compare/acvm-v0.20.1...acvm-v0.21.0) (2023-07-26) + + +### ⚠ BREAKING CHANGES + +* **acir:** Remove `Block`, `RAM` and `ROM` opcodes ([#457](https://github.com/noir-lang/acvm/issues/457)) +* **acvm:** Remove `OpcodeResolution` enum ([#400](https://github.com/noir-lang/acvm/issues/400)) +* **acvm:** Support stepwise execution of ACIR ([#399](https://github.com/noir-lang/acvm/issues/399)) + +### Features + +* **acvm:** Remove `OpcodeResolution` enum ([#400](https://github.com/noir-lang/acvm/issues/400)) ([d0ce48c](https://github.com/noir-lang/acvm/commit/d0ce48c506619a5560412ef6693bfa11036b501e)) +* **acvm:** Support stepwise execution of ACIR ([#399](https://github.com/noir-lang/acvm/issues/399)) ([6a03950](https://github.com/noir-lang/acvm/commit/6a0395021779a2711353c2fe2948e09b5b538fc0)) + + +### Miscellaneous Chores + +* **acir:** Remove `Block`, `RAM` and `ROM` opcodes ([#457](https://github.com/noir-lang/acvm/issues/457)) ([8dd220a](https://github.com/noir-lang/acvm/commit/8dd220ae127baf6cc5a31d8ab7ffdeeb161f6109)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.20.1 to 0.21.0 + +## [0.20.1](https://github.com/noir-lang/acvm/compare/acvm-v0.20.0...acvm-v0.20.1) (2023-07-26) + + +### Features + +* **stdlib:** Add fallback implementation of `Keccak256` black box function ([#445](https://github.com/noir-lang/acvm/issues/445)) ([f7ebb03](https://github.com/noir-lang/acvm/commit/f7ebb03653c971f119700ff8126d9eb5ff01be0f)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.20.0 to 0.20.1 + +## [0.20.0](https://github.com/noir-lang/acvm/compare/acvm-v0.19.1...acvm-v0.20.0) (2023-07-20) + + +### ⚠ BREAKING CHANGES + +* atomic memory opcodes ([#447](https://github.com/noir-lang/acvm/issues/447)) + +### Features + +* atomic memory opcodes ([#447](https://github.com/noir-lang/acvm/issues/447)) ([3261c7a](https://github.com/noir-lang/acvm/commit/3261c7a2fd4f3a300bc5f39ef4febccd8a853560)) +* **stdlib:** Add fallback implementation of `HashToField128Security` black box function ([#435](https://github.com/noir-lang/acvm/issues/435)) ([ed40f22](https://github.com/noir-lang/acvm/commit/ed40f228529e888d1960bfa70cb92b277e24b37f)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.19.1 to 0.20.0 + +## [0.19.1](https://github.com/noir-lang/acvm/compare/acvm-v0.19.0...acvm-v0.19.1) (2023-07-17) + + +### Bug Fixes + +* Remove panic when we divide 0/0 in quotient directive ([#437](https://github.com/noir-lang/acvm/issues/437)) ([9c8ff64](https://github.com/noir-lang/acvm/commit/9c8ff64ebf27a86787ae184e10ed9581041ec0ff)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.19.0 to 0.19.1 + +## [0.19.0](https://github.com/noir-lang/acvm/compare/acvm-v0.18.2...acvm-v0.19.0) (2023-07-15) + + +### Miscellaneous Chores + +* **acvm:** Synchronize acvm versions + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.18.2 to 0.19.0 + +## [0.18.2](https://github.com/noir-lang/acvm/compare/acvm-v0.18.1...acvm-v0.18.2) (2023-07-12) + + +### Features + +* **acvm:** reexport `blackbox_solver` crate from `acvm` ([#431](https://github.com/noir-lang/acvm/issues/431)) ([517e942](https://github.com/noir-lang/acvm/commit/517e942b732d7107f6e064c6791917d1508229b3)) +* **stdlib:** Add fallback implementation of `Blake2s` black box function ([#424](https://github.com/noir-lang/acvm/issues/424)) ([982d940](https://github.com/noir-lang/acvm/commit/982d94087d46092ce7a5e94dbd7e732195f58e42)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.18.1 to 0.18.2 + +## [0.18.1](https://github.com/noir-lang/acvm/compare/acvm-v0.18.0...acvm-v0.18.1) (2023-07-12) + + +### Miscellaneous Chores + +* **acvm:** Synchronize acvm versions + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.18.0 to 0.18.1 + +## [0.18.0](https://github.com/noir-lang/acvm/compare/acvm-v0.17.0...acvm-v0.18.0) (2023-07-12) + + +### ⚠ BREAKING CHANGES + +* add backend-solvable blackboxes to brillig & unify implementations ([#422](https://github.com/noir-lang/acvm/issues/422)) +* **acvm:** Remove `CircuitSimplifer` ([#421](https://github.com/noir-lang/acvm/issues/421)) +* **acvm:** Add `circuit: &Circuit` to `eth_contract_from_vk` function signature ([#420](https://github.com/noir-lang/acvm/issues/420)) +* Returns index of failing opcode and transformation mapping ([#412](https://github.com/noir-lang/acvm/issues/412)) + +### Features + +* **acvm:** Add `circuit: &Circuit` to `eth_contract_from_vk` function signature ([#420](https://github.com/noir-lang/acvm/issues/420)) ([744e9da](https://github.com/noir-lang/acvm/commit/744e9da71f7ca477a5390a63f47211dd4dffb8b3)) +* add backend-solvable blackboxes to brillig & unify implementations ([#422](https://github.com/noir-lang/acvm/issues/422)) ([093342e](https://github.com/noir-lang/acvm/commit/093342ea9481a311fa71343b8b7a22774788838a)) +* Returns index of failing opcode and transformation mapping ([#412](https://github.com/noir-lang/acvm/issues/412)) ([79950e9](https://github.com/noir-lang/acvm/commit/79950e943f60e4082e1cf5ec4442aa67ea91aade)) +* **stdlib:** Add fallback implementation of `SHA256` black box function ([#407](https://github.com/noir-lang/acvm/issues/407)) ([040369a](https://github.com/noir-lang/acvm/commit/040369adc8749fa5ec2edd255ff54c105c3140f5)) + + +### Miscellaneous Chores + +* **acvm:** Remove `CircuitSimplifer` ([#421](https://github.com/noir-lang/acvm/issues/421)) ([e07a56d](https://github.com/noir-lang/acvm/commit/e07a56d9c542a7f03ce156761054cd403de0bd23)) + + +### Dependencies + +* The following workspace dependencies were updated + * dependencies + * brillig_vm bumped from 0.17.0 to 0.18.0 + +## [0.17.0](https://github.com/noir-lang/acvm/compare/acvm-v0.16.0...acvm-v0.17.0) (2023-07-07) + + +### ⚠ BREAKING CHANGES + +* **acir:** add `EcdsaSecp256r1` blackbox function ([#408](https://github.com/noir-lang/acvm/issues/408)) + +### Features + +* **acir:** add `EcdsaSecp256r1` blackbox function ([#408](https://github.com/noir-lang/acvm/issues/408)) ([9895817](https://github.com/noir-lang/acvm/commit/98958170c9fa9b4731e33b31cb494a72bb90549e)) + +## [0.16.0](https://github.com/noir-lang/acvm/compare/acvm-v0.15.1...acvm-v0.16.0) (2023-07-06) + + +### ⚠ BREAKING CHANGES + +* **acvm:** replace `PartialWitnessGeneratorStatus` with `ACVMStatus` ([#410](https://github.com/noir-lang/acvm/issues/410)) +* **acir:** revert changes to `SchnorrVerify` opcode ([#409](https://github.com/noir-lang/acvm/issues/409)) +* **acvm:** Replace `PartialWitnessGenerator` trait with `BlackBoxFunctionSolver` ([#378](https://github.com/noir-lang/acvm/issues/378)) +* **acvm:** Encapsulate internal state of ACVM within a struct ([#384](https://github.com/noir-lang/acvm/issues/384)) +* remove unused `OpcodeResolutionError::IncorrectNumFunctionArguments` variant ([#397](https://github.com/noir-lang/acvm/issues/397)) +* **acir:** Remove `Oracle` opcode ([#368](https://github.com/noir-lang/acvm/issues/368)) +* **acir:** Use fixed length data structures in black box function inputs/outputs where possible. ([#386](https://github.com/noir-lang/acvm/issues/386)) + +### Features + +* **acir:** Remove `Oracle` opcode ([#368](https://github.com/noir-lang/acvm/issues/368)) ([63354df](https://github.com/noir-lang/acvm/commit/63354df1fe47a4f1128b91641d1b66dfc1281794)) +* **acir:** Use fixed length data structures in black box function inputs/outputs where possible. ([#386](https://github.com/noir-lang/acvm/issues/386)) ([b139d4d](https://github.com/noir-lang/acvm/commit/b139d4d566c715009465a430aab0fb819aacab4f)) +* **acvm:** Derive `Copy` for `Language` ([#406](https://github.com/noir-lang/acvm/issues/406)) ([69a6c22](https://github.com/noir-lang/acvm/commit/69a6c224d80be556ac5388ffeb7a02424df22031)) +* **acvm:** Encapsulate internal state of ACVM within a struct ([#384](https://github.com/noir-lang/acvm/issues/384)) ([84d4867](https://github.com/noir-lang/acvm/commit/84d4867b2d97097d451d59174781555dafd2591f)) +* **acvm:** Replace `PartialWitnessGenerator` trait with `BlackBoxFunctionSolver` ([#378](https://github.com/noir-lang/acvm/issues/378)) ([73fbc95](https://github.com/noir-lang/acvm/commit/73fbc95942b0039565c93719809975f66dc9ec53)) +* **acvm:** replace `PartialWitnessGeneratorStatus` with `ACVMStatus` ([#410](https://github.com/noir-lang/acvm/issues/410)) ([fc3240d](https://github.com/noir-lang/acvm/commit/fc3240d456d0128f6eb42096beb8b7a586ea48da)) +* **brillig:** implemented first blackbox functions ([#401](https://github.com/noir-lang/acvm/issues/401)) ([62d40f7](https://github.com/noir-lang/acvm/commit/62d40f7c03cd1102f615b8d565f82496962db637)) + + +### Bug Fixes + +* **acir:** revert changes to `SchnorrVerify` opcode ([#409](https://github.com/noir-lang/acvm/issues/409)) ([f1c7940](https://github.com/noir-lang/acvm/commit/f1c7940f4ac618c7b440b6ed30199f85cbe72cca)) + + +### Miscellaneous Chores + +* remove unused `OpcodeResolutionError::IncorrectNumFunctionArguments` variant ([#397](https://github.com/noir-lang/acvm/issues/397)) ([d1368d0](https://github.com/noir-lang/acvm/commit/d1368d041eb42d265a4ef385e066b82bc36d0743)) + +## [0.15.1](https://github.com/noir-lang/acvm/compare/acvm-v0.15.0...acvm-v0.15.1) (2023-06-20) + + +### Features + +* **brillig:** Allow dynamic-size foreign calls ([#370](https://github.com/noir-lang/acvm/issues/370)) ([5ba0349](https://github.com/noir-lang/acvm/commit/5ba0349420cc1b20113cb5e96490a0808a769757)) + +## [0.15.0](https://github.com/noir-lang/acvm/compare/acvm-v0.14.2...acvm-v0.15.0) (2023-06-15) + + +### ⚠ BREAKING CHANGES + +* **brillig:** Accept multiple inputs/outputs for foreign calls ([#367](https://github.com/noir-lang/acvm/issues/367)) +* **acvm:** Make internals of ACVM private ([#353](https://github.com/noir-lang/acvm/issues/353)) + +### Features + +* Add method to generate updated `Brillig` opcode from `UnresolvedBrilligCall` ([#363](https://github.com/noir-lang/acvm/issues/363)) ([fda5dbe](https://github.com/noir-lang/acvm/commit/fda5dbe57c28dc4bc28dfd8fe0a4a8ba29635393)) +* **brillig:** Accept multiple inputs/outputs for foreign calls ([#367](https://github.com/noir-lang/acvm/issues/367)) ([78d62b2](https://github.com/noir-lang/acvm/commit/78d62b2d7c1c8b884e1f3fe7983e6e5029700e70)) + + +### Miscellaneous Chores + +* **acvm:** Make internals of ACVM private ([#353](https://github.com/noir-lang/acvm/issues/353)) ([c902a01](https://github.com/noir-lang/acvm/commit/c902a01639033665d106e2d9f4e5c7070af8c0bb)) + +## [0.14.2](https://github.com/noir-lang/acvm/compare/acvm-v0.14.1...acvm-v0.14.2) (2023-06-08) + + +### Miscellaneous Chores + +* **acvm:** Synchronize acvm versions + +## [0.14.1](https://github.com/noir-lang/acvm/compare/acvm-v0.14.0...acvm-v0.14.1) (2023-06-07) + + +### Features + +* Re-use intermediate variables created during width reduction, with proper scale. ([#343](https://github.com/noir-lang/acvm/issues/343)) ([6bd0baa](https://github.com/noir-lang/acvm/commit/6bd0baa4bc9ac204e7710ec6d17d1752d2e924c0)) + +## [0.14.0](https://github.com/noir-lang/acvm/compare/acvm-v0.13.3...acvm-v0.14.0) (2023-06-06) + + +### ⚠ BREAKING CHANGES + +* **acir:** Verify Proof ([#291](https://github.com/noir-lang/acvm/issues/291)) + +### Features + +* **acir:** Verify Proof ([#291](https://github.com/noir-lang/acvm/issues/291)) ([9f34428](https://github.com/noir-lang/acvm/commit/9f34428b7084c7c38de401a16ca76e748d8b1d77)) + +## [0.13.3](https://github.com/noir-lang/acvm/compare/acvm-v0.13.2...acvm-v0.13.3) (2023-06-05) + + +### Bug Fixes + +* Empty commit to trigger release-please ([e8f0748](https://github.com/noir-lang/acvm/commit/e8f0748042ef505d59ab63266d3c36c5358ee30d)) + +## [0.13.2](https://github.com/noir-lang/acvm/compare/acvm-v0.13.1...acvm-v0.13.2) (2023-06-02) + + +### Bug Fixes + +* re-use intermediate vars during width reduction ([#278](https://github.com/noir-lang/acvm/issues/278)) ([5b32920](https://github.com/noir-lang/acvm/commit/5b32920263c4481c60faf0b84f0031aa8149b6b2)) + +## [0.13.1](https://github.com/noir-lang/acvm/compare/acvm-v0.13.0...acvm-v0.13.1) (2023-06-01) + + +### Bug Fixes + +* **brillig:** Proper error handling for Brillig failures ([#329](https://github.com/noir-lang/acvm/issues/329)) ([cffa110](https://github.com/noir-lang/acvm/commit/cffa110c8df30ee3dd8b635d38b17b1fcd54b03e)) +* **ci:** Correct typo to avoid `undefined` in changelogs ([#333](https://github.com/noir-lang/acvm/issues/333)) ([d3424c0](https://github.com/noir-lang/acvm/commit/d3424c04fd303c9cbe25d03118d8b358cbb84b83)) + +## [0.13.0](https://github.com/noir-lang/acvm/compare/acvm-v0.12.0...acvm-v0.13.0) (2023-06-01) + + +### ⚠ BREAKING CHANGES + +* added hash index to pedersen ([#281](https://github.com/noir-lang/acvm/issues/281)) +* Add variable length keccak opcode ([#314](https://github.com/noir-lang/acvm/issues/314)) +* Remove AES opcode ([#302](https://github.com/noir-lang/acvm/issues/302)) +* **acir, acvm:** Remove ComputeMerkleRoot opcode #296 +* Remove backend solvable methods from the interface and solve them in ACVM ([#264](https://github.com/noir-lang/acvm/issues/264)) +* Reorganize code related to `PartialWitnessGenerator` ([#287](https://github.com/noir-lang/acvm/issues/287)) + +### Features + +* **acir, acvm:** Remove ComputeMerkleRoot opcode [#296](https://github.com/noir-lang/acvm/issues/296) ([8b3923e](https://github.com/noir-lang/acvm/commit/8b3923e191e4ac399400025496e8bb4453734040)) +* Add `Brillig` opcode to introduce custom non-determinism to ACVM ([#152](https://github.com/noir-lang/acvm/issues/152)) ([3c6740a](https://github.com/noir-lang/acvm/commit/3c6740af75125afc8ebb4379f781f8274015e2e2)) +* Add variable length keccak opcode ([#314](https://github.com/noir-lang/acvm/issues/314)) ([7bfd169](https://github.com/noir-lang/acvm/commit/7bfd1695b6f119cd70fce4866314c9bb4991eaab)) +* added hash index to pedersen ([#281](https://github.com/noir-lang/acvm/issues/281)) ([61820b6](https://github.com/noir-lang/acvm/commit/61820b651900aac8d9557b4b9477ed0e1763c124)) +* Remove backend solvable methods from the interface and solve them in ACVM ([#264](https://github.com/noir-lang/acvm/issues/264)) ([69916cb](https://github.com/noir-lang/acvm/commit/69916cbdd928875b2e8fe4775f2251f71c3f3c92)) + + +### Bug Fixes + +* Allow async functions without send on async trait ([#292](https://github.com/noir-lang/acvm/issues/292)) ([9f9fc21](https://github.com/noir-lang/acvm/commit/9f9fc216a6d09ca97352ffd365bfd347e94ad8eb)) + + +### Miscellaneous Chores + +* Remove AES opcode ([#302](https://github.com/noir-lang/acvm/issues/302)) ([a429a54](https://github.com/noir-lang/acvm/commit/a429a5422d6f001b6db0d0a0f30c79ec0f96de89)) +* Reorganize code related to `PartialWitnessGenerator` ([#287](https://github.com/noir-lang/acvm/issues/287)) ([b9d61a1](https://github.com/noir-lang/acvm/commit/b9d61a16210d70e350a7e953951362c94f497f89)) + +## [0.12.0](https://github.com/noir-lang/acvm/compare/acvm-v0.11.0...acvm-v0.12.0) (2023-05-17) + + +### ⚠ BREAKING CHANGES + +* remove deprecated circuit hash functions ([#288](https://github.com/noir-lang/acvm/issues/288)) +* allow backends to specify support for all opcode variants ([#273](https://github.com/noir-lang/acvm/issues/273)) +* **acvm:** Add CommonReferenceString backend trait ([#231](https://github.com/noir-lang/acvm/issues/231)) +* Introduce WitnessMap data structure to avoid leaking internal structure ([#252](https://github.com/noir-lang/acvm/issues/252)) +* use struct variants for blackbox function calls ([#269](https://github.com/noir-lang/acvm/issues/269)) +* **acvm:** Backend trait must implement Debug ([#275](https://github.com/noir-lang/acvm/issues/275)) +* remove `OpcodeResolutionError::UnexpectedOpcode` ([#274](https://github.com/noir-lang/acvm/issues/274)) +* **acvm:** rename `hash_to_field128_security` to `hash_to_field_128_security` ([#271](https://github.com/noir-lang/acvm/issues/271)) +* **acvm:** update black box solver interfaces to match `pwg:black_box::solve` ([#268](https://github.com/noir-lang/acvm/issues/268)) +* **acvm:** expose separate solvers for AND and XOR opcodes ([#266](https://github.com/noir-lang/acvm/issues/266)) +* **acvm:** Simplification pass for ACIR ([#151](https://github.com/noir-lang/acvm/issues/151)) +* Remove `solve` from PWG trait & introduce separate solvers for each blackbox ([#257](https://github.com/noir-lang/acvm/issues/257)) + +### Features + +* **acvm:** Add CommonReferenceString backend trait ([#231](https://github.com/noir-lang/acvm/issues/231)) ([eeddcf1](https://github.com/noir-lang/acvm/commit/eeddcf179880f246383f7f67a11e589269c4e3ff)) +* **acvm:** Simplification pass for ACIR ([#151](https://github.com/noir-lang/acvm/issues/151)) ([7bc42c6](https://github.com/noir-lang/acvm/commit/7bc42c62b6e095f838b781c87cbb1ecd2af5f179)) +* **acvm:** update black box solver interfaces to match `pwg:black_box::solve` ([#268](https://github.com/noir-lang/acvm/issues/268)) ([0098b7d](https://github.com/noir-lang/acvm/commit/0098b7d9640076d970e6c15d5fd6f368eb1513ff)) +* Introduce WitnessMap data structure to avoid leaking internal structure ([#252](https://github.com/noir-lang/acvm/issues/252)) ([b248e60](https://github.com/noir-lang/acvm/commit/b248e606dd69c25d33ae77c5c5c0541adbf80cd6)) +* Remove `solve` from PWG trait & introduce separate solvers for each blackbox ([#257](https://github.com/noir-lang/acvm/issues/257)) ([3f3dd74](https://github.com/noir-lang/acvm/commit/3f3dd7460b27ab06b55dfc3fe5dd733f08e30a9f)) +* use struct variants for blackbox function calls ([#269](https://github.com/noir-lang/acvm/issues/269)) ([a83333b](https://github.com/noir-lang/acvm/commit/a83333b9e270dfcfd40a36271896840ec0201bc4)) + + +### Miscellaneous Chores + +* **acvm:** Backend trait must implement Debug ([#275](https://github.com/noir-lang/acvm/issues/275)) ([3288b4c](https://github.com/noir-lang/acvm/commit/3288b4c7eb01f5621e577d5ff9e7c92c7757e021)) +* **acvm:** expose separate solvers for AND and XOR opcodes ([#266](https://github.com/noir-lang/acvm/issues/266)) ([84b5d18](https://github.com/noir-lang/acvm/commit/84b5d18d29a111a42bfc1c3d122129c8f062c3db)) +* **acvm:** rename `hash_to_field128_security` to `hash_to_field_128_security` ([#271](https://github.com/noir-lang/acvm/issues/271)) ([fad9af2](https://github.com/noir-lang/acvm/commit/fad9af27fb102fa34bf7511f8ed7b16b3ec2d115)) +* allow backends to specify support for all opcode variants ([#273](https://github.com/noir-lang/acvm/issues/273)) ([efd37fe](https://github.com/noir-lang/acvm/commit/efd37fedcbbabb3fac810e662731439e07fef49a)) +* remove `OpcodeResolutionError::UnexpectedOpcode` ([#274](https://github.com/noir-lang/acvm/issues/274)) ([0e71aac](https://github.com/noir-lang/acvm/commit/0e71aac7aa85b3e9142972a26ba122c2c7c51d9b)) +* remove deprecated circuit hash functions ([#288](https://github.com/noir-lang/acvm/issues/288)) ([1a22c75](https://github.com/noir-lang/acvm/commit/1a22c752de3354a2a6d34892331ab6623b24c0b0)) + +## [0.11.0](https://github.com/noir-lang/acvm/compare/acvm-v0.10.3...acvm-v0.11.0) (2023-05-04) + + +### ⚠ BREAKING CHANGES + +* **acvm:** Introduce Error type for fallible Backend traits ([#248](https://github.com/noir-lang/acvm/issues/248)) + +### Features + +* **acvm:** Add generic error for failing to solve an opcode ([#251](https://github.com/noir-lang/acvm/issues/251)) ([bc89528](https://github.com/noir-lang/acvm/commit/bc8952820de610e585d505decfac6e590bbb1a35)) +* **acvm:** Introduce Error type for fallible Backend traits ([#248](https://github.com/noir-lang/acvm/issues/248)) ([45c45f7](https://github.com/noir-lang/acvm/commit/45c45f7cdb79c3ccb0373ca0e698b282d4dabc39)) +* Add Keccak Hash function ([#259](https://github.com/noir-lang/acvm/issues/259)) ([443c734](https://github.com/noir-lang/acvm/commit/443c73482eeef6cc42a1a254bf0d7706698ee353)) + +## [0.10.3](https://github.com/noir-lang/acvm/compare/acvm-v0.10.2...acvm-v0.10.3) (2023-04-28) + + +### Bug Fixes + +* add default feature flag to ACVM crate ([#245](https://github.com/noir-lang/acvm/issues/245)) ([455fddb](https://github.com/noir-lang/acvm/commit/455fddbc19af81cb01d54e29cad199691e1a1d98)) + +## [0.10.2](https://github.com/noir-lang/acvm/compare/acvm-v0.10.1...acvm-v0.10.2) (2023-04-28) + + +### Miscellaneous Chores + +* **acvm:** Synchronize acvm versions + +## [0.10.1](https://github.com/noir-lang/acvm/compare/acvm-v0.10.0...acvm-v0.10.1) (2023-04-28) + + +### Miscellaneous Chores + +* **acvm:** Synchronize acvm versions + +## [0.10.0](https://github.com/noir-lang/acvm/compare/acvm-v0.9.0...acvm-v0.10.0) (2023-04-26) + + +### ⚠ BREAKING CHANGES + +* return `Result` from `solve_range_opcode` ([#238](https://github.com/noir-lang/acvm/issues/238)) +* **acvm:** have all black box functions return `Result` ([#237](https://github.com/noir-lang/acvm/issues/237)) +* **acvm:** implement `hash_to_field_128_security` ([#230](https://github.com/noir-lang/acvm/issues/230)) +* require `Backend` to implement `Default` trait ([#223](https://github.com/noir-lang/acvm/issues/223)) +* Make GeneralOptimizer crate visible ([#220](https://github.com/noir-lang/acvm/issues/220)) +* return `PartialWitnessGeneratorStatus` from `PartialWitnessGenerator.solve` ([#213](https://github.com/noir-lang/acvm/issues/213)) +* organise operator implementations for Expression ([#190](https://github.com/noir-lang/acvm/issues/190)) + +### Features + +* **acvm:** have all black box functions return `Result<OpcodeResolution, OpcodeResolutionError>` ([#237](https://github.com/noir-lang/acvm/issues/237)) ([e8e93fd](https://github.com/noir-lang/acvm/commit/e8e93fda0db18f0d266dd1aacbb53ec787992dc9)) +* **acvm:** implement `hash_to_field_128_security` ([#230](https://github.com/noir-lang/acvm/issues/230)) ([198fb69](https://github.com/noir-lang/acvm/commit/198fb69e90a5ed3c0a8716d888b4dc6c2f9b18aa)) +* Add range opcode optimization ([#219](https://github.com/noir-lang/acvm/issues/219)) ([7abe6e5](https://github.com/noir-lang/acvm/commit/7abe6e5f6d6fea379c3748a910afd00db066eb45)) +* require `Backend` to implement `Default` trait ([#223](https://github.com/noir-lang/acvm/issues/223)) ([00282dc](https://github.com/noir-lang/acvm/commit/00282dc5e2b03947bf709a088d829f3e0ba80eed)) +* return `PartialWitnessGeneratorStatus` from `PartialWitnessGenerator.solve` ([#213](https://github.com/noir-lang/acvm/issues/213)) ([e877bed](https://github.com/noir-lang/acvm/commit/e877bed2cca76bd486e9bed66b4230e65a01f0a2)) +* return `Result<OpcodeResolution, OpcodeResolutionError>` from `solve_range_opcode` ([#238](https://github.com/noir-lang/acvm/issues/238)) ([15d3c5a](https://github.com/noir-lang/acvm/commit/15d3c5a9be2dd92f266fcb7e672da17cada9fec5)) + + +### Bug Fixes + +* prevent `bn254` feature flag always being enabled ([#225](https://github.com/noir-lang/acvm/issues/225)) ([82eee6a](https://github.com/noir-lang/acvm/commit/82eee6ab08ae480f04904ca8571fd88f4466c000)) + + +### Miscellaneous Chores + +* Make GeneralOptimizer crate visible ([#220](https://github.com/noir-lang/acvm/issues/220)) ([64bb346](https://github.com/noir-lang/acvm/commit/64bb346524428a0ce196826ea1e5ccde08ad6201)) +* organise operator implementations for Expression ([#190](https://github.com/noir-lang/acvm/issues/190)) ([a619df6](https://github.com/noir-lang/acvm/commit/a619df614bbb9b2518b788b42a7553b069823a0f)) + +## [0.9.0](https://github.com/noir-lang/acvm/compare/acvm-v0.8.1...acvm-v0.9.0) (2023-04-07) + + +### ⚠ BREAKING CHANGES + +* **acvm:** Remove deprecated eth_contract_from_cs from SmartContract trait ([#185](https://github.com/noir-lang/acvm/issues/185)) +* **acvm:** make `Backend` trait object safe ([#180](https://github.com/noir-lang/acvm/issues/180)) + +### Features + +* **acvm:** make `Backend` trait object safe ([#180](https://github.com/noir-lang/acvm/issues/180)) ([fd28657](https://github.com/noir-lang/acvm/commit/fd28657426260ce3c53517b75a27eb5c4a74e234)) + + +### Miscellaneous Chores + +* **acvm:** Remove deprecated eth_contract_from_cs from SmartContract trait ([#185](https://github.com/noir-lang/acvm/issues/185)) ([ee59c9e](https://github.com/noir-lang/acvm/commit/ee59c9efe9a54ff6b97e4daaebf64f3e327e97d9)) + +## [0.8.1](https://github.com/noir-lang/acvm/compare/acvm-v0.8.0...acvm-v0.8.1) (2023-03-30) + + +### Miscellaneous Chores + +* **acvm:** Synchronize acvm versions + +## [0.8.0](https://github.com/noir-lang/acvm/compare/acvm-v0.7.1...acvm-v0.8.0) (2023-03-28) + + +### Miscellaneous Chores + +* **acvm:** Synchronize acvm versions + +## [0.7.1](https://github.com/noir-lang/acvm/compare/acvm-v0.7.0...acvm-v0.7.1) (2023-03-27) + + +### Bug Fixes + +* **pwg:** stall instead of fail for unassigned black box ([#154](https://github.com/noir-lang/acvm/issues/154)) ([412a1a6](https://github.com/noir-lang/acvm/commit/412a1a60b434bef53e12d37c3b2bb3d51a317994)) + +## [0.7.0](https://github.com/noir-lang/acvm/compare/acvm-v0.6.0...acvm-v0.7.0) (2023-03-23) + + +### ⚠ BREAKING CHANGES + +* Add initial oracle opcode ([#149](https://github.com/noir-lang/acvm/issues/149)) +* **acir:** Add RAM and ROM opcodes +* **acir:** Add a public outputs field ([#56](https://github.com/noir-lang/acvm/issues/56)) +* **acvm:** remove `prove_with_meta` and `verify_from_cs` from `ProofSystemCompiler` ([#140](https://github.com/noir-lang/acvm/issues/140)) +* **acvm:** Remove truncate and oddrange directives ([#142](https://github.com/noir-lang/acvm/issues/142)) + +### Features + +* **acir:** Add a public outputs field ([#56](https://github.com/noir-lang/acvm/issues/56)) ([5f358a9](https://github.com/noir-lang/acvm/commit/5f358a97aaa81d87956e182cd8a6d60de75f9752)) +* **acir:** Add RAM and ROM opcodes ([73e9f25](https://github.com/noir-lang/acvm/commit/73e9f25dd87b2ca91245e93d2445eadc0f522fac)) +* Add initial oracle opcode ([#149](https://github.com/noir-lang/acvm/issues/149)) ([88ee2f8](https://github.com/noir-lang/acvm/commit/88ee2f89f37abf5dd1d9f91b4d2eed44dc651348)) + + +### Miscellaneous Chores + +* **acvm:** remove `prove_with_meta` and `verify_from_cs` from `ProofSystemCompiler` ([#140](https://github.com/noir-lang/acvm/issues/140)) ([35dd181](https://github.com/noir-lang/acvm/commit/35dd181102203df17eef510666b327ef41f4b036)) +* **acvm:** Remove truncate and oddrange directives ([#142](https://github.com/noir-lang/acvm/issues/142)) ([85dd6e8](https://github.com/noir-lang/acvm/commit/85dd6e85bfba85bfb97651f7e30e1f75deb986d5)) + +## [0.6.0](https://github.com/noir-lang/acvm/compare/acvm-v0.5.0...acvm-v0.6.0) (2023-03-03) + + +### ⚠ BREAKING CHANGES + +* add block opcode ([#114](https://github.com/noir-lang/acvm/issues/114)) + +### Features + +* add block opcode ([#114](https://github.com/noir-lang/acvm/issues/114)) ([097cfb0](https://github.com/noir-lang/acvm/commit/097cfb069291705ddb4bf1fca77ddcef21dbbd08)) + +## [0.5.0](https://github.com/noir-lang/acvm/compare/acvm-v0.4.1...acvm-v0.5.0) (2023-02-22) + + +### ⚠ BREAKING CHANGES + +* **acvm:** switch to accepting public inputs as a map ([#96](https://github.com/noir-lang/acvm/issues/96)) +* **acvm:** add `eth_contract_from_vk` to `SmartContract +* update `ProofSystemCompiler` to not take ownership of keys ([#111](https://github.com/noir-lang/acvm/issues/111)) +* update `ProofSystemCompiler` methods to take `&Circuit` ([#108](https://github.com/noir-lang/acvm/issues/108)) +* refactor ToRadix to ToRadixLe and ToRadixBe ([#58](https://github.com/noir-lang/acvm/issues/58)) +* reorganise compiler in terms of optimisers and transformers ([#88](https://github.com/noir-lang/acvm/issues/88)) + +### Features + +* **acvm:** add `eth_contract_from_vk` to `SmartContract ([#113](https://github.com/noir-lang/acvm/issues/113)) ([373c18f](https://github.com/noir-lang/acvm/commit/373c18fc05edf673cfec9e8bbb78bd7d7514999e)) +* **acvm:** switch to accepting public inputs as a map ([#96](https://github.com/noir-lang/acvm/issues/96)) ([f57ba57](https://github.com/noir-lang/acvm/commit/f57ba57c2bb2597edf2b02fb1321c69cf11993ee)) +* update `ProofSystemCompiler` methods to take `&Circuit` ([#108](https://github.com/noir-lang/acvm/issues/108)) ([af56ca9](https://github.com/noir-lang/acvm/commit/af56ca9da06068c650c66e76bfd09e65eb0ec213)) +* update `ProofSystemCompiler` to not take ownership of keys ([#111](https://github.com/noir-lang/acvm/issues/111)) ([39b8a41](https://github.com/noir-lang/acvm/commit/39b8a41293e567971f700f61103852cb987a8d16)) + + +### Bug Fixes + +* Clean up Log Directive hex output ([#97](https://github.com/noir-lang/acvm/issues/97)) ([d23c735](https://github.com/noir-lang/acvm/commit/d23c7352523ffb42f3e8f4229b61f9803ab78a7e)) + + +### Miscellaneous Chores + +* refactor ToRadix to ToRadixLe and ToRadixBe ([#58](https://github.com/noir-lang/acvm/issues/58)) ([2427a27](https://github.com/noir-lang/acvm/commit/2427a275048e598c6d651cce8348a4c55148f235)) +* reorganise compiler in terms of optimisers and transformers ([#88](https://github.com/noir-lang/acvm/issues/88)) ([9329307](https://github.com/noir-lang/acvm/commit/9329307e054de202cfc55207162ad952b70d515e)) diff --git a/acvm-repo/acvm/Cargo.toml b/acvm-repo/acvm/Cargo.toml new file mode 100644 index 00000000000..50cda87411f --- /dev/null +++ b/acvm-repo/acvm/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "acvm" +description = "The virtual machine that processes ACIR given a backend/proof system." +version = "0.27.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true +repository.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +num-bigint.workspace = true +num-traits.workspace = true +thiserror.workspace = true + +acir.workspace = true +stdlib.workspace = true +brillig_vm.workspace = true +acvm_blackbox_solver.workspace = true + +indexmap = "1.7.0" + +[features] +default = ["bn254", "testing"] +bn254 = [ + "acir/bn254", + "stdlib/bn254", + "brillig_vm/bn254", + "acvm_blackbox_solver/bn254", +] +bls12_381 = [ + "acir/bls12_381", + "stdlib/bls12_381", + "brillig_vm/bls12_381", + "acvm_blackbox_solver/bls12_381", +] +testing = ["stdlib/testing", "unstable-fallbacks"] +unstable-fallbacks = [] + +[dev-dependencies] +rand = "0.8.5" +proptest = "1.2.0" +paste = "1.0.14" diff --git a/acvm-repo/acvm/src/compiler/mod.rs b/acvm-repo/acvm/src/compiler/mod.rs new file mode 100644 index 00000000000..e824117180f --- /dev/null +++ b/acvm-repo/acvm/src/compiler/mod.rs @@ -0,0 +1,280 @@ +use acir::{ + circuit::{ + brillig::BrilligOutputs, directives::Directive, opcodes::UnsupportedMemoryOpcode, Circuit, + Opcode, OpcodeLocation, + }, + native_types::{Expression, Witness}, + BlackBoxFunc, FieldElement, +}; +use indexmap::IndexMap; +use thiserror::Error; + +use crate::Language; + +// The various passes that we can use over ACIR +mod optimizers; +mod transformers; + +use optimizers::{GeneralOptimizer, RangeOptimizer}; +use transformers::{CSatTransformer, FallbackTransformer, R1CSTransformer}; + +#[derive(PartialEq, Eq, Debug, Error)] +pub enum CompileError { + #[error("The blackbox function {0} is not supported by the backend and acvm does not have a fallback implementation")] + UnsupportedBlackBox(BlackBoxFunc), + #[error("The opcode {0} is not supported by the backend and acvm does not have a fallback implementation")] + UnsupportedMemoryOpcode(UnsupportedMemoryOpcode), +} + +/// This module moves and decomposes acir opcodes. The transformation map allows consumers of this module to map +/// metadata they had about the opcodes to the new opcode structure generated after the transformation. +#[derive(Debug)] +pub struct AcirTransformationMap { + /// This is a vector of pointers to the old acir opcodes. The index of the vector is the new opcode index. + /// The value of the vector is the old opcode index pointed. + acir_opcode_positions: Vec, +} + +impl AcirTransformationMap { + pub fn new_locations( + &self, + old_location: OpcodeLocation, + ) -> impl Iterator + '_ { + let old_acir_index = match old_location { + OpcodeLocation::Acir(index) => index, + OpcodeLocation::Brillig { acir_index, .. } => acir_index, + }; + + self.acir_opcode_positions + .iter() + .enumerate() + .filter(move |(_, &old_index)| old_index == old_acir_index) + .map(move |(new_index, _)| match old_location { + OpcodeLocation::Acir(_) => OpcodeLocation::Acir(new_index), + OpcodeLocation::Brillig { brillig_index, .. } => { + OpcodeLocation::Brillig { acir_index: new_index, brillig_index } + } + }) + } +} + +fn transform_assert_messages( + assert_messages: Vec<(OpcodeLocation, String)>, + map: &AcirTransformationMap, +) -> Vec<(OpcodeLocation, String)> { + assert_messages + .into_iter() + .flat_map(|(location, message)| { + let new_locations = map.new_locations(location); + new_locations.into_iter().map(move |new_location| (new_location, message.clone())) + }) + .collect() +} + +/// Applies [`ProofSystemCompiler`][crate::ProofSystemCompiler] specific optimizations to a [`Circuit`]. +pub fn compile( + acir: Circuit, + np_language: Language, + is_opcode_supported: impl Fn(&Opcode) -> bool, +) -> Result<(Circuit, AcirTransformationMap), CompileError> { + // Instantiate the optimizer. + // Currently the optimizer and reducer are one in the same + // for CSAT + + // Track original acir opcode positions throughout the transformation passes of the compilation + // by applying the modifications done to the circuit opcodes and also to the opcode_positions (delete and insert) + let acir_opcode_positions = acir.opcodes.iter().enumerate().map(|(i, _)| i).collect(); + + // Fallback transformer pass + let (acir, acir_opcode_positions) = + FallbackTransformer::transform(acir, is_opcode_supported, acir_opcode_positions)?; + + // General optimizer pass + let mut opcodes: Vec = Vec::new(); + for opcode in acir.opcodes { + match opcode { + Opcode::Arithmetic(arith_expr) => { + opcodes.push(Opcode::Arithmetic(GeneralOptimizer::optimize(arith_expr))) + } + other_opcode => opcodes.push(other_opcode), + }; + } + let acir = Circuit { opcodes, ..acir }; + + // Range optimization pass + let range_optimizer = RangeOptimizer::new(acir); + let (mut acir, acir_opcode_positions) = + range_optimizer.replace_redundant_ranges(acir_opcode_positions); + + let mut transformer = match &np_language { + crate::Language::R1CS => { + let transformation_map = AcirTransformationMap { acir_opcode_positions }; + acir.assert_messages = + transform_assert_messages(acir.assert_messages, &transformation_map); + let transformer = R1CSTransformer::new(acir); + return Ok((transformer.transform(), transformation_map)); + } + crate::Language::PLONKCSat { width } => { + let mut csat = CSatTransformer::new(*width); + for value in acir.circuit_arguments() { + csat.mark_solvable(value); + } + csat + } + }; + + // TODO: the code below is only for CSAT transformer + // TODO it may be possible to refactor it in a way that we do not need to return early from the r1cs + // TODO or at the very least, we could put all of it inside of CSatOptimizer pass + + let mut new_acir_opcode_positions: Vec = Vec::with_capacity(acir_opcode_positions.len()); + // Optimize the arithmetic gates by reducing them into the correct width and + // creating intermediate variables when necessary + let mut transformed_opcodes = Vec::new(); + + let mut next_witness_index = acir.current_witness_index + 1; + // maps a normalized expression to the intermediate variable which represents the expression, along with its 'norm' + // the 'norm' is simply the value of the first non zero coefficient in the expression, taken from the linear terms, or quadratic terms if there is none. + let mut intermediate_variables: IndexMap = IndexMap::new(); + for (index, opcode) in acir.opcodes.iter().enumerate() { + match opcode { + Opcode::Arithmetic(arith_expr) => { + let len = intermediate_variables.len(); + + let arith_expr = transformer.transform( + arith_expr.clone(), + &mut intermediate_variables, + &mut next_witness_index, + ); + + // Update next_witness counter + next_witness_index += (intermediate_variables.len() - len) as u32; + let mut new_opcodes = Vec::new(); + for (g, (norm, w)) in intermediate_variables.iter().skip(len) { + // de-normalize + let mut intermediate_opcode = g * *norm; + // constrain the intermediate opcode to the intermediate variable + intermediate_opcode.linear_combinations.push((-FieldElement::one(), *w)); + intermediate_opcode.sort(); + new_opcodes.push(intermediate_opcode); + } + new_opcodes.push(arith_expr); + for opcode in new_opcodes { + new_acir_opcode_positions.push(acir_opcode_positions[index]); + transformed_opcodes.push(Opcode::Arithmetic(opcode)); + } + } + Opcode::BlackBoxFuncCall(func) => { + match func { + acir::circuit::opcodes::BlackBoxFuncCall::AND { output, .. } + | acir::circuit::opcodes::BlackBoxFuncCall::XOR { output, .. } => { + transformer.mark_solvable(*output) + } + acir::circuit::opcodes::BlackBoxFuncCall::RANGE { .. } => (), + acir::circuit::opcodes::BlackBoxFuncCall::SHA256 { outputs, .. } + | acir::circuit::opcodes::BlackBoxFuncCall::Keccak256 { outputs, .. } + | acir::circuit::opcodes::BlackBoxFuncCall::Keccak256VariableLength { + outputs, + .. + } + | acir::circuit::opcodes::BlackBoxFuncCall::RecursiveAggregation { + output_aggregation_object: outputs, + .. + } + | acir::circuit::opcodes::BlackBoxFuncCall::Blake2s { outputs, .. } => { + for witness in outputs { + transformer.mark_solvable(*witness); + } + } + acir::circuit::opcodes::BlackBoxFuncCall::FixedBaseScalarMul { + outputs, + .. + } + | acir::circuit::opcodes::BlackBoxFuncCall::Pedersen { outputs, .. } => { + transformer.mark_solvable(outputs.0); + transformer.mark_solvable(outputs.1) + } + acir::circuit::opcodes::BlackBoxFuncCall::HashToField128Security { + output, + .. + } + | acir::circuit::opcodes::BlackBoxFuncCall::EcdsaSecp256k1 { output, .. } + | acir::circuit::opcodes::BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } + | acir::circuit::opcodes::BlackBoxFuncCall::SchnorrVerify { output, .. } => { + transformer.mark_solvable(*output) + } + } + + new_acir_opcode_positions.push(acir_opcode_positions[index]); + transformed_opcodes.push(opcode.clone()); + } + Opcode::Directive(directive) => { + match directive { + Directive::Quotient(quotient_directive) => { + transformer.mark_solvable(quotient_directive.q); + transformer.mark_solvable(quotient_directive.r); + } + Directive::ToLeRadix { b, .. } => { + for witness in b { + transformer.mark_solvable(*witness); + } + } + Directive::PermutationSort { bits, .. } => { + for witness in bits { + transformer.mark_solvable(*witness); + } + } + } + new_acir_opcode_positions.push(acir_opcode_positions[index]); + transformed_opcodes.push(opcode.clone()); + } + Opcode::MemoryInit { .. } => { + // `MemoryInit` does not write values to the `WitnessMap` + new_acir_opcode_positions.push(acir_opcode_positions[index]); + transformed_opcodes.push(opcode.clone()); + } + Opcode::MemoryOp { op, .. } => { + for (_, witness1, witness2) in &op.value.mul_terms { + transformer.mark_solvable(*witness1); + transformer.mark_solvable(*witness2); + } + for (_, witness) in &op.value.linear_combinations { + transformer.mark_solvable(*witness); + } + new_acir_opcode_positions.push(acir_opcode_positions[index]); + transformed_opcodes.push(opcode.clone()); + } + Opcode::Brillig(brillig) => { + for output in &brillig.outputs { + match output { + BrilligOutputs::Simple(w) => transformer.mark_solvable(*w), + BrilligOutputs::Array(v) => { + for witness in v { + transformer.mark_solvable(*witness); + } + } + } + } + new_acir_opcode_positions.push(acir_opcode_positions[index]); + transformed_opcodes.push(opcode.clone()); + } + } + } + + let current_witness_index = next_witness_index - 1; + + let transformation_map = + AcirTransformationMap { acir_opcode_positions: new_acir_opcode_positions }; + + let acir = Circuit { + current_witness_index, + opcodes: transformed_opcodes, + // The optimizer does not add new public inputs + private_parameters: acir.private_parameters, + public_parameters: acir.public_parameters, + return_values: acir.return_values, + assert_messages: transform_assert_messages(acir.assert_messages, &transformation_map), + }; + + Ok((acir, transformation_map)) +} diff --git a/acvm-repo/acvm/src/compiler/optimizers/general.rs b/acvm-repo/acvm/src/compiler/optimizers/general.rs new file mode 100644 index 00000000000..be5359a4114 --- /dev/null +++ b/acvm-repo/acvm/src/compiler/optimizers/general.rs @@ -0,0 +1,44 @@ +use acir::{ + native_types::{Expression, Witness}, + FieldElement, +}; +use indexmap::IndexMap; + +/// The `GeneralOptimizer` processes all [`Expression`]s to: +/// - remove any zero-coefficient terms. +/// - merge any quadratic terms containing the same two witnesses. +pub(crate) struct GeneralOptimizer; + +impl GeneralOptimizer { + pub(crate) fn optimize(opcode: Expression) -> Expression { + // XXX: Perhaps this optimization can be done on the fly + let opcode = remove_zero_coefficients(opcode); + simplify_mul_terms(opcode) + } +} + +// Remove all terms with zero as a coefficient +fn remove_zero_coefficients(mut opcode: Expression) -> Expression { + // Check the mul terms + opcode.mul_terms.retain(|(scale, _, _)| !scale.is_zero()); + // Check the linear combination terms + opcode.linear_combinations.retain(|(scale, _)| !scale.is_zero()); + opcode +} + +// Simplifies all mul terms with the same bi-variate variables +fn simplify_mul_terms(mut gate: Expression) -> Expression { + let mut hash_map: IndexMap<(Witness, Witness), FieldElement> = IndexMap::new(); + + // Canonicalize the ordering of the multiplication, lets just order by variable name + for (scale, w_l, w_r) in gate.mul_terms.clone().into_iter() { + let mut pair = vec![w_l, w_r]; + // Sort using rust sort algorithm + pair.sort(); + + *hash_map.entry((pair[0], pair[1])).or_insert_with(FieldElement::zero) += scale; + } + + gate.mul_terms = hash_map.into_iter().map(|((w_l, w_r), scale)| (scale, w_l, w_r)).collect(); + gate +} diff --git a/acvm-repo/acvm/src/compiler/optimizers/mod.rs b/acvm-repo/acvm/src/compiler/optimizers/mod.rs new file mode 100644 index 00000000000..cde7bdd2064 --- /dev/null +++ b/acvm-repo/acvm/src/compiler/optimizers/mod.rs @@ -0,0 +1,5 @@ +mod general; +mod redundant_range; + +pub(crate) use general::GeneralOptimizer; +pub(crate) use redundant_range::RangeOptimizer; diff --git a/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs new file mode 100644 index 00000000000..ac6ffef305d --- /dev/null +++ b/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs @@ -0,0 +1,238 @@ +use acir::{ + circuit::{opcodes::BlackBoxFuncCall, Circuit, Opcode}, + native_types::Witness, +}; +use std::collections::{BTreeMap, HashSet}; + +/// `RangeOptimizer` will remove redundant range constraints. +/// +/// # Example +/// +/// Suppose we had the following pseudo-code: +/// +/// ```noir +/// let z1 = x as u16; +/// let z2 = x as u32; +/// ``` +/// It is clear that if `x` fits inside of a 16-bit integer, +/// it must also fit inside of a 32-bit integer. +/// +/// The generated ACIR may produce two range opcodes however; +/// - One for the 16 bit range constraint of `x` +/// - One for the 32-bit range constraint of `x` +/// +/// This optimization pass will keep the 16-bit range constraint +/// and remove the 32-bit range constraint opcode. +pub(crate) struct RangeOptimizer { + /// Maps witnesses to their lowest known bit sizes. + lists: BTreeMap, + circuit: Circuit, +} + +impl RangeOptimizer { + /// Creates a new `RangeOptimizer` by collecting all known range + /// constraints from `Circuit`. + pub(crate) fn new(circuit: Circuit) -> Self { + let range_list = Self::collect_ranges(&circuit); + Self { circuit, lists: range_list } + } + + /// Stores the lowest bit range, that a witness + /// has been constrained to be. + /// For example, if we constrain a witness `x` to be + /// both 32 bits and 16 bits. This function will + /// only store the fact that we have constrained it to + /// be 16 bits. + fn collect_ranges(circuit: &Circuit) -> BTreeMap { + let mut witness_to_bit_sizes = BTreeMap::new(); + + for opcode in &circuit.opcodes { + // Extract the witness index and number of bits, + // if it is a range constraint + let (witness, num_bits) = match extract_range_opcode(opcode) { + Some(func_inputs) => func_inputs, + None => continue, + }; + + // Check if the witness has already been recorded and if the witness + // size is more than the current one, we replace it + let should_replace = match witness_to_bit_sizes.get(&witness).copied() { + Some(old_range_bits) => old_range_bits > num_bits, + None => true, + }; + if should_replace { + witness_to_bit_sizes.insert(witness, num_bits); + } + } + witness_to_bit_sizes + } + + /// Returns a `Circuit` where each Witness is only range constrained + /// once to the lowest number `bit size` possible. + pub(crate) fn replace_redundant_ranges(self, order_list: Vec) -> (Circuit, Vec) { + let mut already_seen_witness = HashSet::new(); + + let mut new_order_list = Vec::with_capacity(order_list.len()); + let mut optimized_opcodes = Vec::with_capacity(self.circuit.opcodes.len()); + for (idx, opcode) in self.circuit.opcodes.iter().enumerate() { + let (witness, num_bits) = match extract_range_opcode(opcode) { + Some(range_opcode) => range_opcode, + None => { + // If its not the range opcode, add it to the opcode + // list and continue; + optimized_opcodes.push(opcode.clone()); + new_order_list.push(order_list[idx]); + continue; + } + }; + // If we've already applied the range constraint for this witness then skip this opcode. + let already_added = already_seen_witness.contains(&witness); + if already_added { + continue; + } + + // Check if this is the lowest number of bits in the circuit + let stored_num_bits = self.lists.get(&witness).expect("Could not find witness. This should never be the case if `collect_ranges` is called"); + let is_lowest_bit_size = num_bits <= *stored_num_bits; + + // If the opcode is associated with the lowest bit size + // and we have not added a duplicate of this opcode yet, + // then we should add retain this range opcode. + if is_lowest_bit_size { + already_seen_witness.insert(witness); + new_order_list.push(order_list[idx]); + optimized_opcodes.push(opcode.clone()); + } + } + + ( + Circuit { + current_witness_index: self.circuit.current_witness_index, + opcodes: optimized_opcodes, + ..self.circuit + }, + new_order_list, + ) + } +} + +/// Extract the range opcode from the `Opcode` enum +/// Returns None, if `Opcode` is not the range opcode. +fn extract_range_opcode(opcode: &Opcode) -> Option<(Witness, u32)> { + // Range constraints are blackbox function calls + // so we first extract the function call + let func_call = match opcode { + acir::circuit::Opcode::BlackBoxFuncCall(func_call) => func_call, + _ => return None, + }; + + // Skip if it is not a range constraint + match func_call { + BlackBoxFuncCall::RANGE { input } => Some((input.witness, input.num_bits)), + _ => None, + } +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeSet; + + use crate::compiler::optimizers::redundant_range::{extract_range_opcode, RangeOptimizer}; + use acir::{ + circuit::{ + opcodes::{BlackBoxFuncCall, FunctionInput}, + Circuit, Opcode, PublicInputs, + }, + native_types::{Expression, Witness}, + }; + + fn test_circuit(ranges: Vec<(Witness, u32)>) -> Circuit { + fn test_range_constraint(witness: Witness, num_bits: u32) -> Opcode { + Opcode::BlackBoxFuncCall(BlackBoxFuncCall::RANGE { + input: FunctionInput { witness, num_bits }, + }) + } + + let opcodes: Vec<_> = ranges + .into_iter() + .map(|(witness, num_bits)| test_range_constraint(witness, num_bits)) + .collect(); + + Circuit { + current_witness_index: 1, + opcodes, + private_parameters: BTreeSet::new(), + public_parameters: PublicInputs::default(), + return_values: PublicInputs::default(), + assert_messages: Default::default(), + } + } + + #[test] + fn retain_lowest_range_size() { + // The optimizer should keep the lowest bit size range constraint + let circuit = test_circuit(vec![(Witness(1), 32), (Witness(1), 16)]); + let acir_opcode_positions = circuit.opcodes.iter().enumerate().map(|(i, _)| i).collect(); + let optimizer = RangeOptimizer::new(circuit); + + let range_size = *optimizer + .lists + .get(&Witness(1)) + .expect("Witness(1) was inserted, but it is missing from the map"); + assert_eq!( + range_size, 16, + "expected a range size of 16 since that was the lowest bit size provided" + ); + + let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); + assert_eq!(optimized_circuit.opcodes.len(), 1); + + let (witness, num_bits) = + extract_range_opcode(&optimized_circuit.opcodes[0]).expect("expected one range opcode"); + + assert_eq!(witness, Witness(1)); + assert_eq!(num_bits, 16); + } + + #[test] + fn remove_duplicates() { + // The optimizer should remove all duplicate range opcodes. + + let circuit = test_circuit(vec![ + (Witness(1), 16), + (Witness(1), 16), + (Witness(2), 23), + (Witness(2), 23), + ]); + let acir_opcode_positions = circuit.opcodes.iter().enumerate().map(|(i, _)| i).collect(); + let optimizer = RangeOptimizer::new(circuit); + let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); + assert_eq!(optimized_circuit.opcodes.len(), 2); + + let (witness_a, num_bits_a) = + extract_range_opcode(&optimized_circuit.opcodes[0]).expect("expected two range opcode"); + let (witness_b, num_bits_b) = + extract_range_opcode(&optimized_circuit.opcodes[1]).expect("expected two range opcode"); + + assert_eq!(witness_a, Witness(1)); + assert_eq!(witness_b, Witness(2)); + assert_eq!(num_bits_a, 16); + assert_eq!(num_bits_b, 23); + } + + #[test] + fn non_range_opcodes() { + // The optimizer should not remove or change non-range opcodes + // The four Arithmetic opcodes should remain unchanged. + let mut circuit = test_circuit(vec![(Witness(1), 16), (Witness(1), 16)]); + + circuit.opcodes.push(Opcode::Arithmetic(Expression::default())); + circuit.opcodes.push(Opcode::Arithmetic(Expression::default())); + circuit.opcodes.push(Opcode::Arithmetic(Expression::default())); + circuit.opcodes.push(Opcode::Arithmetic(Expression::default())); + let acir_opcode_positions = circuit.opcodes.iter().enumerate().map(|(i, _)| i).collect(); + let optimizer = RangeOptimizer::new(circuit); + let (optimized_circuit, _) = optimizer.replace_redundant_ranges(acir_opcode_positions); + assert_eq!(optimized_circuit.opcodes.len(), 5) + } +} diff --git a/acvm-repo/acvm/src/compiler/transformers/csat.rs b/acvm-repo/acvm/src/compiler/transformers/csat.rs new file mode 100644 index 00000000000..8976778547c --- /dev/null +++ b/acvm-repo/acvm/src/compiler/transformers/csat.rs @@ -0,0 +1,509 @@ +use std::{cmp::Ordering, collections::HashSet}; + +use acir::{ + native_types::{Expression, Witness}, + FieldElement, +}; +use indexmap::IndexMap; + +/// A transformer which processes any [`Expression`]s to break them up such that they +/// fit within the [`ProofSystemCompiler`][crate::ProofSystemCompiler]'s width. +/// +/// This transformer is only used when targetting the [`PLONKCSat`][crate::Language::PLONKCSat] language. +/// +/// This is done by creating intermediate variables to hold partial calculations and then combining them +/// to calculate the original expression. +// Should we give it all of the opcodes? +// Have a single transformer that you instantiate with a width, then pass many opcodes through +pub(crate) struct CSatTransformer { + width: usize, + /// Track the witness that can be solved + solvable_witness: HashSet, +} + +impl CSatTransformer { + // Configure the width for the optimizer + pub(crate) fn new(width: usize) -> CSatTransformer { + assert!(width > 2); + + CSatTransformer { width, solvable_witness: HashSet::new() } + } + + /// Check if the equation 'expression=0' can be solved, and if yes, add the solved witness to set of solvable witness + fn try_solve(&mut self, opcode: &Expression) { + let mut unresolved = Vec::new(); + for (_, w1, w2) in &opcode.mul_terms { + if !self.solvable_witness.contains(w1) { + unresolved.push(w1); + if !self.solvable_witness.contains(w2) { + return; + } + } + if !self.solvable_witness.contains(w2) { + unresolved.push(w2); + if !self.solvable_witness.contains(w1) { + return; + } + } + } + for (_, w) in &opcode.linear_combinations { + if !self.solvable_witness.contains(w) { + unresolved.push(w); + } + } + if unresolved.len() == 1 { + self.mark_solvable(*unresolved[0]); + } + } + + /// Adds the witness to set of solvable witness + pub(crate) fn mark_solvable(&mut self, witness: Witness) { + self.solvable_witness.insert(witness); + } + + // Still missing dead witness optimization. + // To do this, we will need the whole set of arithmetic opcodes + // I think it can also be done before the local optimization seen here, as dead variables will come from the user + pub(crate) fn transform( + &mut self, + opcode: Expression, + intermediate_variables: &mut IndexMap, + num_witness: &mut u32, + ) -> Expression { + // Here we create intermediate variables and constrain them to be equal to any subset of the polynomial that can be represented as a full opcode + let opcode = + self.full_opcode_scan_optimization(opcode, intermediate_variables, num_witness); + // The last optimization to do is to create intermediate variables in order to flatten the fan-in and the amount of mul terms + // If a opcode has more than one mul term. We may need an intermediate variable for each one. Since not every variable will need to link to + // the mul term, we could possibly do it that way. + // We wil call this a partial opcode scan optimization which will result in the opcodes being able to fit into the correct width + let mut opcode = + self.partial_opcode_scan_optimization(opcode, intermediate_variables, num_witness); + opcode.sort(); + self.try_solve(&opcode); + opcode + } + + // This optimization will search for combinations of terms which can be represented in a single arithmetic opcode + // Case 1 : qM * wL * wR + qL * wL + qR * wR + qO * wO + qC + // This polynomial does not require any further optimizations, it can be safely represented in one opcode + // ie a polynomial with 1 mul(bi-variate) term and 3 (univariate) terms where 2 of those terms match the bivariate term + // wL and wR, we can represent it in one opcode + // GENERALIZED for WIDTH: instead of the number 3, we use `WIDTH` + // + // + // Case 2: qM * wL * wR + qL * wL + qR * wR + qO * wO + qC + qM2 * wL2 * wR2 + qL * wL2 + qR * wR2 + qO * wO2 + qC2 + // This polynomial cannot be represented using one arithmetic opcode. + // + // This algorithm will first extract the first full opcode(if possible): + // t = qM * wL * wR + qL * wL + qR * wR + qO * wO + qC + // + // The polynomial now looks like so t + qM2 * wL2 * wR2 + qL * wL2 + qR * wR2 + qO * wO2 + qC2 + // This polynomial cannot be represented using one arithmetic opcode. + // + // This algorithm will then extract the second full opcode(if possible): + // t2 = qM2 * wL2 * wR2 + qL * wL2 + qR * wR2 + qO * wO2 + qC2 + // + // The polynomial now looks like so t + t2 + // We can no longer extract another full opcode, hence the algorithm terminates. Creating two intermediate variables t and t2. + // This stage of preprocessing does not guarantee that all polynomials can fit into a opcode. It only guarantees that all full opcodes have been extracted from each polynomial + fn full_opcode_scan_optimization( + &mut self, + mut opcode: Expression, + intermediate_variables: &mut IndexMap, + num_witness: &mut u32, + ) -> Expression { + // We pass around this intermediate variable IndexMap, so that we do not create intermediate variables that we have created before + // One instance where this might happen is t1 = wL * wR and t2 = wR * wL + + // First check that this is not a simple opcode which does not need optimization + // + // If the opcode only has one mul term, then this algorithm cannot optimize it any further + // Either it can be represented in a single arithmetic equation or it's fan-in is too large and we need intermediate variables for those + // large-fan-in optimization is not this algorithms purpose. + // If the opcode has 0 mul terms, then it is an add opcode and similarly it can either fit into a single arithmetic opcode or it has a large fan-in + if opcode.mul_terms.len() <= 1 { + return opcode; + } + + // We now know that this opcode has multiple mul terms and can possibly be simplified into multiple full opcodes + // We need to create a (wl, wr) IndexMap and then check the simplified fan-in to verify if we have terms both with wl and wr + // In general, we can then push more terms into the opcode until we are at width-1 then the last variable will be the intermediate variable + // + + // This will be our new opcode which will be equal to `self` except we will have intermediate variables that will be constrained to any + // subset of the terms that can be represented as full opcodes + let mut new_opcode = Expression::default(); + let mut remaining_mul_terms = Vec::with_capacity(opcode.mul_terms.len()); + for pair in opcode.mul_terms { + // We want to layout solvable intermediate variable, if we cannot solve one of the witness + // that means the intermediate opcode will not be immediately solvable + if !self.solvable_witness.contains(&pair.1) || !self.solvable_witness.contains(&pair.2) + { + remaining_mul_terms.push(pair); + continue; + } + + // Check if this pair is present in the simplified fan-in + // We are assuming that the fan-in/fan-out has been simplified. + // Note this function is not public, and can only be called within the optimize method, so this guarantee will always hold + let index_wl = + opcode.linear_combinations.iter().position(|(_scale, witness)| *witness == pair.1); + let index_wr = + opcode.linear_combinations.iter().position(|(_scale, witness)| *witness == pair.2); + + match (index_wl, index_wr) { + (None, _) => { + // This means that the polynomial does not contain both terms + // Just push the Qm term as it cannot form a full opcode + new_opcode.mul_terms.push(pair); + } + (_, None) => { + // This means that the polynomial does not contain both terms + // Just push the Qm term as it cannot form a full opcode + new_opcode.mul_terms.push(pair); + } + (Some(x), Some(y)) => { + // This means that we can form a full opcode with this Qm term + + // First fetch the left and right wires which match the mul term + let left_wire_term = opcode.linear_combinations[x]; + let right_wire_term = opcode.linear_combinations[y]; + + // Lets create an intermediate opcode to store this full opcode + // + let mut intermediate_opcode = Expression::default(); + intermediate_opcode.mul_terms.push(pair); + + // Add the left and right wires + intermediate_opcode.linear_combinations.push(left_wire_term); + intermediate_opcode.linear_combinations.push(right_wire_term); + // Remove the left and right wires so we do not re-add them + match x.cmp(&y) { + Ordering::Greater => { + opcode.linear_combinations.remove(x); + opcode.linear_combinations.remove(y); + } + Ordering::Less => { + opcode.linear_combinations.remove(y); + opcode.linear_combinations.remove(x); + } + Ordering::Equal => { + opcode.linear_combinations.remove(x); + intermediate_opcode.linear_combinations.pop(); + } + } + + // Now we have used up 2 spaces in our arithmetic opcode. The width now dictates, how many more we can add + let mut remaining_space = self.width - 2 - 1; // We minus 1 because we need an extra space to contain the intermediate variable + // Keep adding terms until we have no more left, or we reach the width + let mut remaining_linear_terms = + Vec::with_capacity(opcode.linear_combinations.len()); + while remaining_space > 0 { + if let Some(wire_term) = opcode.linear_combinations.pop() { + // Add this element into the new opcode + if self.solvable_witness.contains(&wire_term.1) { + intermediate_opcode.linear_combinations.push(wire_term); + remaining_space -= 1; + } else { + remaining_linear_terms.push(wire_term); + } + } else { + // No more usable elements left in the old opcode + opcode.linear_combinations = remaining_linear_terms; + break; + } + } + // Constraint this intermediate_opcode to be equal to the temp variable by adding it into the IndexMap + // We need a unique name for our intermediate variable + // XXX: Another optimization, which could be applied in another algorithm + // If two opcodes have a large fan-in/out and they share a few common terms, then we should create intermediate variables for them + // Do some sort of subset matching algorithm for this on the terms of the polynomial + + let inter_var = Self::get_or_create_intermediate_vars( + intermediate_variables, + intermediate_opcode, + num_witness, + ); + + // Add intermediate variable to the new opcode instead of the full opcode + self.mark_solvable(inter_var.1); + new_opcode.linear_combinations.push(inter_var); + } + }; + } + opcode.mul_terms = remaining_mul_terms; + + // Add the rest of the elements back into the new_opcode + new_opcode.mul_terms.extend(opcode.mul_terms.clone()); + new_opcode.linear_combinations.extend(opcode.linear_combinations.clone()); + new_opcode.q_c = opcode.q_c; + new_opcode.sort(); + new_opcode + } + + /// Normalize an expression by dividing it by its first coefficient + /// The first coefficient here means coefficient of the first linear term, or of the first quadratic term if no linear terms exist. + /// The function panic if the input expression is constant + fn normalize(mut expr: Expression) -> (FieldElement, Expression) { + expr.sort(); + let a = if !expr.linear_combinations.is_empty() { + expr.linear_combinations[0].0 + } else { + expr.mul_terms[0].0 + }; + (a, &expr * a.inverse()) + } + + /// Get or generate a scaled intermediate witness which is equal to the provided expression + /// The sets of previously generated witness and their (normalized) expression is cached in the intermediate_variables map + /// If there is no cache hit, we generate a new witness (and add the expression to the cache) + /// else, we return the cached witness along with the scaling factor so it is equal to the provided expression + fn get_or_create_intermediate_vars( + intermediate_variables: &mut IndexMap, + expr: Expression, + num_witness: &mut u32, + ) -> (FieldElement, Witness) { + let (k, normalized_expr) = Self::normalize(expr); + + if intermediate_variables.contains_key(&normalized_expr) { + let (l, iv) = intermediate_variables[&normalized_expr]; + (k / l, iv) + } else { + let inter_var = Witness(*num_witness); + *num_witness += 1; + // Add intermediate opcode and variable to map + intermediate_variables.insert(normalized_expr, (k, inter_var)); + (FieldElement::one(), inter_var) + } + } + + // A partial opcode scan optimization aim to create intermediate variables in order to compress the polynomial + // So that it fits within the given width + // Note that this opcode follows the full opcode scan optimization. + // We define the partial width as equal to the full width - 2. + // This is because two of our variables cannot be used as they are linked to the multiplication terms + // Example: qM1 * wL1 * wR2 + qL1 * wL3 + qR1 * wR4+ qR2 * wR5 + qO1 * wO5 + qC + // One thing to note is that the multiplication wires do not match any of the fan-in/out wires. This is guaranteed as we have + // just completed the full opcode optimization algorithm. + // + //Actually we can optimize in two ways here: We can create an intermediate variable which is equal to the fan-in terms + // t = qL1 * wL3 + qR1 * wR4 -> width = 3 + // This `t` value can only use width - 1 terms + // The opcode now looks like: qM1 * wL1 * wR2 + t + qR2 * wR5+ qO1 * wO5 + qC + // But this is still not acceptable since wR5 is not wR2, so we need another intermediate variable + // t2 = t + qR2 * wR5 + // + // The opcode now looks like: qM1 * wL1 * wR2 + t2 + qO1 * wO5 + qC + // This is still not good, so we do it one more time: + // t3 = t2 + qO1 * wO5 + // The opcode now looks like: qM1 * wL1 * wR2 + t3 + qC + // + // Another strategy is to create a temporary variable for the multiplier term and then we can see it as a term in the fan-in + // + // Same Example: qM1 * wL1 * wR2 + qL1 * wL3 + qR1 * wR4+ qR2 * wR5 + qO1 * wO5 + qC + // t = qM1 * wL1 * wR2 + // The opcode now looks like: t + qL1 * wL3 + qR1 * wR4+ qR2 * wR5 + qO1 * wO5 + qC + // Still assuming width3, we still need to use width-1 terms for the intermediate variables, however we can stop at an earlier stage because + // the opcode does not need the multiplier term to match with any of the fan-in terms + // t2 = t + qL1 * wL3 + // The opcode now looks like: t2 + qR1 * wR4+ qR2 * wR5 + qO1 * wO5 + qC + // t3 = t2 + qR1 * wR4 + // The opcode now looks like: t3 + qR2 * wR5 + qO1 * wO5 + qC + // This took the same amount of opcodes, but which one is better when the width increases? Compute this and maybe do both optimizations + // naming : partial_opcode_mul_first_opt and partial_opcode_fan_first_opt + // Also remember that since we did full opcode scan, there is no way we can have a non-zero mul term along with the wL and wR terms being non-zero + // + // Cases, a lot of mul terms, a lot of fan-in terms, 50/50 + fn partial_opcode_scan_optimization( + &mut self, + mut opcode: Expression, + intermediate_variables: &mut IndexMap, + num_witness: &mut u32, + ) -> Expression { + // We will go for the easiest route, which is to convert all multiplications into additions using intermediate variables + // Then use intermediate variables again to squash the fan-in, so that it can fit into the appropriate width + + // First check if this polynomial actually needs a partial opcode optimization + // There is the chance that it fits perfectly within the arithmetic opcode + if opcode.fits_in_one_identity(self.width) { + return opcode; + } + + // 2. Create Intermediate variables for the multiplication opcodes + let mut remaining_mul_terms = Vec::with_capacity(opcode.mul_terms.len()); + for mul_term in opcode.mul_terms.clone().into_iter() { + if self.solvable_witness.contains(&mul_term.1) + && self.solvable_witness.contains(&mul_term.2) + { + let mut intermediate_opcode = Expression::default(); + + // Push mul term into the opcode + intermediate_opcode.mul_terms.push(mul_term); + // Get an intermediate variable which squashes the multiplication term + let inter_var = Self::get_or_create_intermediate_vars( + intermediate_variables, + intermediate_opcode, + num_witness, + ); + + // Add intermediate variable as a part of the fan-in for the original opcode + opcode.linear_combinations.push(inter_var); + self.mark_solvable(inter_var.1); + } else { + remaining_mul_terms.push(mul_term); + } + } + + // Remove all of the mul terms as we have intermediate variables to represent them now + opcode.mul_terms = remaining_mul_terms; + + // We now only have a polynomial with only fan-in/fan-out terms i.e. terms of the form Ax + By + Cd + ... + // Lets create intermediate variables if all of them cannot fit into the width + // + // If the polynomial fits perfectly within the given width, we are finished + if opcode.linear_combinations.len() <= self.width { + return opcode; + } + + // Stores the intermediate variables that are used to + // reduce the fan in. + let mut added = Vec::new(); + + while opcode.linear_combinations.len() > self.width { + // Collect as many terms up to the given width-1 and constrain them to an intermediate variable + let mut intermediate_opcode = Expression::default(); + + let mut remaining_linear_terms = Vec::with_capacity(opcode.linear_combinations.len()); + + for term in opcode.linear_combinations { + if self.solvable_witness.contains(&term.1) + && intermediate_opcode.linear_combinations.len() < self.width - 1 + { + intermediate_opcode.linear_combinations.push(term); + } else { + remaining_linear_terms.push(term); + } + } + opcode.linear_combinations = remaining_linear_terms; + let not_full = intermediate_opcode.linear_combinations.len() < self.width - 1; + if intermediate_opcode.linear_combinations.len() > 1 { + let inter_var = Self::get_or_create_intermediate_vars( + intermediate_variables, + intermediate_opcode, + num_witness, + ); + self.mark_solvable(inter_var.1); + added.push(inter_var); + } + // The intermediate opcode is not full, but the opcode still has too many terms + if not_full && opcode.linear_combinations.len() > self.width { + unreachable!("Could not reduce the expression"); + } + } + + // Add back the intermediate variables to + // keep consistency with the original equation. + opcode.linear_combinations.extend(added); + self.partial_opcode_scan_optimization(opcode, intermediate_variables, num_witness) + } +} + +#[test] +fn simple_reduction_smoke_test() { + let a = Witness(0); + let b = Witness(1); + let c = Witness(2); + let d = Witness(3); + + // a = b + c + d; + let opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), a), + (-FieldElement::one(), b), + (-FieldElement::one(), c), + (-FieldElement::one(), d), + ], + q_c: FieldElement::zero(), + }; + + let mut intermediate_variables: IndexMap = IndexMap::new(); + + let mut num_witness = 4; + + let mut optimizer = CSatTransformer::new(3); + optimizer.mark_solvable(b); + optimizer.mark_solvable(c); + optimizer.mark_solvable(d); + let got_optimized_opcode_a = + optimizer.transform(opcode_a, &mut intermediate_variables, &mut num_witness); + + // a = b + c + d => a - b - c - d = 0 + // For width3, the result becomes: + // a - d + e = 0 + // - c - b - e = 0 + // + // a - b + e = 0 + let e = Witness(4); + let expected_optimized_opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), a), + (-FieldElement::one(), d), + (FieldElement::one(), e), + ], + q_c: FieldElement::zero(), + }; + assert_eq!(expected_optimized_opcode_a, got_optimized_opcode_a); + + assert_eq!(intermediate_variables.len(), 1); + + // e = - c - b + let expected_intermediate_opcode = Expression { + mul_terms: vec![], + linear_combinations: vec![(-FieldElement::one(), c), (-FieldElement::one(), b)], + q_c: FieldElement::zero(), + }; + let (_, normalized_opcode) = CSatTransformer::normalize(expected_intermediate_opcode); + assert!(intermediate_variables.contains_key(&normalized_opcode)); + assert_eq!(intermediate_variables[&normalized_opcode].1, e); +} + +#[test] +fn stepwise_reduction_test() { + let a = Witness(0); + let b = Witness(1); + let c = Witness(2); + let d = Witness(3); + let e = Witness(4); + + // a = b + c + d + e; + let opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (-FieldElement::one(), a), + (FieldElement::one(), b), + (FieldElement::one(), c), + (FieldElement::one(), d), + (FieldElement::one(), e), + ], + q_c: FieldElement::zero(), + }; + + let mut intermediate_variables: IndexMap = IndexMap::new(); + + let mut num_witness = 4; + + let mut optimizer = CSatTransformer::new(3); + optimizer.mark_solvable(a); + optimizer.mark_solvable(c); + optimizer.mark_solvable(d); + optimizer.mark_solvable(e); + let got_optimized_opcode_a = + optimizer.transform(opcode_a, &mut intermediate_variables, &mut num_witness); + + // Since b is not known, it cannot be put inside intermediate opcodes, so it must belong to the transformed opcode. + let contains_b = got_optimized_opcode_a.linear_combinations.iter().any(|(_, w)| *w == b); + assert!(contains_b); +} diff --git a/acvm-repo/acvm/src/compiler/transformers/fallback.rs b/acvm-repo/acvm/src/compiler/transformers/fallback.rs new file mode 100644 index 00000000000..e96fa7283bd --- /dev/null +++ b/acvm-repo/acvm/src/compiler/transformers/fallback.rs @@ -0,0 +1,170 @@ +use super::super::CompileError; +use acir::{ + circuit::{opcodes::BlackBoxFuncCall, Circuit, Opcode}, + native_types::Expression, +}; + +/// The initial transformer to act on a [`Circuit`]. This replaces any unsupported opcodes with +/// fallback implementations consisting of well supported opcodes. +pub(crate) struct FallbackTransformer; + +impl FallbackTransformer { + //ACIR pass which replace unsupported opcodes using arithmetic fallback + pub(crate) fn transform( + acir: Circuit, + is_supported: impl Fn(&Opcode) -> bool, + opcode_positions: Vec, + ) -> Result<(Circuit, Vec), CompileError> { + let mut acir_supported_opcodes = Vec::with_capacity(acir.opcodes.len()); + let mut new_opcode_positions = Vec::with_capacity(opcode_positions.len()); + let mut witness_idx = acir.current_witness_index + 1; + + for (idx, opcode) in acir.opcodes.into_iter().enumerate() { + match &opcode { + Opcode::Arithmetic(_) | Opcode::Directive(_) | Opcode::Brillig(_) => { + // directive, arithmetic expression or blocks are handled by acvm + new_opcode_positions.push(opcode_positions[idx]); + acir_supported_opcodes.push(opcode); + continue; + } + Opcode::MemoryInit { .. } | Opcode::MemoryOp { .. } => { + if !is_supported(&opcode) { + return Err(CompileError::UnsupportedMemoryOpcode( + opcode.unsupported_opcode(), + )); + } + new_opcode_positions.push(opcode_positions[idx]); + acir_supported_opcodes.push(opcode); + } + Opcode::BlackBoxFuncCall(bb_func_call) => { + // We know it is an black box function. Now check if it is + // supported by the backend. If it is supported, then we can simply + // collect the opcode + if is_supported(&opcode) { + new_opcode_positions.push(opcode_positions[idx]); + acir_supported_opcodes.push(opcode); + continue; + } else { + // If we get here then we know that this black box function is not supported + // so we need to replace it with a version of the opcode which only uses arithmetic + // expressions + let (updated_witness_index, opcodes_fallback) = + Self::opcode_fallback(bb_func_call, witness_idx)?; + witness_idx = updated_witness_index; + new_opcode_positions + .extend(vec![opcode_positions[idx]; opcodes_fallback.len()]); + acir_supported_opcodes.extend(opcodes_fallback); + } + } + } + } + + Ok(( + Circuit { current_witness_index: witness_idx, opcodes: acir_supported_opcodes, ..acir }, + new_opcode_positions, + )) + } + + fn opcode_fallback( + gc: &BlackBoxFuncCall, + current_witness_idx: u32, + ) -> Result<(u32, Vec), CompileError> { + let (updated_witness_index, opcodes_fallback) = match gc { + BlackBoxFuncCall::AND { lhs, rhs, output } => { + assert_eq!( + lhs.num_bits, rhs.num_bits, + "number of bits specified for each input must be the same" + ); + stdlib::blackbox_fallbacks::and( + Expression::from(lhs.witness), + Expression::from(rhs.witness), + *output, + lhs.num_bits, + current_witness_idx, + ) + } + BlackBoxFuncCall::XOR { lhs, rhs, output } => { + assert_eq!( + lhs.num_bits, rhs.num_bits, + "number of bits specified for each input must be the same" + ); + stdlib::blackbox_fallbacks::xor( + Expression::from(lhs.witness), + Expression::from(rhs.witness), + *output, + lhs.num_bits, + current_witness_idx, + ) + } + BlackBoxFuncCall::RANGE { input } => { + // Note there are no outputs because range produces no outputs + stdlib::blackbox_fallbacks::range( + Expression::from(input.witness), + input.num_bits, + current_witness_idx, + ) + } + #[cfg(feature = "unstable-fallbacks")] + BlackBoxFuncCall::SHA256 { inputs, outputs } => { + let mut sha256_inputs = Vec::new(); + for input in inputs.iter() { + let witness_index = Expression::from(input.witness); + let num_bits = input.num_bits; + sha256_inputs.push((witness_index, num_bits)); + } + stdlib::blackbox_fallbacks::sha256( + sha256_inputs, + outputs.to_vec(), + current_witness_idx, + ) + } + #[cfg(feature = "unstable-fallbacks")] + BlackBoxFuncCall::Blake2s { inputs, outputs } => { + let mut blake2s_input = Vec::new(); + for input in inputs.iter() { + let witness_index = Expression::from(input.witness); + let num_bits = input.num_bits; + blake2s_input.push((witness_index, num_bits)); + } + stdlib::blackbox_fallbacks::blake2s( + blake2s_input, + outputs.to_vec(), + current_witness_idx, + ) + } + #[cfg(feature = "unstable-fallbacks")] + BlackBoxFuncCall::HashToField128Security { inputs, output } => { + let mut blake2s_input = Vec::new(); + for input in inputs.iter() { + let witness_index = Expression::from(input.witness); + let num_bits = input.num_bits; + blake2s_input.push((witness_index, num_bits)); + } + stdlib::blackbox_fallbacks::hash_to_field( + blake2s_input, + *output, + current_witness_idx, + ) + } + #[cfg(feature = "unstable-fallbacks")] + BlackBoxFuncCall::Keccak256 { inputs, outputs } => { + let mut keccak_input = Vec::new(); + for input in inputs.iter() { + let witness_index = Expression::from(input.witness); + let num_bits = input.num_bits; + keccak_input.push((witness_index, num_bits)); + } + stdlib::blackbox_fallbacks::keccak256( + keccak_input, + outputs.to_vec(), + current_witness_idx, + ) + } + _ => { + return Err(CompileError::UnsupportedBlackBox(gc.get_black_box_func())); + } + }; + + Ok((updated_witness_index, opcodes_fallback)) + } +} diff --git a/acvm-repo/acvm/src/compiler/transformers/mod.rs b/acvm-repo/acvm/src/compiler/transformers/mod.rs new file mode 100644 index 00000000000..89e17ca68d0 --- /dev/null +++ b/acvm-repo/acvm/src/compiler/transformers/mod.rs @@ -0,0 +1,7 @@ +mod csat; +mod fallback; +mod r1cs; + +pub(crate) use csat::CSatTransformer; +pub(crate) use fallback::FallbackTransformer; +pub(crate) use r1cs::R1CSTransformer; diff --git a/acvm-repo/acvm/src/compiler/transformers/r1cs.rs b/acvm-repo/acvm/src/compiler/transformers/r1cs.rs new file mode 100644 index 00000000000..3bdd29c9c53 --- /dev/null +++ b/acvm-repo/acvm/src/compiler/transformers/r1cs.rs @@ -0,0 +1,16 @@ +use acir::circuit::Circuit; + +/// Currently a "noop" transformer. +pub(crate) struct R1CSTransformer { + acir: Circuit, +} + +impl R1CSTransformer { + pub(crate) fn new(acir: Circuit) -> Self { + Self { acir } + } + // TODO: We could possibly make sure that all polynomials are at most degree-2 + pub(crate) fn transform(self) -> Circuit { + self.acir + } +} diff --git a/acvm-repo/acvm/src/lib.rs b/acvm-repo/acvm/src/lib.rs new file mode 100644 index 00000000000..f32d30ee9aa --- /dev/null +++ b/acvm-repo/acvm/src/lib.rs @@ -0,0 +1,25 @@ +#![warn(unused_crate_dependencies)] +#![warn(unreachable_pub)] + +pub mod compiler; +pub mod pwg; + +pub use acvm_blackbox_solver::{BlackBoxFunctionSolver, BlackBoxResolutionError}; +use core::fmt::Debug; +use pwg::OpcodeResolutionError; + +// re-export acir +pub use acir; +pub use acir::FieldElement; +// re-export brillig vm +pub use brillig_vm; +// re-export blackbox solver +pub use acvm_blackbox_solver as blackbox_solver; + +/// Supported NP complete languages +/// This might need to be in ACIR instead +#[derive(Debug, Clone, Copy)] +pub enum Language { + R1CS, + PLONKCSat { width: usize }, +} diff --git a/acvm-repo/acvm/src/pwg/arithmetic.rs b/acvm-repo/acvm/src/pwg/arithmetic.rs new file mode 100644 index 00000000000..93a39fb249c --- /dev/null +++ b/acvm-repo/acvm/src/pwg/arithmetic.rs @@ -0,0 +1,281 @@ +use acir::{ + native_types::{Expression, Witness, WitnessMap}, + FieldElement, +}; + +use super::{insert_value, ErrorLocation, OpcodeNotSolvable, OpcodeResolutionError}; + +/// An Arithmetic solver will take a Circuit's arithmetic opcodes with witness assignments +/// and create the other witness variables +pub(super) struct ArithmeticSolver; + +#[allow(clippy::enum_variant_names)] +pub(super) enum OpcodeStatus { + OpcodeSatisfied(FieldElement), + OpcodeSolvable(FieldElement, (FieldElement, Witness)), + OpcodeUnsolvable, +} + +pub(crate) enum MulTerm { + OneUnknown(FieldElement, Witness), // (qM * known_witness, unknown_witness) + TooManyUnknowns, + Solved(FieldElement), +} + +impl ArithmeticSolver { + /// Derives the rest of the witness based on the initial low level variables + pub(super) fn solve( + initial_witness: &mut WitnessMap, + opcode: &Expression, + ) -> Result<(), OpcodeResolutionError> { + let opcode = &ArithmeticSolver::evaluate(opcode, initial_witness); + // Evaluate multiplication term + let mul_result = ArithmeticSolver::solve_mul_term(opcode, initial_witness); + // Evaluate the fan-in terms + let opcode_status = ArithmeticSolver::solve_fan_in_term(opcode, initial_witness); + + match (mul_result, opcode_status) { + (MulTerm::TooManyUnknowns, _) | (_, OpcodeStatus::OpcodeUnsolvable) => { + Err(OpcodeResolutionError::OpcodeNotSolvable( + OpcodeNotSolvable::ExpressionHasTooManyUnknowns(opcode.clone()), + )) + } + (MulTerm::OneUnknown(q, w1), OpcodeStatus::OpcodeSolvable(a, (b, w2))) => { + if w1 == w2 { + // We have one unknown so we can solve the equation + let total_sum = a + opcode.q_c; + if (q + b).is_zero() { + if !total_sum.is_zero() { + Err(OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: ErrorLocation::Unresolved, + }) + } else { + Ok(()) + } + } else { + let assignment = -total_sum / (q + b); + // Add this into the witness assignments + insert_value(&w1, assignment, initial_witness)?; + Ok(()) + } + } else { + // TODO: can we be more specific with this error? + Err(OpcodeResolutionError::OpcodeNotSolvable( + OpcodeNotSolvable::ExpressionHasTooManyUnknowns(opcode.clone()), + )) + } + } + ( + MulTerm::OneUnknown(partial_prod, unknown_var), + OpcodeStatus::OpcodeSatisfied(sum), + ) => { + // We have one unknown in the mul term and the fan-in terms are solved. + // Hence the equation is solvable, since there is a single unknown + // The equation is: partial_prod * unknown_var + sum + qC = 0 + + let total_sum = sum + opcode.q_c; + if partial_prod.is_zero() { + if !total_sum.is_zero() { + Err(OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: ErrorLocation::Unresolved, + }) + } else { + Ok(()) + } + } else { + let assignment = -(total_sum / partial_prod); + // Add this into the witness assignments + insert_value(&unknown_var, assignment, initial_witness)?; + Ok(()) + } + } + (MulTerm::Solved(a), OpcodeStatus::OpcodeSatisfied(b)) => { + // All the variables in the MulTerm are solved and the Fan-in is also solved + // There is nothing to solve + if !(a + b + opcode.q_c).is_zero() { + Err(OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: ErrorLocation::Unresolved, + }) + } else { + Ok(()) + } + } + ( + MulTerm::Solved(total_prod), + OpcodeStatus::OpcodeSolvable(partial_sum, (coeff, unknown_var)), + ) => { + // The variables in the MulTerm are solved nad there is one unknown in the Fan-in + // Hence the equation is solvable, since we have one unknown + // The equation is total_prod + partial_sum + coeff * unknown_var + q_C = 0 + let total_sum = total_prod + partial_sum + opcode.q_c; + if coeff.is_zero() { + if !total_sum.is_zero() { + Err(OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: ErrorLocation::Unresolved, + }) + } else { + Ok(()) + } + } else { + let assignment = -(total_sum / coeff); + // Add this into the witness assignments + insert_value(&unknown_var, assignment, initial_witness)?; + Ok(()) + } + } + } + } + + /// Returns the evaluation of the multiplication term in the arithmetic opcode + /// If the witness values are not known, then the function returns a None + /// XXX: Do we need to account for the case where 5xy + 6x = 0 ? We do not know y, but it can be solved given x . But I believe x can be solved with another opcode + /// XXX: What about making a mul opcode = a constant 5xy + 7 = 0 ? This is the same as the above. + fn solve_mul_term(arith_opcode: &Expression, witness_assignments: &WitnessMap) -> MulTerm { + // First note that the mul term can only contain one/zero term + // We are assuming it has been optimized. + match arith_opcode.mul_terms.len() { + 0 => MulTerm::Solved(FieldElement::zero()), + 1 => ArithmeticSolver::solve_mul_term_helper( + &arith_opcode.mul_terms[0], + witness_assignments, + ), + _ => panic!("Mul term in the arithmetic opcode must contain either zero or one term"), + } + } + + fn solve_mul_term_helper( + term: &(FieldElement, Witness, Witness), + witness_assignments: &WitnessMap, + ) -> MulTerm { + let (q_m, w_l, w_r) = term; + // Check if these values are in the witness assignments + let w_l_value = witness_assignments.get(w_l); + let w_r_value = witness_assignments.get(w_r); + + match (w_l_value, w_r_value) { + (None, None) => MulTerm::TooManyUnknowns, + (Some(w_l), Some(w_r)) => MulTerm::Solved(*q_m * *w_l * *w_r), + (None, Some(w_r)) => MulTerm::OneUnknown(*q_m * *w_r, *w_l), + (Some(w_l), None) => MulTerm::OneUnknown(*q_m * *w_l, *w_r), + } + } + + fn solve_fan_in_term_helper( + term: &(FieldElement, Witness), + witness_assignments: &WitnessMap, + ) -> Option { + let (q_l, w_l) = term; + // Check if we have w_l + let w_l_value = witness_assignments.get(w_l); + w_l_value.map(|a| *q_l * *a) + } + + /// Returns the summation of all of the variables, plus the unknown variable + /// Returns None, if there is more than one unknown variable + /// We cannot assign + pub(super) fn solve_fan_in_term( + arith_opcode: &Expression, + witness_assignments: &WitnessMap, + ) -> OpcodeStatus { + // This is assuming that the fan-in is more than 0 + + // This is the variable that we want to assign the value to + let mut unknown_variable = (FieldElement::zero(), Witness::default()); + let mut num_unknowns = 0; + // This is the sum of all of the known variables + let mut result = FieldElement::zero(); + + for term in arith_opcode.linear_combinations.iter() { + let value = ArithmeticSolver::solve_fan_in_term_helper(term, witness_assignments); + match value { + Some(a) => result += a, + None => { + unknown_variable = *term; + num_unknowns += 1; + } + } + + // If we have more than 1 unknown, then we cannot solve this equation + if num_unknowns > 1 { + return OpcodeStatus::OpcodeUnsolvable; + } + } + + if num_unknowns == 0 { + return OpcodeStatus::OpcodeSatisfied(result); + } + + OpcodeStatus::OpcodeSolvable(result, unknown_variable) + } + + // Partially evaluate the opcode using the known witnesses + pub(super) fn evaluate(expr: &Expression, initial_witness: &WitnessMap) -> Expression { + let mut result = Expression::default(); + for &(c, w1, w2) in &expr.mul_terms { + let mul_result = ArithmeticSolver::solve_mul_term_helper(&(c, w1, w2), initial_witness); + match mul_result { + MulTerm::OneUnknown(v, w) => { + if !v.is_zero() { + result.linear_combinations.push((v, w)); + } + } + MulTerm::TooManyUnknowns => { + if !c.is_zero() { + result.mul_terms.push((c, w1, w2)); + } + } + MulTerm::Solved(f) => result.q_c += f, + } + } + for &(c, w) in &expr.linear_combinations { + if let Some(f) = ArithmeticSolver::solve_fan_in_term_helper(&(c, w), initial_witness) { + result.q_c += f; + } else if !c.is_zero() { + result.linear_combinations.push((c, w)); + } + } + result.q_c += expr.q_c; + result + } +} + +#[test] +fn arithmetic_smoke_test() { + let a = Witness(0); + let b = Witness(1); + let c = Witness(2); + let d = Witness(3); + + // a = b + c + d; + let opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), a), + (-FieldElement::one(), b), + (-FieldElement::one(), c), + (-FieldElement::one(), d), + ], + q_c: FieldElement::zero(), + }; + + let e = Witness(4); + let opcode_b = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), e), + (-FieldElement::one(), a), + (-FieldElement::one(), b), + ], + q_c: FieldElement::zero(), + }; + + let mut values = WitnessMap::new(); + values.insert(b, FieldElement::from(2_i128)); + values.insert(c, FieldElement::from(1_i128)); + values.insert(d, FieldElement::from(1_i128)); + + assert_eq!(ArithmeticSolver::solve(&mut values, &opcode_a), Ok(())); + assert_eq!(ArithmeticSolver::solve(&mut values, &opcode_b), Ok(())); + + assert_eq!(values.get(&a).unwrap(), &FieldElement::from(4_i128)); +} diff --git a/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs b/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs new file mode 100644 index 00000000000..975025971dc --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/fixed_base_scalar_mul.rs @@ -0,0 +1,27 @@ +use acir::{ + circuit::opcodes::FunctionInput, + native_types::{Witness, WitnessMap}, +}; + +use crate::{ + pwg::{insert_value, witness_to_value, OpcodeResolutionError}, + BlackBoxFunctionSolver, +}; + +pub(super) fn fixed_base_scalar_mul( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, + low: FunctionInput, + high: FunctionInput, + outputs: (Witness, Witness), +) -> Result<(), OpcodeResolutionError> { + let low = witness_to_value(initial_witness, low.witness)?; + let high = witness_to_value(initial_witness, high.witness)?; + + let (pub_x, pub_y) = backend.fixed_base_scalar_mul(low, high)?; + + insert_value(&outputs.0, pub_x, initial_witness)?; + insert_value(&outputs.1, pub_y, initial_witness)?; + + Ok(()) +} diff --git a/acvm-repo/acvm/src/pwg/blackbox/hash.rs b/acvm-repo/acvm/src/pwg/blackbox/hash.rs new file mode 100644 index 00000000000..80665a743c4 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/hash.rs @@ -0,0 +1,103 @@ +use acir::{ + circuit::opcodes::FunctionInput, + native_types::{Witness, WitnessMap}, + BlackBoxFunc, FieldElement, +}; +use acvm_blackbox_solver::{hash_to_field_128_security, BlackBoxResolutionError}; + +use crate::pwg::{insert_value, witness_to_value}; +use crate::OpcodeResolutionError; + +/// Attempts to solve a `HashToField128Security` opcode +/// If successful, `initial_witness` will be mutated to contain the new witness assignment. +pub(super) fn solve_hash_to_field( + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + output: &Witness, +) -> Result<(), OpcodeResolutionError> { + let message_input = get_hash_input(initial_witness, inputs, None)?; + let field = hash_to_field_128_security(&message_input)?; + + insert_value(output, field, initial_witness)?; + + Ok(()) +} + +/// Attempts to solve a 256 bit hash function opcode. +/// If successful, `initial_witness` will be mutated to contain the new witness assignment. +pub(super) fn solve_generic_256_hash_opcode( + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + var_message_size: Option<&FunctionInput>, + outputs: &[Witness], + hash_function: fn(data: &[u8]) -> Result<[u8; 32], BlackBoxResolutionError>, + black_box_func: BlackBoxFunc, +) -> Result<(), OpcodeResolutionError> { + let message_input = get_hash_input(initial_witness, inputs, var_message_size)?; + let digest: [u8; 32] = hash_function(&message_input)?; + + let outputs: [Witness; 32] = outputs.try_into().map_err(|_| { + OpcodeResolutionError::BlackBoxFunctionFailed( + black_box_func, + format!("Expected 32 outputs but encountered {}", outputs.len()), + ) + })?; + write_digest_to_outputs(initial_witness, outputs, digest)?; + + Ok(()) +} + +/// Reads the hash function input from a [`WitnessMap`]. +fn get_hash_input( + initial_witness: &WitnessMap, + inputs: &[FunctionInput], + message_size: Option<&FunctionInput>, +) -> Result, OpcodeResolutionError> { + // Read witness assignments. + let mut message_input = Vec::new(); + for input in inputs.iter() { + let witness = input.witness; + let num_bits = input.num_bits as usize; + + let witness_assignment = witness_to_value(initial_witness, witness)?; + let bytes = witness_assignment.fetch_nearest_bytes(num_bits); + message_input.extend(bytes); + } + + // Truncate the message if there is a `message_size` parameter given + match message_size { + Some(input) => { + let num_bytes_to_take = + witness_to_value(initial_witness, input.witness)?.to_u128() as usize; + + // If the number of bytes to take is more than the amount of bytes available + // in the message, then we error. + if num_bytes_to_take > message_input.len() { + return Err(OpcodeResolutionError::BlackBoxFunctionFailed( + acir::BlackBoxFunc::Keccak256, + format!("the number of bytes to take from the message is more than the number of bytes in the message. {} > {}", num_bytes_to_take, message_input.len()), + )); + } + let truncated_message = message_input[0..num_bytes_to_take].to_vec(); + Ok(truncated_message) + } + None => Ok(message_input), + } +} + +/// Writes a `digest` to the [`WitnessMap`] at witness indices `outputs`. +fn write_digest_to_outputs( + initial_witness: &mut WitnessMap, + outputs: [Witness; 32], + digest: [u8; 32], +) -> Result<(), OpcodeResolutionError> { + for (output_witness, value) in outputs.iter().zip(digest.into_iter()) { + insert_value( + output_witness, + FieldElement::from_be_bytes_reduce(&[value]), + initial_witness, + )?; + } + + Ok(()) +} diff --git a/acvm-repo/acvm/src/pwg/blackbox/logic.rs b/acvm-repo/acvm/src/pwg/blackbox/logic.rs new file mode 100644 index 00000000000..8e69730f71d --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/logic.rs @@ -0,0 +1,56 @@ +use crate::pwg::{insert_value, witness_to_value}; +use crate::OpcodeResolutionError; +use acir::{ + circuit::opcodes::FunctionInput, + native_types::{Witness, WitnessMap}, + FieldElement, +}; + +/// Solves a [`BlackBoxFunc::And`][acir::circuit::black_box_functions::BlackBoxFunc::AND] opcode and inserts +/// the result into the supplied witness map +pub(super) fn and( + initial_witness: &mut WitnessMap, + lhs: &FunctionInput, + rhs: &FunctionInput, + output: &Witness, +) -> Result<(), OpcodeResolutionError> { + assert_eq!( + lhs.num_bits, rhs.num_bits, + "number of bits specified for each input must be the same" + ); + solve_logic_opcode(initial_witness, &lhs.witness, &rhs.witness, *output, |left, right| { + left.and(right, lhs.num_bits) + }) +} + +/// Solves a [`BlackBoxFunc::XOR`][acir::circuit::black_box_functions::BlackBoxFunc::XOR] opcode and inserts +/// the result into the supplied witness map +pub(super) fn xor( + initial_witness: &mut WitnessMap, + lhs: &FunctionInput, + rhs: &FunctionInput, + output: &Witness, +) -> Result<(), OpcodeResolutionError> { + assert_eq!( + lhs.num_bits, rhs.num_bits, + "number of bits specified for each input must be the same" + ); + solve_logic_opcode(initial_witness, &lhs.witness, &rhs.witness, *output, |left, right| { + left.xor(right, lhs.num_bits) + }) +} + +/// Derives the rest of the witness based on the initial low level variables +fn solve_logic_opcode( + initial_witness: &mut WitnessMap, + a: &Witness, + b: &Witness, + result: Witness, + logic_op: impl Fn(&FieldElement, &FieldElement) -> FieldElement, +) -> Result<(), OpcodeResolutionError> { + let w_l_value = witness_to_value(initial_witness, *a)?; + let w_r_value = witness_to_value(initial_witness, *b)?; + let assignment = logic_op(w_l_value, w_r_value); + + insert_value(&result, assignment, initial_witness) +} diff --git a/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/acvm-repo/acvm/src/pwg/blackbox/mod.rs new file mode 100644 index 00000000000..c4d9d561f46 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -0,0 +1,163 @@ +use acir::{ + circuit::opcodes::{BlackBoxFuncCall, FunctionInput}, + native_types::{Witness, WitnessMap}, + FieldElement, +}; +use acvm_blackbox_solver::{blake2s, keccak256, sha256}; + +use super::{insert_value, OpcodeNotSolvable, OpcodeResolutionError}; +use crate::BlackBoxFunctionSolver; + +mod fixed_base_scalar_mul; +mod hash; +mod logic; +mod pedersen; +mod range; +mod signature; + +use fixed_base_scalar_mul::fixed_base_scalar_mul; +// Hash functions should eventually be exposed for external consumers. +use hash::{solve_generic_256_hash_opcode, solve_hash_to_field}; +use logic::{and, xor}; +use pedersen::pedersen; +use range::solve_range_opcode; +use signature::{ + ecdsa::{secp256k1_prehashed, secp256r1_prehashed}, + schnorr::schnorr_verify, +}; + +/// Check if all of the inputs to the function have assignments +/// +/// Returns the first missing assignment if any are missing +fn first_missing_assignment( + witness_assignments: &WitnessMap, + inputs: &[FunctionInput], +) -> Option { + inputs.iter().find_map(|input| { + if witness_assignments.contains_key(&input.witness) { + None + } else { + Some(input.witness) + } + }) +} + +/// Check if all of the inputs to the function have assignments +fn contains_all_inputs(witness_assignments: &WitnessMap, inputs: &[FunctionInput]) -> bool { + inputs.iter().all(|input| witness_assignments.contains_key(&input.witness)) +} + +pub(crate) fn solve( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, + bb_func: &BlackBoxFuncCall, +) -> Result<(), OpcodeResolutionError> { + let inputs = bb_func.get_inputs_vec(); + if !contains_all_inputs(initial_witness, &inputs) { + let unassigned_witness = first_missing_assignment(initial_witness, &inputs) + .expect("Some assignments must be missing because it does not contains all inputs"); + return Err(OpcodeResolutionError::OpcodeNotSolvable( + OpcodeNotSolvable::MissingAssignment(unassigned_witness.0), + )); + } + + match bb_func { + BlackBoxFuncCall::AND { lhs, rhs, output } => and(initial_witness, lhs, rhs, output), + BlackBoxFuncCall::XOR { lhs, rhs, output } => xor(initial_witness, lhs, rhs, output), + BlackBoxFuncCall::RANGE { input } => solve_range_opcode(initial_witness, input), + BlackBoxFuncCall::SHA256 { inputs, outputs } => solve_generic_256_hash_opcode( + initial_witness, + inputs, + None, + outputs, + sha256, + bb_func.get_black_box_func(), + ), + BlackBoxFuncCall::Blake2s { inputs, outputs } => solve_generic_256_hash_opcode( + initial_witness, + inputs, + None, + outputs, + blake2s, + bb_func.get_black_box_func(), + ), + BlackBoxFuncCall::Keccak256 { inputs, outputs } => solve_generic_256_hash_opcode( + initial_witness, + inputs, + None, + outputs, + keccak256, + bb_func.get_black_box_func(), + ), + BlackBoxFuncCall::Keccak256VariableLength { inputs, var_message_size, outputs } => { + solve_generic_256_hash_opcode( + initial_witness, + inputs, + Some(var_message_size), + outputs, + keccak256, + bb_func.get_black_box_func(), + ) + } + BlackBoxFuncCall::HashToField128Security { inputs, output } => { + solve_hash_to_field(initial_witness, inputs, output) + } + BlackBoxFuncCall::SchnorrVerify { + public_key_x, + public_key_y, + signature, + message, + output, + } => schnorr_verify( + backend, + initial_witness, + *public_key_x, + *public_key_y, + signature, + message, + *output, + ), + BlackBoxFuncCall::Pedersen { inputs, domain_separator, outputs } => { + pedersen(backend, initial_witness, inputs, *domain_separator, *outputs) + } + BlackBoxFuncCall::EcdsaSecp256k1 { + public_key_x, + public_key_y, + signature, + hashed_message: message, + output, + } => secp256k1_prehashed( + initial_witness, + public_key_x, + public_key_y, + signature, + message, + *output, + ), + BlackBoxFuncCall::EcdsaSecp256r1 { + public_key_x, + public_key_y, + signature, + hashed_message: message, + output, + } => secp256r1_prehashed( + initial_witness, + public_key_x, + public_key_y, + signature, + message, + *output, + ), + BlackBoxFuncCall::FixedBaseScalarMul { low, high, outputs } => { + fixed_base_scalar_mul(backend, initial_witness, *low, *high, *outputs) + } + BlackBoxFuncCall::RecursiveAggregation { output_aggregation_object, .. } => { + // Solve the output of the recursive aggregation to zero to prevent missing assignment errors + // The correct value will be computed by the backend + for witness in output_aggregation_object { + insert_value(witness, FieldElement::zero(), initial_witness)?; + } + Ok(()) + } + } +} diff --git a/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs b/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs new file mode 100644 index 00000000000..44b4c91dc63 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs @@ -0,0 +1,28 @@ +use acir::{ + circuit::opcodes::FunctionInput, + native_types::{Witness, WitnessMap}, +}; + +use crate::{ + pwg::{insert_value, witness_to_value, OpcodeResolutionError}, + BlackBoxFunctionSolver, +}; + +pub(super) fn pedersen( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + domain_separator: u32, + outputs: (Witness, Witness), +) -> Result<(), OpcodeResolutionError> { + let scalars: Result, _> = + inputs.iter().map(|input| witness_to_value(initial_witness, input.witness)).collect(); + let scalars: Vec<_> = scalars?.into_iter().cloned().collect(); + + let (res_x, res_y) = backend.pedersen(&scalars, domain_separator)?; + + insert_value(&outputs.0, res_x, initial_witness)?; + insert_value(&outputs.1, res_y, initial_witness)?; + + Ok(()) +} diff --git a/acvm-repo/acvm/src/pwg/blackbox/range.rs b/acvm-repo/acvm/src/pwg/blackbox/range.rs new file mode 100644 index 00000000000..2c2b96cd753 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/range.rs @@ -0,0 +1,18 @@ +use crate::{ + pwg::{witness_to_value, ErrorLocation}, + OpcodeResolutionError, +}; +use acir::{circuit::opcodes::FunctionInput, native_types::WitnessMap}; + +pub(super) fn solve_range_opcode( + initial_witness: &mut WitnessMap, + input: &FunctionInput, +) -> Result<(), OpcodeResolutionError> { + let w_value = witness_to_value(initial_witness, input.witness)?; + if w_value.num_bits() > input.num_bits { + return Err(OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: ErrorLocation::Unresolved, + }); + } + Ok(()) +} diff --git a/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs b/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs new file mode 100644 index 00000000000..8f0df8378ad --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/signature/ecdsa.rs @@ -0,0 +1,91 @@ +use acir::{ + circuit::opcodes::FunctionInput, + native_types::{Witness, WitnessMap}, + FieldElement, +}; +use acvm_blackbox_solver::{ecdsa_secp256k1_verify, ecdsa_secp256r1_verify}; + +use crate::{pwg::insert_value, OpcodeResolutionError}; + +use super::to_u8_vec; + +pub(crate) fn secp256k1_prehashed( + initial_witness: &mut WitnessMap, + public_key_x_inputs: &[FunctionInput], + public_key_y_inputs: &[FunctionInput], + signature_inputs: &[FunctionInput], + hashed_message_inputs: &[FunctionInput], + output: Witness, +) -> Result<(), OpcodeResolutionError> { + let hashed_message = to_u8_vec(initial_witness, hashed_message_inputs)?; + + // These errors should never be emitted in practice as they would imply malformed ACIR generation. + let pub_key_x: [u8; 32] = + to_u8_vec(initial_witness, public_key_x_inputs)?.try_into().map_err(|_| { + OpcodeResolutionError::BlackBoxFunctionFailed( + acir::BlackBoxFunc::EcdsaSecp256k1, + format!("expected pubkey_x size 32 but received {}", public_key_x_inputs.len()), + ) + })?; + + let pub_key_y: [u8; 32] = + to_u8_vec(initial_witness, public_key_y_inputs)?.try_into().map_err(|_| { + OpcodeResolutionError::BlackBoxFunctionFailed( + acir::BlackBoxFunc::EcdsaSecp256k1, + format!("expected pubkey_y size 32 but received {}", public_key_y_inputs.len()), + ) + })?; + + let signature: [u8; 64] = + to_u8_vec(initial_witness, signature_inputs)?.try_into().map_err(|_| { + OpcodeResolutionError::BlackBoxFunctionFailed( + acir::BlackBoxFunc::EcdsaSecp256k1, + format!("expected signature size 64 but received {}", signature_inputs.len()), + ) + })?; + + let is_valid = ecdsa_secp256k1_verify(&hashed_message, &pub_key_x, &pub_key_y, &signature)?; + + insert_value(&output, FieldElement::from(is_valid), initial_witness)?; + Ok(()) +} + +pub(crate) fn secp256r1_prehashed( + initial_witness: &mut WitnessMap, + public_key_x_inputs: &[FunctionInput], + public_key_y_inputs: &[FunctionInput], + signature_inputs: &[FunctionInput], + hashed_message_inputs: &[FunctionInput], + output: Witness, +) -> Result<(), OpcodeResolutionError> { + let hashed_message = to_u8_vec(initial_witness, hashed_message_inputs)?; + + let pub_key_x: [u8; 32] = + to_u8_vec(initial_witness, public_key_x_inputs)?.try_into().map_err(|_| { + OpcodeResolutionError::BlackBoxFunctionFailed( + acir::BlackBoxFunc::EcdsaSecp256r1, + format!("expected pubkey_x size 32 but received {}", public_key_x_inputs.len()), + ) + })?; + + let pub_key_y: [u8; 32] = + to_u8_vec(initial_witness, public_key_y_inputs)?.try_into().map_err(|_| { + OpcodeResolutionError::BlackBoxFunctionFailed( + acir::BlackBoxFunc::EcdsaSecp256r1, + format!("expected pubkey_y size 32 but received {}", public_key_y_inputs.len()), + ) + })?; + + let signature: [u8; 64] = + to_u8_vec(initial_witness, signature_inputs)?.try_into().map_err(|_| { + OpcodeResolutionError::BlackBoxFunctionFailed( + acir::BlackBoxFunc::EcdsaSecp256r1, + format!("expected signature size 64 but received {}", signature_inputs.len()), + ) + })?; + + let is_valid = ecdsa_secp256r1_verify(&hashed_message, &pub_key_x, &pub_key_y, &signature)?; + + insert_value(&output, FieldElement::from(is_valid), initial_witness)?; + Ok(()) +} diff --git a/acvm-repo/acvm/src/pwg/blackbox/signature/mod.rs b/acvm-repo/acvm/src/pwg/blackbox/signature/mod.rs new file mode 100644 index 00000000000..0e28a63ff68 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/signature/mod.rs @@ -0,0 +1,21 @@ +use acir::{circuit::opcodes::FunctionInput, native_types::WitnessMap}; + +use crate::pwg::{witness_to_value, OpcodeResolutionError}; + +fn to_u8_vec( + initial_witness: &WitnessMap, + inputs: &[FunctionInput], +) -> Result, OpcodeResolutionError> { + let mut result = Vec::with_capacity(inputs.len()); + for input in inputs { + let witness_value_bytes = witness_to_value(initial_witness, input.witness)?.to_be_bytes(); + let byte = witness_value_bytes + .last() + .expect("Field element must be represented by non-zero amount of bytes"); + result.push(*byte); + } + Ok(result) +} + +pub(super) mod ecdsa; +pub(super) mod schnorr; diff --git a/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs b/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs new file mode 100644 index 00000000000..7f5381cee91 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/signature/schnorr.rs @@ -0,0 +1,35 @@ +use super::to_u8_vec; +use crate::{ + pwg::{insert_value, witness_to_value, OpcodeResolutionError}, + BlackBoxFunctionSolver, +}; +use acir::{ + circuit::opcodes::FunctionInput, + native_types::{Witness, WitnessMap}, + FieldElement, +}; + +#[allow(clippy::too_many_arguments)] +pub(crate) fn schnorr_verify( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, + public_key_x: FunctionInput, + public_key_y: FunctionInput, + signature: &[FunctionInput], + message: &[FunctionInput], + output: Witness, +) -> Result<(), OpcodeResolutionError> { + let public_key_x: &FieldElement = witness_to_value(initial_witness, public_key_x.witness)?; + let public_key_y: &FieldElement = witness_to_value(initial_witness, public_key_y.witness)?; + + let signature = to_u8_vec(initial_witness, signature)?; + + let message = to_u8_vec(initial_witness, message)?; + + let valid_signature = + backend.schnorr_verify(public_key_x, public_key_y, &signature, &message)?; + + insert_value(&output, FieldElement::from(valid_signature), initial_witness)?; + + Ok(()) +} diff --git a/acvm-repo/acvm/src/pwg/brillig.rs b/acvm-repo/acvm/src/pwg/brillig.rs new file mode 100644 index 00000000000..8662dab71e1 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/brillig.rs @@ -0,0 +1,163 @@ +use acir::{ + brillig::{RegisterIndex, Value}, + circuit::{ + brillig::{Brillig, BrilligInputs, BrilligOutputs}, + OpcodeLocation, + }, + native_types::WitnessMap, + FieldElement, +}; +use acvm_blackbox_solver::BlackBoxFunctionSolver; +use brillig_vm::{Registers, VMStatus, VM}; + +use crate::{pwg::OpcodeNotSolvable, OpcodeResolutionError}; + +use super::{get_value, insert_value}; + +pub(super) struct BrilligSolver; + +impl BrilligSolver { + pub(super) fn solve( + initial_witness: &mut WitnessMap, + brillig: &Brillig, + bb_solver: &B, + acir_index: usize, + ) -> Result, OpcodeResolutionError> { + // If the predicate is `None`, then we simply return the value 1 + // If the predicate is `Some` but we cannot find a value, then we return stalled + let pred_value = match &brillig.predicate { + Some(pred) => get_value(pred, initial_witness), + None => Ok(FieldElement::one()), + }?; + + // A zero predicate indicates the oracle should be skipped, and its outputs zeroed. + if pred_value.is_zero() { + Self::zero_out_brillig_outputs(initial_witness, brillig)?; + return Ok(None); + } + + // Set input values + let mut input_register_values: Vec = Vec::new(); + let mut input_memory: Vec = Vec::new(); + // Each input represents an expression or array of expressions to evaluate. + // Iterate over each input and evaluate the expression(s) associated with it. + // Push the results into registers and/or memory. + // If a certain expression is not solvable, we stall the ACVM and do not proceed with Brillig VM execution. + for input in &brillig.inputs { + match input { + BrilligInputs::Single(expr) => match get_value(expr, initial_witness) { + Ok(value) => input_register_values.push(value.into()), + Err(_) => { + return Err(OpcodeResolutionError::OpcodeNotSolvable( + OpcodeNotSolvable::ExpressionHasTooManyUnknowns(expr.clone()), + )) + } + }, + BrilligInputs::Array(expr_arr) => { + // Attempt to fetch all array input values + let memory_pointer = input_memory.len(); + for expr in expr_arr.iter() { + match get_value(expr, initial_witness) { + Ok(value) => input_memory.push(value.into()), + Err(_) => { + return Err(OpcodeResolutionError::OpcodeNotSolvable( + OpcodeNotSolvable::ExpressionHasTooManyUnknowns(expr.clone()), + )) + } + } + } + + // Push value of the array pointer as a register + input_register_values.push(Value::from(memory_pointer)); + } + } + } + + // Instantiate a Brillig VM given the solved input registers and memory + // along with the Brillig bytecode, and any present foreign call results. + let input_registers = Registers::load(input_register_values); + let mut vm = VM::new( + input_registers, + input_memory, + brillig.bytecode.clone(), + brillig.foreign_call_results.clone(), + bb_solver, + ); + + // Run the Brillig VM on these inputs, bytecode, etc! + let vm_status = vm.process_opcodes(); + + // Check the status of the Brillig VM. + // It may be finished, in-progress, failed, or may be waiting for results of a foreign call. + // Return the "resolution" to the caller who may choose to make subsequent calls + // (when it gets foreign call results for example). + match vm_status { + VMStatus::Finished => { + for (i, output) in brillig.outputs.iter().enumerate() { + let register_value = vm.get_registers().get(RegisterIndex::from(i)); + match output { + BrilligOutputs::Simple(witness) => { + insert_value(witness, register_value.to_field(), initial_witness)?; + } + BrilligOutputs::Array(witness_arr) => { + // Treat the register value as a pointer to memory + for (i, witness) in witness_arr.iter().enumerate() { + let value = &vm.get_memory()[register_value.to_usize() + i]; + insert_value(witness, value.to_field(), initial_witness)?; + } + } + } + } + Ok(None) + } + VMStatus::InProgress => unreachable!("Brillig VM has not completed execution"), + VMStatus::Failure { message, call_stack } => { + Err(OpcodeResolutionError::BrilligFunctionFailed { + message, + call_stack: call_stack + .iter() + .map(|brillig_index| OpcodeLocation::Brillig { + acir_index, + brillig_index: *brillig_index, + }) + .collect(), + }) + } + VMStatus::ForeignCallWait { function, inputs } => { + Ok(Some(ForeignCallWaitInfo { function, inputs })) + } + } + } + + /// Assigns the zero value to all outputs of the given [`Brillig`] bytecode. + fn zero_out_brillig_outputs( + initial_witness: &mut WitnessMap, + brillig: &Brillig, + ) -> Result<(), OpcodeResolutionError> { + for output in &brillig.outputs { + match output { + BrilligOutputs::Simple(witness) => { + insert_value(witness, FieldElement::zero(), initial_witness)? + } + BrilligOutputs::Array(witness_arr) => { + for witness in witness_arr { + insert_value(witness, FieldElement::zero(), initial_witness)? + } + } + } + } + Ok(()) + } +} + +/// Encapsulates a request from a Brillig VM process that encounters a [foreign call opcode][acir::brillig_vm::Opcode::ForeignCall] +/// where the result of the foreign call has not yet been provided. +/// +/// The caller must resolve this opcode externally based upon the information in the request. +#[derive(Debug, PartialEq, Clone)] +pub struct ForeignCallWaitInfo { + /// An identifier interpreted by the caller process + pub function: String, + /// Resolved inputs to a foreign call computed in the previous steps of a Brillig VM process + pub inputs: Vec>, +} diff --git a/acvm-repo/acvm/src/pwg/directives/mod.rs b/acvm-repo/acvm/src/pwg/directives/mod.rs new file mode 100644 index 00000000000..d7dbb3edaf2 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/directives/mod.rs @@ -0,0 +1,150 @@ +use std::cmp::Ordering; + +use acir::{ + circuit::directives::{Directive, QuotientDirective}, + native_types::WitnessMap, + FieldElement, +}; +use num_bigint::BigUint; +use num_traits::Zero; + +use crate::OpcodeResolutionError; + +use super::{get_value, insert_value, ErrorLocation}; + +mod sorting; + +/// Attempts to solve the [`Directive`] opcode `directive`. +/// If successful, `initial_witness` will be mutated to contain the new witness assignment. +/// +/// Returns `Ok(OpcodeResolution)` to signal whether the directive was successful solved. +/// +/// Returns `Err(OpcodeResolutionError)` if a circuit constraint is unsatisfied. +pub(super) fn solve_directives( + initial_witness: &mut WitnessMap, + directive: &Directive, +) -> Result<(), OpcodeResolutionError> { + match directive { + Directive::Quotient(QuotientDirective { a, b, q, r, predicate }) => { + let val_a = get_value(a, initial_witness)?; + let val_b = get_value(b, initial_witness)?; + let int_a = BigUint::from_bytes_be(&val_a.to_be_bytes()); + let int_b = BigUint::from_bytes_be(&val_b.to_be_bytes()); + + // If the predicate is `None`, then we simply return the value 1 + // If the predicate is `Some` but we cannot find a value, then we return unresolved + let pred_value = match predicate { + Some(pred) => get_value(pred, initial_witness)?, + None => FieldElement::one(), + }; + + let (int_r, int_q) = if pred_value.is_zero() || int_b.is_zero() { + (BigUint::zero(), BigUint::zero()) + } else { + (&int_a % &int_b, &int_a / &int_b) + }; + + insert_value( + q, + FieldElement::from_be_bytes_reduce(&int_q.to_bytes_be()), + initial_witness, + )?; + insert_value( + r, + FieldElement::from_be_bytes_reduce(&int_r.to_bytes_be()), + initial_witness, + )?; + + Ok(()) + } + Directive::ToLeRadix { a, b, radix } => { + let value_a = get_value(a, initial_witness)?; + let big_integer = BigUint::from_bytes_be(&value_a.to_be_bytes()); + + // Decompose the integer into its radix digits in little endian form. + let decomposed_integer = big_integer.to_radix_le(*radix); + + if b.len() < decomposed_integer.len() { + return Err(OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: ErrorLocation::Unresolved, + }); + } + + for (i, witness) in b.iter().enumerate() { + // Fetch the `i'th` digit from the decomposed integer list + // and convert it to a field element. + // If it is not available, which can happen when the decomposed integer + // list is shorter than the witness list, we return 0. + let value = match decomposed_integer.get(i) { + Some(digit) => FieldElement::from_be_bytes_reduce(&[*digit]), + None => FieldElement::zero(), + }; + + insert_value(witness, value, initial_witness)? + } + + Ok(()) + } + Directive::PermutationSort { inputs: a, tuple, bits, sort_by } => { + let mut val_a = Vec::new(); + let mut base = Vec::new(); + for (i, element) in a.iter().enumerate() { + assert_eq!(element.len(), *tuple as usize); + let mut element_val = Vec::with_capacity(*tuple as usize + 1); + for e in element { + element_val.push(get_value(e, initial_witness)?); + } + let field_i = FieldElement::from(i as i128); + element_val.push(field_i); + base.push(field_i); + val_a.push(element_val); + } + val_a.sort_by(|a, b| { + for i in sort_by { + let int_a = BigUint::from_bytes_be(&a[*i as usize].to_be_bytes()); + let int_b = BigUint::from_bytes_be(&b[*i as usize].to_be_bytes()); + let cmp = int_a.cmp(&int_b); + if cmp != Ordering::Equal { + return cmp; + } + } + Ordering::Equal + }); + let b = val_a.iter().map(|a| *a.last().unwrap()).collect(); + let control = sorting::route(base, b); + for (w, value) in bits.iter().zip(control) { + let value = if value { FieldElement::one() } else { FieldElement::zero() }; + insert_value(w, value, initial_witness)?; + } + Ok(()) + } + } +} + +#[cfg(test)] +mod tests { + use acir::{ + circuit::directives::{Directive, QuotientDirective}, + native_types::{Expression, Witness, WitnessMap}, + FieldElement, + }; + + use super::solve_directives; + + #[test] + fn divisor_is_zero() { + let quotient_directive = QuotientDirective { + a: Expression::zero(), + b: Expression::zero(), + q: Witness(0), + r: Witness(0), + predicate: Some(Expression::one()), + }; + + let mut witness_map = WitnessMap::new(); + witness_map.insert(Witness(0), FieldElement::zero()); + + solve_directives(&mut witness_map, &Directive::Quotient(quotient_directive)) + .expect("expected 0/0 to return 0"); + } +} diff --git a/acvm-repo/acvm/src/pwg/directives/sorting.rs b/acvm-repo/acvm/src/pwg/directives/sorting.rs new file mode 100644 index 00000000000..5ff43320226 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/directives/sorting.rs @@ -0,0 +1,396 @@ +use std::collections::{BTreeMap, BTreeSet}; + +use acir::FieldElement; + +// A sorting network is a graph of connected switches +// It is defined recursively so here we only keep track of the outer layer of switches +struct SortingNetwork { + n: usize, // size of the network + x_inputs: Vec, // inputs of the network + y_inputs: Vec, // outputs of the network + x_values: BTreeMap, // map for matching a y value with a x value + y_values: BTreeMap, // map for matching a x value with a y value + inner_x: Vec, // positions after the switch_x + inner_y: Vec, // positions after the sub-networks, and before the switch_y + switch_x: Vec, // outer switches for the inputs + switch_y: Vec, // outer switches for the outputs + free: BTreeSet, // outer switches available for looping +} + +impl SortingNetwork { + fn new(n: usize) -> SortingNetwork { + let free_len = (n - 1) / 2; + let mut free = BTreeSet::new(); + for i in 0..free_len { + free.insert(i); + } + SortingNetwork { + n, + x_inputs: Vec::with_capacity(n), + y_inputs: Vec::with_capacity(n), + x_values: BTreeMap::new(), + y_values: BTreeMap::new(), + inner_x: Vec::with_capacity(n), + inner_y: Vec::with_capacity(n), + switch_x: Vec::with_capacity(n / 2), + switch_y: Vec::with_capacity(free_len), + free, + } + } + + fn init(&mut self, inputs: Vec, outputs: Vec) { + let n = self.n; + assert_eq!(inputs.len(), outputs.len()); + assert_eq!(inputs.len(), n); + + self.x_inputs = inputs; + self.y_inputs = outputs; + for i in 0..self.n { + self.x_values.insert(self.x_inputs[i], i); + self.y_values.insert(self.y_inputs[i], i); + } + self.switch_x = vec![false; n / 2]; + self.switch_y = vec![false; (n - 1) / 2]; + self.inner_x = vec![FieldElement::zero(); n]; + self.inner_y = vec![FieldElement::zero(); n]; + + //Route the single wires so we do not need to handle this case later on + self.inner_y[n - 1] = self.y_inputs[n - 1]; + if n % 2 == 0 { + self.inner_y[n / 2 - 1] = self.y_inputs[n - 2]; + } else { + self.inner_x[n - 1] = self.x_inputs[n - 1]; + } + } + + //route a wire from outputs to its value in the inputs + fn route_out_wire(&mut self, y: usize, sub: bool) -> usize { + // sub <- y + if self.is_single_y(y) { + assert!(sub); + } else { + let port = y % 2 != 0; + let s1 = sub ^ port; + let inner = self.compute_inner(y, s1); + self.configure_y(y, s1, inner); + } + // x <- sub + let x = self.x_values.remove(&self.y_inputs[y]).unwrap(); + if !self.is_single_x(x) { + let port2 = x % 2 != 0; + let s2 = sub ^ port2; + let inner = self.compute_inner(x, s2); + self.configure_x(x, s2, inner); + } + x + } + + //route a wire from inputs to its value in the outputs + fn route_in_wire(&mut self, x: usize, sub: bool) -> usize { + // x -> sub + assert!(!self.is_single_x(x)); + let port = x % 2 != 0; + let s1 = sub ^ port; + let inner = self.compute_inner(x, s1); + self.configure_x(x, s1, inner); + + // sub -> y + let y = self.y_values.remove(&self.x_inputs[x]).unwrap(); + if !self.is_single_y(y) { + let port = y % 2 != 0; + let s2 = sub ^ port; + let inner = self.compute_inner(y, s2); + self.configure_y(y, s2, inner); + } + y + } + + //update the computed switch and inner values for an input wire + fn configure_x(&mut self, x: usize, switch: bool, inner: usize) { + self.inner_x[inner] = self.x_inputs[x]; + self.switch_x[x / 2] = switch; + } + + //update the computed switch and inner values for an output wire + fn configure_y(&mut self, y: usize, switch: bool, inner: usize) { + self.inner_y[inner] = self.y_inputs[y]; + self.switch_y[y / 2] = switch; + } + + // returns the other wire belonging to the same switch + fn sibling(index: usize) -> usize { + index + 1 - 2 * (index % 2) + } + + // returns a free switch + fn take(&mut self) -> Option { + self.free.first().copied() + } + + fn is_single_x(&self, a: usize) -> bool { + let n = self.x_inputs.len(); + n % 2 == 1 && a == n - 1 + } + + fn is_single_y(&mut self, a: usize) -> bool { + let n = self.x_inputs.len(); + a >= n - 2 + n % 2 + } + + // compute the inner position of idx through its switch + fn compute_inner(&self, idx: usize, switch: bool) -> usize { + if switch ^ (idx % 2 == 1) { + idx / 2 + self.n / 2 + } else { + idx / 2 + } + } + + fn new_start(&mut self) -> (Option, usize) { + let next = self.take(); + if let Some(switch) = next { + (next, 2 * switch) + } else { + (None, 0) + } + } +} + +// Computes the control bits of the sorting network which transform inputs into outputs +// implementation is based on https://www.mdpi.com/2227-7080/10/1/16 +pub(super) fn route(inputs: Vec, outputs: Vec) -> Vec { + assert_eq!(inputs.len(), outputs.len()); + match inputs.len() { + 0 => Vec::new(), + 1 => { + assert_eq!(inputs[0], outputs[0]); + Vec::new() + } + 2 => { + if inputs[0] == outputs[0] { + assert_eq!(inputs[1], outputs[1]); + vec![false] + } else { + assert_eq!(inputs[1], outputs[0]); + assert_eq!(inputs[0], outputs[1]); + vec![true] + } + } + _ => { + let n = inputs.len(); + + let mut result; + let n1 = n / 2; + let in_sub1; + let out_sub1; + let in_sub2; + let out_sub2; + + // process the outer layer in a code block so that the intermediate data is cleared before recursion + { + let mut network = SortingNetwork::new(n); + network.init(inputs, outputs); + + //We start with the last single wire + let mut out_idx = n - 1; + let mut start_sub = true; //it is connected to the lower inner network + let mut switch = None; + let mut start = None; + + while !network.free.is_empty() { + // the processed switch is no more available + if let Some(free_switch) = switch { + network.free.remove(&free_switch); + } + + // connect the output wire to its matching input + let in_idx = network.route_out_wire(out_idx, start_sub); + if network.is_single_x(in_idx) { + start_sub = !start_sub; //We need to restart, but did not complete the loop so we switch the sub network + (start, out_idx) = network.new_start(); + switch = start; + continue; + } + + // loop from the sibling + let next = SortingNetwork::sibling(in_idx); + // connect the input wire to its matching output, using the other sub-network + out_idx = network.route_in_wire(next, !start_sub); + switch = Some(out_idx / 2); + if start == switch || network.is_single_y(out_idx) { + //loop is complete, need a fresh start + (start, out_idx) = network.new_start(); + switch = start; + } else { + // we loop back from the sibling + out_idx = SortingNetwork::sibling(out_idx); + } + } + //All the wires are connected, we can now route the sub-networks + result = network.switch_x; + result.extend(network.switch_y); + in_sub1 = network.inner_x[0..n1].to_vec(); + in_sub2 = network.inner_x[n1..].to_vec(); + out_sub1 = network.inner_y[0..n1].to_vec(); + out_sub2 = network.inner_y[n1..].to_vec(); + } + let s1 = route(in_sub1, out_sub1); + result.extend(s1); + let s2 = route(in_sub2, out_sub2); + result.extend(s2); + result + } + } +} + +#[cfg(test)] +mod tests { + // Silence `unused_crate_dependencies` warning + use paste as _; + use proptest as _; + + use super::route; + use acir::FieldElement; + use rand::prelude::*; + + fn execute_network(config: Vec, inputs: Vec) -> Vec { + let n = inputs.len(); + if n == 1 { + return inputs; + } + let mut in1 = Vec::new(); + let mut in2 = Vec::new(); + //layer 1: + for i in 0..n / 2 { + if config[i] { + in1.push(inputs[2 * i + 1]); + in2.push(inputs[2 * i]); + } else { + in1.push(inputs[2 * i]); + in2.push(inputs[2 * i + 1]); + } + } + if n % 2 == 1 { + in2.push(*inputs.last().unwrap()); + } + let n2 = n / 2 + (n - 1) / 2; + let n3 = n2 + switch_nb(n / 2); + let mut result = Vec::new(); + let out1 = execute_network(config[n2..n3].to_vec(), in1); + let out2 = execute_network(config[n3..].to_vec(), in2); + //last layer: + for i in 0..(n - 1) / 2 { + if config[n / 2 + i] { + result.push(out2[i]); + result.push(out1[i]); + } else { + result.push(out1[i]); + result.push(out2[i]); + } + } + if n % 2 == 0 { + result.push(*out1.last().unwrap()); + result.push(*out2.last().unwrap()); + } else { + result.push(*out2.last().unwrap()) + } + result + } + + // returns the number of switches in the network + fn switch_nb(n: usize) -> usize { + let mut s = 0; + for i in 0..n { + s += f64::from((i + 1) as u32).log2().ceil() as usize; + } + s + } + + #[test] + fn test_route() { + //basic tests + let a = vec![ + FieldElement::from(1_i128), + FieldElement::from(2_i128), + FieldElement::from(3_i128), + ]; + let b = vec![ + FieldElement::from(1_i128), + FieldElement::from(2_i128), + FieldElement::from(3_i128), + ]; + let c = route(a, b); + assert_eq!(c, vec![false, false, false]); + + let a = vec![ + FieldElement::from(1_i128), + FieldElement::from(2_i128), + FieldElement::from(3_i128), + ]; + let b = vec![ + FieldElement::from(1_i128), + FieldElement::from(3_i128), + FieldElement::from(2_i128), + ]; + let c = route(a, b); + assert_eq!(c, vec![false, false, true]); + + let a = vec![ + FieldElement::from(1_i128), + FieldElement::from(2_i128), + FieldElement::from(3_i128), + ]; + let b = vec![ + FieldElement::from(3_i128), + FieldElement::from(2_i128), + FieldElement::from(1_i128), + ]; + let c = route(a, b); + assert_eq!(c, vec![true, true, true]); + + let a = vec![ + FieldElement::from(0_i128), + FieldElement::from(1_i128), + FieldElement::from(2_i128), + FieldElement::from(3_i128), + ]; + let b = vec![ + FieldElement::from(2_i128), + FieldElement::from(3_i128), + FieldElement::from(0_i128), + FieldElement::from(1_i128), + ]; + let c = route(a, b); + assert_eq!(c, vec![false, true, true, true, true]); + + let a = vec![ + FieldElement::from(0_i128), + FieldElement::from(1_i128), + FieldElement::from(2_i128), + FieldElement::from(3_i128), + FieldElement::from(4_i128), + ]; + let b = vec![ + FieldElement::from(0_i128), + FieldElement::from(3_i128), + FieldElement::from(4_i128), + FieldElement::from(2_i128), + FieldElement::from(1_i128), + ]; + let c = route(a, b); + assert_eq!(c, vec![false, false, false, true, false, true, false, true]); + + // random tests + for i in 2..50 { + let mut a = vec![FieldElement::zero()]; + for j in 0..i - 1 { + a.push(a[j] + FieldElement::one()); + } + let mut rng = rand::thread_rng(); + let mut b = a.clone(); + b.shuffle(&mut rng); + let c = route(a.clone(), b.clone()); + assert_eq!(b, execute_network(c, a)); + } + } +} diff --git a/acvm-repo/acvm/src/pwg/memory_op.rs b/acvm-repo/acvm/src/pwg/memory_op.rs new file mode 100644 index 00000000000..42951dfa3c1 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/memory_op.rs @@ -0,0 +1,259 @@ +use std::collections::HashMap; + +use acir::{ + circuit::opcodes::MemOp, + native_types::{Expression, Witness, WitnessMap}, + FieldElement, +}; + +use super::{arithmetic::ArithmeticSolver, get_value, insert_value, witness_to_value}; +use super::{ErrorLocation, OpcodeResolutionError}; + +type MemoryIndex = u32; + +/// Maintains the state for solving [`MemoryInit`][`acir::circuit::Opcode::MemoryInit`] and [`MemoryOp`][`acir::circuit::Opcode::MemoryOp`] opcodes. +#[derive(Default)] +pub(super) struct MemoryOpSolver { + block_value: HashMap, + block_len: u32, +} + +impl MemoryOpSolver { + fn write_memory_index( + &mut self, + index: MemoryIndex, + value: FieldElement, + ) -> Result<(), OpcodeResolutionError> { + if index >= self.block_len { + return Err(OpcodeResolutionError::IndexOutOfBounds { + opcode_location: ErrorLocation::Unresolved, + index, + array_size: self.block_len, + }); + } + self.block_value.insert(index, value); + Ok(()) + } + + fn read_memory_index(&self, index: MemoryIndex) -> Result { + self.block_value.get(&index).copied().ok_or(OpcodeResolutionError::IndexOutOfBounds { + opcode_location: ErrorLocation::Unresolved, + index, + array_size: self.block_len, + }) + } + + /// Set the block_value from a MemoryInit opcode + pub(crate) fn init( + &mut self, + init: &[Witness], + initial_witness: &WitnessMap, + ) -> Result<(), OpcodeResolutionError> { + self.block_len = init.len() as u32; + for (memory_index, witness) in init.iter().enumerate() { + self.write_memory_index( + memory_index as MemoryIndex, + *witness_to_value(initial_witness, *witness)?, + )?; + } + Ok(()) + } + + pub(crate) fn solve_memory_op( + &mut self, + op: &MemOp, + initial_witness: &mut WitnessMap, + predicate: &Option, + ) -> Result<(), OpcodeResolutionError> { + let operation = get_value(&op.operation, initial_witness)?; + + // Find the memory index associated with this memory operation. + let index = get_value(&op.index, initial_witness)?; + let memory_index = index.try_to_u64().unwrap() as MemoryIndex; + + // Calculate the value associated with this memory operation. + // + // In read operations, this corresponds to the witness index at which the value from memory will be written. + // In write operations, this corresponds to the expression which will be written to memory. + let value = ArithmeticSolver::evaluate(&op.value, initial_witness); + + // `operation == 0` implies a read operation. (`operation == 1` implies write operation). + let is_read_operation = operation.is_zero(); + + // If the predicate is `None`, then we simply return the value 1 + let pred_value = match predicate { + Some(pred) => get_value(pred, initial_witness), + None => Ok(FieldElement::one()), + }?; + + if is_read_operation { + // `value_read = arr[memory_index]` + // + // This is the value that we want to read into; i.e. copy from the memory block + // into this value. + let value_read_witness = value.to_witness().expect( + "Memory must be read into a specified witness index, encountered an Expression", + ); + + // A zero predicate indicates that we should skip the read operation + // and zero out the operation's output. + let value_in_array = if pred_value.is_zero() { + FieldElement::zero() + } else { + self.read_memory_index(memory_index)? + }; + insert_value(&value_read_witness, value_in_array, initial_witness) + } else { + // `arr[memory_index] = value_write` + // + // This is the value that we want to write into; i.e. copy from `value_write` + // into the memory block. + let value_write = value; + + // A zero predicate indicates that we should skip the write operation. + if pred_value.is_zero() { + // We only want to write to already initialized memory. + // Do nothing if the predicate is zero. + Ok(()) + } else { + let value_to_write = get_value(&value_write, initial_witness)?; + self.write_memory_index(memory_index, value_to_write) + } + } + } +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + + use acir::{ + circuit::opcodes::MemOp, + native_types::{Expression, Witness, WitnessMap}, + FieldElement, + }; + + use super::MemoryOpSolver; + + #[test] + fn test_solver() { + let mut initial_witness = WitnessMap::from(BTreeMap::from_iter([ + (Witness(1), FieldElement::from(1u128)), + (Witness(2), FieldElement::from(1u128)), + (Witness(3), FieldElement::from(2u128)), + ])); + + let init = vec![Witness(1), Witness(2)]; + + let trace = vec![ + MemOp::write_to_mem_index(FieldElement::from(1u128).into(), Witness(3).into()), + MemOp::read_at_mem_index(FieldElement::one().into(), Witness(4)), + ]; + + let mut block_solver = MemoryOpSolver::default(); + block_solver.init(&init, &initial_witness).unwrap(); + + for op in trace { + block_solver.solve_memory_op(&op, &mut initial_witness, &None).unwrap(); + } + + assert_eq!(initial_witness[&Witness(4)], FieldElement::from(2u128)); + } + + #[test] + fn test_index_out_of_bounds() { + let mut initial_witness = WitnessMap::from(BTreeMap::from_iter([ + (Witness(1), FieldElement::from(1u128)), + (Witness(2), FieldElement::from(1u128)), + (Witness(3), FieldElement::from(2u128)), + ])); + + let init = vec![Witness(1), Witness(2)]; + + let invalid_trace = vec![ + MemOp::write_to_mem_index(FieldElement::from(1u128).into(), Witness(3).into()), + MemOp::read_at_mem_index(FieldElement::from(2u128).into(), Witness(4)), + ]; + let mut block_solver = MemoryOpSolver::default(); + block_solver.init(&init, &initial_witness).unwrap(); + let mut err = None; + for op in invalid_trace { + if err.is_none() { + err = block_solver.solve_memory_op(&op, &mut initial_witness, &None).err(); + } + } + + assert!(matches!( + err, + Some(crate::pwg::OpcodeResolutionError::IndexOutOfBounds { + opcode_location: _, + index: 2, + array_size: 2 + }) + )); + } + + #[test] + fn test_predicate_on_read() { + let mut initial_witness = WitnessMap::from(BTreeMap::from_iter([ + (Witness(1), FieldElement::from(1u128)), + (Witness(2), FieldElement::from(1u128)), + (Witness(3), FieldElement::from(2u128)), + ])); + + let init = vec![Witness(1), Witness(2)]; + + let invalid_trace = vec![ + MemOp::write_to_mem_index(FieldElement::from(1u128).into(), Witness(3).into()), + MemOp::read_at_mem_index(FieldElement::from(2u128).into(), Witness(4)), + ]; + let mut block_solver = MemoryOpSolver::default(); + block_solver.init(&init, &initial_witness).unwrap(); + let mut err = None; + for op in invalid_trace { + if err.is_none() { + err = block_solver + .solve_memory_op(&op, &mut initial_witness, &Some(Expression::zero())) + .err(); + } + } + + // Should have no index out of bounds error where predicate is zero + assert_eq!(err, None); + // The result of a read under a zero predicate should be zero + assert_eq!(initial_witness[&Witness(4)], FieldElement::from(0u128)); + } + + #[test] + fn test_predicate_on_write() { + let mut initial_witness = WitnessMap::from(BTreeMap::from_iter([ + (Witness(1), FieldElement::from(1u128)), + (Witness(2), FieldElement::from(1u128)), + (Witness(3), FieldElement::from(2u128)), + ])); + + let init = vec![Witness(1), Witness(2)]; + + let invalid_trace = vec![ + MemOp::write_to_mem_index(FieldElement::from(2u128).into(), Witness(3).into()), + MemOp::read_at_mem_index(FieldElement::from(0u128).into(), Witness(4)), + MemOp::read_at_mem_index(FieldElement::from(1u128).into(), Witness(5)), + ]; + let mut block_solver = MemoryOpSolver::default(); + block_solver.init(&init, &initial_witness).unwrap(); + let mut err = None; + for op in invalid_trace { + if err.is_none() { + err = block_solver + .solve_memory_op(&op, &mut initial_witness, &Some(Expression::zero())) + .err(); + } + } + + // Should have no index out of bounds error where predicate is zero + assert_eq!(err, None); + // The memory under a zero predicate should be zeroed out + assert_eq!(initial_witness[&Witness(4)], FieldElement::from(0u128)); + assert_eq!(initial_witness[&Witness(5)], FieldElement::from(0u128)); + } +} diff --git a/acvm-repo/acvm/src/pwg/mod.rs b/acvm-repo/acvm/src/pwg/mod.rs new file mode 100644 index 00000000000..3fcf1088225 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/mod.rs @@ -0,0 +1,399 @@ +// Re-usable methods that backends can use to implement their PWG + +use std::collections::HashMap; + +use acir::{ + brillig::ForeignCallResult, + circuit::{opcodes::BlockId, Opcode, OpcodeLocation}, + native_types::{Expression, Witness, WitnessMap}, + BlackBoxFunc, FieldElement, +}; +use acvm_blackbox_solver::BlackBoxResolutionError; + +use self::{ + arithmetic::ArithmeticSolver, brillig::BrilligSolver, directives::solve_directives, + memory_op::MemoryOpSolver, +}; +use crate::{BlackBoxFunctionSolver, Language}; + +use thiserror::Error; + +// arithmetic +pub(crate) mod arithmetic; +// Brillig bytecode +mod brillig; +// Directives +mod directives; +// black box functions +mod blackbox; +mod memory_op; + +pub use brillig::ForeignCallWaitInfo; + +#[derive(Debug, Clone, PartialEq)] +pub enum ACVMStatus { + /// All opcodes have been solved. + Solved, + + /// The ACVM is in the process of executing the circuit. + InProgress, + + /// The ACVM has encountered an irrecoverable error while executing the circuit and can not progress. + /// Most commonly this will be due to an unsatisfied constraint due to invalid inputs to the circuit. + Failure(OpcodeResolutionError), + + /// The ACVM has encountered a request for a Brillig [foreign call][acir::brillig_vm::Opcode::ForeignCall] + /// to retrieve information from outside of the ACVM. The result of the foreign call must be passed back + /// to the ACVM using [`ACVM::resolve_pending_foreign_call`]. + /// + /// Once this is done, the ACVM can be restarted to solve the remaining opcodes. + RequiresForeignCall(ForeignCallWaitInfo), +} + +impl std::fmt::Display for ACVMStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ACVMStatus::Solved => write!(f, "Solved"), + ACVMStatus::InProgress => write!(f, "In progress"), + ACVMStatus::Failure(_) => write!(f, "Execution failure"), + ACVMStatus::RequiresForeignCall(_) => write!(f, "Waiting on foreign call"), + } + } +} + +// This enum represents the different cases in which an +// opcode can be unsolvable. +// The most common being that one of its input has not been +// assigned a value. +// +// TODO: ExpressionHasTooManyUnknowns is specific for arithmetic expressions +// TODO: we could have a error enum for arithmetic failure cases in that module +// TODO that can be converted into an OpcodeNotSolvable or OpcodeResolutionError enum +#[derive(Clone, PartialEq, Eq, Debug, Error)] +pub enum OpcodeNotSolvable { + #[error("missing assignment for witness index {0}")] + MissingAssignment(u32), + #[error("expression has too many unknowns {0}")] + ExpressionHasTooManyUnknowns(Expression), +} + +/// Allows to point to a specific opcode as cause in errors. +/// Some errors don't have a specific opcode associated with them, or are created without one and added later. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] +pub enum ErrorLocation { + #[default] + Unresolved, + Resolved(OpcodeLocation), +} + +impl std::fmt::Display for ErrorLocation { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ErrorLocation::Unresolved => write!(f, "unresolved"), + ErrorLocation::Resolved(location) => { + write!(f, "{location}") + } + } + } +} + +#[derive(Clone, PartialEq, Eq, Debug, Error)] +pub enum OpcodeResolutionError { + #[error("Cannot solve opcode: {0}")] + OpcodeNotSolvable(#[from] OpcodeNotSolvable), + #[error("Backend does not currently support the {0} opcode. ACVM does not currently have a fallback for this opcode.")] + UnsupportedBlackBoxFunc(BlackBoxFunc), + #[error("Cannot satisfy constraint")] + UnsatisfiedConstrain { opcode_location: ErrorLocation }, + #[error("Index out of bounds, array has size {array_size:?}, but index was {index:?}")] + IndexOutOfBounds { opcode_location: ErrorLocation, index: u32, array_size: u32 }, + #[error("Failed to solve blackbox function: {0}, reason: {1}")] + BlackBoxFunctionFailed(BlackBoxFunc, String), + #[error("Failed to solve brillig function, reason: {message}")] + BrilligFunctionFailed { message: String, call_stack: Vec }, +} + +impl From for OpcodeResolutionError { + fn from(value: BlackBoxResolutionError) -> Self { + match value { + BlackBoxResolutionError::Failed(func, reason) => { + OpcodeResolutionError::BlackBoxFunctionFailed(func, reason) + } + BlackBoxResolutionError::Unsupported(func) => { + OpcodeResolutionError::UnsupportedBlackBoxFunc(func) + } + } + } +} + +pub struct ACVM<'backend, B: BlackBoxFunctionSolver> { + status: ACVMStatus, + + backend: &'backend B, + + /// Stores the solver for memory operations acting on blocks of memory disambiguated by [block][`BlockId`]. + block_solvers: HashMap, + + /// A list of opcodes which are to be executed by the ACVM. + opcodes: Vec, + /// Index of the next opcode to be executed. + instruction_pointer: usize, + + witness_map: WitnessMap, +} + +impl<'backend, B: BlackBoxFunctionSolver> ACVM<'backend, B> { + pub fn new(backend: &'backend B, opcodes: Vec, initial_witness: WitnessMap) -> Self { + let status = if opcodes.is_empty() { ACVMStatus::Solved } else { ACVMStatus::InProgress }; + ACVM { + status, + backend, + block_solvers: HashMap::default(), + opcodes, + instruction_pointer: 0, + witness_map: initial_witness, + } + } + + /// Returns a reference to the current state of the ACVM's [`WitnessMap`]. + /// + /// Once execution has completed, the witness map can be extracted using [`ACVM::finalize`] + pub fn witness_map(&self) -> &WitnessMap { + &self.witness_map + } + + /// Returns a slice containing the opcodes of the circuit being executed. + pub fn opcodes(&self) -> &[Opcode] { + &self.opcodes + } + + /// Returns the index of the current opcode to be executed. + pub fn instruction_pointer(&self) -> usize { + self.instruction_pointer + } + + /// Finalize the ACVM execution, returning the resulting [`WitnessMap`]. + pub fn finalize(self) -> WitnessMap { + if self.status != ACVMStatus::Solved { + panic!("ACVM execution is not complete: ({})", self.status); + } + self.witness_map + } + + /// Updates the current status of the VM. + /// Returns the given status. + fn status(&mut self, status: ACVMStatus) -> ACVMStatus { + self.status = status.clone(); + status + } + + /// Sets the VM status to [ACVMStatus::Failure] using the provided `error`. + /// Returns the new status. + fn fail(&mut self, error: OpcodeResolutionError) -> ACVMStatus { + self.status(ACVMStatus::Failure(error)) + } + + /// Sets the status of the VM to `RequiresForeignCall`. + /// Indicating that the VM is now waiting for a foreign call to be resolved. + fn wait_for_foreign_call(&mut self, foreign_call: ForeignCallWaitInfo) -> ACVMStatus { + self.status(ACVMStatus::RequiresForeignCall(foreign_call)) + } + + /// Return a reference to the arguments for the next pending foreign call, if one exists. + pub fn get_pending_foreign_call(&self) -> Option<&ForeignCallWaitInfo> { + if let ACVMStatus::RequiresForeignCall(foreign_call) = &self.status { + Some(foreign_call) + } else { + None + } + } + + /// Resolves a foreign call's [result][acir::brillig_vm::ForeignCallResult] using a result calculated outside of the ACVM. + /// + /// The ACVM can then be restarted to solve the remaining Brillig VM process as well as the remaining ACIR opcodes. + pub fn resolve_pending_foreign_call(&mut self, foreign_call_result: ForeignCallResult) { + if !matches!(self.status, ACVMStatus::RequiresForeignCall(_)) { + panic!("ACVM is not expecting a foreign call response as no call was made"); + } + + // We want to inject the foreign call result into the brillig opcode which initiated the call. + let opcode = &mut self.opcodes[self.instruction_pointer]; + let Opcode::Brillig(brillig) = opcode else { + unreachable!("ACVM can only enter `RequiresForeignCall` state on a Brillig opcode"); + }; + brillig.foreign_call_results.push(foreign_call_result); + + // Now that the foreign call has been resolved then we can resume execution. + self.status(ACVMStatus::InProgress); + } + + /// Executes the ACVM's circuit until execution halts. + /// + /// Execution can halt due to three reasons: + /// 1. All opcodes have been executed successfully. + /// 2. The circuit has been found to be unsatisfiable. + /// 2. A Brillig [foreign call][`ForeignCallWaitInfo`] has been encountered and must be resolved. + pub fn solve(&mut self) -> ACVMStatus { + while self.status == ACVMStatus::InProgress { + self.solve_opcode(); + } + self.status.clone() + } + + pub fn solve_opcode(&mut self) -> ACVMStatus { + let opcode = &self.opcodes[self.instruction_pointer]; + + let resolution = match opcode { + Opcode::Arithmetic(expr) => ArithmeticSolver::solve(&mut self.witness_map, expr), + Opcode::BlackBoxFuncCall(bb_func) => { + blackbox::solve(self.backend, &mut self.witness_map, bb_func) + } + Opcode::Directive(directive) => solve_directives(&mut self.witness_map, directive), + Opcode::MemoryInit { block_id, init } => { + let solver = self.block_solvers.entry(*block_id).or_default(); + solver.init(init, &self.witness_map) + } + Opcode::MemoryOp { block_id, op, predicate } => { + let solver = self.block_solvers.entry(*block_id).or_default(); + solver.solve_memory_op(op, &mut self.witness_map, predicate) + } + Opcode::Brillig(brillig) => { + match BrilligSolver::solve( + &mut self.witness_map, + brillig, + self.backend, + self.instruction_pointer, + ) { + Ok(Some(foreign_call)) => return self.wait_for_foreign_call(foreign_call), + res => res.map(|_| ()), + } + } + }; + match resolution { + Ok(()) => { + self.instruction_pointer += 1; + if self.instruction_pointer == self.opcodes.len() { + self.status(ACVMStatus::Solved) + } else { + self.status(ACVMStatus::InProgress) + } + } + Err(mut error) => { + match &mut error { + // If we have an index out of bounds or an unsatisfied constraint, the opcode label will be unresolved + // because the solvers do not have knowledge of this information. + // We resolve, by setting this to the corresponding opcode that we just attempted to solve. + OpcodeResolutionError::IndexOutOfBounds { + opcode_location: opcode_index, + .. + } + | OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: opcode_index, + } => { + *opcode_index = ErrorLocation::Resolved(OpcodeLocation::Acir( + self.instruction_pointer(), + )); + } + // All other errors are thrown normally. + _ => (), + }; + self.fail(error) + } + } + } +} + +// Returns the concrete value for a particular witness +// If the witness has no assignment, then +// an error is returned +pub fn witness_to_value( + initial_witness: &WitnessMap, + witness: Witness, +) -> Result<&FieldElement, OpcodeResolutionError> { + match initial_witness.get(&witness) { + Some(value) => Ok(value), + None => Err(OpcodeNotSolvable::MissingAssignment(witness.0).into()), + } +} + +// TODO: There is an issue open to decide on whether we need to get values from Expressions +// TODO versus just getting values from Witness +pub fn get_value( + expr: &Expression, + initial_witness: &WitnessMap, +) -> Result { + let expr = ArithmeticSolver::evaluate(expr, initial_witness); + match expr.to_const() { + Some(value) => Ok(value), + None => Err(OpcodeResolutionError::OpcodeNotSolvable( + OpcodeNotSolvable::MissingAssignment(any_witness_from_expression(&expr).unwrap().0), + )), + } +} + +/// Inserts `value` into the initial witness map under the index `witness`. +/// +/// Returns an error if there was already a value in the map +/// which does not match the value that one is about to insert +pub fn insert_value( + witness: &Witness, + value_to_insert: FieldElement, + initial_witness: &mut WitnessMap, +) -> Result<(), OpcodeResolutionError> { + let optional_old_value = initial_witness.insert(*witness, value_to_insert); + + let old_value = match optional_old_value { + Some(old_value) => old_value, + None => return Ok(()), + }; + + if old_value != value_to_insert { + return Err(OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: ErrorLocation::Unresolved, + }); + } + + Ok(()) +} + +// Returns one witness belonging to an expression, in no relevant order +// Returns None if the expression is const +// The function is used during partial witness generation to report unsolved witness +fn any_witness_from_expression(expr: &Expression) -> Option { + if expr.linear_combinations.is_empty() { + if expr.mul_terms.is_empty() { + None + } else { + Some(expr.mul_terms[0].1) + } + } else { + Some(expr.linear_combinations[0].1) + } +} + +#[deprecated( + note = "For backwards compatibility, this method allows you to derive _sensible_ defaults for opcode support based on the np language. \n Backends should simply specify what they support." +)] +// This is set to match the previous functionality that we had +// Where we could deduce what opcodes were supported +// by knowing the np complete language +pub fn default_is_opcode_supported(language: Language) -> fn(&Opcode) -> bool { + // R1CS does not support any of the opcode except Arithmetic by default. + // The compiler will replace those that it can -- ie range, xor, and + fn r1cs_is_supported(opcode: &Opcode) -> bool { + matches!(opcode, Opcode::Arithmetic(_)) + } + + // PLONK supports most of the opcodes by default + // The ones which are not supported, the acvm compiler will + // attempt to transform into supported opcodes. If these are also not available + // then a compiler error will be emitted. + fn plonk_is_supported(_opcode: &Opcode) -> bool { + true + } + + match language { + Language::R1CS => r1cs_is_supported, + Language::PLONKCSat { .. } => plonk_is_supported, + } +} diff --git a/acvm-repo/acvm/tests/solver.rs b/acvm-repo/acvm/tests/solver.rs new file mode 100644 index 00000000000..ca0ca99ba07 --- /dev/null +++ b/acvm-repo/acvm/tests/solver.rs @@ -0,0 +1,648 @@ +use std::collections::BTreeMap; + +use acir::{ + brillig::{BinaryFieldOp, Opcode as BrilligOpcode, RegisterIndex, RegisterOrMemory, Value}, + circuit::{ + brillig::{Brillig, BrilligInputs, BrilligOutputs}, + opcodes::{BlockId, MemOp}, + Opcode, OpcodeLocation, + }, + native_types::{Expression, Witness, WitnessMap}, + FieldElement, +}; + +use acvm::{ + pwg::{ACVMStatus, ErrorLocation, ForeignCallWaitInfo, OpcodeResolutionError, ACVM}, + BlackBoxFunctionSolver, +}; +use acvm_blackbox_solver::BlackBoxResolutionError; + +pub(crate) struct StubbedBackend; + +impl BlackBoxFunctionSolver for StubbedBackend { + fn schnorr_verify( + &self, + _public_key_x: &FieldElement, + _public_key_y: &FieldElement, + _signature: &[u8], + _message: &[u8], + ) -> Result { + panic!("Path not trodden by this test") + } + fn pedersen( + &self, + _inputs: &[FieldElement], + _domain_separator: u32, + ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + panic!("Path not trodden by this test") + } + fn fixed_base_scalar_mul( + &self, + _low: &FieldElement, + _high: &FieldElement, + ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + panic!("Path not trodden by this test") + } +} + +// Reenable these test cases once we move the brillig implementation of inversion down into the acvm stdlib. + +#[test] +#[ignore] +fn inversion_brillig_oracle_equivalence() { + // Opcodes below describe the following: + // fn main(x : Field, y : pub Field) { + // let z = x + y; + // assert( 1/z == Oracle("inverse", x + y) ); + // } + // Also performs an unrelated equality check + // just for the sake of testing multiple brillig opcodes. + let fe_0 = FieldElement::zero(); + let fe_1 = FieldElement::one(); + let w_x = Witness(1); + let w_y = Witness(2); + let w_oracle = Witness(3); + let w_z = Witness(4); + let w_z_inverse = Witness(5); + let w_x_plus_y = Witness(6); + let w_equal_res = Witness(7); + + let equal_opcode = BrilligOpcode::BinaryFieldOp { + op: BinaryFieldOp::Equals, + lhs: RegisterIndex::from(0), + rhs: RegisterIndex::from(1), + destination: RegisterIndex::from(2), + }; + + let brillig_data = Brillig { + inputs: vec![ + BrilligInputs::Single(Expression { + // Input Register 0 + mul_terms: vec![], + linear_combinations: vec![(fe_1, w_x), (fe_1, w_y)], + q_c: fe_0, + }), + BrilligInputs::Single(Expression::default()), // Input Register 1 + ], + // This tells the BrilligSolver which witnesses its output registers correspond to + outputs: vec![ + BrilligOutputs::Simple(w_x_plus_y), // Output Register 0 - from input + BrilligOutputs::Simple(w_oracle), // Output Register 1 + BrilligOutputs::Simple(w_equal_res), // Output Register 2 + ], + // stack of foreign call/oracle resolutions, starts empty + foreign_call_results: vec![], + bytecode: vec![ + equal_opcode, + // Oracles are named 'foreign calls' in brillig + BrilligOpcode::ForeignCall { + function: "invert".into(), + destinations: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(1))], + inputs: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(0))], + }, + ], + predicate: None, + }; + + let opcodes = vec![ + Opcode::Brillig(brillig_data), + Opcode::Arithmetic(Expression { + mul_terms: vec![], + linear_combinations: vec![(fe_1, w_x), (fe_1, w_y), (-fe_1, w_z)], + q_c: fe_0, + }), + // Opcode::Directive(Directive::Invert { x: w_z, result: w_z_inverse }), + Opcode::Arithmetic(Expression { + mul_terms: vec![(fe_1, w_z, w_z_inverse)], + linear_combinations: vec![], + q_c: -fe_1, + }), + Opcode::Arithmetic(Expression { + mul_terms: vec![], + linear_combinations: vec![(-fe_1, w_oracle), (fe_1, w_z_inverse)], + q_c: fe_0, + }), + ]; + + let witness_assignments = BTreeMap::from([ + (Witness(1), FieldElement::from(2u128)), + (Witness(2), FieldElement::from(3u128)), + ]) + .into(); + + let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + // use the partial witness generation solver with our acir program + let solver_status = acvm.solve(); + + assert!( + matches!(solver_status, ACVMStatus::RequiresForeignCall(_)), + "should require foreign call response" + ); + assert_eq!(acvm.instruction_pointer(), 0, "brillig should have been removed"); + + let foreign_call_wait_info: &ForeignCallWaitInfo = + acvm.get_pending_foreign_call().expect("should have a brillig foreign call request"); + assert_eq!(foreign_call_wait_info.inputs.len(), 1, "Should be waiting for a single input"); + + // As caller of VM, need to resolve foreign calls + let foreign_call_result = Value::from(foreign_call_wait_info.inputs[0][0].to_field().inverse()); + // Alter Brillig oracle opcode with foreign call resolution + acvm.resolve_pending_foreign_call(foreign_call_result.into()); + + // After filling data request, continue solving + let solver_status = acvm.solve(); + assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + + // ACVM should be able to be finalized in `Solved` state. + acvm.finalize(); +} + +#[test] +#[ignore] +fn double_inversion_brillig_oracle() { + // Opcodes below describe the following: + // fn main(x : Field, y : pub Field) { + // let z = x + y; + // let ij = i + j; + // assert( 1/z == Oracle("inverse", x + y) ); + // assert( 1/ij == Oracle("inverse", i + j) ); + // } + // Also performs an unrelated equality check + // just for the sake of testing multiple brillig opcodes. + let fe_0 = FieldElement::zero(); + let fe_1 = FieldElement::one(); + let w_x = Witness(1); + let w_y = Witness(2); + let w_oracle = Witness(3); + let w_z = Witness(4); + let w_z_inverse = Witness(5); + let w_x_plus_y = Witness(6); + let w_equal_res = Witness(7); + let w_i = Witness(8); + let w_j = Witness(9); + let w_ij_oracle = Witness(10); + let w_i_plus_j = Witness(11); + + let equal_opcode = BrilligOpcode::BinaryFieldOp { + op: BinaryFieldOp::Equals, + lhs: RegisterIndex::from(0), + rhs: RegisterIndex::from(1), + destination: RegisterIndex::from(4), + }; + + let brillig_data = Brillig { + inputs: vec![ + BrilligInputs::Single(Expression { + // Input Register 0 + mul_terms: vec![], + linear_combinations: vec![(fe_1, w_x), (fe_1, w_y)], + q_c: fe_0, + }), + BrilligInputs::Single(Expression::default()), // Input Register 1 + BrilligInputs::Single(Expression { + // Input Register 2 + mul_terms: vec![], + linear_combinations: vec![(fe_1, w_i), (fe_1, w_j)], + q_c: fe_0, + }), + ], + outputs: vec![ + BrilligOutputs::Simple(w_x_plus_y), // Output Register 0 - from input + BrilligOutputs::Simple(w_oracle), // Output Register 1 + BrilligOutputs::Simple(w_i_plus_j), // Output Register 2 - from input + BrilligOutputs::Simple(w_ij_oracle), // Output Register 3 + BrilligOutputs::Simple(w_equal_res), // Output Register 4 + ], + // stack of foreign call/oracle resolutions, starts empty + foreign_call_results: vec![], + bytecode: vec![ + equal_opcode, + // Oracles are named 'foreign calls' in brillig + BrilligOpcode::ForeignCall { + function: "invert".into(), + destinations: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(1))], + inputs: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(0))], + }, + BrilligOpcode::ForeignCall { + function: "invert".into(), + destinations: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(3))], + inputs: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(2))], + }, + ], + predicate: None, + }; + + let opcodes = vec![ + Opcode::Brillig(brillig_data), + Opcode::Arithmetic(Expression { + mul_terms: vec![], + linear_combinations: vec![(fe_1, w_x), (fe_1, w_y), (-fe_1, w_z)], + q_c: fe_0, + }), + // Opcode::Directive(Directive::Invert { x: w_z, result: w_z_inverse }), + Opcode::Arithmetic(Expression { + mul_terms: vec![(fe_1, w_z, w_z_inverse)], + linear_combinations: vec![], + q_c: -fe_1, + }), + Opcode::Arithmetic(Expression { + mul_terms: vec![], + linear_combinations: vec![(-fe_1, w_oracle), (fe_1, w_z_inverse)], + q_c: fe_0, + }), + ]; + + let witness_assignments = BTreeMap::from([ + (Witness(1), FieldElement::from(2u128)), + (Witness(2), FieldElement::from(3u128)), + (Witness(8), FieldElement::from(5u128)), + (Witness(9), FieldElement::from(10u128)), + ]) + .into(); + + let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + + // use the partial witness generation solver with our acir program + let solver_status = acvm.solve(); + assert!( + matches!(solver_status, ACVMStatus::RequiresForeignCall(_)), + "should require foreign call response" + ); + assert_eq!(acvm.instruction_pointer(), 0, "should stall on brillig"); + + let foreign_call_wait_info: &ForeignCallWaitInfo = + acvm.get_pending_foreign_call().expect("should have a brillig foreign call request"); + assert_eq!(foreign_call_wait_info.inputs.len(), 1, "Should be waiting for a single input"); + + let x_plus_y_inverse = Value::from(foreign_call_wait_info.inputs[0][0].to_field().inverse()); + + // Resolve Brillig foreign call + acvm.resolve_pending_foreign_call(x_plus_y_inverse.into()); + + // After filling data request, continue solving + let solver_status = acvm.solve(); + assert!( + matches!(solver_status, ACVMStatus::RequiresForeignCall(_)), + "should require foreign call response" + ); + assert_eq!(acvm.instruction_pointer(), 0, "should stall on brillig"); + + let foreign_call_wait_info = + acvm.get_pending_foreign_call().expect("should have a brillig foreign call request"); + assert_eq!(foreign_call_wait_info.inputs.len(), 1, "Should be waiting for a single input"); + + let i_plus_j_inverse = Value::from(foreign_call_wait_info.inputs[0][0].to_field().inverse()); + assert_ne!(x_plus_y_inverse, i_plus_j_inverse); + + // Alter Brillig oracle opcode + acvm.resolve_pending_foreign_call(i_plus_j_inverse.into()); + + // After filling data request, continue solving + let solver_status = acvm.solve(); + assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + + // ACVM should be able to be finalized in `Solved` state. + acvm.finalize(); +} + +#[test] +fn oracle_dependent_execution() { + // This test ensures that we properly track the list of opcodes which still need to be resolved + // across any brillig foreign calls we may have to perform. + // + // Opcodes below describe the following: + // fn main(x : Field, y : pub Field) { + // assert(x == y); + // let x_inv = Oracle("inverse", x); + // let y_inv = Oracle("inverse", y); + // + // assert(x_inv == y_inv); + // } + // Also performs an unrelated equality check + // just for the sake of testing multiple brillig opcodes. + let fe_0 = FieldElement::zero(); + let fe_1 = FieldElement::one(); + let w_x = Witness(1); + let w_y = Witness(2); + let w_x_inv = Witness(3); + let w_y_inv = Witness(4); + + let brillig_data = Brillig { + inputs: vec![ + BrilligInputs::Single(w_x.into()), // Input Register 0 + BrilligInputs::Single(Expression::default()), // Input Register 1 + BrilligInputs::Single(w_y.into()), // Input Register 2, + ], + outputs: vec![ + BrilligOutputs::Simple(w_x), // Output Register 0 - from input + BrilligOutputs::Simple(w_y_inv), // Output Register 1 + BrilligOutputs::Simple(w_y), // Output Register 2 - from input + BrilligOutputs::Simple(w_y_inv), // Output Register 3 + ], + // stack of foreign call/oracle resolutions, starts empty + foreign_call_results: vec![], + bytecode: vec![ + // Oracles are named 'foreign calls' in brillig + BrilligOpcode::ForeignCall { + function: "invert".into(), + destinations: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(1))], + inputs: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(0))], + }, + BrilligOpcode::ForeignCall { + function: "invert".into(), + destinations: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(3))], + inputs: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(2))], + }, + ], + predicate: None, + }; + + // This equality check can be executed immediately before resolving any foreign calls. + let equality_check = Expression { + mul_terms: vec![], + linear_combinations: vec![(-fe_1, w_x), (fe_1, w_y)], + q_c: fe_0, + }; + + // This equality check relies on the outputs of the Brillig call. + // It then cannot be solved until the foreign calls are resolved. + let inverse_equality_check = Expression { + mul_terms: vec![], + linear_combinations: vec![(-fe_1, w_x_inv), (fe_1, w_y_inv)], + q_c: fe_0, + }; + + let opcodes = vec![ + Opcode::Arithmetic(equality_check), + Opcode::Brillig(brillig_data), + Opcode::Arithmetic(inverse_equality_check), + ]; + + let witness_assignments = + BTreeMap::from([(w_x, FieldElement::from(2u128)), (w_y, FieldElement::from(2u128))]).into(); + + let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + + // use the partial witness generation solver with our acir program + let solver_status = acvm.solve(); + assert!( + matches!(solver_status, ACVMStatus::RequiresForeignCall(_)), + "should require foreign call response" + ); + assert_eq!(acvm.instruction_pointer(), 1, "should stall on brillig"); + + let foreign_call_wait_info: &ForeignCallWaitInfo = + acvm.get_pending_foreign_call().expect("should have a brillig foreign call request"); + assert_eq!(foreign_call_wait_info.inputs.len(), 1, "Should be waiting for a single input"); + + // Resolve Brillig foreign call + let x_inverse = Value::from(foreign_call_wait_info.inputs[0][0].to_field().inverse()); + acvm.resolve_pending_foreign_call(x_inverse.into()); + + // After filling data request, continue solving + let solver_status = acvm.solve(); + assert!( + matches!(solver_status, ACVMStatus::RequiresForeignCall(_)), + "should require foreign call response" + ); + assert_eq!(acvm.instruction_pointer(), 1, "should stall on brillig"); + + let foreign_call_wait_info: &ForeignCallWaitInfo = + acvm.get_pending_foreign_call().expect("should have a brillig foreign call request"); + assert_eq!(foreign_call_wait_info.inputs.len(), 1, "Should be waiting for a single input"); + + // Resolve Brillig foreign call + let y_inverse = Value::from(foreign_call_wait_info.inputs[0][0].to_field().inverse()); + acvm.resolve_pending_foreign_call(y_inverse.into()); + + // We've resolved all the brillig foreign calls so we should be able to complete execution now. + + // After filling data request, continue solving + let solver_status = acvm.solve(); + assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + + // ACVM should be able to be finalized in `Solved` state. + acvm.finalize(); +} + +#[test] +fn brillig_oracle_predicate() { + let fe_0 = FieldElement::zero(); + let fe_1 = FieldElement::one(); + let w_x = Witness(1); + let w_y = Witness(2); + let w_oracle = Witness(3); + let w_x_plus_y = Witness(4); + let w_equal_res = Witness(5); + let w_lt_res = Witness(6); + + let equal_opcode = BrilligOpcode::BinaryFieldOp { + op: BinaryFieldOp::Equals, + lhs: RegisterIndex::from(0), + rhs: RegisterIndex::from(1), + destination: RegisterIndex::from(2), + }; + + let brillig_opcode = Opcode::Brillig(Brillig { + inputs: vec![ + BrilligInputs::Single(Expression { + mul_terms: vec![], + linear_combinations: vec![(fe_1, w_x), (fe_1, w_y)], + q_c: fe_0, + }), + BrilligInputs::Single(Expression::default()), + ], + outputs: vec![ + BrilligOutputs::Simple(w_x_plus_y), + BrilligOutputs::Simple(w_oracle), + BrilligOutputs::Simple(w_equal_res), + BrilligOutputs::Simple(w_lt_res), + ], + bytecode: vec![ + equal_opcode, + // Oracles are named 'foreign calls' in brillig + BrilligOpcode::ForeignCall { + function: "invert".into(), + destinations: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(1))], + inputs: vec![RegisterOrMemory::RegisterIndex(RegisterIndex::from(0))], + }, + ], + predicate: Some(Expression::default()), + // oracle results + foreign_call_results: vec![], + }); + + let opcodes = vec![brillig_opcode]; + + let witness_assignments = BTreeMap::from([ + (Witness(1), FieldElement::from(2u128)), + (Witness(2), FieldElement::from(3u128)), + ]) + .into(); + + let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + let solver_status = acvm.solve(); + assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + + // ACVM should be able to be finalized in `Solved` state. + acvm.finalize(); +} +#[test] +fn unsatisfied_opcode_resolved() { + let a = Witness(0); + let b = Witness(1); + let c = Witness(2); + let d = Witness(3); + + // a = b + c + d; + let opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), a), + (-FieldElement::one(), b), + (-FieldElement::one(), c), + (-FieldElement::one(), d), + ], + q_c: FieldElement::zero(), + }; + + let mut values = WitnessMap::new(); + values.insert(a, FieldElement::from(4_i128)); + values.insert(b, FieldElement::from(2_i128)); + values.insert(c, FieldElement::from(1_i128)); + values.insert(d, FieldElement::from(2_i128)); + + let opcodes = vec![Opcode::Arithmetic(opcode_a)]; + let mut acvm = ACVM::new(&StubbedBackend, opcodes, values); + let solver_status = acvm.solve(); + assert_eq!( + solver_status, + ACVMStatus::Failure(OpcodeResolutionError::UnsatisfiedConstrain { + opcode_location: ErrorLocation::Resolved(OpcodeLocation::Acir(0)), + }), + "The first opcode is not satisfiable, expected an error indicating this" + ); +} + +#[test] +fn unsatisfied_opcode_resolved_brillig() { + let a = Witness(0); + let b = Witness(1); + let c = Witness(2); + let d = Witness(3); + + let fe_1 = FieldElement::one(); + let fe_0 = FieldElement::zero(); + let w_x = Witness(4); + let w_y = Witness(5); + let w_result = Witness(6); + + let equal_opcode = BrilligOpcode::BinaryFieldOp { + op: BinaryFieldOp::Equals, + lhs: RegisterIndex::from(0), + rhs: RegisterIndex::from(1), + destination: RegisterIndex::from(2), + }; + // Jump pass the trap if the values are equal, else + // jump to the trap + let location_of_stop = 3; + + let jmp_if_opcode = + BrilligOpcode::JumpIf { condition: RegisterIndex::from(2), location: location_of_stop }; + + let trap_opcode = BrilligOpcode::Trap; + let stop_opcode = BrilligOpcode::Stop; + + let brillig_opcode = Opcode::Brillig(Brillig { + inputs: vec![ + BrilligInputs::Single(Expression { + mul_terms: vec![], + linear_combinations: vec![(fe_1, w_x)], + q_c: fe_0, + }), + BrilligInputs::Single(Expression { + mul_terms: vec![], + linear_combinations: vec![(fe_1, w_y)], + q_c: fe_0, + }), + ], + outputs: vec![BrilligOutputs::Simple(w_result)], + bytecode: vec![equal_opcode, jmp_if_opcode, trap_opcode, stop_opcode], + predicate: Some(Expression::one()), + // oracle results + foreign_call_results: vec![], + }); + + let opcode_a = Expression { + mul_terms: vec![], + linear_combinations: vec![ + (FieldElement::one(), a), + (-FieldElement::one(), b), + (-FieldElement::one(), c), + (-FieldElement::one(), d), + ], + q_c: FieldElement::zero(), + }; + + let mut values = WitnessMap::new(); + values.insert(a, FieldElement::from(4_i128)); + values.insert(b, FieldElement::from(2_i128)); + values.insert(c, FieldElement::from(1_i128)); + values.insert(d, FieldElement::from(2_i128)); + values.insert(w_x, FieldElement::from(0_i128)); + values.insert(w_y, FieldElement::from(1_i128)); + values.insert(w_result, FieldElement::from(0_i128)); + + let opcodes = vec![brillig_opcode, Opcode::Arithmetic(opcode_a)]; + + let mut acvm = ACVM::new(&StubbedBackend, opcodes, values); + let solver_status = acvm.solve(); + assert_eq!( + solver_status, + ACVMStatus::Failure(OpcodeResolutionError::BrilligFunctionFailed { + message: "explicit trap hit in brillig".to_string(), + call_stack: vec![OpcodeLocation::Brillig { acir_index: 0, brillig_index: 2 }] + }), + "The first opcode is not satisfiable, expected an error indicating this" + ); +} + +#[test] +fn memory_operations() { + let initial_witness = WitnessMap::from(BTreeMap::from_iter([ + (Witness(1), FieldElement::from(1u128)), + (Witness(2), FieldElement::from(2u128)), + (Witness(3), FieldElement::from(3u128)), + (Witness(4), FieldElement::from(4u128)), + (Witness(5), FieldElement::from(5u128)), + (Witness(6), FieldElement::from(4u128)), + ])); + + let block_id = BlockId(0); + + let init = Opcode::MemoryInit { block_id, init: (1..6).map(Witness).collect() }; + + let read_op = Opcode::MemoryOp { + block_id, + op: MemOp::read_at_mem_index(Witness(6).into(), Witness(7)), + predicate: None, + }; + + let expression = Opcode::Arithmetic(Expression { + mul_terms: Vec::new(), + linear_combinations: vec![ + (FieldElement::one(), Witness(7)), + (-FieldElement::one(), Witness(8)), + ], + q_c: FieldElement::one(), + }); + + let opcodes = vec![init, read_op, expression]; + + let mut acvm = ACVM::new(&StubbedBackend, opcodes, initial_witness); + let solver_status = acvm.solve(); + assert_eq!(solver_status, ACVMStatus::Solved); + let witness_map = acvm.finalize(); + + assert_eq!(witness_map[&Witness(8)], FieldElement::from(6u128)); +} diff --git a/acvm-repo/acvm/tests/stdlib.rs b/acvm-repo/acvm/tests/stdlib.rs new file mode 100644 index 00000000000..309130d3992 --- /dev/null +++ b/acvm-repo/acvm/tests/stdlib.rs @@ -0,0 +1,354 @@ +#![cfg(feature = "testing")] +mod solver; +use crate::solver::StubbedBackend; +use acir::{ + circuit::{ + opcodes::{BlackBoxFuncCall, FunctionInput}, + Circuit, Opcode, + }, + native_types::{Expression, Witness}, + FieldElement, +}; +use acvm::{ + compiler::compile, + pwg::{ACVMStatus, ACVM}, + Language, +}; +use acvm_blackbox_solver::{blake2s, hash_to_field_128_security, keccak256, sha256}; +use paste::paste; +use proptest::prelude::*; +use std::collections::{BTreeMap, BTreeSet}; +use stdlib::blackbox_fallbacks::{UInt32, UInt64, UInt8}; + +test_uint!(test_uint8, UInt8, u8, 8); +test_uint!(test_uint32, UInt32, u32, 32); +test_uint!(test_uint64, UInt64, u64, 64); + +#[macro_export] +macro_rules! test_uint { + ( + $name:tt, + $uint:ident, + $u:ident, + $size:expr + ) => { + paste! { + test_uint_inner!( + [<$name _rol>], + [<$name _ror>], + [<$name _euclidean_division>], + [<$name _add>], + [<$name _sub>], + [<$name _left_shift>], + [<$name _right_shift>], + [<$name _less_than>], + $uint, + $u, + $size + ); + } + }; +} + +#[macro_export] +macro_rules! test_uint_inner { + ( + $rol:tt, + $ror:tt, + $euclidean_division:tt, + $add:tt, + $sub:tt, + $left_shift:tt, + $right_shift:tt, + $less_than:tt, + $uint: ident, + $u: ident, + $size: expr + ) => { + proptest! { + #[test] + fn $rol(x in 0..$u::MAX, y in 0..32_u32) { + let fe = FieldElement::from(x as u128); + let w = Witness(1); + let result = x.rotate_left(y); + let uint = $uint::new(w); + let (w, extra_opcodes, _) = uint.rol(y, 2); + let witness_assignments = BTreeMap::from([(Witness(1), fe)]).into(); + let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let solver_status = acvm.solve(); + + prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } + + #[test] + fn $ror(x in 0..$u::MAX, y in 0..32_u32) { + let fe = FieldElement::from(x as u128); + let w = Witness(1); + let result = x.rotate_right(y); + let uint = $uint::new(w); + let (w, extra_opcodes, _) = uint.ror(y, 2); + let witness_assignments = BTreeMap::from([(Witness(1), fe)]).into(); + let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let solver_status = acvm.solve(); + + prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } + + #[test] + fn $euclidean_division(x in 0..$u::MAX, y in 1 + ..$u::MAX) { + let lhs = FieldElement::from(x as u128); + let rhs = FieldElement::from(y as u128); + let w1 = Witness(1); + let w2 = Witness(2); + let q = x.div_euclid(y); + let r = x.rem_euclid(y); + let u32_1 = $uint::new(w1); + let u32_2 = $uint::new(w2); + let (q_w, r_w, extra_opcodes, _) = $uint::euclidean_division(&u32_1, &u32_2, 3); + let witness_assignments = BTreeMap::from([(Witness(1), lhs),(Witness(2), rhs)]).into(); + let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let solver_status = acvm.solve(); + + prop_assert_eq!(acvm.witness_map().get(&q_w.get_inner()).unwrap(), &FieldElement::from(q as u128)); + prop_assert_eq!(acvm.witness_map().get(&r_w.get_inner()).unwrap(), &FieldElement::from(r as u128)); + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } + + #[test] + fn $add(x in 0..$u::MAX, y in 0..$u::MAX, z in 0..$u::MAX) { + let lhs = FieldElement::from(x as u128); + let rhs = FieldElement::from(y as u128); + let rhs_z = FieldElement::from(z as u128); + let result = FieldElement::from(((x as u128).wrapping_add(y as u128) % (1_u128 << $size)).wrapping_add(z as u128) % (1_u128 << $size)); + let w1 = Witness(1); + let w2 = Witness(2); + let w3 = Witness(3); + let u32_1 = $uint::new(w1); + let u32_2 = $uint::new(w2); + let u32_3 = $uint::new(w3); + let mut opcodes = Vec::new(); + let (w, extra_opcodes, num_witness) = u32_1.add(&u32_2, 4); + opcodes.extend(extra_opcodes); + let (w2, extra_opcodes, _) = w.add(&u32_3, num_witness); + opcodes.extend(extra_opcodes); + let witness_assignments = BTreeMap::from([(Witness(1), lhs), (Witness(2), rhs), (Witness(3), rhs_z)]).into(); + let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + let solver_status = acvm.solve(); + + prop_assert_eq!(acvm.witness_map().get(&w2.get_inner()).unwrap(), &result); + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } + + #[test] + fn $sub(x in 0..$u::MAX, y in 0..$u::MAX, z in 0..$u::MAX) { + let lhs = FieldElement::from(x as u128); + let rhs = FieldElement::from(y as u128); + let rhs_z = FieldElement::from(z as u128); + let result = FieldElement::from(((x as u128).wrapping_sub(y as u128) % (1_u128 << $size)).wrapping_sub(z as u128) % (1_u128 << $size)); + let w1 = Witness(1); + let w2 = Witness(2); + let w3 = Witness(3); + let u32_1 = $uint::new(w1); + let u32_2 = $uint::new(w2); + let u32_3 = $uint::new(w3); + let mut opcodes = Vec::new(); + let (w, extra_opcodes, num_witness) = u32_1.sub(&u32_2, 4); + opcodes.extend(extra_opcodes); + let (w2, extra_opcodes, _) = w.sub(&u32_3, num_witness); + opcodes.extend(extra_opcodes); + let witness_assignments = BTreeMap::from([(Witness(1), lhs), (Witness(2), rhs), (Witness(3), rhs_z)]).into(); + let mut acvm = ACVM::new(&StubbedBackend, opcodes, witness_assignments); + let solver_status = acvm.solve(); + + prop_assert_eq!(acvm.witness_map().get(&w2.get_inner()).unwrap(), &result); + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } + + #[test] + fn $left_shift(x in 0..$u::MAX, y in 0..32_u32) { + let lhs = FieldElement::from(x as u128); + let w1 = Witness(1); + let result = x.overflowing_shl(y).0; + let u32_1 = $uint::new(w1); + let (w, extra_opcodes, _) = u32_1.leftshift(y, 2); + let witness_assignments = BTreeMap::from([(Witness(1), lhs)]).into(); + let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let solver_status = acvm.solve(); + + prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } + + #[test] + fn $right_shift(x in 0..$u::MAX, y in 0..32_u32) { + let lhs = FieldElement::from(x as u128); + let w1 = Witness(1); + let result = x.overflowing_shr(y).0; + let u32_1 = $uint::new(w1); + let (w, extra_opcodes, _) = u32_1.rightshift(y, 2); + let witness_assignments = BTreeMap::from([(Witness(1), lhs)]).into(); + let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let solver_status = acvm.solve(); + + prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } + + #[test] + fn $less_than(x in 0..$u::MAX, y in 0..$u::MAX) { + let lhs = FieldElement::from(x as u128); + let rhs = FieldElement::from(y as u128); + let w1 = Witness(1); + let w2 = Witness(2); + let result = x < y; + let u32_1 = $uint::new(w1); + let u32_2 = $uint::new(w2); + let (w, extra_opcodes, _) = u32_1.less_than_comparison(&u32_2, 3); + let witness_assignments = BTreeMap::from([(Witness(1), lhs), (Witness(2), rhs)]).into(); + let mut acvm = ACVM::new(&StubbedBackend, extra_opcodes, witness_assignments); + let solver_status = acvm.solve(); + + prop_assert_eq!(acvm.witness_map().get(&w.get_inner()).unwrap(), &FieldElement::from(result as u128)); + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } + } + }; +} + +test_hashes!(test_sha256, sha256, SHA256, does_not_support_sha256); +test_hashes!(test_blake2s, blake2s, Blake2s, does_not_support_blake2s); +test_hashes!(test_keccak, keccak256, Keccak256, does_not_support_keccak); + +fn does_not_support_sha256(opcode: &Opcode) -> bool { + !matches!(opcode, Opcode::BlackBoxFuncCall(BlackBoxFuncCall::SHA256 { .. })) +} +fn does_not_support_blake2s(opcode: &Opcode) -> bool { + !matches!(opcode, Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Blake2s { .. })) +} +fn does_not_support_keccak(opcode: &Opcode) -> bool { + !matches!(opcode, Opcode::BlackBoxFuncCall(BlackBoxFuncCall::Keccak256 { .. })) +} + +#[macro_export] +macro_rules! test_hashes { + ( + $name:ident, + $hasher:ident, + $opcode:ident, + $opcode_support: ident + ) => { + proptest! { + #![proptest_config(ProptestConfig::with_cases(3))] + #[test] + fn $name(input_values in proptest::collection::vec(0..u8::MAX, 1..50)) { + let mut opcodes = Vec::new(); + let mut witness_assignments = BTreeMap::new(); + let mut input_witnesses: Vec = Vec::new(); + let mut correct_result_witnesses: Vec = Vec::new(); + let mut output_witnesses: Vec = Vec::new(); + + // prepare test data + let mut counter = 0; + let output = $hasher(&input_values).unwrap(); + for inp_v in input_values { + counter += 1; + let function_input = FunctionInput { witness: Witness(counter), num_bits: 8 }; + input_witnesses.push(function_input); + witness_assignments.insert(Witness(counter), FieldElement::from(inp_v as u128)); + } + + for o_v in output { + counter += 1; + correct_result_witnesses.push(Witness(counter)); + witness_assignments.insert(Witness(counter), FieldElement::from(o_v as u128)); + } + + for _ in 0..32 { + counter += 1; + output_witnesses.push(Witness(counter)); + } + let blackbox = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::$opcode { inputs: input_witnesses, outputs: output_witnesses.clone() }); + opcodes.push(blackbox); + + // constrain the output to be the same as the hasher + for i in 0..correct_result_witnesses.len() { + let mut output_constraint = Expression::from(correct_result_witnesses[i]); + output_constraint.push_addition_term(-FieldElement::one(), output_witnesses[i]); + opcodes.push(Opcode::Arithmetic(output_constraint)); + } + + // compile circuit + let circuit = Circuit { + current_witness_index: witness_assignments.len() as u32 + 32, + opcodes, + private_parameters: BTreeSet::new(), // This is not correct but is unused in this test. + ..Circuit::default() + }; + let circuit = compile(circuit, Language::PLONKCSat{ width: 3 }, $opcode_support).unwrap().0; + + // solve witnesses + let mut acvm = ACVM::new(&StubbedBackend, circuit.opcodes, witness_assignments.into()); + let solver_status = acvm.solve(); + + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } + } + }; +} + +fn does_not_support_hash_to_field(opcode: &Opcode) -> bool { + !matches!(opcode, Opcode::BlackBoxFuncCall(BlackBoxFuncCall::HashToField128Security { .. })) +} + +proptest! { + #![proptest_config(ProptestConfig::with_cases(3))] + #[test] + fn test_hash_to_field(input_values in proptest::collection::vec(0..u8::MAX, 1..50)) { + let mut opcodes = Vec::new(); + let mut witness_assignments = BTreeMap::new(); + let mut input_witnesses: Vec = Vec::new(); + + // prepare test data + let mut counter = 0; + let output = hash_to_field_128_security(&input_values).unwrap(); + for inp_v in input_values { + counter += 1; + let function_input = FunctionInput { witness: Witness(counter), num_bits: 8 }; + input_witnesses.push(function_input); + witness_assignments.insert(Witness(counter), FieldElement::from(inp_v as u128)); + } + + counter += 1; + let correct_result_witnesses: Witness = Witness(counter); + witness_assignments.insert(Witness(counter), output); + + counter += 1; + let output_witness: Witness = Witness(counter); + + let blackbox = Opcode::BlackBoxFuncCall(BlackBoxFuncCall::HashToField128Security { inputs: input_witnesses, output: output_witness }); + opcodes.push(blackbox); + + // constrain the output to be the same as the hasher + let mut output_constraint = Expression::from(correct_result_witnesses); + output_constraint.push_addition_term(-FieldElement::one(), output_witness); + opcodes.push(Opcode::Arithmetic(output_constraint)); + + // compile circuit + let circuit = Circuit { + current_witness_index: witness_assignments.len() as u32 + 1, + opcodes, + private_parameters: BTreeSet::new(), // This is not correct but is unused in this test. + ..Circuit::default() + }; + let circuit = compile(circuit, Language::PLONKCSat{ width: 3 }, does_not_support_hash_to_field).unwrap().0; + + // solve witnesses + let mut acvm = ACVM::new(&StubbedBackend, circuit.opcodes, witness_assignments.into()); + let solver_status = acvm.solve(); + + prop_assert_eq!(solver_status, ACVMStatus::Solved, "should be fully solved"); + } +} diff --git a/acvm-repo/acvm_js/.cargo/config.toml b/acvm-repo/acvm_js/.cargo/config.toml new file mode 100644 index 00000000000..85c748284e9 --- /dev/null +++ b/acvm-repo/acvm_js/.cargo/config.toml @@ -0,0 +1,5 @@ +[build] +target = "wasm32-unknown-unknown" + +[target.wasm32-unknown-unknown] +runner = 'wasm-bindgen-test-runner' diff --git a/acvm-repo/acvm_js/.eslintignore b/acvm-repo/acvm_js/.eslintignore new file mode 100644 index 00000000000..200ae222150 --- /dev/null +++ b/acvm-repo/acvm_js/.eslintignore @@ -0,0 +1,2 @@ +node_modules +pkg \ No newline at end of file diff --git a/acvm-repo/acvm_js/.eslintrc.js b/acvm-repo/acvm_js/.eslintrc.js new file mode 100644 index 00000000000..b1346a8792f --- /dev/null +++ b/acvm-repo/acvm_js/.eslintrc.js @@ -0,0 +1,19 @@ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint", "prettier"], + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + rules: { + "comma-spacing": ["error", { before: false, after: true }], + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", // or "error" + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + caughtErrorsIgnorePattern: "^_", + }, + ], + "prettier/prettier": "error", + }, +}; diff --git a/acvm-repo/acvm_js/.gitignore b/acvm-repo/acvm_js/.gitignore new file mode 100644 index 00000000000..d7d3d1dbe09 --- /dev/null +++ b/acvm-repo/acvm_js/.gitignore @@ -0,0 +1,20 @@ +/target +.DS_Store +examples/**/target/ +examples/9 +.vscode +node_modules +pkg/ +lib/ +result +.direnv +**/outputs + +# Yarn +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions \ No newline at end of file diff --git a/acvm-repo/acvm_js/.mocharc.json b/acvm-repo/acvm_js/.mocharc.json new file mode 100644 index 00000000000..27273835070 --- /dev/null +++ b/acvm-repo/acvm_js/.mocharc.json @@ -0,0 +1,5 @@ +{ + "extension": ["ts"], + "spec": "test/node/**/*.test.ts", + "require": "ts-node/register" +} \ No newline at end of file diff --git a/acvm-repo/acvm_js/.yarn/releases/yarn-3.5.1.cjs b/acvm-repo/acvm_js/.yarn/releases/yarn-3.5.1.cjs new file mode 100755 index 00000000000..97eed758032 --- /dev/null +++ b/acvm-repo/acvm_js/.yarn/releases/yarn-3.5.1.cjs @@ -0,0 +1,873 @@ +#!/usr/bin/env node +/* eslint-disable */ +//prettier-ignore +(()=>{var Sge=Object.create;var lS=Object.defineProperty;var vge=Object.getOwnPropertyDescriptor;var xge=Object.getOwnPropertyNames;var Pge=Object.getPrototypeOf,Dge=Object.prototype.hasOwnProperty;var J=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+r+'" is not supported')});var kge=(r,e)=>()=>(r&&(e=r(r=0)),e);var w=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),ut=(r,e)=>{for(var t in e)lS(r,t,{get:e[t],enumerable:!0})},Rge=(r,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of xge(e))!Dge.call(r,n)&&n!==t&&lS(r,n,{get:()=>e[n],enumerable:!(i=vge(e,n))||i.enumerable});return r};var Pe=(r,e,t)=>(t=r!=null?Sge(Pge(r)):{},Rge(e||!r||!r.__esModule?lS(t,"default",{value:r,enumerable:!0}):t,r));var vU=w((j7e,SU)=>{SU.exports=bU;bU.sync=$ge;var BU=J("fs");function _ge(r,e){var t=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;if(!t||(t=t.split(";"),t.indexOf("")!==-1))return!0;for(var i=0;i{kU.exports=PU;PU.sync=efe;var xU=J("fs");function PU(r,e,t){xU.stat(r,function(i,n){t(i,i?!1:DU(n,e))})}function efe(r,e){return DU(xU.statSync(r),e)}function DU(r,e){return r.isFile()&&tfe(r,e)}function tfe(r,e){var t=r.mode,i=r.uid,n=r.gid,s=e.uid!==void 0?e.uid:process.getuid&&process.getuid(),o=e.gid!==void 0?e.gid:process.getgid&&process.getgid(),a=parseInt("100",8),l=parseInt("010",8),c=parseInt("001",8),u=a|l,g=t&c||t&l&&n===o||t&a&&i===s||t&u&&s===0;return g}});var NU=w((W7e,FU)=>{var J7e=J("fs"),lI;process.platform==="win32"||global.TESTING_WINDOWS?lI=vU():lI=RU();FU.exports=SS;SS.sync=rfe;function SS(r,e,t){if(typeof e=="function"&&(t=e,e={}),!t){if(typeof Promise!="function")throw new TypeError("callback not provided");return new Promise(function(i,n){SS(r,e||{},function(s,o){s?n(s):i(o)})})}lI(r,e||{},function(i,n){i&&(i.code==="EACCES"||e&&e.ignoreErrors)&&(i=null,n=!1),t(i,n)})}function rfe(r,e){try{return lI.sync(r,e||{})}catch(t){if(e&&e.ignoreErrors||t.code==="EACCES")return!1;throw t}}});var HU=w((z7e,KU)=>{var Dg=process.platform==="win32"||process.env.OSTYPE==="cygwin"||process.env.OSTYPE==="msys",LU=J("path"),ife=Dg?";":":",TU=NU(),OU=r=>Object.assign(new Error(`not found: ${r}`),{code:"ENOENT"}),MU=(r,e)=>{let t=e.colon||ife,i=r.match(/\//)||Dg&&r.match(/\\/)?[""]:[...Dg?[process.cwd()]:[],...(e.path||process.env.PATH||"").split(t)],n=Dg?e.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",s=Dg?n.split(t):[""];return Dg&&r.indexOf(".")!==-1&&s[0]!==""&&s.unshift(""),{pathEnv:i,pathExt:s,pathExtExe:n}},UU=(r,e,t)=>{typeof e=="function"&&(t=e,e={}),e||(e={});let{pathEnv:i,pathExt:n,pathExtExe:s}=MU(r,e),o=[],a=c=>new Promise((u,g)=>{if(c===i.length)return e.all&&o.length?u(o):g(OU(r));let f=i[c],h=/^".*"$/.test(f)?f.slice(1,-1):f,p=LU.join(h,r),C=!h&&/^\.[\\\/]/.test(r)?r.slice(0,2)+p:p;u(l(C,c,0))}),l=(c,u,g)=>new Promise((f,h)=>{if(g===n.length)return f(a(u+1));let p=n[g];TU(c+p,{pathExt:s},(C,y)=>{if(!C&&y)if(e.all)o.push(c+p);else return f(c+p);return f(l(c,u,g+1))})});return t?a(0).then(c=>t(null,c),t):a(0)},nfe=(r,e)=>{e=e||{};let{pathEnv:t,pathExt:i,pathExtExe:n}=MU(r,e),s=[];for(let o=0;o{"use strict";var GU=(r={})=>{let e=r.env||process.env;return(r.platform||process.platform)!=="win32"?"PATH":Object.keys(e).reverse().find(i=>i.toUpperCase()==="PATH")||"Path"};vS.exports=GU;vS.exports.default=GU});var WU=w((X7e,JU)=>{"use strict";var jU=J("path"),sfe=HU(),ofe=YU();function qU(r,e){let t=r.options.env||process.env,i=process.cwd(),n=r.options.cwd!=null,s=n&&process.chdir!==void 0&&!process.chdir.disabled;if(s)try{process.chdir(r.options.cwd)}catch{}let o;try{o=sfe.sync(r.command,{path:t[ofe({env:t})],pathExt:e?jU.delimiter:void 0})}catch{}finally{s&&process.chdir(i)}return o&&(o=jU.resolve(n?r.options.cwd:"",o)),o}function afe(r){return qU(r)||qU(r,!0)}JU.exports=afe});var zU=w((Z7e,PS)=>{"use strict";var xS=/([()\][%!^"`<>&|;, *?])/g;function Afe(r){return r=r.replace(xS,"^$1"),r}function lfe(r,e){return r=`${r}`,r=r.replace(/(\\*)"/g,'$1$1\\"'),r=r.replace(/(\\*)$/,"$1$1"),r=`"${r}"`,r=r.replace(xS,"^$1"),e&&(r=r.replace(xS,"^$1")),r}PS.exports.command=Afe;PS.exports.argument=lfe});var XU=w((_7e,VU)=>{"use strict";VU.exports=/^#!(.*)/});var _U=w(($7e,ZU)=>{"use strict";var cfe=XU();ZU.exports=(r="")=>{let e=r.match(cfe);if(!e)return null;let[t,i]=e[0].replace(/#! ?/,"").split(" "),n=t.split("/").pop();return n==="env"?i:i?`${n} ${i}`:n}});var eK=w((eZe,$U)=>{"use strict";var DS=J("fs"),ufe=_U();function gfe(r){let t=Buffer.alloc(150),i;try{i=DS.openSync(r,"r"),DS.readSync(i,t,0,150,0),DS.closeSync(i)}catch{}return ufe(t.toString())}$U.exports=gfe});var nK=w((tZe,iK)=>{"use strict";var ffe=J("path"),tK=WU(),rK=zU(),hfe=eK(),pfe=process.platform==="win32",dfe=/\.(?:com|exe)$/i,Cfe=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function mfe(r){r.file=tK(r);let e=r.file&&hfe(r.file);return e?(r.args.unshift(r.file),r.command=e,tK(r)):r.file}function Efe(r){if(!pfe)return r;let e=mfe(r),t=!dfe.test(e);if(r.options.forceShell||t){let i=Cfe.test(e);r.command=ffe.normalize(r.command),r.command=rK.command(r.command),r.args=r.args.map(s=>rK.argument(s,i));let n=[r.command].concat(r.args).join(" ");r.args=["/d","/s","/c",`"${n}"`],r.command=process.env.comspec||"cmd.exe",r.options.windowsVerbatimArguments=!0}return r}function Ife(r,e,t){e&&!Array.isArray(e)&&(t=e,e=null),e=e?e.slice(0):[],t=Object.assign({},t);let i={command:r,args:e,options:t,file:void 0,original:{command:r,args:e}};return t.shell?i:Efe(i)}iK.exports=Ife});var aK=w((rZe,oK)=>{"use strict";var kS=process.platform==="win32";function RS(r,e){return Object.assign(new Error(`${e} ${r.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${e} ${r.command}`,path:r.command,spawnargs:r.args})}function yfe(r,e){if(!kS)return;let t=r.emit;r.emit=function(i,n){if(i==="exit"){let s=sK(n,e,"spawn");if(s)return t.call(r,"error",s)}return t.apply(r,arguments)}}function sK(r,e){return kS&&r===1&&!e.file?RS(e.original,"spawn"):null}function wfe(r,e){return kS&&r===1&&!e.file?RS(e.original,"spawnSync"):null}oK.exports={hookChildProcess:yfe,verifyENOENT:sK,verifyENOENTSync:wfe,notFoundError:RS}});var LS=w((iZe,kg)=>{"use strict";var AK=J("child_process"),FS=nK(),NS=aK();function lK(r,e,t){let i=FS(r,e,t),n=AK.spawn(i.command,i.args,i.options);return NS.hookChildProcess(n,i),n}function Bfe(r,e,t){let i=FS(r,e,t),n=AK.spawnSync(i.command,i.args,i.options);return n.error=n.error||NS.verifyENOENTSync(n.status,i),n}kg.exports=lK;kg.exports.spawn=lK;kg.exports.sync=Bfe;kg.exports._parse=FS;kg.exports._enoent=NS});var uK=w((nZe,cK)=>{"use strict";function Qfe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function Zl(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,Zl)}Qfe(Zl,Error);Zl.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g>",ie=me(">>",!1),de=">&",_e=me(">&",!1),Pt=">",It=me(">",!1),Or="<<<",ii=me("<<<",!1),gi="<&",hr=me("<&",!1),fi="<",ni=me("<",!1),Us=function(m){return{type:"argument",segments:[].concat(...m)}},pr=function(m){return m},Ii="$'",rs=me("$'",!1),ga="'",dA=me("'",!1),cg=function(m){return[{type:"text",text:m}]},is='""',CA=me('""',!1),fa=function(){return{type:"text",text:""}},wp='"',mA=me('"',!1),EA=function(m){return m},wr=function(m){return{type:"arithmetic",arithmetic:m,quoted:!0}},Ll=function(m){return{type:"shell",shell:m,quoted:!0}},ug=function(m){return{type:"variable",...m,quoted:!0}},Io=function(m){return{type:"text",text:m}},gg=function(m){return{type:"arithmetic",arithmetic:m,quoted:!1}},Bp=function(m){return{type:"shell",shell:m,quoted:!1}},Qp=function(m){return{type:"variable",...m,quoted:!1}},vr=function(m){return{type:"glob",pattern:m}},se=/^[^']/,yo=Je(["'"],!0,!1),Rn=function(m){return m.join("")},fg=/^[^$"]/,Qt=Je(["$",'"'],!0,!1),Tl=`\\ +`,Fn=me(`\\ +`,!1),ns=function(){return""},ss="\\",gt=me("\\",!1),wo=/^[\\$"`]/,At=Je(["\\","$",'"',"`"],!1,!1),An=function(m){return m},S="\\a",Tt=me("\\a",!1),hg=function(){return"a"},Ol="\\b",bp=me("\\b",!1),Sp=function(){return"\b"},vp=/^[Ee]/,xp=Je(["E","e"],!1,!1),Pp=function(){return"\x1B"},G="\\f",yt=me("\\f",!1),IA=function(){return"\f"},Wi="\\n",Ml=me("\\n",!1),Xe=function(){return` +`},ha="\\r",pg=me("\\r",!1),OE=function(){return"\r"},Dp="\\t",ME=me("\\t",!1),ar=function(){return" "},Nn="\\v",Ul=me("\\v",!1),kp=function(){return"\v"},Ks=/^[\\'"?]/,pa=Je(["\\","'",'"',"?"],!1,!1),ln=function(m){return String.fromCharCode(parseInt(m,16))},Te="\\x",dg=me("\\x",!1),Kl="\\u",Hs=me("\\u",!1),Hl="\\U",yA=me("\\U",!1),Cg=function(m){return String.fromCodePoint(parseInt(m,16))},mg=/^[0-7]/,da=Je([["0","7"]],!1,!1),Ca=/^[0-9a-fA-f]/,rt=Je([["0","9"],["a","f"],["A","f"]],!1,!1),Bo=nt(),wA="-",Gl=me("-",!1),Gs="+",Yl=me("+",!1),UE=".",Rp=me(".",!1),Eg=function(m,b,N){return{type:"number",value:(m==="-"?-1:1)*parseFloat(b.join("")+"."+N.join(""))}},Fp=function(m,b){return{type:"number",value:(m==="-"?-1:1)*parseInt(b.join(""))}},KE=function(m){return{type:"variable",...m}},jl=function(m){return{type:"variable",name:m}},HE=function(m){return m},Ig="*",BA=me("*",!1),Rr="/",GE=me("/",!1),Ys=function(m,b,N){return{type:b==="*"?"multiplication":"division",right:N}},js=function(m,b){return b.reduce((N,K)=>({left:N,...K}),m)},yg=function(m,b,N){return{type:b==="+"?"addition":"subtraction",right:N}},QA="$((",R=me("$((",!1),q="))",Ce=me("))",!1),Ue=function(m){return m},Re="$(",ze=me("$(",!1),dt=function(m){return m},Ft="${",Ln=me("${",!1),Jb=":-",P1=me(":-",!1),D1=function(m,b){return{name:m,defaultValue:b}},Wb=":-}",k1=me(":-}",!1),R1=function(m){return{name:m,defaultValue:[]}},zb=":+",F1=me(":+",!1),N1=function(m,b){return{name:m,alternativeValue:b}},Vb=":+}",L1=me(":+}",!1),T1=function(m){return{name:m,alternativeValue:[]}},Xb=function(m){return{name:m}},O1="$",M1=me("$",!1),U1=function(m){return e.isGlobPattern(m)},K1=function(m){return m},Zb=/^[a-zA-Z0-9_]/,_b=Je([["a","z"],["A","Z"],["0","9"],"_"],!1,!1),$b=function(){return T()},eS=/^[$@*?#a-zA-Z0-9_\-]/,tS=Je(["$","@","*","?","#",["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1),H1=/^[(){}<>$|&; \t"']/,wg=Je(["(",")","{","}","<",">","$","|","&",";"," "," ",'"',"'"],!1,!1),rS=/^[<>&; \t"']/,iS=Je(["<",">","&",";"," "," ",'"',"'"],!1,!1),YE=/^[ \t]/,jE=Je([" "," "],!1,!1),Q=0,Me=0,bA=[{line:1,column:1}],d=0,E=[],I=0,k;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function T(){return r.substring(Me,Q)}function Z(){return Et(Me,Q)}function te(m,b){throw b=b!==void 0?b:Et(Me,Q),Ri([lt(m)],r.substring(Me,Q),b)}function we(m,b){throw b=b!==void 0?b:Et(Me,Q),Tn(m,b)}function me(m,b){return{type:"literal",text:m,ignoreCase:b}}function Je(m,b,N){return{type:"class",parts:m,inverted:b,ignoreCase:N}}function nt(){return{type:"any"}}function wt(){return{type:"end"}}function lt(m){return{type:"other",description:m}}function it(m){var b=bA[m],N;if(b)return b;for(N=m-1;!bA[N];)N--;for(b=bA[N],b={line:b.line,column:b.column};Nd&&(d=Q,E=[]),E.push(m))}function Tn(m,b){return new Zl(m,null,null,b)}function Ri(m,b,N){return new Zl(Zl.buildMessage(m,b),m,b,N)}function SA(){var m,b;return m=Q,b=Mr(),b===t&&(b=null),b!==t&&(Me=m,b=s(b)),m=b,m}function Mr(){var m,b,N,K,ce;if(m=Q,b=Ur(),b!==t){for(N=[],K=He();K!==t;)N.push(K),K=He();N!==t?(K=ma(),K!==t?(ce=os(),ce===t&&(ce=null),ce!==t?(Me=m,b=o(b,K,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;if(m===t)if(m=Q,b=Ur(),b!==t){for(N=[],K=He();K!==t;)N.push(K),K=He();N!==t?(K=ma(),K===t&&(K=null),K!==t?(Me=m,b=a(b,K),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;return m}function os(){var m,b,N,K,ce;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(N=Mr(),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();K!==t?(Me=m,b=l(N),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t;return m}function ma(){var m;return r.charCodeAt(Q)===59?(m=c,Q++):(m=t,I===0&&Qe(u)),m===t&&(r.charCodeAt(Q)===38?(m=g,Q++):(m=t,I===0&&Qe(f))),m}function Ur(){var m,b,N;return m=Q,b=G1(),b!==t?(N=lge(),N===t&&(N=null),N!==t?(Me=m,b=h(b,N),m=b):(Q=m,m=t)):(Q=m,m=t),m}function lge(){var m,b,N,K,ce,Se,ht;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(N=cge(),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t)if(ce=Ur(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();Se!==t?(Me=m,b=p(N,ce),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;return m}function cge(){var m;return r.substr(Q,2)===C?(m=C,Q+=2):(m=t,I===0&&Qe(y)),m===t&&(r.substr(Q,2)===B?(m=B,Q+=2):(m=t,I===0&&Qe(v))),m}function G1(){var m,b,N;return m=Q,b=fge(),b!==t?(N=uge(),N===t&&(N=null),N!==t?(Me=m,b=D(b,N),m=b):(Q=m,m=t)):(Q=m,m=t),m}function uge(){var m,b,N,K,ce,Se,ht;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(N=gge(),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t)if(ce=G1(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();Se!==t?(Me=m,b=L(N,ce),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;return m}function gge(){var m;return r.substr(Q,2)===H?(m=H,Q+=2):(m=t,I===0&&Qe(j)),m===t&&(r.charCodeAt(Q)===124?(m=$,Q++):(m=t,I===0&&Qe(V))),m}function qE(){var m,b,N,K,ce,Se;if(m=Q,b=eU(),b!==t)if(r.charCodeAt(Q)===61?(N=W,Q++):(N=t,I===0&&Qe(_)),N!==t)if(K=q1(),K!==t){for(ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();ce!==t?(Me=m,b=A(b,K),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t;else Q=m,m=t;if(m===t)if(m=Q,b=eU(),b!==t)if(r.charCodeAt(Q)===61?(N=W,Q++):(N=t,I===0&&Qe(_)),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();K!==t?(Me=m,b=Ae(b),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t;return m}function fge(){var m,b,N,K,ce,Se,ht,Bt,Jr,hi,as;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(r.charCodeAt(Q)===40?(N=ge,Q++):(N=t,I===0&&Qe(re)),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t)if(ce=Mr(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();if(Se!==t)if(r.charCodeAt(Q)===41?(ht=O,Q++):(ht=t,I===0&&Qe(F)),ht!==t){for(Bt=[],Jr=He();Jr!==t;)Bt.push(Jr),Jr=He();if(Bt!==t){for(Jr=[],hi=Np();hi!==t;)Jr.push(hi),hi=Np();if(Jr!==t){for(hi=[],as=He();as!==t;)hi.push(as),as=He();hi!==t?(Me=m,b=ue(ce,Jr),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;if(m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t)if(r.charCodeAt(Q)===123?(N=pe,Q++):(N=t,I===0&&Qe(ke)),N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t)if(ce=Mr(),ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();if(Se!==t)if(r.charCodeAt(Q)===125?(ht=Fe,Q++):(ht=t,I===0&&Qe(Ne)),ht!==t){for(Bt=[],Jr=He();Jr!==t;)Bt.push(Jr),Jr=He();if(Bt!==t){for(Jr=[],hi=Np();hi!==t;)Jr.push(hi),hi=Np();if(Jr!==t){for(hi=[],as=He();as!==t;)hi.push(as),as=He();hi!==t?(Me=m,b=oe(ce,Jr),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;else Q=m,m=t;if(m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t){for(N=[],K=qE();K!==t;)N.push(K),K=qE();if(N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();if(K!==t){if(ce=[],Se=j1(),Se!==t)for(;Se!==t;)ce.push(Se),Se=j1();else ce=t;if(ce!==t){for(Se=[],ht=He();ht!==t;)Se.push(ht),ht=He();Se!==t?(Me=m,b=le(N,ce),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t}else Q=m,m=t;if(m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t){if(N=[],K=qE(),K!==t)for(;K!==t;)N.push(K),K=qE();else N=t;if(N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();K!==t?(Me=m,b=Be(N),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t}}}return m}function Y1(){var m,b,N,K,ce;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t){if(N=[],K=JE(),K!==t)for(;K!==t;)N.push(K),K=JE();else N=t;if(N!==t){for(K=[],ce=He();ce!==t;)K.push(ce),ce=He();K!==t?(Me=m,b=fe(N),m=b):(Q=m,m=t)}else Q=m,m=t}else Q=m,m=t;return m}function j1(){var m,b,N;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();if(b!==t?(N=Np(),N!==t?(Me=m,b=ae(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t){for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();b!==t?(N=JE(),N!==t?(Me=m,b=ae(N),m=b):(Q=m,m=t)):(Q=m,m=t)}return m}function Np(){var m,b,N,K,ce;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();return b!==t?(qe.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(ne)),N===t&&(N=null),N!==t?(K=hge(),K!==t?(ce=JE(),ce!==t?(Me=m,b=Y(N,K,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function hge(){var m;return r.substr(Q,2)===he?(m=he,Q+=2):(m=t,I===0&&Qe(ie)),m===t&&(r.substr(Q,2)===de?(m=de,Q+=2):(m=t,I===0&&Qe(_e)),m===t&&(r.charCodeAt(Q)===62?(m=Pt,Q++):(m=t,I===0&&Qe(It)),m===t&&(r.substr(Q,3)===Or?(m=Or,Q+=3):(m=t,I===0&&Qe(ii)),m===t&&(r.substr(Q,2)===gi?(m=gi,Q+=2):(m=t,I===0&&Qe(hr)),m===t&&(r.charCodeAt(Q)===60?(m=fi,Q++):(m=t,I===0&&Qe(ni))))))),m}function JE(){var m,b,N;for(m=Q,b=[],N=He();N!==t;)b.push(N),N=He();return b!==t?(N=q1(),N!==t?(Me=m,b=ae(N),m=b):(Q=m,m=t)):(Q=m,m=t),m}function q1(){var m,b,N;if(m=Q,b=[],N=J1(),N!==t)for(;N!==t;)b.push(N),N=J1();else b=t;return b!==t&&(Me=m,b=Us(b)),m=b,m}function J1(){var m,b;return m=Q,b=pge(),b!==t&&(Me=m,b=pr(b)),m=b,m===t&&(m=Q,b=dge(),b!==t&&(Me=m,b=pr(b)),m=b,m===t&&(m=Q,b=Cge(),b!==t&&(Me=m,b=pr(b)),m=b,m===t&&(m=Q,b=mge(),b!==t&&(Me=m,b=pr(b)),m=b))),m}function pge(){var m,b,N,K;return m=Q,r.substr(Q,2)===Ii?(b=Ii,Q+=2):(b=t,I===0&&Qe(rs)),b!==t?(N=yge(),N!==t?(r.charCodeAt(Q)===39?(K=ga,Q++):(K=t,I===0&&Qe(dA)),K!==t?(Me=m,b=cg(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function dge(){var m,b,N,K;return m=Q,r.charCodeAt(Q)===39?(b=ga,Q++):(b=t,I===0&&Qe(dA)),b!==t?(N=Ege(),N!==t?(r.charCodeAt(Q)===39?(K=ga,Q++):(K=t,I===0&&Qe(dA)),K!==t?(Me=m,b=cg(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function Cge(){var m,b,N,K;if(m=Q,r.substr(Q,2)===is?(b=is,Q+=2):(b=t,I===0&&Qe(CA)),b!==t&&(Me=m,b=fa()),m=b,m===t)if(m=Q,r.charCodeAt(Q)===34?(b=wp,Q++):(b=t,I===0&&Qe(mA)),b!==t){for(N=[],K=W1();K!==t;)N.push(K),K=W1();N!==t?(r.charCodeAt(Q)===34?(K=wp,Q++):(K=t,I===0&&Qe(mA)),K!==t?(Me=m,b=EA(N),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;return m}function mge(){var m,b,N;if(m=Q,b=[],N=z1(),N!==t)for(;N!==t;)b.push(N),N=z1();else b=t;return b!==t&&(Me=m,b=EA(b)),m=b,m}function W1(){var m,b;return m=Q,b=_1(),b!==t&&(Me=m,b=wr(b)),m=b,m===t&&(m=Q,b=$1(),b!==t&&(Me=m,b=Ll(b)),m=b,m===t&&(m=Q,b=aS(),b!==t&&(Me=m,b=ug(b)),m=b,m===t&&(m=Q,b=Ige(),b!==t&&(Me=m,b=Io(b)),m=b))),m}function z1(){var m,b;return m=Q,b=_1(),b!==t&&(Me=m,b=gg(b)),m=b,m===t&&(m=Q,b=$1(),b!==t&&(Me=m,b=Bp(b)),m=b,m===t&&(m=Q,b=aS(),b!==t&&(Me=m,b=Qp(b)),m=b,m===t&&(m=Q,b=Qge(),b!==t&&(Me=m,b=vr(b)),m=b,m===t&&(m=Q,b=Bge(),b!==t&&(Me=m,b=Io(b)),m=b)))),m}function Ege(){var m,b,N;for(m=Q,b=[],se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(yo));N!==t;)b.push(N),se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(yo));return b!==t&&(Me=m,b=Rn(b)),m=b,m}function Ige(){var m,b,N;if(m=Q,b=[],N=V1(),N===t&&(fg.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Qt))),N!==t)for(;N!==t;)b.push(N),N=V1(),N===t&&(fg.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(Qt)));else b=t;return b!==t&&(Me=m,b=Rn(b)),m=b,m}function V1(){var m,b,N;return m=Q,r.substr(Q,2)===Tl?(b=Tl,Q+=2):(b=t,I===0&&Qe(Fn)),b!==t&&(Me=m,b=ns()),m=b,m===t&&(m=Q,r.charCodeAt(Q)===92?(b=ss,Q++):(b=t,I===0&&Qe(gt)),b!==t?(wo.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(At)),N!==t?(Me=m,b=An(N),m=b):(Q=m,m=t)):(Q=m,m=t)),m}function yge(){var m,b,N;for(m=Q,b=[],N=X1(),N===t&&(se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(yo)));N!==t;)b.push(N),N=X1(),N===t&&(se.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(yo)));return b!==t&&(Me=m,b=Rn(b)),m=b,m}function X1(){var m,b,N;return m=Q,r.substr(Q,2)===S?(b=S,Q+=2):(b=t,I===0&&Qe(Tt)),b!==t&&(Me=m,b=hg()),m=b,m===t&&(m=Q,r.substr(Q,2)===Ol?(b=Ol,Q+=2):(b=t,I===0&&Qe(bp)),b!==t&&(Me=m,b=Sp()),m=b,m===t&&(m=Q,r.charCodeAt(Q)===92?(b=ss,Q++):(b=t,I===0&&Qe(gt)),b!==t?(vp.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(xp)),N!==t?(Me=m,b=Pp(),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===G?(b=G,Q+=2):(b=t,I===0&&Qe(yt)),b!==t&&(Me=m,b=IA()),m=b,m===t&&(m=Q,r.substr(Q,2)===Wi?(b=Wi,Q+=2):(b=t,I===0&&Qe(Ml)),b!==t&&(Me=m,b=Xe()),m=b,m===t&&(m=Q,r.substr(Q,2)===ha?(b=ha,Q+=2):(b=t,I===0&&Qe(pg)),b!==t&&(Me=m,b=OE()),m=b,m===t&&(m=Q,r.substr(Q,2)===Dp?(b=Dp,Q+=2):(b=t,I===0&&Qe(ME)),b!==t&&(Me=m,b=ar()),m=b,m===t&&(m=Q,r.substr(Q,2)===Nn?(b=Nn,Q+=2):(b=t,I===0&&Qe(Ul)),b!==t&&(Me=m,b=kp()),m=b,m===t&&(m=Q,r.charCodeAt(Q)===92?(b=ss,Q++):(b=t,I===0&&Qe(gt)),b!==t?(Ks.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(pa)),N!==t?(Me=m,b=An(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=wge()))))))))),m}function wge(){var m,b,N,K,ce,Se,ht,Bt,Jr,hi,as,AS;return m=Q,r.charCodeAt(Q)===92?(b=ss,Q++):(b=t,I===0&&Qe(gt)),b!==t?(N=nS(),N!==t?(Me=m,b=ln(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Te?(b=Te,Q+=2):(b=t,I===0&&Qe(dg)),b!==t?(N=Q,K=Q,ce=nS(),ce!==t?(Se=On(),Se!==t?(ce=[ce,Se],K=ce):(Q=K,K=t)):(Q=K,K=t),K===t&&(K=nS()),K!==t?N=r.substring(N,Q):N=K,N!==t?(Me=m,b=ln(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Kl?(b=Kl,Q+=2):(b=t,I===0&&Qe(Hs)),b!==t?(N=Q,K=Q,ce=On(),ce!==t?(Se=On(),Se!==t?(ht=On(),ht!==t?(Bt=On(),Bt!==t?(ce=[ce,Se,ht,Bt],K=ce):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t),K!==t?N=r.substring(N,Q):N=K,N!==t?(Me=m,b=ln(N),m=b):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Hl?(b=Hl,Q+=2):(b=t,I===0&&Qe(yA)),b!==t?(N=Q,K=Q,ce=On(),ce!==t?(Se=On(),Se!==t?(ht=On(),ht!==t?(Bt=On(),Bt!==t?(Jr=On(),Jr!==t?(hi=On(),hi!==t?(as=On(),as!==t?(AS=On(),AS!==t?(ce=[ce,Se,ht,Bt,Jr,hi,as,AS],K=ce):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t)):(Q=K,K=t),K!==t?N=r.substring(N,Q):N=K,N!==t?(Me=m,b=Cg(N),m=b):(Q=m,m=t)):(Q=m,m=t)))),m}function nS(){var m;return mg.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(da)),m}function On(){var m;return Ca.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(rt)),m}function Bge(){var m,b,N,K,ce;if(m=Q,b=[],N=Q,r.charCodeAt(Q)===92?(K=ss,Q++):(K=t,I===0&&Qe(gt)),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t),N===t&&(N=Q,K=Q,I++,ce=tU(),I--,ce===t?K=void 0:(Q=K,K=t),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t)),N!==t)for(;N!==t;)b.push(N),N=Q,r.charCodeAt(Q)===92?(K=ss,Q++):(K=t,I===0&&Qe(gt)),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t),N===t&&(N=Q,K=Q,I++,ce=tU(),I--,ce===t?K=void 0:(Q=K,K=t),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t));else b=t;return b!==t&&(Me=m,b=Rn(b)),m=b,m}function sS(){var m,b,N,K,ce,Se;if(m=Q,r.charCodeAt(Q)===45?(b=wA,Q++):(b=t,I===0&&Qe(Gl)),b===t&&(r.charCodeAt(Q)===43?(b=Gs,Q++):(b=t,I===0&&Qe(Yl))),b===t&&(b=null),b!==t){if(N=[],qe.test(r.charAt(Q))?(K=r.charAt(Q),Q++):(K=t,I===0&&Qe(ne)),K!==t)for(;K!==t;)N.push(K),qe.test(r.charAt(Q))?(K=r.charAt(Q),Q++):(K=t,I===0&&Qe(ne));else N=t;if(N!==t)if(r.charCodeAt(Q)===46?(K=UE,Q++):(K=t,I===0&&Qe(Rp)),K!==t){if(ce=[],qe.test(r.charAt(Q))?(Se=r.charAt(Q),Q++):(Se=t,I===0&&Qe(ne)),Se!==t)for(;Se!==t;)ce.push(Se),qe.test(r.charAt(Q))?(Se=r.charAt(Q),Q++):(Se=t,I===0&&Qe(ne));else ce=t;ce!==t?(Me=m,b=Eg(b,N,ce),m=b):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;if(m===t){if(m=Q,r.charCodeAt(Q)===45?(b=wA,Q++):(b=t,I===0&&Qe(Gl)),b===t&&(r.charCodeAt(Q)===43?(b=Gs,Q++):(b=t,I===0&&Qe(Yl))),b===t&&(b=null),b!==t){if(N=[],qe.test(r.charAt(Q))?(K=r.charAt(Q),Q++):(K=t,I===0&&Qe(ne)),K!==t)for(;K!==t;)N.push(K),qe.test(r.charAt(Q))?(K=r.charAt(Q),Q++):(K=t,I===0&&Qe(ne));else N=t;N!==t?(Me=m,b=Fp(b,N),m=b):(Q=m,m=t)}else Q=m,m=t;if(m===t&&(m=Q,b=aS(),b!==t&&(Me=m,b=KE(b)),m=b,m===t&&(m=Q,b=ql(),b!==t&&(Me=m,b=jl(b)),m=b,m===t)))if(m=Q,r.charCodeAt(Q)===40?(b=ge,Q++):(b=t,I===0&&Qe(re)),b!==t){for(N=[],K=He();K!==t;)N.push(K),K=He();if(N!==t)if(K=Z1(),K!==t){for(ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();ce!==t?(r.charCodeAt(Q)===41?(Se=O,Q++):(Se=t,I===0&&Qe(F)),Se!==t?(Me=m,b=HE(K),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t}return m}function oS(){var m,b,N,K,ce,Se,ht,Bt;if(m=Q,b=sS(),b!==t){for(N=[],K=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===42?(Se=Ig,Q++):(Se=t,I===0&&Qe(BA)),Se===t&&(r.charCodeAt(Q)===47?(Se=Rr,Q++):(Se=t,I===0&&Qe(GE))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=sS(),Bt!==t?(Me=K,ce=Ys(b,Se,Bt),K=ce):(Q=K,K=t)):(Q=K,K=t)}else Q=K,K=t;else Q=K,K=t;for(;K!==t;){for(N.push(K),K=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===42?(Se=Ig,Q++):(Se=t,I===0&&Qe(BA)),Se===t&&(r.charCodeAt(Q)===47?(Se=Rr,Q++):(Se=t,I===0&&Qe(GE))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=sS(),Bt!==t?(Me=K,ce=Ys(b,Se,Bt),K=ce):(Q=K,K=t)):(Q=K,K=t)}else Q=K,K=t;else Q=K,K=t}N!==t?(Me=m,b=js(b,N),m=b):(Q=m,m=t)}else Q=m,m=t;return m}function Z1(){var m,b,N,K,ce,Se,ht,Bt;if(m=Q,b=oS(),b!==t){for(N=[],K=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===43?(Se=Gs,Q++):(Se=t,I===0&&Qe(Yl)),Se===t&&(r.charCodeAt(Q)===45?(Se=wA,Q++):(Se=t,I===0&&Qe(Gl))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=oS(),Bt!==t?(Me=K,ce=yg(b,Se,Bt),K=ce):(Q=K,K=t)):(Q=K,K=t)}else Q=K,K=t;else Q=K,K=t;for(;K!==t;){for(N.push(K),K=Q,ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();if(ce!==t)if(r.charCodeAt(Q)===43?(Se=Gs,Q++):(Se=t,I===0&&Qe(Yl)),Se===t&&(r.charCodeAt(Q)===45?(Se=wA,Q++):(Se=t,I===0&&Qe(Gl))),Se!==t){for(ht=[],Bt=He();Bt!==t;)ht.push(Bt),Bt=He();ht!==t?(Bt=oS(),Bt!==t?(Me=K,ce=yg(b,Se,Bt),K=ce):(Q=K,K=t)):(Q=K,K=t)}else Q=K,K=t;else Q=K,K=t}N!==t?(Me=m,b=js(b,N),m=b):(Q=m,m=t)}else Q=m,m=t;return m}function _1(){var m,b,N,K,ce,Se;if(m=Q,r.substr(Q,3)===QA?(b=QA,Q+=3):(b=t,I===0&&Qe(R)),b!==t){for(N=[],K=He();K!==t;)N.push(K),K=He();if(N!==t)if(K=Z1(),K!==t){for(ce=[],Se=He();Se!==t;)ce.push(Se),Se=He();ce!==t?(r.substr(Q,2)===q?(Se=q,Q+=2):(Se=t,I===0&&Qe(Ce)),Se!==t?(Me=m,b=Ue(K),m=b):(Q=m,m=t)):(Q=m,m=t)}else Q=m,m=t;else Q=m,m=t}else Q=m,m=t;return m}function $1(){var m,b,N,K;return m=Q,r.substr(Q,2)===Re?(b=Re,Q+=2):(b=t,I===0&&Qe(ze)),b!==t?(N=Mr(),N!==t?(r.charCodeAt(Q)===41?(K=O,Q++):(K=t,I===0&&Qe(F)),K!==t?(Me=m,b=dt(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m}function aS(){var m,b,N,K,ce,Se;return m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.substr(Q,2)===Jb?(K=Jb,Q+=2):(K=t,I===0&&Qe(P1)),K!==t?(ce=Y1(),ce!==t?(r.charCodeAt(Q)===125?(Se=Fe,Q++):(Se=t,I===0&&Qe(Ne)),Se!==t?(Me=m,b=D1(N,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.substr(Q,3)===Wb?(K=Wb,Q+=3):(K=t,I===0&&Qe(k1)),K!==t?(Me=m,b=R1(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.substr(Q,2)===zb?(K=zb,Q+=2):(K=t,I===0&&Qe(F1)),K!==t?(ce=Y1(),ce!==t?(r.charCodeAt(Q)===125?(Se=Fe,Q++):(Se=t,I===0&&Qe(Ne)),Se!==t?(Me=m,b=N1(N,ce),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.substr(Q,3)===Vb?(K=Vb,Q+=3):(K=t,I===0&&Qe(L1)),K!==t?(Me=m,b=T1(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.substr(Q,2)===Ft?(b=Ft,Q+=2):(b=t,I===0&&Qe(Ln)),b!==t?(N=ql(),N!==t?(r.charCodeAt(Q)===125?(K=Fe,Q++):(K=t,I===0&&Qe(Ne)),K!==t?(Me=m,b=Xb(N),m=b):(Q=m,m=t)):(Q=m,m=t)):(Q=m,m=t),m===t&&(m=Q,r.charCodeAt(Q)===36?(b=O1,Q++):(b=t,I===0&&Qe(M1)),b!==t?(N=ql(),N!==t?(Me=m,b=Xb(N),m=b):(Q=m,m=t)):(Q=m,m=t)))))),m}function Qge(){var m,b,N;return m=Q,b=bge(),b!==t?(Me=Q,N=U1(b),N?N=void 0:N=t,N!==t?(Me=m,b=K1(b),m=b):(Q=m,m=t)):(Q=m,m=t),m}function bge(){var m,b,N,K,ce;if(m=Q,b=[],N=Q,K=Q,I++,ce=rU(),I--,ce===t?K=void 0:(Q=K,K=t),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t),N!==t)for(;N!==t;)b.push(N),N=Q,K=Q,I++,ce=rU(),I--,ce===t?K=void 0:(Q=K,K=t),K!==t?(r.length>Q?(ce=r.charAt(Q),Q++):(ce=t,I===0&&Qe(Bo)),ce!==t?(Me=N,K=An(ce),N=K):(Q=N,N=t)):(Q=N,N=t);else b=t;return b!==t&&(Me=m,b=Rn(b)),m=b,m}function eU(){var m,b,N;if(m=Q,b=[],Zb.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(_b)),N!==t)for(;N!==t;)b.push(N),Zb.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(_b));else b=t;return b!==t&&(Me=m,b=$b()),m=b,m}function ql(){var m,b,N;if(m=Q,b=[],eS.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(tS)),N!==t)for(;N!==t;)b.push(N),eS.test(r.charAt(Q))?(N=r.charAt(Q),Q++):(N=t,I===0&&Qe(tS));else b=t;return b!==t&&(Me=m,b=$b()),m=b,m}function tU(){var m;return H1.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(wg)),m}function rU(){var m;return rS.test(r.charAt(Q))?(m=r.charAt(Q),Q++):(m=t,I===0&&Qe(iS)),m}function He(){var m,b;if(m=[],YE.test(r.charAt(Q))?(b=r.charAt(Q),Q++):(b=t,I===0&&Qe(jE)),b!==t)for(;b!==t;)m.push(b),YE.test(r.charAt(Q))?(b=r.charAt(Q),Q++):(b=t,I===0&&Qe(jE));else m=t;return m}if(k=n(),k!==t&&Q===r.length)return k;throw k!==t&&Q{"use strict";function Sfe(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function $l(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,$l)}Sfe($l,Error);$l.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;gH&&(H=v,j=[]),j.push(ne))}function Ne(ne,Y){return new $l(ne,null,null,Y)}function oe(ne,Y,he){return new $l($l.buildMessage(ne,Y),ne,Y,he)}function le(){var ne,Y,he,ie;return ne=v,Y=Be(),Y!==t?(r.charCodeAt(v)===47?(he=s,v++):(he=t,$===0&&Fe(o)),he!==t?(ie=Be(),ie!==t?(D=ne,Y=a(Y,ie),ne=Y):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t),ne===t&&(ne=v,Y=Be(),Y!==t&&(D=ne,Y=l(Y)),ne=Y),ne}function Be(){var ne,Y,he,ie;return ne=v,Y=fe(),Y!==t?(r.charCodeAt(v)===64?(he=c,v++):(he=t,$===0&&Fe(u)),he!==t?(ie=qe(),ie!==t?(D=ne,Y=g(Y,ie),ne=Y):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t),ne===t&&(ne=v,Y=fe(),Y!==t&&(D=ne,Y=f(Y)),ne=Y),ne}function fe(){var ne,Y,he,ie,de;return ne=v,r.charCodeAt(v)===64?(Y=c,v++):(Y=t,$===0&&Fe(u)),Y!==t?(he=ae(),he!==t?(r.charCodeAt(v)===47?(ie=s,v++):(ie=t,$===0&&Fe(o)),ie!==t?(de=ae(),de!==t?(D=ne,Y=h(),ne=Y):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t)):(v=ne,ne=t),ne===t&&(ne=v,Y=ae(),Y!==t&&(D=ne,Y=h()),ne=Y),ne}function ae(){var ne,Y,he;if(ne=v,Y=[],p.test(r.charAt(v))?(he=r.charAt(v),v++):(he=t,$===0&&Fe(C)),he!==t)for(;he!==t;)Y.push(he),p.test(r.charAt(v))?(he=r.charAt(v),v++):(he=t,$===0&&Fe(C));else Y=t;return Y!==t&&(D=ne,Y=h()),ne=Y,ne}function qe(){var ne,Y,he;if(ne=v,Y=[],y.test(r.charAt(v))?(he=r.charAt(v),v++):(he=t,$===0&&Fe(B)),he!==t)for(;he!==t;)Y.push(he),y.test(r.charAt(v))?(he=r.charAt(v),v++):(he=t,$===0&&Fe(B));else Y=t;return Y!==t&&(D=ne,Y=h()),ne=Y,ne}if(V=n(),V!==t&&v===r.length)return V;throw V!==t&&v{"use strict";function dK(r){return typeof r>"u"||r===null}function xfe(r){return typeof r=="object"&&r!==null}function Pfe(r){return Array.isArray(r)?r:dK(r)?[]:[r]}function Dfe(r,e){var t,i,n,s;if(e)for(s=Object.keys(e),t=0,i=s.length;t{"use strict";function Vp(r,e){Error.call(this),this.name="YAMLException",this.reason=r,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():""),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack||""}Vp.prototype=Object.create(Error.prototype);Vp.prototype.constructor=Vp;Vp.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t};CK.exports=Vp});var IK=w((wZe,EK)=>{"use strict";var mK=tc();function HS(r,e,t,i,n){this.name=r,this.buffer=e,this.position=t,this.line=i,this.column=n}HS.prototype.getSnippet=function(e,t){var i,n,s,o,a;if(!this.buffer)return null;for(e=e||4,t=t||75,i="",n=this.position;n>0&&`\0\r +\x85\u2028\u2029`.indexOf(this.buffer.charAt(n-1))===-1;)if(n-=1,this.position-n>t/2-1){i=" ... ",n+=5;break}for(s="",o=this.position;ot/2-1){s=" ... ",o-=5;break}return a=this.buffer.slice(n,o),mK.repeat(" ",e)+i+a+s+` +`+mK.repeat(" ",e+this.position-n+i.length)+"^"};HS.prototype.toString=function(e){var t,i="";return this.name&&(i+='in "'+this.name+'" '),i+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(i+=`: +`+t)),i};EK.exports=HS});var si=w((BZe,wK)=>{"use strict";var yK=Ng(),Ffe=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],Nfe=["scalar","sequence","mapping"];function Lfe(r){var e={};return r!==null&&Object.keys(r).forEach(function(t){r[t].forEach(function(i){e[String(i)]=t})}),e}function Tfe(r,e){if(e=e||{},Object.keys(e).forEach(function(t){if(Ffe.indexOf(t)===-1)throw new yK('Unknown option "'+t+'" is met in definition of "'+r+'" YAML type.')}),this.tag=r,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=Lfe(e.styleAliases||null),Nfe.indexOf(this.kind)===-1)throw new yK('Unknown kind "'+this.kind+'" is specified for "'+r+'" YAML type.')}wK.exports=Tfe});var rc=w((QZe,QK)=>{"use strict";var BK=tc(),dI=Ng(),Ofe=si();function GS(r,e,t){var i=[];return r.include.forEach(function(n){t=GS(n,e,t)}),r[e].forEach(function(n){t.forEach(function(s,o){s.tag===n.tag&&s.kind===n.kind&&i.push(o)}),t.push(n)}),t.filter(function(n,s){return i.indexOf(s)===-1})}function Mfe(){var r={scalar:{},sequence:{},mapping:{},fallback:{}},e,t;function i(n){r[n.kind][n.tag]=r.fallback[n.tag]=n}for(e=0,t=arguments.length;e{"use strict";var Ufe=si();bK.exports=new Ufe("tag:yaml.org,2002:str",{kind:"scalar",construct:function(r){return r!==null?r:""}})});var xK=w((SZe,vK)=>{"use strict";var Kfe=si();vK.exports=new Kfe("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(r){return r!==null?r:[]}})});var DK=w((vZe,PK)=>{"use strict";var Hfe=si();PK.exports=new Hfe("tag:yaml.org,2002:map",{kind:"mapping",construct:function(r){return r!==null?r:{}}})});var CI=w((xZe,kK)=>{"use strict";var Gfe=rc();kK.exports=new Gfe({explicit:[SK(),xK(),DK()]})});var FK=w((PZe,RK)=>{"use strict";var Yfe=si();function jfe(r){if(r===null)return!0;var e=r.length;return e===1&&r==="~"||e===4&&(r==="null"||r==="Null"||r==="NULL")}function qfe(){return null}function Jfe(r){return r===null}RK.exports=new Yfe("tag:yaml.org,2002:null",{kind:"scalar",resolve:jfe,construct:qfe,predicate:Jfe,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})});var LK=w((DZe,NK)=>{"use strict";var Wfe=si();function zfe(r){if(r===null)return!1;var e=r.length;return e===4&&(r==="true"||r==="True"||r==="TRUE")||e===5&&(r==="false"||r==="False"||r==="FALSE")}function Vfe(r){return r==="true"||r==="True"||r==="TRUE"}function Xfe(r){return Object.prototype.toString.call(r)==="[object Boolean]"}NK.exports=new Wfe("tag:yaml.org,2002:bool",{kind:"scalar",resolve:zfe,construct:Vfe,predicate:Xfe,represent:{lowercase:function(r){return r?"true":"false"},uppercase:function(r){return r?"TRUE":"FALSE"},camelcase:function(r){return r?"True":"False"}},defaultStyle:"lowercase"})});var OK=w((kZe,TK)=>{"use strict";var Zfe=tc(),_fe=si();function $fe(r){return 48<=r&&r<=57||65<=r&&r<=70||97<=r&&r<=102}function ehe(r){return 48<=r&&r<=55}function the(r){return 48<=r&&r<=57}function rhe(r){if(r===null)return!1;var e=r.length,t=0,i=!1,n;if(!e)return!1;if(n=r[t],(n==="-"||n==="+")&&(n=r[++t]),n==="0"){if(t+1===e)return!0;if(n=r[++t],n==="b"){for(t++;t=0?"0b"+r.toString(2):"-0b"+r.toString(2).slice(1)},octal:function(r){return r>=0?"0"+r.toString(8):"-0"+r.toString(8).slice(1)},decimal:function(r){return r.toString(10)},hexadecimal:function(r){return r>=0?"0x"+r.toString(16).toUpperCase():"-0x"+r.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})});var KK=w((RZe,UK)=>{"use strict";var MK=tc(),she=si(),ohe=new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function ahe(r){return!(r===null||!ohe.test(r)||r[r.length-1]==="_")}function Ahe(r){var e,t,i,n;return e=r.replace(/_/g,"").toLowerCase(),t=e[0]==="-"?-1:1,n=[],"+-".indexOf(e[0])>=0&&(e=e.slice(1)),e===".inf"?t===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:e===".nan"?NaN:e.indexOf(":")>=0?(e.split(":").forEach(function(s){n.unshift(parseFloat(s,10))}),e=0,i=1,n.forEach(function(s){e+=s*i,i*=60}),t*e):t*parseFloat(e,10)}var lhe=/^[-+]?[0-9]+e/;function che(r,e){var t;if(isNaN(r))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===r)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===r)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(MK.isNegativeZero(r))return"-0.0";return t=r.toString(10),lhe.test(t)?t.replace("e",".e"):t}function uhe(r){return Object.prototype.toString.call(r)==="[object Number]"&&(r%1!==0||MK.isNegativeZero(r))}UK.exports=new she("tag:yaml.org,2002:float",{kind:"scalar",resolve:ahe,construct:Ahe,predicate:uhe,represent:che,defaultStyle:"lowercase"})});var YS=w((FZe,HK)=>{"use strict";var ghe=rc();HK.exports=new ghe({include:[CI()],implicit:[FK(),LK(),OK(),KK()]})});var jS=w((NZe,GK)=>{"use strict";var fhe=rc();GK.exports=new fhe({include:[YS()]})});var JK=w((LZe,qK)=>{"use strict";var hhe=si(),YK=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),jK=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function phe(r){return r===null?!1:YK.exec(r)!==null||jK.exec(r)!==null}function dhe(r){var e,t,i,n,s,o,a,l=0,c=null,u,g,f;if(e=YK.exec(r),e===null&&(e=jK.exec(r)),e===null)throw new Error("Date resolve error");if(t=+e[1],i=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(t,i,n));if(s=+e[4],o=+e[5],a=+e[6],e[7]){for(l=e[7].slice(0,3);l.length<3;)l+="0";l=+l}return e[9]&&(u=+e[10],g=+(e[11]||0),c=(u*60+g)*6e4,e[9]==="-"&&(c=-c)),f=new Date(Date.UTC(t,i,n,s,o,a,l)),c&&f.setTime(f.getTime()-c),f}function Che(r){return r.toISOString()}qK.exports=new hhe("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:phe,construct:dhe,instanceOf:Date,represent:Che})});var zK=w((TZe,WK)=>{"use strict";var mhe=si();function Ehe(r){return r==="<<"||r===null}WK.exports=new mhe("tag:yaml.org,2002:merge",{kind:"scalar",resolve:Ehe})});var ZK=w((OZe,XK)=>{"use strict";var ic;try{VK=J,ic=VK("buffer").Buffer}catch{}var VK,Ihe=si(),qS=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= +\r`;function yhe(r){if(r===null)return!1;var e,t,i=0,n=r.length,s=qS;for(t=0;t64)){if(e<0)return!1;i+=6}return i%8===0}function whe(r){var e,t,i=r.replace(/[\r\n=]/g,""),n=i.length,s=qS,o=0,a=[];for(e=0;e>16&255),a.push(o>>8&255),a.push(o&255)),o=o<<6|s.indexOf(i.charAt(e));return t=n%4*6,t===0?(a.push(o>>16&255),a.push(o>>8&255),a.push(o&255)):t===18?(a.push(o>>10&255),a.push(o>>2&255)):t===12&&a.push(o>>4&255),ic?ic.from?ic.from(a):new ic(a):a}function Bhe(r){var e="",t=0,i,n,s=r.length,o=qS;for(i=0;i>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]),t=(t<<8)+r[i];return n=s%3,n===0?(e+=o[t>>18&63],e+=o[t>>12&63],e+=o[t>>6&63],e+=o[t&63]):n===2?(e+=o[t>>10&63],e+=o[t>>4&63],e+=o[t<<2&63],e+=o[64]):n===1&&(e+=o[t>>2&63],e+=o[t<<4&63],e+=o[64],e+=o[64]),e}function Qhe(r){return ic&&ic.isBuffer(r)}XK.exports=new Ihe("tag:yaml.org,2002:binary",{kind:"scalar",resolve:yhe,construct:whe,predicate:Qhe,represent:Bhe})});var $K=w((UZe,_K)=>{"use strict";var bhe=si(),She=Object.prototype.hasOwnProperty,vhe=Object.prototype.toString;function xhe(r){if(r===null)return!0;var e=[],t,i,n,s,o,a=r;for(t=0,i=a.length;t{"use strict";var Dhe=si(),khe=Object.prototype.toString;function Rhe(r){if(r===null)return!0;var e,t,i,n,s,o=r;for(s=new Array(o.length),e=0,t=o.length;e{"use strict";var Nhe=si(),Lhe=Object.prototype.hasOwnProperty;function The(r){if(r===null)return!0;var e,t=r;for(e in t)if(Lhe.call(t,e)&&t[e]!==null)return!1;return!0}function Ohe(r){return r!==null?r:{}}r2.exports=new Nhe("tag:yaml.org,2002:set",{kind:"mapping",resolve:The,construct:Ohe})});var Tg=w((GZe,n2)=>{"use strict";var Mhe=rc();n2.exports=new Mhe({include:[jS()],implicit:[JK(),zK()],explicit:[ZK(),$K(),t2(),i2()]})});var o2=w((YZe,s2)=>{"use strict";var Uhe=si();function Khe(){return!0}function Hhe(){}function Ghe(){return""}function Yhe(r){return typeof r>"u"}s2.exports=new Uhe("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:Khe,construct:Hhe,predicate:Yhe,represent:Ghe})});var A2=w((jZe,a2)=>{"use strict";var jhe=si();function qhe(r){if(r===null||r.length===0)return!1;var e=r,t=/\/([gim]*)$/.exec(r),i="";return!(e[0]==="/"&&(t&&(i=t[1]),i.length>3||e[e.length-i.length-1]!=="/"))}function Jhe(r){var e=r,t=/\/([gim]*)$/.exec(r),i="";return e[0]==="/"&&(t&&(i=t[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function Whe(r){var e="/"+r.source+"/";return r.global&&(e+="g"),r.multiline&&(e+="m"),r.ignoreCase&&(e+="i"),e}function zhe(r){return Object.prototype.toString.call(r)==="[object RegExp]"}a2.exports=new jhe("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:qhe,construct:Jhe,predicate:zhe,represent:Whe})});var u2=w((qZe,c2)=>{"use strict";var mI;try{l2=J,mI=l2("esprima")}catch{typeof window<"u"&&(mI=window.esprima)}var l2,Vhe=si();function Xhe(r){if(r===null)return!1;try{var e="("+r+")",t=mI.parse(e,{range:!0});return!(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")}catch{return!1}}function Zhe(r){var e="("+r+")",t=mI.parse(e,{range:!0}),i=[],n;if(t.type!=="Program"||t.body.length!==1||t.body[0].type!=="ExpressionStatement"||t.body[0].expression.type!=="ArrowFunctionExpression"&&t.body[0].expression.type!=="FunctionExpression")throw new Error("Failed to resolve function");return t.body[0].expression.params.forEach(function(s){i.push(s.name)}),n=t.body[0].expression.body.range,t.body[0].expression.body.type==="BlockStatement"?new Function(i,e.slice(n[0]+1,n[1]-1)):new Function(i,"return "+e.slice(n[0],n[1]))}function _he(r){return r.toString()}function $he(r){return Object.prototype.toString.call(r)==="[object Function]"}c2.exports=new Vhe("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:Xhe,construct:Zhe,predicate:$he,represent:_he})});var Xp=w((WZe,f2)=>{"use strict";var g2=rc();f2.exports=g2.DEFAULT=new g2({include:[Tg()],explicit:[o2(),A2(),u2()]})});var R2=w((zZe,Zp)=>{"use strict";var wa=tc(),I2=Ng(),epe=IK(),y2=Tg(),tpe=Xp(),kA=Object.prototype.hasOwnProperty,EI=1,w2=2,B2=3,II=4,JS=1,rpe=2,h2=3,ipe=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,npe=/[\x85\u2028\u2029]/,spe=/[,\[\]\{\}]/,Q2=/^(?:!|!!|![a-z\-]+!)$/i,b2=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function p2(r){return Object.prototype.toString.call(r)}function vo(r){return r===10||r===13}function sc(r){return r===9||r===32}function gn(r){return r===9||r===32||r===10||r===13}function Og(r){return r===44||r===91||r===93||r===123||r===125}function ope(r){var e;return 48<=r&&r<=57?r-48:(e=r|32,97<=e&&e<=102?e-97+10:-1)}function ape(r){return r===120?2:r===117?4:r===85?8:0}function Ape(r){return 48<=r&&r<=57?r-48:-1}function d2(r){return r===48?"\0":r===97?"\x07":r===98?"\b":r===116||r===9?" ":r===110?` +`:r===118?"\v":r===102?"\f":r===114?"\r":r===101?"\x1B":r===32?" ":r===34?'"':r===47?"/":r===92?"\\":r===78?"\x85":r===95?"\xA0":r===76?"\u2028":r===80?"\u2029":""}function lpe(r){return r<=65535?String.fromCharCode(r):String.fromCharCode((r-65536>>10)+55296,(r-65536&1023)+56320)}var S2=new Array(256),v2=new Array(256);for(nc=0;nc<256;nc++)S2[nc]=d2(nc)?1:0,v2[nc]=d2(nc);var nc;function cpe(r,e){this.input=r,this.filename=e.filename||null,this.schema=e.schema||tpe,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=r.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function x2(r,e){return new I2(e,new epe(r.filename,r.input,r.position,r.line,r.position-r.lineStart))}function ft(r,e){throw x2(r,e)}function yI(r,e){r.onWarning&&r.onWarning.call(null,x2(r,e))}var C2={YAML:function(e,t,i){var n,s,o;e.version!==null&&ft(e,"duplication of %YAML directive"),i.length!==1&&ft(e,"YAML directive accepts exactly one argument"),n=/^([0-9]+)\.([0-9]+)$/.exec(i[0]),n===null&&ft(e,"ill-formed argument of the YAML directive"),s=parseInt(n[1],10),o=parseInt(n[2],10),s!==1&&ft(e,"unacceptable YAML version of the document"),e.version=i[0],e.checkLineBreaks=o<2,o!==1&&o!==2&&yI(e,"unsupported YAML version of the document")},TAG:function(e,t,i){var n,s;i.length!==2&&ft(e,"TAG directive accepts exactly two arguments"),n=i[0],s=i[1],Q2.test(n)||ft(e,"ill-formed tag handle (first argument) of the TAG directive"),kA.call(e.tagMap,n)&&ft(e,'there is a previously declared suffix for "'+n+'" tag handle'),b2.test(s)||ft(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[n]=s}};function DA(r,e,t,i){var n,s,o,a;if(e1&&(r.result+=wa.repeat(` +`,e-1))}function upe(r,e,t){var i,n,s,o,a,l,c,u,g=r.kind,f=r.result,h;if(h=r.input.charCodeAt(r.position),gn(h)||Og(h)||h===35||h===38||h===42||h===33||h===124||h===62||h===39||h===34||h===37||h===64||h===96||(h===63||h===45)&&(n=r.input.charCodeAt(r.position+1),gn(n)||t&&Og(n)))return!1;for(r.kind="scalar",r.result="",s=o=r.position,a=!1;h!==0;){if(h===58){if(n=r.input.charCodeAt(r.position+1),gn(n)||t&&Og(n))break}else if(h===35){if(i=r.input.charCodeAt(r.position-1),gn(i))break}else{if(r.position===r.lineStart&&wI(r)||t&&Og(h))break;if(vo(h))if(l=r.line,c=r.lineStart,u=r.lineIndent,zr(r,!1,-1),r.lineIndent>=e){a=!0,h=r.input.charCodeAt(r.position);continue}else{r.position=o,r.line=l,r.lineStart=c,r.lineIndent=u;break}}a&&(DA(r,s,o,!1),zS(r,r.line-l),s=o=r.position,a=!1),sc(h)||(o=r.position+1),h=r.input.charCodeAt(++r.position)}return DA(r,s,o,!1),r.result?!0:(r.kind=g,r.result=f,!1)}function gpe(r,e){var t,i,n;if(t=r.input.charCodeAt(r.position),t!==39)return!1;for(r.kind="scalar",r.result="",r.position++,i=n=r.position;(t=r.input.charCodeAt(r.position))!==0;)if(t===39)if(DA(r,i,r.position,!0),t=r.input.charCodeAt(++r.position),t===39)i=r.position,r.position++,n=r.position;else return!0;else vo(t)?(DA(r,i,n,!0),zS(r,zr(r,!1,e)),i=n=r.position):r.position===r.lineStart&&wI(r)?ft(r,"unexpected end of the document within a single quoted scalar"):(r.position++,n=r.position);ft(r,"unexpected end of the stream within a single quoted scalar")}function fpe(r,e){var t,i,n,s,o,a;if(a=r.input.charCodeAt(r.position),a!==34)return!1;for(r.kind="scalar",r.result="",r.position++,t=i=r.position;(a=r.input.charCodeAt(r.position))!==0;){if(a===34)return DA(r,t,r.position,!0),r.position++,!0;if(a===92){if(DA(r,t,r.position,!0),a=r.input.charCodeAt(++r.position),vo(a))zr(r,!1,e);else if(a<256&&S2[a])r.result+=v2[a],r.position++;else if((o=ape(a))>0){for(n=o,s=0;n>0;n--)a=r.input.charCodeAt(++r.position),(o=ope(a))>=0?s=(s<<4)+o:ft(r,"expected hexadecimal character");r.result+=lpe(s),r.position++}else ft(r,"unknown escape sequence");t=i=r.position}else vo(a)?(DA(r,t,i,!0),zS(r,zr(r,!1,e)),t=i=r.position):r.position===r.lineStart&&wI(r)?ft(r,"unexpected end of the document within a double quoted scalar"):(r.position++,i=r.position)}ft(r,"unexpected end of the stream within a double quoted scalar")}function hpe(r,e){var t=!0,i,n=r.tag,s,o=r.anchor,a,l,c,u,g,f={},h,p,C,y;if(y=r.input.charCodeAt(r.position),y===91)l=93,g=!1,s=[];else if(y===123)l=125,g=!0,s={};else return!1;for(r.anchor!==null&&(r.anchorMap[r.anchor]=s),y=r.input.charCodeAt(++r.position);y!==0;){if(zr(r,!0,e),y=r.input.charCodeAt(r.position),y===l)return r.position++,r.tag=n,r.anchor=o,r.kind=g?"mapping":"sequence",r.result=s,!0;t||ft(r,"missed comma between flow collection entries"),p=h=C=null,c=u=!1,y===63&&(a=r.input.charCodeAt(r.position+1),gn(a)&&(c=u=!0,r.position++,zr(r,!0,e))),i=r.line,Ug(r,e,EI,!1,!0),p=r.tag,h=r.result,zr(r,!0,e),y=r.input.charCodeAt(r.position),(u||r.line===i)&&y===58&&(c=!0,y=r.input.charCodeAt(++r.position),zr(r,!0,e),Ug(r,e,EI,!1,!0),C=r.result),g?Mg(r,s,f,p,h,C):c?s.push(Mg(r,null,f,p,h,C)):s.push(h),zr(r,!0,e),y=r.input.charCodeAt(r.position),y===44?(t=!0,y=r.input.charCodeAt(++r.position)):t=!1}ft(r,"unexpected end of the stream within a flow collection")}function ppe(r,e){var t,i,n=JS,s=!1,o=!1,a=e,l=0,c=!1,u,g;if(g=r.input.charCodeAt(r.position),g===124)i=!1;else if(g===62)i=!0;else return!1;for(r.kind="scalar",r.result="";g!==0;)if(g=r.input.charCodeAt(++r.position),g===43||g===45)JS===n?n=g===43?h2:rpe:ft(r,"repeat of a chomping mode identifier");else if((u=Ape(g))>=0)u===0?ft(r,"bad explicit indentation width of a block scalar; it cannot be less than one"):o?ft(r,"repeat of an indentation width identifier"):(a=e+u-1,o=!0);else break;if(sc(g)){do g=r.input.charCodeAt(++r.position);while(sc(g));if(g===35)do g=r.input.charCodeAt(++r.position);while(!vo(g)&&g!==0)}for(;g!==0;){for(WS(r),r.lineIndent=0,g=r.input.charCodeAt(r.position);(!o||r.lineIndenta&&(a=r.lineIndent),vo(g)){l++;continue}if(r.lineIndente)&&l!==0)ft(r,"bad indentation of a sequence entry");else if(r.lineIndente)&&(Ug(r,e,II,!0,n)&&(p?f=r.result:h=r.result),p||(Mg(r,c,u,g,f,h,s,o),g=f=h=null),zr(r,!0,-1),y=r.input.charCodeAt(r.position)),r.lineIndent>e&&y!==0)ft(r,"bad indentation of a mapping entry");else if(r.lineIndente?l=1:r.lineIndent===e?l=0:r.lineIndente?l=1:r.lineIndent===e?l=0:r.lineIndent tag; it should be "scalar", not "'+r.kind+'"'),g=0,f=r.implicitTypes.length;g tag; it should be "'+h.kind+'", not "'+r.kind+'"'),h.resolve(r.result)?(r.result=h.construct(r.result),r.anchor!==null&&(r.anchorMap[r.anchor]=r.result)):ft(r,"cannot resolve a node with !<"+r.tag+"> explicit tag")):ft(r,"unknown tag !<"+r.tag+">");return r.listener!==null&&r.listener("close",r),r.tag!==null||r.anchor!==null||u}function Ipe(r){var e=r.position,t,i,n,s=!1,o;for(r.version=null,r.checkLineBreaks=r.legacy,r.tagMap={},r.anchorMap={};(o=r.input.charCodeAt(r.position))!==0&&(zr(r,!0,-1),o=r.input.charCodeAt(r.position),!(r.lineIndent>0||o!==37));){for(s=!0,o=r.input.charCodeAt(++r.position),t=r.position;o!==0&&!gn(o);)o=r.input.charCodeAt(++r.position);for(i=r.input.slice(t,r.position),n=[],i.length<1&&ft(r,"directive name must not be less than one character in length");o!==0;){for(;sc(o);)o=r.input.charCodeAt(++r.position);if(o===35){do o=r.input.charCodeAt(++r.position);while(o!==0&&!vo(o));break}if(vo(o))break;for(t=r.position;o!==0&&!gn(o);)o=r.input.charCodeAt(++r.position);n.push(r.input.slice(t,r.position))}o!==0&&WS(r),kA.call(C2,i)?C2[i](r,i,n):yI(r,'unknown document directive "'+i+'"')}if(zr(r,!0,-1),r.lineIndent===0&&r.input.charCodeAt(r.position)===45&&r.input.charCodeAt(r.position+1)===45&&r.input.charCodeAt(r.position+2)===45?(r.position+=3,zr(r,!0,-1)):s&&ft(r,"directives end mark is expected"),Ug(r,r.lineIndent-1,II,!1,!0),zr(r,!0,-1),r.checkLineBreaks&&npe.test(r.input.slice(e,r.position))&&yI(r,"non-ASCII line breaks are interpreted as content"),r.documents.push(r.result),r.position===r.lineStart&&wI(r)){r.input.charCodeAt(r.position)===46&&(r.position+=3,zr(r,!0,-1));return}if(r.position"u"&&(t=e,e=null);var i=P2(r,t);if(typeof e!="function")return i;for(var n=0,s=i.length;n"u"&&(t=e,e=null),D2(r,e,wa.extend({schema:y2},t))}function wpe(r,e){return k2(r,wa.extend({schema:y2},e))}Zp.exports.loadAll=D2;Zp.exports.load=k2;Zp.exports.safeLoadAll=ype;Zp.exports.safeLoad=wpe});var tH=w((VZe,_S)=>{"use strict";var $p=tc(),ed=Ng(),Bpe=Xp(),Qpe=Tg(),K2=Object.prototype.toString,H2=Object.prototype.hasOwnProperty,bpe=9,_p=10,Spe=13,vpe=32,xpe=33,Ppe=34,G2=35,Dpe=37,kpe=38,Rpe=39,Fpe=42,Y2=44,Npe=45,j2=58,Lpe=61,Tpe=62,Ope=63,Mpe=64,q2=91,J2=93,Upe=96,W2=123,Kpe=124,z2=125,Ni={};Ni[0]="\\0";Ni[7]="\\a";Ni[8]="\\b";Ni[9]="\\t";Ni[10]="\\n";Ni[11]="\\v";Ni[12]="\\f";Ni[13]="\\r";Ni[27]="\\e";Ni[34]='\\"';Ni[92]="\\\\";Ni[133]="\\N";Ni[160]="\\_";Ni[8232]="\\L";Ni[8233]="\\P";var Hpe=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];function Gpe(r,e){var t,i,n,s,o,a,l;if(e===null)return{};for(t={},i=Object.keys(e),n=0,s=i.length;n0?r.charCodeAt(s-1):null,f=f&&L2(o,a)}else{for(s=0;si&&r[g+1]!==" ",g=s);else if(!Kg(o))return BI;a=s>0?r.charCodeAt(s-1):null,f=f&&L2(o,a)}c=c||u&&s-g-1>i&&r[g+1]!==" "}return!l&&!c?f&&!n(r)?X2:Z2:t>9&&V2(r)?BI:c?$2:_2}function zpe(r,e,t,i){r.dump=function(){if(e.length===0)return"''";if(!r.noCompatMode&&Hpe.indexOf(e)!==-1)return"'"+e+"'";var n=r.indent*Math.max(1,t),s=r.lineWidth===-1?-1:Math.max(Math.min(r.lineWidth,40),r.lineWidth-n),o=i||r.flowLevel>-1&&t>=r.flowLevel;function a(l){return jpe(r,l)}switch(Wpe(e,o,r.indent,s,a)){case X2:return e;case Z2:return"'"+e.replace(/'/g,"''")+"'";case _2:return"|"+T2(e,r.indent)+O2(N2(e,n));case $2:return">"+T2(e,r.indent)+O2(N2(Vpe(e,s),n));case BI:return'"'+Xpe(e,s)+'"';default:throw new ed("impossible error: invalid scalar style")}}()}function T2(r,e){var t=V2(r)?String(e):"",i=r[r.length-1]===` +`,n=i&&(r[r.length-2]===` +`||r===` +`),s=n?"+":i?"":"-";return t+s+` +`}function O2(r){return r[r.length-1]===` +`?r.slice(0,-1):r}function Vpe(r,e){for(var t=/(\n+)([^\n]*)/g,i=function(){var c=r.indexOf(` +`);return c=c!==-1?c:r.length,t.lastIndex=c,M2(r.slice(0,c),e)}(),n=r[0]===` +`||r[0]===" ",s,o;o=t.exec(r);){var a=o[1],l=o[2];s=l[0]===" ",i+=a+(!n&&!s&&l!==""?` +`:"")+M2(l,e),n=s}return i}function M2(r,e){if(r===""||r[0]===" ")return r;for(var t=/ [^ ]/g,i,n=0,s,o=0,a=0,l="";i=t.exec(r);)a=i.index,a-n>e&&(s=o>n?o:a,l+=` +`+r.slice(n,s),n=s+1),o=a;return l+=` +`,r.length-n>e&&o>n?l+=r.slice(n,o)+` +`+r.slice(o+1):l+=r.slice(n),l.slice(1)}function Xpe(r){for(var e="",t,i,n,s=0;s=55296&&t<=56319&&(i=r.charCodeAt(s+1),i>=56320&&i<=57343)){e+=F2((t-55296)*1024+i-56320+65536),s++;continue}n=Ni[t],e+=!n&&Kg(t)?r[s]:n||F2(t)}return e}function Zpe(r,e,t){var i="",n=r.tag,s,o;for(s=0,o=t.length;s1024&&(u+="? "),u+=r.dump+(r.condenseFlow?'"':"")+":"+(r.condenseFlow?"":" "),oc(r,e,c,!1,!1)&&(u+=r.dump,i+=u));r.tag=n,r.dump="{"+i+"}"}function ede(r,e,t,i){var n="",s=r.tag,o=Object.keys(t),a,l,c,u,g,f;if(r.sortKeys===!0)o.sort();else if(typeof r.sortKeys=="function")o.sort(r.sortKeys);else if(r.sortKeys)throw new ed("sortKeys must be a boolean or a function");for(a=0,l=o.length;a1024,g&&(r.dump&&_p===r.dump.charCodeAt(0)?f+="?":f+="? "),f+=r.dump,g&&(f+=VS(r,e)),oc(r,e+1,u,!0,g)&&(r.dump&&_p===r.dump.charCodeAt(0)?f+=":":f+=": ",f+=r.dump,n+=f));r.tag=s,r.dump=n||"{}"}function U2(r,e,t){var i,n,s,o,a,l;for(n=t?r.explicitTypes:r.implicitTypes,s=0,o=n.length;s tag resolver accepts not "'+l+'" style');r.dump=i}return!0}return!1}function oc(r,e,t,i,n,s){r.tag=null,r.dump=t,U2(r,t,!1)||U2(r,t,!0);var o=K2.call(r.dump);i&&(i=r.flowLevel<0||r.flowLevel>e);var a=o==="[object Object]"||o==="[object Array]",l,c;if(a&&(l=r.duplicates.indexOf(t),c=l!==-1),(r.tag!==null&&r.tag!=="?"||c||r.indent!==2&&e>0)&&(n=!1),c&&r.usedDuplicates[l])r.dump="*ref_"+l;else{if(a&&c&&!r.usedDuplicates[l]&&(r.usedDuplicates[l]=!0),o==="[object Object]")i&&Object.keys(r.dump).length!==0?(ede(r,e,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):($pe(r,e,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump));else if(o==="[object Array]"){var u=r.noArrayIndent&&e>0?e-1:e;i&&r.dump.length!==0?(_pe(r,u,r.dump,n),c&&(r.dump="&ref_"+l+r.dump)):(Zpe(r,u,r.dump),c&&(r.dump="&ref_"+l+" "+r.dump))}else if(o==="[object String]")r.tag!=="?"&&zpe(r,r.dump,e,s);else{if(r.skipInvalid)return!1;throw new ed("unacceptable kind of an object to dump "+o)}r.tag!==null&&r.tag!=="?"&&(r.dump="!<"+r.tag+"> "+r.dump)}return!0}function tde(r,e){var t=[],i=[],n,s;for(XS(r,t,i),n=0,s=i.length;n{"use strict";var QI=R2(),rH=tH();function bI(r){return function(){throw new Error("Function "+r+" is deprecated and cannot be used.")}}Fr.exports.Type=si();Fr.exports.Schema=rc();Fr.exports.FAILSAFE_SCHEMA=CI();Fr.exports.JSON_SCHEMA=YS();Fr.exports.CORE_SCHEMA=jS();Fr.exports.DEFAULT_SAFE_SCHEMA=Tg();Fr.exports.DEFAULT_FULL_SCHEMA=Xp();Fr.exports.load=QI.load;Fr.exports.loadAll=QI.loadAll;Fr.exports.safeLoad=QI.safeLoad;Fr.exports.safeLoadAll=QI.safeLoadAll;Fr.exports.dump=rH.dump;Fr.exports.safeDump=rH.safeDump;Fr.exports.YAMLException=Ng();Fr.exports.MINIMAL_SCHEMA=CI();Fr.exports.SAFE_SCHEMA=Tg();Fr.exports.DEFAULT_SCHEMA=Xp();Fr.exports.scan=bI("scan");Fr.exports.parse=bI("parse");Fr.exports.compose=bI("compose");Fr.exports.addConstructor=bI("addConstructor")});var sH=w((ZZe,nH)=>{"use strict";var ide=iH();nH.exports=ide});var aH=w((_Ze,oH)=>{"use strict";function nde(r,e){function t(){this.constructor=r}t.prototype=e.prototype,r.prototype=new t}function ac(r,e,t,i){this.message=r,this.expected=e,this.found=t,this.location=i,this.name="SyntaxError",typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,ac)}nde(ac,Error);ac.buildMessage=function(r,e){var t={literal:function(c){return'"'+n(c.text)+'"'},class:function(c){var u="",g;for(g=0;g0){for(g=1,f=1;g({[Ue]:Ce})))},H=function(R){return R},j=function(R){return R},$=Ks("correct indentation"),V=" ",W=ar(" ",!1),_=function(R){return R.length===QA*yg},A=function(R){return R.length===(QA+1)*yg},Ae=function(){return QA++,!0},ge=function(){return QA--,!0},re=function(){return pg()},O=Ks("pseudostring"),F=/^[^\r\n\t ?:,\][{}#&*!|>'"%@`\-]/,ue=Nn(["\r",` +`," "," ","?",":",",","]","[","{","}","#","&","*","!","|",">","'",'"',"%","@","`","-"],!0,!1),pe=/^[^\r\n\t ,\][{}:#"']/,ke=Nn(["\r",` +`," "," ",",","]","[","{","}",":","#",'"',"'"],!0,!1),Fe=function(){return pg().replace(/^ *| *$/g,"")},Ne="--",oe=ar("--",!1),le=/^[a-zA-Z\/0-9]/,Be=Nn([["a","z"],["A","Z"],"/",["0","9"]],!1,!1),fe=/^[^\r\n\t :,]/,ae=Nn(["\r",` +`," "," ",":",","],!0,!1),qe="null",ne=ar("null",!1),Y=function(){return null},he="true",ie=ar("true",!1),de=function(){return!0},_e="false",Pt=ar("false",!1),It=function(){return!1},Or=Ks("string"),ii='"',gi=ar('"',!1),hr=function(){return""},fi=function(R){return R},ni=function(R){return R.join("")},Us=/^[^"\\\0-\x1F\x7F]/,pr=Nn(['"',"\\",["\0",""],"\x7F"],!0,!1),Ii='\\"',rs=ar('\\"',!1),ga=function(){return'"'},dA="\\\\",cg=ar("\\\\",!1),is=function(){return"\\"},CA="\\/",fa=ar("\\/",!1),wp=function(){return"/"},mA="\\b",EA=ar("\\b",!1),wr=function(){return"\b"},Ll="\\f",ug=ar("\\f",!1),Io=function(){return"\f"},gg="\\n",Bp=ar("\\n",!1),Qp=function(){return` +`},vr="\\r",se=ar("\\r",!1),yo=function(){return"\r"},Rn="\\t",fg=ar("\\t",!1),Qt=function(){return" "},Tl="\\u",Fn=ar("\\u",!1),ns=function(R,q,Ce,Ue){return String.fromCharCode(parseInt(`0x${R}${q}${Ce}${Ue}`))},ss=/^[0-9a-fA-F]/,gt=Nn([["0","9"],["a","f"],["A","F"]],!1,!1),wo=Ks("blank space"),At=/^[ \t]/,An=Nn([" "," "],!1,!1),S=Ks("white space"),Tt=/^[ \t\n\r]/,hg=Nn([" "," ",` +`,"\r"],!1,!1),Ol=`\r +`,bp=ar(`\r +`,!1),Sp=` +`,vp=ar(` +`,!1),xp="\r",Pp=ar("\r",!1),G=0,yt=0,IA=[{line:1,column:1}],Wi=0,Ml=[],Xe=0,ha;if("startRule"in e){if(!(e.startRule in i))throw new Error(`Can't start parsing from rule "`+e.startRule+'".');n=i[e.startRule]}function pg(){return r.substring(yt,G)}function OE(){return ln(yt,G)}function Dp(R,q){throw q=q!==void 0?q:ln(yt,G),Kl([Ks(R)],r.substring(yt,G),q)}function ME(R,q){throw q=q!==void 0?q:ln(yt,G),dg(R,q)}function ar(R,q){return{type:"literal",text:R,ignoreCase:q}}function Nn(R,q,Ce){return{type:"class",parts:R,inverted:q,ignoreCase:Ce}}function Ul(){return{type:"any"}}function kp(){return{type:"end"}}function Ks(R){return{type:"other",description:R}}function pa(R){var q=IA[R],Ce;if(q)return q;for(Ce=R-1;!IA[Ce];)Ce--;for(q=IA[Ce],q={line:q.line,column:q.column};CeWi&&(Wi=G,Ml=[]),Ml.push(R))}function dg(R,q){return new ac(R,null,null,q)}function Kl(R,q,Ce){return new ac(ac.buildMessage(R,q),R,q,Ce)}function Hs(){var R;return R=Cg(),R}function Hl(){var R,q,Ce;for(R=G,q=[],Ce=yA();Ce!==t;)q.push(Ce),Ce=yA();return q!==t&&(yt=R,q=s(q)),R=q,R}function yA(){var R,q,Ce,Ue,Re;return R=G,q=Ca(),q!==t?(r.charCodeAt(G)===45?(Ce=o,G++):(Ce=t,Xe===0&&Te(a)),Ce!==t?(Ue=Rr(),Ue!==t?(Re=da(),Re!==t?(yt=R,q=l(Re),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R}function Cg(){var R,q,Ce;for(R=G,q=[],Ce=mg();Ce!==t;)q.push(Ce),Ce=mg();return q!==t&&(yt=R,q=c(q)),R=q,R}function mg(){var R,q,Ce,Ue,Re,ze,dt,Ft,Ln;if(R=G,q=Rr(),q===t&&(q=null),q!==t){if(Ce=G,r.charCodeAt(G)===35?(Ue=u,G++):(Ue=t,Xe===0&&Te(g)),Ue!==t){if(Re=[],ze=G,dt=G,Xe++,Ft=js(),Xe--,Ft===t?dt=void 0:(G=dt,dt=t),dt!==t?(r.length>G?(Ft=r.charAt(G),G++):(Ft=t,Xe===0&&Te(f)),Ft!==t?(dt=[dt,Ft],ze=dt):(G=ze,ze=t)):(G=ze,ze=t),ze!==t)for(;ze!==t;)Re.push(ze),ze=G,dt=G,Xe++,Ft=js(),Xe--,Ft===t?dt=void 0:(G=dt,dt=t),dt!==t?(r.length>G?(Ft=r.charAt(G),G++):(Ft=t,Xe===0&&Te(f)),Ft!==t?(dt=[dt,Ft],ze=dt):(G=ze,ze=t)):(G=ze,ze=t);else Re=t;Re!==t?(Ue=[Ue,Re],Ce=Ue):(G=Ce,Ce=t)}else G=Ce,Ce=t;if(Ce===t&&(Ce=null),Ce!==t){if(Ue=[],Re=Ys(),Re!==t)for(;Re!==t;)Ue.push(Re),Re=Ys();else Ue=t;Ue!==t?(yt=R,q=h(),R=q):(G=R,R=t)}else G=R,R=t}else G=R,R=t;if(R===t&&(R=G,q=Ca(),q!==t?(Ce=Gl(),Ce!==t?(Ue=Rr(),Ue===t&&(Ue=null),Ue!==t?(r.charCodeAt(G)===58?(Re=p,G++):(Re=t,Xe===0&&Te(C)),Re!==t?(ze=Rr(),ze===t&&(ze=null),ze!==t?(dt=da(),dt!==t?(yt=R,q=y(Ce,dt),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t&&(R=G,q=Ca(),q!==t?(Ce=Gs(),Ce!==t?(Ue=Rr(),Ue===t&&(Ue=null),Ue!==t?(r.charCodeAt(G)===58?(Re=p,G++):(Re=t,Xe===0&&Te(C)),Re!==t?(ze=Rr(),ze===t&&(ze=null),ze!==t?(dt=da(),dt!==t?(yt=R,q=y(Ce,dt),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t))){if(R=G,q=Ca(),q!==t)if(Ce=Gs(),Ce!==t)if(Ue=Rr(),Ue!==t)if(Re=UE(),Re!==t){if(ze=[],dt=Ys(),dt!==t)for(;dt!==t;)ze.push(dt),dt=Ys();else ze=t;ze!==t?(yt=R,q=y(Ce,Re),R=q):(G=R,R=t)}else G=R,R=t;else G=R,R=t;else G=R,R=t;else G=R,R=t;if(R===t)if(R=G,q=Ca(),q!==t)if(Ce=Gs(),Ce!==t){if(Ue=[],Re=G,ze=Rr(),ze===t&&(ze=null),ze!==t?(r.charCodeAt(G)===44?(dt=B,G++):(dt=t,Xe===0&&Te(v)),dt!==t?(Ft=Rr(),Ft===t&&(Ft=null),Ft!==t?(Ln=Gs(),Ln!==t?(yt=Re,ze=D(Ce,Ln),Re=ze):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t),Re!==t)for(;Re!==t;)Ue.push(Re),Re=G,ze=Rr(),ze===t&&(ze=null),ze!==t?(r.charCodeAt(G)===44?(dt=B,G++):(dt=t,Xe===0&&Te(v)),dt!==t?(Ft=Rr(),Ft===t&&(Ft=null),Ft!==t?(Ln=Gs(),Ln!==t?(yt=Re,ze=D(Ce,Ln),Re=ze):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t)):(G=Re,Re=t);else Ue=t;Ue!==t?(Re=Rr(),Re===t&&(Re=null),Re!==t?(r.charCodeAt(G)===58?(ze=p,G++):(ze=t,Xe===0&&Te(C)),ze!==t?(dt=Rr(),dt===t&&(dt=null),dt!==t?(Ft=da(),Ft!==t?(yt=R,q=L(Ce,Ue,Ft),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)}else G=R,R=t;else G=R,R=t}return R}function da(){var R,q,Ce,Ue,Re,ze,dt;if(R=G,q=G,Xe++,Ce=G,Ue=js(),Ue!==t?(Re=rt(),Re!==t?(r.charCodeAt(G)===45?(ze=o,G++):(ze=t,Xe===0&&Te(a)),ze!==t?(dt=Rr(),dt!==t?(Ue=[Ue,Re,ze,dt],Ce=Ue):(G=Ce,Ce=t)):(G=Ce,Ce=t)):(G=Ce,Ce=t)):(G=Ce,Ce=t),Xe--,Ce!==t?(G=q,q=void 0):q=t,q!==t?(Ce=Ys(),Ce!==t?(Ue=Bo(),Ue!==t?(Re=Hl(),Re!==t?(ze=wA(),ze!==t?(yt=R,q=H(Re),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t&&(R=G,q=js(),q!==t?(Ce=Bo(),Ce!==t?(Ue=Cg(),Ue!==t?(Re=wA(),Re!==t?(yt=R,q=H(Ue),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t),R===t))if(R=G,q=Yl(),q!==t){if(Ce=[],Ue=Ys(),Ue!==t)for(;Ue!==t;)Ce.push(Ue),Ue=Ys();else Ce=t;Ce!==t?(yt=R,q=j(q),R=q):(G=R,R=t)}else G=R,R=t;return R}function Ca(){var R,q,Ce;for(Xe++,R=G,q=[],r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));Ce!==t;)q.push(Ce),r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));return q!==t?(yt=G,Ce=_(q),Ce?Ce=void 0:Ce=t,Ce!==t?(q=[q,Ce],R=q):(G=R,R=t)):(G=R,R=t),Xe--,R===t&&(q=t,Xe===0&&Te($)),R}function rt(){var R,q,Ce;for(R=G,q=[],r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));Ce!==t;)q.push(Ce),r.charCodeAt(G)===32?(Ce=V,G++):(Ce=t,Xe===0&&Te(W));return q!==t?(yt=G,Ce=A(q),Ce?Ce=void 0:Ce=t,Ce!==t?(q=[q,Ce],R=q):(G=R,R=t)):(G=R,R=t),R}function Bo(){var R;return yt=G,R=Ae(),R?R=void 0:R=t,R}function wA(){var R;return yt=G,R=ge(),R?R=void 0:R=t,R}function Gl(){var R;return R=jl(),R===t&&(R=Rp()),R}function Gs(){var R,q,Ce;if(R=jl(),R===t){if(R=G,q=[],Ce=Eg(),Ce!==t)for(;Ce!==t;)q.push(Ce),Ce=Eg();else q=t;q!==t&&(yt=R,q=re()),R=q}return R}function Yl(){var R;return R=Fp(),R===t&&(R=KE(),R===t&&(R=jl(),R===t&&(R=Rp()))),R}function UE(){var R;return R=Fp(),R===t&&(R=jl(),R===t&&(R=Eg())),R}function Rp(){var R,q,Ce,Ue,Re,ze;if(Xe++,R=G,F.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(ue)),q!==t){for(Ce=[],Ue=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(pe.test(r.charAt(G))?(ze=r.charAt(G),G++):(ze=t,Xe===0&&Te(ke)),ze!==t?(Re=[Re,ze],Ue=Re):(G=Ue,Ue=t)):(G=Ue,Ue=t);Ue!==t;)Ce.push(Ue),Ue=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(pe.test(r.charAt(G))?(ze=r.charAt(G),G++):(ze=t,Xe===0&&Te(ke)),ze!==t?(Re=[Re,ze],Ue=Re):(G=Ue,Ue=t)):(G=Ue,Ue=t);Ce!==t?(yt=R,q=Fe(),R=q):(G=R,R=t)}else G=R,R=t;return Xe--,R===t&&(q=t,Xe===0&&Te(O)),R}function Eg(){var R,q,Ce,Ue,Re;if(R=G,r.substr(G,2)===Ne?(q=Ne,G+=2):(q=t,Xe===0&&Te(oe)),q===t&&(q=null),q!==t)if(le.test(r.charAt(G))?(Ce=r.charAt(G),G++):(Ce=t,Xe===0&&Te(Be)),Ce!==t){for(Ue=[],fe.test(r.charAt(G))?(Re=r.charAt(G),G++):(Re=t,Xe===0&&Te(ae));Re!==t;)Ue.push(Re),fe.test(r.charAt(G))?(Re=r.charAt(G),G++):(Re=t,Xe===0&&Te(ae));Ue!==t?(yt=R,q=Fe(),R=q):(G=R,R=t)}else G=R,R=t;else G=R,R=t;return R}function Fp(){var R,q;return R=G,r.substr(G,4)===qe?(q=qe,G+=4):(q=t,Xe===0&&Te(ne)),q!==t&&(yt=R,q=Y()),R=q,R}function KE(){var R,q;return R=G,r.substr(G,4)===he?(q=he,G+=4):(q=t,Xe===0&&Te(ie)),q!==t&&(yt=R,q=de()),R=q,R===t&&(R=G,r.substr(G,5)===_e?(q=_e,G+=5):(q=t,Xe===0&&Te(Pt)),q!==t&&(yt=R,q=It()),R=q),R}function jl(){var R,q,Ce,Ue;return Xe++,R=G,r.charCodeAt(G)===34?(q=ii,G++):(q=t,Xe===0&&Te(gi)),q!==t?(r.charCodeAt(G)===34?(Ce=ii,G++):(Ce=t,Xe===0&&Te(gi)),Ce!==t?(yt=R,q=hr(),R=q):(G=R,R=t)):(G=R,R=t),R===t&&(R=G,r.charCodeAt(G)===34?(q=ii,G++):(q=t,Xe===0&&Te(gi)),q!==t?(Ce=HE(),Ce!==t?(r.charCodeAt(G)===34?(Ue=ii,G++):(Ue=t,Xe===0&&Te(gi)),Ue!==t?(yt=R,q=fi(Ce),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)),Xe--,R===t&&(q=t,Xe===0&&Te(Or)),R}function HE(){var R,q,Ce;if(R=G,q=[],Ce=Ig(),Ce!==t)for(;Ce!==t;)q.push(Ce),Ce=Ig();else q=t;return q!==t&&(yt=R,q=ni(q)),R=q,R}function Ig(){var R,q,Ce,Ue,Re,ze;return Us.test(r.charAt(G))?(R=r.charAt(G),G++):(R=t,Xe===0&&Te(pr)),R===t&&(R=G,r.substr(G,2)===Ii?(q=Ii,G+=2):(q=t,Xe===0&&Te(rs)),q!==t&&(yt=R,q=ga()),R=q,R===t&&(R=G,r.substr(G,2)===dA?(q=dA,G+=2):(q=t,Xe===0&&Te(cg)),q!==t&&(yt=R,q=is()),R=q,R===t&&(R=G,r.substr(G,2)===CA?(q=CA,G+=2):(q=t,Xe===0&&Te(fa)),q!==t&&(yt=R,q=wp()),R=q,R===t&&(R=G,r.substr(G,2)===mA?(q=mA,G+=2):(q=t,Xe===0&&Te(EA)),q!==t&&(yt=R,q=wr()),R=q,R===t&&(R=G,r.substr(G,2)===Ll?(q=Ll,G+=2):(q=t,Xe===0&&Te(ug)),q!==t&&(yt=R,q=Io()),R=q,R===t&&(R=G,r.substr(G,2)===gg?(q=gg,G+=2):(q=t,Xe===0&&Te(Bp)),q!==t&&(yt=R,q=Qp()),R=q,R===t&&(R=G,r.substr(G,2)===vr?(q=vr,G+=2):(q=t,Xe===0&&Te(se)),q!==t&&(yt=R,q=yo()),R=q,R===t&&(R=G,r.substr(G,2)===Rn?(q=Rn,G+=2):(q=t,Xe===0&&Te(fg)),q!==t&&(yt=R,q=Qt()),R=q,R===t&&(R=G,r.substr(G,2)===Tl?(q=Tl,G+=2):(q=t,Xe===0&&Te(Fn)),q!==t?(Ce=BA(),Ce!==t?(Ue=BA(),Ue!==t?(Re=BA(),Re!==t?(ze=BA(),ze!==t?(yt=R,q=ns(Ce,Ue,Re,ze),R=q):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)):(G=R,R=t)))))))))),R}function BA(){var R;return ss.test(r.charAt(G))?(R=r.charAt(G),G++):(R=t,Xe===0&&Te(gt)),R}function Rr(){var R,q;if(Xe++,R=[],At.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(An)),q!==t)for(;q!==t;)R.push(q),At.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(An));else R=t;return Xe--,R===t&&(q=t,Xe===0&&Te(wo)),R}function GE(){var R,q;if(Xe++,R=[],Tt.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(hg)),q!==t)for(;q!==t;)R.push(q),Tt.test(r.charAt(G))?(q=r.charAt(G),G++):(q=t,Xe===0&&Te(hg));else R=t;return Xe--,R===t&&(q=t,Xe===0&&Te(S)),R}function Ys(){var R,q,Ce,Ue,Re,ze;if(R=G,q=js(),q!==t){for(Ce=[],Ue=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(ze=js(),ze!==t?(Re=[Re,ze],Ue=Re):(G=Ue,Ue=t)):(G=Ue,Ue=t);Ue!==t;)Ce.push(Ue),Ue=G,Re=Rr(),Re===t&&(Re=null),Re!==t?(ze=js(),ze!==t?(Re=[Re,ze],Ue=Re):(G=Ue,Ue=t)):(G=Ue,Ue=t);Ce!==t?(q=[q,Ce],R=q):(G=R,R=t)}else G=R,R=t;return R}function js(){var R;return r.substr(G,2)===Ol?(R=Ol,G+=2):(R=t,Xe===0&&Te(bp)),R===t&&(r.charCodeAt(G)===10?(R=Sp,G++):(R=t,Xe===0&&Te(vp)),R===t&&(r.charCodeAt(G)===13?(R=xp,G++):(R=t,Xe===0&&Te(Pp)))),R}let yg=2,QA=0;if(ha=n(),ha!==t&&G===r.length)return ha;throw ha!==t&&G{"use strict";var cde=r=>{let e=!1,t=!1,i=!1;for(let n=0;n{if(!(typeof r=="string"||Array.isArray(r)))throw new TypeError("Expected the input to be `string | string[]`");e=Object.assign({pascalCase:!1},e);let t=n=>e.pascalCase?n.charAt(0).toUpperCase()+n.slice(1):n;return Array.isArray(r)?r=r.map(n=>n.trim()).filter(n=>n.length).join("-"):r=r.trim(),r.length===0?"":r.length===1?e.pascalCase?r.toUpperCase():r.toLowerCase():(r!==r.toLowerCase()&&(r=cde(r)),r=r.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(n,s)=>s.toUpperCase()).replace(/\d+(\w|$)/g,n=>n.toUpperCase()),t(r))};ev.exports=gH;ev.exports.default=gH});var hH=w((n_e,ude)=>{ude.exports=[{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",pr:"SYSTEM_PULLREQUEST_PULLREQUESTID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE"},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Shippable",constant:"SHIPPABLE",env:"SHIPPABLE",pr:{IS_PULL_REQUEST:"true"}},{name:"Solano CI",constant:"SOLANO",env:"TDDIUM",pr:"TDDIUM_PR_ID"},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vercel",constant:"VERCEL",env:"NOW_BUILDER"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"}]});var Ac=w(Un=>{"use strict";var dH=hH(),xo=process.env;Object.defineProperty(Un,"_vendors",{value:dH.map(function(r){return r.constant})});Un.name=null;Un.isPR=null;dH.forEach(function(r){let t=(Array.isArray(r.env)?r.env:[r.env]).every(function(i){return pH(i)});if(Un[r.constant]=t,t)switch(Un.name=r.name,typeof r.pr){case"string":Un.isPR=!!xo[r.pr];break;case"object":"env"in r.pr?Un.isPR=r.pr.env in xo&&xo[r.pr.env]!==r.pr.ne:"any"in r.pr?Un.isPR=r.pr.any.some(function(i){return!!xo[i]}):Un.isPR=pH(r.pr);break;default:Un.isPR=null}});Un.isCI=!!(xo.CI||xo.CONTINUOUS_INTEGRATION||xo.BUILD_NUMBER||xo.RUN_ID||Un.name);function pH(r){return typeof r=="string"?!!xo[r]:Object.keys(r).every(function(e){return xo[e]===r[e]})}});var fn={};ut(fn,{KeyRelationship:()=>lc,applyCascade:()=>od,base64RegExp:()=>yH,colorStringAlphaRegExp:()=>IH,colorStringRegExp:()=>EH,computeKey:()=>RA,getPrintable:()=>Vr,hasExactLength:()=>SH,hasForbiddenKeys:()=>Yde,hasKeyRelationship:()=>av,hasMaxLength:()=>Sde,hasMinLength:()=>bde,hasMutuallyExclusiveKeys:()=>jde,hasRequiredKeys:()=>Gde,hasUniqueItems:()=>vde,isArray:()=>Cde,isAtLeast:()=>Dde,isAtMost:()=>kde,isBase64:()=>Kde,isBoolean:()=>hde,isDate:()=>dde,isDict:()=>Ede,isEnum:()=>Xi,isHexColor:()=>Ude,isISO8601:()=>Mde,isInExclusiveRange:()=>Fde,isInInclusiveRange:()=>Rde,isInstanceOf:()=>yde,isInteger:()=>Nde,isJSON:()=>Hde,isLiteral:()=>gde,isLowerCase:()=>Lde,isNegative:()=>xde,isNullable:()=>Qde,isNumber:()=>pde,isObject:()=>Ide,isOneOf:()=>wde,isOptional:()=>Bde,isPositive:()=>Pde,isString:()=>sd,isTuple:()=>mde,isUUID4:()=>Ode,isUnknown:()=>bH,isUpperCase:()=>Tde,iso8601RegExp:()=>ov,makeCoercionFn:()=>cc,makeSetter:()=>QH,makeTrait:()=>BH,makeValidator:()=>bt,matchesRegExp:()=>ad,plural:()=>kI,pushError:()=>pt,simpleKeyRegExp:()=>mH,uuid4RegExp:()=>wH});function bt({test:r}){return BH(r)()}function Vr(r){return r===null?"null":r===void 0?"undefined":r===""?"an empty string":JSON.stringify(r)}function RA(r,e){var t,i,n;return typeof e=="number"?`${(t=r==null?void 0:r.p)!==null&&t!==void 0?t:"."}[${e}]`:mH.test(e)?`${(i=r==null?void 0:r.p)!==null&&i!==void 0?i:""}.${e}`:`${(n=r==null?void 0:r.p)!==null&&n!==void 0?n:"."}[${JSON.stringify(e)}]`}function cc(r,e){return t=>{let i=r[e];return r[e]=t,cc(r,e).bind(null,i)}}function QH(r,e){return t=>{r[e]=t}}function kI(r,e,t){return r===1?e:t}function pt({errors:r,p:e}={},t){return r==null||r.push(`${e!=null?e:"."}: ${t}`),!1}function gde(r){return bt({test:(e,t)=>e!==r?pt(t,`Expected a literal (got ${Vr(r)})`):!0})}function Xi(r){let e=Array.isArray(r)?r:Object.values(r),t=new Set(e);return bt({test:(i,n)=>t.has(i)?!0:pt(n,`Expected a valid enumeration value (got ${Vr(i)})`)})}var mH,EH,IH,yH,wH,ov,BH,bH,sd,fde,hde,pde,dde,Cde,mde,Ede,Ide,yde,wde,od,Bde,Qde,bde,Sde,SH,vde,xde,Pde,Dde,kde,Rde,Fde,Nde,ad,Lde,Tde,Ode,Mde,Ude,Kde,Hde,Gde,Yde,jde,lc,qde,av,ls=kge(()=>{mH=/^[a-zA-Z_][a-zA-Z0-9_]*$/,EH=/^#[0-9a-f]{6}$/i,IH=/^#[0-9a-f]{6}([0-9a-f]{2})?$/i,yH=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,wH=/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i,ov=/^(?:[1-9]\d{3}(-?)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])(?:\1)31|00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[0-5]))|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)(?:(-?)02(?:\2)29|-?366))T(?:[01]\d|2[0-3])(:?)[0-5]\d(?:\3[0-5]\d)?(?:Z|[+-][01]\d(?:\3[0-5]\d)?)$/,BH=r=>()=>r;bH=()=>bt({test:(r,e)=>!0});sd=()=>bt({test:(r,e)=>typeof r!="string"?pt(e,`Expected a string (got ${Vr(r)})`):!0});fde=new Map([["true",!0],["True",!0],["1",!0],[1,!0],["false",!1],["False",!1],["0",!1],[0,!1]]),hde=()=>bt({test:(r,e)=>{var t;if(typeof r!="boolean"){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return pt(e,"Unbound coercion result");let i=fde.get(r);if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return pt(e,`Expected a boolean (got ${Vr(r)})`)}return!0}}),pde=()=>bt({test:(r,e)=>{var t;if(typeof r!="number"){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return pt(e,"Unbound coercion result");let i;if(typeof r=="string"){let n;try{n=JSON.parse(r)}catch{}if(typeof n=="number")if(JSON.stringify(n)===r)i=n;else return pt(e,`Received a number that can't be safely represented by the runtime (${r})`)}if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return pt(e,`Expected a number (got ${Vr(r)})`)}return!0}}),dde=()=>bt({test:(r,e)=>{var t;if(!(r instanceof Date)){if(typeof(e==null?void 0:e.coercions)<"u"){if(typeof(e==null?void 0:e.coercion)>"u")return pt(e,"Unbound coercion result");let i;if(typeof r=="string"&&ov.test(r))i=new Date(r);else{let n;if(typeof r=="string"){let s;try{s=JSON.parse(r)}catch{}typeof s=="number"&&(n=s)}else typeof r=="number"&&(n=r);if(typeof n<"u")if(Number.isSafeInteger(n)||!Number.isSafeInteger(n*1e3))i=new Date(n*1e3);else return pt(e,`Received a timestamp that can't be safely represented by the runtime (${r})`)}if(typeof i<"u")return e.coercions.push([(t=e.p)!==null&&t!==void 0?t:".",e.coercion.bind(null,i)]),!0}return pt(e,`Expected a date (got ${Vr(r)})`)}return!0}}),Cde=(r,{delimiter:e}={})=>bt({test:(t,i)=>{var n;if(typeof t=="string"&&typeof e<"u"&&typeof(i==null?void 0:i.coercions)<"u"){if(typeof(i==null?void 0:i.coercion)>"u")return pt(i,"Unbound coercion result");t=t.split(e),i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,t)])}if(!Array.isArray(t))return pt(i,`Expected an array (got ${Vr(t)})`);let s=!0;for(let o=0,a=t.length;o{let t=SH(r.length);return bt({test:(i,n)=>{var s;if(typeof i=="string"&&typeof e<"u"&&typeof(n==null?void 0:n.coercions)<"u"){if(typeof(n==null?void 0:n.coercion)>"u")return pt(n,"Unbound coercion result");i=i.split(e),n.coercions.push([(s=n.p)!==null&&s!==void 0?s:".",n.coercion.bind(null,i)])}if(!Array.isArray(i))return pt(n,`Expected a tuple (got ${Vr(i)})`);let o=t(i,Object.assign({},n));for(let a=0,l=i.length;abt({test:(t,i)=>{if(typeof t!="object"||t===null)return pt(i,`Expected an object (got ${Vr(t)})`);let n=Object.keys(t),s=!0;for(let o=0,a=n.length;o{let t=Object.keys(r);return bt({test:(i,n)=>{if(typeof i!="object"||i===null)return pt(n,`Expected an object (got ${Vr(i)})`);let s=new Set([...t,...Object.keys(i)]),o={},a=!0;for(let l of s){if(l==="constructor"||l==="__proto__")a=pt(Object.assign(Object.assign({},n),{p:RA(n,l)}),"Unsafe property name");else{let c=Object.prototype.hasOwnProperty.call(r,l)?r[l]:void 0,u=Object.prototype.hasOwnProperty.call(i,l)?i[l]:void 0;typeof c<"u"?a=c(u,Object.assign(Object.assign({},n),{p:RA(n,l),coercion:cc(i,l)}))&&a:e===null?a=pt(Object.assign(Object.assign({},n),{p:RA(n,l)}),`Extraneous property (got ${Vr(u)})`):Object.defineProperty(o,l,{enumerable:!0,get:()=>u,set:QH(i,l)})}if(!a&&(n==null?void 0:n.errors)==null)break}return e!==null&&(a||(n==null?void 0:n.errors)!=null)&&(a=e(o,n)&&a),a}})},yde=r=>bt({test:(e,t)=>e instanceof r?!0:pt(t,`Expected an instance of ${r.name} (got ${Vr(e)})`)}),wde=(r,{exclusive:e=!1}={})=>bt({test:(t,i)=>{var n,s,o;let a=[],l=typeof(i==null?void 0:i.errors)<"u"?[]:void 0;for(let c=0,u=r.length;c1?pt(i,`Expected to match exactly a single predicate (matched ${a.join(", ")})`):(o=i==null?void 0:i.errors)===null||o===void 0||o.push(...l),!1}}),od=(r,e)=>bt({test:(t,i)=>{var n,s;let o={value:t},a=typeof(i==null?void 0:i.coercions)<"u"?cc(o,"value"):void 0,l=typeof(i==null?void 0:i.coercions)<"u"?[]:void 0;if(!r(t,Object.assign(Object.assign({},i),{coercion:a,coercions:l})))return!1;let c=[];if(typeof l<"u")for(let[,u]of l)c.push(u());try{if(typeof(i==null?void 0:i.coercions)<"u"){if(o.value!==t){if(typeof(i==null?void 0:i.coercion)>"u")return pt(i,"Unbound coercion result");i.coercions.push([(n=i.p)!==null&&n!==void 0?n:".",i.coercion.bind(null,o.value)])}(s=i==null?void 0:i.coercions)===null||s===void 0||s.push(...l)}return e.every(u=>u(o.value,i))}finally{for(let u of c)u()}}}),Bde=r=>bt({test:(e,t)=>typeof e>"u"?!0:r(e,t)}),Qde=r=>bt({test:(e,t)=>e===null?!0:r(e,t)}),bde=r=>bt({test:(e,t)=>e.length>=r?!0:pt(t,`Expected to have a length of at least ${r} elements (got ${e.length})`)}),Sde=r=>bt({test:(e,t)=>e.length<=r?!0:pt(t,`Expected to have a length of at most ${r} elements (got ${e.length})`)}),SH=r=>bt({test:(e,t)=>e.length!==r?pt(t,`Expected to have a length of exactly ${r} elements (got ${e.length})`):!0}),vde=({map:r}={})=>bt({test:(e,t)=>{let i=new Set,n=new Set;for(let s=0,o=e.length;sbt({test:(r,e)=>r<=0?!0:pt(e,`Expected to be negative (got ${r})`)}),Pde=()=>bt({test:(r,e)=>r>=0?!0:pt(e,`Expected to be positive (got ${r})`)}),Dde=r=>bt({test:(e,t)=>e>=r?!0:pt(t,`Expected to be at least ${r} (got ${e})`)}),kde=r=>bt({test:(e,t)=>e<=r?!0:pt(t,`Expected to be at most ${r} (got ${e})`)}),Rde=(r,e)=>bt({test:(t,i)=>t>=r&&t<=e?!0:pt(i,`Expected to be in the [${r}; ${e}] range (got ${t})`)}),Fde=(r,e)=>bt({test:(t,i)=>t>=r&&tbt({test:(e,t)=>e!==Math.round(e)?pt(t,`Expected to be an integer (got ${e})`):Number.isSafeInteger(e)?!0:pt(t,`Expected to be a safe integer (got ${e})`)}),ad=r=>bt({test:(e,t)=>r.test(e)?!0:pt(t,`Expected to match the pattern ${r.toString()} (got ${Vr(e)})`)}),Lde=()=>bt({test:(r,e)=>r!==r.toLowerCase()?pt(e,`Expected to be all-lowercase (got ${r})`):!0}),Tde=()=>bt({test:(r,e)=>r!==r.toUpperCase()?pt(e,`Expected to be all-uppercase (got ${r})`):!0}),Ode=()=>bt({test:(r,e)=>wH.test(r)?!0:pt(e,`Expected to be a valid UUID v4 (got ${Vr(r)})`)}),Mde=()=>bt({test:(r,e)=>ov.test(r)?!1:pt(e,`Expected to be a valid ISO 8601 date string (got ${Vr(r)})`)}),Ude=({alpha:r=!1})=>bt({test:(e,t)=>(r?EH.test(e):IH.test(e))?!0:pt(t,`Expected to be a valid hexadecimal color string (got ${Vr(e)})`)}),Kde=()=>bt({test:(r,e)=>yH.test(r)?!0:pt(e,`Expected to be a valid base 64 string (got ${Vr(r)})`)}),Hde=(r=bH())=>bt({test:(e,t)=>{let i;try{i=JSON.parse(e)}catch{return pt(t,`Expected to be a valid JSON string (got ${Vr(e)})`)}return r(i,t)}}),Gde=r=>{let e=new Set(r);return bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)||s.push(o);return s.length>0?pt(i,`Missing required ${kI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},Yde=r=>{let e=new Set(r);return bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>0?pt(i,`Forbidden ${kI(s.length,"property","properties")} ${s.map(o=>`"${o}"`).join(", ")}`):!0}})},jde=r=>{let e=new Set(r);return bt({test:(t,i)=>{let n=new Set(Object.keys(t)),s=[];for(let o of e)n.has(o)&&s.push(o);return s.length>1?pt(i,`Mutually exclusive properties ${s.map(o=>`"${o}"`).join(", ")}`):!0}})};(function(r){r.Forbids="Forbids",r.Requires="Requires"})(lc||(lc={}));qde={[lc.Forbids]:{expect:!1,message:"forbids using"},[lc.Requires]:{expect:!0,message:"requires using"}},av=(r,e,t,{ignore:i=[]}={})=>{let n=new Set(i),s=new Set(t),o=qde[e];return bt({test:(a,l)=>{let c=new Set(Object.keys(a));if(!c.has(r)||n.has(a[r]))return!0;let u=[];for(let g of s)(c.has(g)&&!n.has(a[g]))!==o.expect&&u.push(g);return u.length>=1?pt(l,`Property "${r}" ${o.message} ${kI(u.length,"property","properties")} ${u.map(g=>`"${g}"`).join(", ")}`):!0}})}});var YH=w((n$e,GH)=>{"use strict";GH.exports=(r,...e)=>new Promise(t=>{t(r(...e))})});var Jg=w((s$e,pv)=>{"use strict";var ACe=YH(),jH=r=>{if(r<1)throw new TypeError("Expected `concurrency` to be a number from 1 and up");let e=[],t=0,i=()=>{t--,e.length>0&&e.shift()()},n=(a,l,...c)=>{t++;let u=ACe(a,...c);l(u),u.then(i,i)},s=(a,l,...c)=>{tnew Promise(c=>s(a,c,...l));return Object.defineProperties(o,{activeCount:{get:()=>t},pendingCount:{get:()=>e.length}}),o};pv.exports=jH;pv.exports.default=jH});var gd=w((a$e,qH)=>{var lCe="2.0.0",cCe=Number.MAX_SAFE_INTEGER||9007199254740991,uCe=16;qH.exports={SEMVER_SPEC_VERSION:lCe,MAX_LENGTH:256,MAX_SAFE_INTEGER:cCe,MAX_SAFE_COMPONENT_LENGTH:uCe}});var fd=w((A$e,JH)=>{var gCe=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...r)=>console.error("SEMVER",...r):()=>{};JH.exports=gCe});var uc=w((NA,WH)=>{var{MAX_SAFE_COMPONENT_LENGTH:dv}=gd(),fCe=fd();NA=WH.exports={};var hCe=NA.re=[],et=NA.src=[],tt=NA.t={},pCe=0,St=(r,e,t)=>{let i=pCe++;fCe(i,e),tt[r]=i,et[i]=e,hCe[i]=new RegExp(e,t?"g":void 0)};St("NUMERICIDENTIFIER","0|[1-9]\\d*");St("NUMERICIDENTIFIERLOOSE","[0-9]+");St("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*");St("MAINVERSION",`(${et[tt.NUMERICIDENTIFIER]})\\.(${et[tt.NUMERICIDENTIFIER]})\\.(${et[tt.NUMERICIDENTIFIER]})`);St("MAINVERSIONLOOSE",`(${et[tt.NUMERICIDENTIFIERLOOSE]})\\.(${et[tt.NUMERICIDENTIFIERLOOSE]})\\.(${et[tt.NUMERICIDENTIFIERLOOSE]})`);St("PRERELEASEIDENTIFIER",`(?:${et[tt.NUMERICIDENTIFIER]}|${et[tt.NONNUMERICIDENTIFIER]})`);St("PRERELEASEIDENTIFIERLOOSE",`(?:${et[tt.NUMERICIDENTIFIERLOOSE]}|${et[tt.NONNUMERICIDENTIFIER]})`);St("PRERELEASE",`(?:-(${et[tt.PRERELEASEIDENTIFIER]}(?:\\.${et[tt.PRERELEASEIDENTIFIER]})*))`);St("PRERELEASELOOSE",`(?:-?(${et[tt.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${et[tt.PRERELEASEIDENTIFIERLOOSE]})*))`);St("BUILDIDENTIFIER","[0-9A-Za-z-]+");St("BUILD",`(?:\\+(${et[tt.BUILDIDENTIFIER]}(?:\\.${et[tt.BUILDIDENTIFIER]})*))`);St("FULLPLAIN",`v?${et[tt.MAINVERSION]}${et[tt.PRERELEASE]}?${et[tt.BUILD]}?`);St("FULL",`^${et[tt.FULLPLAIN]}$`);St("LOOSEPLAIN",`[v=\\s]*${et[tt.MAINVERSIONLOOSE]}${et[tt.PRERELEASELOOSE]}?${et[tt.BUILD]}?`);St("LOOSE",`^${et[tt.LOOSEPLAIN]}$`);St("GTLT","((?:<|>)?=?)");St("XRANGEIDENTIFIERLOOSE",`${et[tt.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);St("XRANGEIDENTIFIER",`${et[tt.NUMERICIDENTIFIER]}|x|X|\\*`);St("XRANGEPLAIN",`[v=\\s]*(${et[tt.XRANGEIDENTIFIER]})(?:\\.(${et[tt.XRANGEIDENTIFIER]})(?:\\.(${et[tt.XRANGEIDENTIFIER]})(?:${et[tt.PRERELEASE]})?${et[tt.BUILD]}?)?)?`);St("XRANGEPLAINLOOSE",`[v=\\s]*(${et[tt.XRANGEIDENTIFIERLOOSE]})(?:\\.(${et[tt.XRANGEIDENTIFIERLOOSE]})(?:\\.(${et[tt.XRANGEIDENTIFIERLOOSE]})(?:${et[tt.PRERELEASELOOSE]})?${et[tt.BUILD]}?)?)?`);St("XRANGE",`^${et[tt.GTLT]}\\s*${et[tt.XRANGEPLAIN]}$`);St("XRANGELOOSE",`^${et[tt.GTLT]}\\s*${et[tt.XRANGEPLAINLOOSE]}$`);St("COERCE",`(^|[^\\d])(\\d{1,${dv}})(?:\\.(\\d{1,${dv}}))?(?:\\.(\\d{1,${dv}}))?(?:$|[^\\d])`);St("COERCERTL",et[tt.COERCE],!0);St("LONETILDE","(?:~>?)");St("TILDETRIM",`(\\s*)${et[tt.LONETILDE]}\\s+`,!0);NA.tildeTrimReplace="$1~";St("TILDE",`^${et[tt.LONETILDE]}${et[tt.XRANGEPLAIN]}$`);St("TILDELOOSE",`^${et[tt.LONETILDE]}${et[tt.XRANGEPLAINLOOSE]}$`);St("LONECARET","(?:\\^)");St("CARETTRIM",`(\\s*)${et[tt.LONECARET]}\\s+`,!0);NA.caretTrimReplace="$1^";St("CARET",`^${et[tt.LONECARET]}${et[tt.XRANGEPLAIN]}$`);St("CARETLOOSE",`^${et[tt.LONECARET]}${et[tt.XRANGEPLAINLOOSE]}$`);St("COMPARATORLOOSE",`^${et[tt.GTLT]}\\s*(${et[tt.LOOSEPLAIN]})$|^$`);St("COMPARATOR",`^${et[tt.GTLT]}\\s*(${et[tt.FULLPLAIN]})$|^$`);St("COMPARATORTRIM",`(\\s*)${et[tt.GTLT]}\\s*(${et[tt.LOOSEPLAIN]}|${et[tt.XRANGEPLAIN]})`,!0);NA.comparatorTrimReplace="$1$2$3";St("HYPHENRANGE",`^\\s*(${et[tt.XRANGEPLAIN]})\\s+-\\s+(${et[tt.XRANGEPLAIN]})\\s*$`);St("HYPHENRANGELOOSE",`^\\s*(${et[tt.XRANGEPLAINLOOSE]})\\s+-\\s+(${et[tt.XRANGEPLAINLOOSE]})\\s*$`);St("STAR","(<|>)?=?\\s*\\*");St("GTE0","^\\s*>=\\s*0.0.0\\s*$");St("GTE0PRE","^\\s*>=\\s*0.0.0-0\\s*$")});var hd=w((l$e,zH)=>{var dCe=["includePrerelease","loose","rtl"],CCe=r=>r?typeof r!="object"?{loose:!0}:dCe.filter(e=>r[e]).reduce((e,t)=>(e[t]=!0,e),{}):{};zH.exports=CCe});var OI=w((c$e,ZH)=>{var VH=/^[0-9]+$/,XH=(r,e)=>{let t=VH.test(r),i=VH.test(e);return t&&i&&(r=+r,e=+e),r===e?0:t&&!i?-1:i&&!t?1:rXH(e,r);ZH.exports={compareIdentifiers:XH,rcompareIdentifiers:mCe}});var Ti=w((u$e,tG)=>{var MI=fd(),{MAX_LENGTH:_H,MAX_SAFE_INTEGER:UI}=gd(),{re:$H,t:eG}=uc(),ECe=hd(),{compareIdentifiers:pd}=OI(),Gn=class{constructor(e,t){if(t=ECe(t),e instanceof Gn){if(e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease)return e;e=e.version}else if(typeof e!="string")throw new TypeError(`Invalid Version: ${e}`);if(e.length>_H)throw new TypeError(`version is longer than ${_H} characters`);MI("SemVer",e,t),this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease;let i=e.trim().match(t.loose?$H[eG.LOOSE]:$H[eG.FULL]);if(!i)throw new TypeError(`Invalid Version: ${e}`);if(this.raw=e,this.major=+i[1],this.minor=+i[2],this.patch=+i[3],this.major>UI||this.major<0)throw new TypeError("Invalid major version");if(this.minor>UI||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>UI||this.patch<0)throw new TypeError("Invalid patch version");i[4]?this.prerelease=i[4].split(".").map(n=>{if(/^[0-9]+$/.test(n)){let s=+n;if(s>=0&&s=0;)typeof this.prerelease[i]=="number"&&(this.prerelease[i]++,i=-2);i===-1&&this.prerelease.push(0)}t&&(this.prerelease[0]===t?isNaN(this.prerelease[1])&&(this.prerelease=[t,0]):this.prerelease=[t,0]);break;default:throw new Error(`invalid increment argument: ${e}`)}return this.format(),this.raw=this.version,this}};tG.exports=Gn});var gc=w((g$e,sG)=>{var{MAX_LENGTH:ICe}=gd(),{re:rG,t:iG}=uc(),nG=Ti(),yCe=hd(),wCe=(r,e)=>{if(e=yCe(e),r instanceof nG)return r;if(typeof r!="string"||r.length>ICe||!(e.loose?rG[iG.LOOSE]:rG[iG.FULL]).test(r))return null;try{return new nG(r,e)}catch{return null}};sG.exports=wCe});var aG=w((f$e,oG)=>{var BCe=gc(),QCe=(r,e)=>{let t=BCe(r,e);return t?t.version:null};oG.exports=QCe});var lG=w((h$e,AG)=>{var bCe=gc(),SCe=(r,e)=>{let t=bCe(r.trim().replace(/^[=v]+/,""),e);return t?t.version:null};AG.exports=SCe});var uG=w((p$e,cG)=>{var vCe=Ti(),xCe=(r,e,t,i)=>{typeof t=="string"&&(i=t,t=void 0);try{return new vCe(r,t).inc(e,i).version}catch{return null}};cG.exports=xCe});var cs=w((d$e,fG)=>{var gG=Ti(),PCe=(r,e,t)=>new gG(r,t).compare(new gG(e,t));fG.exports=PCe});var KI=w((C$e,hG)=>{var DCe=cs(),kCe=(r,e,t)=>DCe(r,e,t)===0;hG.exports=kCe});var CG=w((m$e,dG)=>{var pG=gc(),RCe=KI(),FCe=(r,e)=>{if(RCe(r,e))return null;{let t=pG(r),i=pG(e),n=t.prerelease.length||i.prerelease.length,s=n?"pre":"",o=n?"prerelease":"";for(let a in t)if((a==="major"||a==="minor"||a==="patch")&&t[a]!==i[a])return s+a;return o}};dG.exports=FCe});var EG=w((E$e,mG)=>{var NCe=Ti(),LCe=(r,e)=>new NCe(r,e).major;mG.exports=LCe});var yG=w((I$e,IG)=>{var TCe=Ti(),OCe=(r,e)=>new TCe(r,e).minor;IG.exports=OCe});var BG=w((y$e,wG)=>{var MCe=Ti(),UCe=(r,e)=>new MCe(r,e).patch;wG.exports=UCe});var bG=w((w$e,QG)=>{var KCe=gc(),HCe=(r,e)=>{let t=KCe(r,e);return t&&t.prerelease.length?t.prerelease:null};QG.exports=HCe});var vG=w((B$e,SG)=>{var GCe=cs(),YCe=(r,e,t)=>GCe(e,r,t);SG.exports=YCe});var PG=w((Q$e,xG)=>{var jCe=cs(),qCe=(r,e)=>jCe(r,e,!0);xG.exports=qCe});var HI=w((b$e,kG)=>{var DG=Ti(),JCe=(r,e,t)=>{let i=new DG(r,t),n=new DG(e,t);return i.compare(n)||i.compareBuild(n)};kG.exports=JCe});var FG=w((S$e,RG)=>{var WCe=HI(),zCe=(r,e)=>r.sort((t,i)=>WCe(t,i,e));RG.exports=zCe});var LG=w((v$e,NG)=>{var VCe=HI(),XCe=(r,e)=>r.sort((t,i)=>VCe(i,t,e));NG.exports=XCe});var dd=w((x$e,TG)=>{var ZCe=cs(),_Ce=(r,e,t)=>ZCe(r,e,t)>0;TG.exports=_Ce});var GI=w((P$e,OG)=>{var $Ce=cs(),eme=(r,e,t)=>$Ce(r,e,t)<0;OG.exports=eme});var Cv=w((D$e,MG)=>{var tme=cs(),rme=(r,e,t)=>tme(r,e,t)!==0;MG.exports=rme});var YI=w((k$e,UG)=>{var ime=cs(),nme=(r,e,t)=>ime(r,e,t)>=0;UG.exports=nme});var jI=w((R$e,KG)=>{var sme=cs(),ome=(r,e,t)=>sme(r,e,t)<=0;KG.exports=ome});var mv=w((F$e,HG)=>{var ame=KI(),Ame=Cv(),lme=dd(),cme=YI(),ume=GI(),gme=jI(),fme=(r,e,t,i)=>{switch(e){case"===":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r===t;case"!==":return typeof r=="object"&&(r=r.version),typeof t=="object"&&(t=t.version),r!==t;case"":case"=":case"==":return ame(r,t,i);case"!=":return Ame(r,t,i);case">":return lme(r,t,i);case">=":return cme(r,t,i);case"<":return ume(r,t,i);case"<=":return gme(r,t,i);default:throw new TypeError(`Invalid operator: ${e}`)}};HG.exports=fme});var YG=w((N$e,GG)=>{var hme=Ti(),pme=gc(),{re:qI,t:JI}=uc(),dme=(r,e)=>{if(r instanceof hme)return r;if(typeof r=="number"&&(r=String(r)),typeof r!="string")return null;e=e||{};let t=null;if(!e.rtl)t=r.match(qI[JI.COERCE]);else{let i;for(;(i=qI[JI.COERCERTL].exec(r))&&(!t||t.index+t[0].length!==r.length);)(!t||i.index+i[0].length!==t.index+t[0].length)&&(t=i),qI[JI.COERCERTL].lastIndex=i.index+i[1].length+i[2].length;qI[JI.COERCERTL].lastIndex=-1}return t===null?null:pme(`${t[2]}.${t[3]||"0"}.${t[4]||"0"}`,e)};GG.exports=dme});var qG=w((L$e,jG)=>{"use strict";jG.exports=function(r){r.prototype[Symbol.iterator]=function*(){for(let e=this.head;e;e=e.next)yield e.value}}});var WI=w((T$e,JG)=>{"use strict";JG.exports=Ht;Ht.Node=fc;Ht.create=Ht;function Ht(r){var e=this;if(e instanceof Ht||(e=new Ht),e.tail=null,e.head=null,e.length=0,r&&typeof r.forEach=="function")r.forEach(function(n){e.push(n)});else if(arguments.length>0)for(var t=0,i=arguments.length;t1)t=e;else if(this.head)i=this.head.next,t=this.head.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=0;i!==null;n++)t=r(t,i.value,n),i=i.next;return t};Ht.prototype.reduceReverse=function(r,e){var t,i=this.tail;if(arguments.length>1)t=e;else if(this.tail)i=this.tail.prev,t=this.tail.value;else throw new TypeError("Reduce of empty list with no initial value");for(var n=this.length-1;i!==null;n--)t=r(t,i.value,n),i=i.prev;return t};Ht.prototype.toArray=function(){for(var r=new Array(this.length),e=0,t=this.head;t!==null;e++)r[e]=t.value,t=t.next;return r};Ht.prototype.toArrayReverse=function(){for(var r=new Array(this.length),e=0,t=this.tail;t!==null;e++)r[e]=t.value,t=t.prev;return r};Ht.prototype.slice=function(r,e){e=e||this.length,e<0&&(e+=this.length),r=r||0,r<0&&(r+=this.length);var t=new Ht;if(ethis.length&&(e=this.length);for(var i=0,n=this.head;n!==null&&ithis.length&&(e=this.length);for(var i=this.length,n=this.tail;n!==null&&i>e;i--)n=n.prev;for(;n!==null&&i>r;i--,n=n.prev)t.push(n.value);return t};Ht.prototype.splice=function(r,e,...t){r>this.length&&(r=this.length-1),r<0&&(r=this.length+r);for(var i=0,n=this.head;n!==null&&i{"use strict";var Ime=WI(),hc=Symbol("max"),Sa=Symbol("length"),Wg=Symbol("lengthCalculator"),md=Symbol("allowStale"),pc=Symbol("maxAge"),ba=Symbol("dispose"),WG=Symbol("noDisposeOnSet"),di=Symbol("lruList"),Zs=Symbol("cache"),VG=Symbol("updateAgeOnGet"),Ev=()=>1,yv=class{constructor(e){if(typeof e=="number"&&(e={max:e}),e||(e={}),e.max&&(typeof e.max!="number"||e.max<0))throw new TypeError("max must be a non-negative number");let t=this[hc]=e.max||1/0,i=e.length||Ev;if(this[Wg]=typeof i!="function"?Ev:i,this[md]=e.stale||!1,e.maxAge&&typeof e.maxAge!="number")throw new TypeError("maxAge must be a number");this[pc]=e.maxAge||0,this[ba]=e.dispose,this[WG]=e.noDisposeOnSet||!1,this[VG]=e.updateAgeOnGet||!1,this.reset()}set max(e){if(typeof e!="number"||e<0)throw new TypeError("max must be a non-negative number");this[hc]=e||1/0,Cd(this)}get max(){return this[hc]}set allowStale(e){this[md]=!!e}get allowStale(){return this[md]}set maxAge(e){if(typeof e!="number")throw new TypeError("maxAge must be a non-negative number");this[pc]=e,Cd(this)}get maxAge(){return this[pc]}set lengthCalculator(e){typeof e!="function"&&(e=Ev),e!==this[Wg]&&(this[Wg]=e,this[Sa]=0,this[di].forEach(t=>{t.length=this[Wg](t.value,t.key),this[Sa]+=t.length})),Cd(this)}get lengthCalculator(){return this[Wg]}get length(){return this[Sa]}get itemCount(){return this[di].length}rforEach(e,t){t=t||this;for(let i=this[di].tail;i!==null;){let n=i.prev;zG(this,e,i,t),i=n}}forEach(e,t){t=t||this;for(let i=this[di].head;i!==null;){let n=i.next;zG(this,e,i,t),i=n}}keys(){return this[di].toArray().map(e=>e.key)}values(){return this[di].toArray().map(e=>e.value)}reset(){this[ba]&&this[di]&&this[di].length&&this[di].forEach(e=>this[ba](e.key,e.value)),this[Zs]=new Map,this[di]=new Ime,this[Sa]=0}dump(){return this[di].map(e=>zI(this,e)?!1:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}).toArray().filter(e=>e)}dumpLru(){return this[di]}set(e,t,i){if(i=i||this[pc],i&&typeof i!="number")throw new TypeError("maxAge must be a number");let n=i?Date.now():0,s=this[Wg](t,e);if(this[Zs].has(e)){if(s>this[hc])return zg(this,this[Zs].get(e)),!1;let l=this[Zs].get(e).value;return this[ba]&&(this[WG]||this[ba](e,l.value)),l.now=n,l.maxAge=i,l.value=t,this[Sa]+=s-l.length,l.length=s,this.get(e),Cd(this),!0}let o=new wv(e,t,s,n,i);return o.length>this[hc]?(this[ba]&&this[ba](e,t),!1):(this[Sa]+=o.length,this[di].unshift(o),this[Zs].set(e,this[di].head),Cd(this),!0)}has(e){if(!this[Zs].has(e))return!1;let t=this[Zs].get(e).value;return!zI(this,t)}get(e){return Iv(this,e,!0)}peek(e){return Iv(this,e,!1)}pop(){let e=this[di].tail;return e?(zg(this,e),e.value):null}del(e){zg(this,this[Zs].get(e))}load(e){this.reset();let t=Date.now();for(let i=e.length-1;i>=0;i--){let n=e[i],s=n.e||0;if(s===0)this.set(n.k,n.v);else{let o=s-t;o>0&&this.set(n.k,n.v,o)}}}prune(){this[Zs].forEach((e,t)=>Iv(this,t,!1))}},Iv=(r,e,t)=>{let i=r[Zs].get(e);if(i){let n=i.value;if(zI(r,n)){if(zg(r,i),!r[md])return}else t&&(r[VG]&&(i.value.now=Date.now()),r[di].unshiftNode(i));return n.value}},zI=(r,e)=>{if(!e||!e.maxAge&&!r[pc])return!1;let t=Date.now()-e.now;return e.maxAge?t>e.maxAge:r[pc]&&t>r[pc]},Cd=r=>{if(r[Sa]>r[hc])for(let e=r[di].tail;r[Sa]>r[hc]&&e!==null;){let t=e.prev;zg(r,e),e=t}},zg=(r,e)=>{if(e){let t=e.value;r[ba]&&r[ba](t.key,t.value),r[Sa]-=t.length,r[Zs].delete(t.key),r[di].removeNode(e)}},wv=class{constructor(e,t,i,n,s){this.key=e,this.value=t,this.length=i,this.now=n,this.maxAge=s||0}},zG=(r,e,t,i)=>{let n=t.value;zI(r,n)&&(zg(r,t),r[md]||(n=void 0)),n&&e.call(i,n.value,n.key,r)};XG.exports=yv});var us=w((M$e,tY)=>{var dc=class{constructor(e,t){if(t=wme(t),e instanceof dc)return e.loose===!!t.loose&&e.includePrerelease===!!t.includePrerelease?e:new dc(e.raw,t);if(e instanceof Bv)return this.raw=e.value,this.set=[[e]],this.format(),this;if(this.options=t,this.loose=!!t.loose,this.includePrerelease=!!t.includePrerelease,this.raw=e,this.set=e.split(/\s*\|\|\s*/).map(i=>this.parseRange(i.trim())).filter(i=>i.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${e}`);if(this.set.length>1){let i=this.set[0];if(this.set=this.set.filter(n=>!$G(n[0])),this.set.length===0)this.set=[i];else if(this.set.length>1){for(let n of this.set)if(n.length===1&&vme(n[0])){this.set=[n];break}}}this.format()}format(){return this.range=this.set.map(e=>e.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(e){e=e.trim();let i=`parseRange:${Object.keys(this.options).join(",")}:${e}`,n=_G.get(i);if(n)return n;let s=this.options.loose,o=s?Oi[Qi.HYPHENRANGELOOSE]:Oi[Qi.HYPHENRANGE];e=e.replace(o,Ome(this.options.includePrerelease)),Gr("hyphen replace",e),e=e.replace(Oi[Qi.COMPARATORTRIM],Qme),Gr("comparator trim",e,Oi[Qi.COMPARATORTRIM]),e=e.replace(Oi[Qi.TILDETRIM],bme),e=e.replace(Oi[Qi.CARETTRIM],Sme),e=e.split(/\s+/).join(" ");let a=s?Oi[Qi.COMPARATORLOOSE]:Oi[Qi.COMPARATOR],l=e.split(" ").map(f=>xme(f,this.options)).join(" ").split(/\s+/).map(f=>Tme(f,this.options)).filter(this.options.loose?f=>!!f.match(a):()=>!0).map(f=>new Bv(f,this.options)),c=l.length,u=new Map;for(let f of l){if($G(f))return[f];u.set(f.value,f)}u.size>1&&u.has("")&&u.delete("");let g=[...u.values()];return _G.set(i,g),g}intersects(e,t){if(!(e instanceof dc))throw new TypeError("a Range is required");return this.set.some(i=>eY(i,t)&&e.set.some(n=>eY(n,t)&&i.every(s=>n.every(o=>s.intersects(o,t)))))}test(e){if(!e)return!1;if(typeof e=="string")try{e=new Bme(e,this.options)}catch{return!1}for(let t=0;tr.value==="<0.0.0-0",vme=r=>r.value==="",eY=(r,e)=>{let t=!0,i=r.slice(),n=i.pop();for(;t&&i.length;)t=i.every(s=>n.intersects(s,e)),n=i.pop();return t},xme=(r,e)=>(Gr("comp",r,e),r=kme(r,e),Gr("caret",r),r=Pme(r,e),Gr("tildes",r),r=Fme(r,e),Gr("xrange",r),r=Lme(r,e),Gr("stars",r),r),_i=r=>!r||r.toLowerCase()==="x"||r==="*",Pme=(r,e)=>r.trim().split(/\s+/).map(t=>Dme(t,e)).join(" "),Dme=(r,e)=>{let t=e.loose?Oi[Qi.TILDELOOSE]:Oi[Qi.TILDE];return r.replace(t,(i,n,s,o,a)=>{Gr("tilde",r,i,n,s,o,a);let l;return _i(n)?l="":_i(s)?l=`>=${n}.0.0 <${+n+1}.0.0-0`:_i(o)?l=`>=${n}.${s}.0 <${n}.${+s+1}.0-0`:a?(Gr("replaceTilde pr",a),l=`>=${n}.${s}.${o}-${a} <${n}.${+s+1}.0-0`):l=`>=${n}.${s}.${o} <${n}.${+s+1}.0-0`,Gr("tilde return",l),l})},kme=(r,e)=>r.trim().split(/\s+/).map(t=>Rme(t,e)).join(" "),Rme=(r,e)=>{Gr("caret",r,e);let t=e.loose?Oi[Qi.CARETLOOSE]:Oi[Qi.CARET],i=e.includePrerelease?"-0":"";return r.replace(t,(n,s,o,a,l)=>{Gr("caret",r,n,s,o,a,l);let c;return _i(s)?c="":_i(o)?c=`>=${s}.0.0${i} <${+s+1}.0.0-0`:_i(a)?s==="0"?c=`>=${s}.${o}.0${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.0${i} <${+s+1}.0.0-0`:l?(Gr("replaceCaret pr",l),s==="0"?o==="0"?c=`>=${s}.${o}.${a}-${l} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}-${l} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a}-${l} <${+s+1}.0.0-0`):(Gr("no pr"),s==="0"?o==="0"?c=`>=${s}.${o}.${a}${i} <${s}.${o}.${+a+1}-0`:c=`>=${s}.${o}.${a}${i} <${s}.${+o+1}.0-0`:c=`>=${s}.${o}.${a} <${+s+1}.0.0-0`),Gr("caret return",c),c})},Fme=(r,e)=>(Gr("replaceXRanges",r,e),r.split(/\s+/).map(t=>Nme(t,e)).join(" ")),Nme=(r,e)=>{r=r.trim();let t=e.loose?Oi[Qi.XRANGELOOSE]:Oi[Qi.XRANGE];return r.replace(t,(i,n,s,o,a,l)=>{Gr("xRange",r,i,n,s,o,a,l);let c=_i(s),u=c||_i(o),g=u||_i(a),f=g;return n==="="&&f&&(n=""),l=e.includePrerelease?"-0":"",c?n===">"||n==="<"?i="<0.0.0-0":i="*":n&&f?(u&&(o=0),a=0,n===">"?(n=">=",u?(s=+s+1,o=0,a=0):(o=+o+1,a=0)):n==="<="&&(n="<",u?s=+s+1:o=+o+1),n==="<"&&(l="-0"),i=`${n+s}.${o}.${a}${l}`):u?i=`>=${s}.0.0${l} <${+s+1}.0.0-0`:g&&(i=`>=${s}.${o}.0${l} <${s}.${+o+1}.0-0`),Gr("xRange return",i),i})},Lme=(r,e)=>(Gr("replaceStars",r,e),r.trim().replace(Oi[Qi.STAR],"")),Tme=(r,e)=>(Gr("replaceGTE0",r,e),r.trim().replace(Oi[e.includePrerelease?Qi.GTE0PRE:Qi.GTE0],"")),Ome=r=>(e,t,i,n,s,o,a,l,c,u,g,f,h)=>(_i(i)?t="":_i(n)?t=`>=${i}.0.0${r?"-0":""}`:_i(s)?t=`>=${i}.${n}.0${r?"-0":""}`:o?t=`>=${t}`:t=`>=${t}${r?"-0":""}`,_i(c)?l="":_i(u)?l=`<${+c+1}.0.0-0`:_i(g)?l=`<${c}.${+u+1}.0-0`:f?l=`<=${c}.${u}.${g}-${f}`:r?l=`<${c}.${u}.${+g+1}-0`:l=`<=${l}`,`${t} ${l}`.trim()),Mme=(r,e,t)=>{for(let i=0;i0){let n=r[i].semver;if(n.major===e.major&&n.minor===e.minor&&n.patch===e.patch)return!0}return!1}return!0}});var Ed=w((U$e,oY)=>{var Id=Symbol("SemVer ANY"),Vg=class{static get ANY(){return Id}constructor(e,t){if(t=Ume(t),e instanceof Vg){if(e.loose===!!t.loose)return e;e=e.value}bv("comparator",e,t),this.options=t,this.loose=!!t.loose,this.parse(e),this.semver===Id?this.value="":this.value=this.operator+this.semver.version,bv("comp",this)}parse(e){let t=this.options.loose?rY[iY.COMPARATORLOOSE]:rY[iY.COMPARATOR],i=e.match(t);if(!i)throw new TypeError(`Invalid comparator: ${e}`);this.operator=i[1]!==void 0?i[1]:"",this.operator==="="&&(this.operator=""),i[2]?this.semver=new nY(i[2],this.options.loose):this.semver=Id}toString(){return this.value}test(e){if(bv("Comparator.test",e,this.options.loose),this.semver===Id||e===Id)return!0;if(typeof e=="string")try{e=new nY(e,this.options)}catch{return!1}return Qv(e,this.operator,this.semver,this.options)}intersects(e,t){if(!(e instanceof Vg))throw new TypeError("a Comparator is required");if((!t||typeof t!="object")&&(t={loose:!!t,includePrerelease:!1}),this.operator==="")return this.value===""?!0:new sY(e.value,t).test(this.value);if(e.operator==="")return e.value===""?!0:new sY(this.value,t).test(e.semver);let i=(this.operator===">="||this.operator===">")&&(e.operator===">="||e.operator===">"),n=(this.operator==="<="||this.operator==="<")&&(e.operator==="<="||e.operator==="<"),s=this.semver.version===e.semver.version,o=(this.operator===">="||this.operator==="<=")&&(e.operator===">="||e.operator==="<="),a=Qv(this.semver,"<",e.semver,t)&&(this.operator===">="||this.operator===">")&&(e.operator==="<="||e.operator==="<"),l=Qv(this.semver,">",e.semver,t)&&(this.operator==="<="||this.operator==="<")&&(e.operator===">="||e.operator===">");return i||n||s&&o||a||l}};oY.exports=Vg;var Ume=hd(),{re:rY,t:iY}=uc(),Qv=mv(),bv=fd(),nY=Ti(),sY=us()});var yd=w((K$e,aY)=>{var Kme=us(),Hme=(r,e,t)=>{try{e=new Kme(e,t)}catch{return!1}return e.test(r)};aY.exports=Hme});var lY=w((H$e,AY)=>{var Gme=us(),Yme=(r,e)=>new Gme(r,e).set.map(t=>t.map(i=>i.value).join(" ").trim().split(" "));AY.exports=Yme});var uY=w((G$e,cY)=>{var jme=Ti(),qme=us(),Jme=(r,e,t)=>{let i=null,n=null,s=null;try{s=new qme(e,t)}catch{return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===-1)&&(i=o,n=new jme(i,t))}),i};cY.exports=Jme});var fY=w((Y$e,gY)=>{var Wme=Ti(),zme=us(),Vme=(r,e,t)=>{let i=null,n=null,s=null;try{s=new zme(e,t)}catch{return null}return r.forEach(o=>{s.test(o)&&(!i||n.compare(o)===1)&&(i=o,n=new Wme(i,t))}),i};gY.exports=Vme});var dY=w((j$e,pY)=>{var Sv=Ti(),Xme=us(),hY=dd(),Zme=(r,e)=>{r=new Xme(r,e);let t=new Sv("0.0.0");if(r.test(t)||(t=new Sv("0.0.0-0"),r.test(t)))return t;t=null;for(let i=0;i{let a=new Sv(o.semver.version);switch(o.operator){case">":a.prerelease.length===0?a.patch++:a.prerelease.push(0),a.raw=a.format();case"":case">=":(!s||hY(a,s))&&(s=a);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${o.operator}`)}}),s&&(!t||hY(t,s))&&(t=s)}return t&&r.test(t)?t:null};pY.exports=Zme});var mY=w((q$e,CY)=>{var _me=us(),$me=(r,e)=>{try{return new _me(r,e).range||"*"}catch{return null}};CY.exports=$me});var VI=w((J$e,wY)=>{var eEe=Ti(),yY=Ed(),{ANY:tEe}=yY,rEe=us(),iEe=yd(),EY=dd(),IY=GI(),nEe=jI(),sEe=YI(),oEe=(r,e,t,i)=>{r=new eEe(r,i),e=new rEe(e,i);let n,s,o,a,l;switch(t){case">":n=EY,s=nEe,o=IY,a=">",l=">=";break;case"<":n=IY,s=sEe,o=EY,a="<",l="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(iEe(r,e,i))return!1;for(let c=0;c{h.semver===tEe&&(h=new yY(">=0.0.0")),g=g||h,f=f||h,n(h.semver,g.semver,i)?g=h:o(h.semver,f.semver,i)&&(f=h)}),g.operator===a||g.operator===l||(!f.operator||f.operator===a)&&s(r,f.semver))return!1;if(f.operator===l&&o(r,f.semver))return!1}return!0};wY.exports=oEe});var QY=w((W$e,BY)=>{var aEe=VI(),AEe=(r,e,t)=>aEe(r,e,">",t);BY.exports=AEe});var SY=w((z$e,bY)=>{var lEe=VI(),cEe=(r,e,t)=>lEe(r,e,"<",t);bY.exports=cEe});var PY=w((V$e,xY)=>{var vY=us(),uEe=(r,e,t)=>(r=new vY(r,t),e=new vY(e,t),r.intersects(e));xY.exports=uEe});var kY=w((X$e,DY)=>{var gEe=yd(),fEe=cs();DY.exports=(r,e,t)=>{let i=[],n=null,s=null,o=r.sort((u,g)=>fEe(u,g,t));for(let u of o)gEe(u,e,t)?(s=u,n||(n=u)):(s&&i.push([n,s]),s=null,n=null);n&&i.push([n,null]);let a=[];for(let[u,g]of i)u===g?a.push(u):!g&&u===o[0]?a.push("*"):g?u===o[0]?a.push(`<=${g}`):a.push(`${u} - ${g}`):a.push(`>=${u}`);let l=a.join(" || "),c=typeof e.raw=="string"?e.raw:String(e);return l.length{var RY=us(),XI=Ed(),{ANY:vv}=XI,wd=yd(),xv=cs(),hEe=(r,e,t={})=>{if(r===e)return!0;r=new RY(r,t),e=new RY(e,t);let i=!1;e:for(let n of r.set){for(let s of e.set){let o=pEe(n,s,t);if(i=i||o!==null,o)continue e}if(i)return!1}return!0},pEe=(r,e,t)=>{if(r===e)return!0;if(r.length===1&&r[0].semver===vv){if(e.length===1&&e[0].semver===vv)return!0;t.includePrerelease?r=[new XI(">=0.0.0-0")]:r=[new XI(">=0.0.0")]}if(e.length===1&&e[0].semver===vv){if(t.includePrerelease)return!0;e=[new XI(">=0.0.0")]}let i=new Set,n,s;for(let h of r)h.operator===">"||h.operator===">="?n=FY(n,h,t):h.operator==="<"||h.operator==="<="?s=NY(s,h,t):i.add(h.semver);if(i.size>1)return null;let o;if(n&&s){if(o=xv(n.semver,s.semver,t),o>0)return null;if(o===0&&(n.operator!==">="||s.operator!=="<="))return null}for(let h of i){if(n&&!wd(h,String(n),t)||s&&!wd(h,String(s),t))return null;for(let p of e)if(!wd(h,String(p),t))return!1;return!0}let a,l,c,u,g=s&&!t.includePrerelease&&s.semver.prerelease.length?s.semver:!1,f=n&&!t.includePrerelease&&n.semver.prerelease.length?n.semver:!1;g&&g.prerelease.length===1&&s.operator==="<"&&g.prerelease[0]===0&&(g=!1);for(let h of e){if(u=u||h.operator===">"||h.operator===">=",c=c||h.operator==="<"||h.operator==="<=",n){if(f&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===f.major&&h.semver.minor===f.minor&&h.semver.patch===f.patch&&(f=!1),h.operator===">"||h.operator===">="){if(a=FY(n,h,t),a===h&&a!==n)return!1}else if(n.operator===">="&&!wd(n.semver,String(h),t))return!1}if(s){if(g&&h.semver.prerelease&&h.semver.prerelease.length&&h.semver.major===g.major&&h.semver.minor===g.minor&&h.semver.patch===g.patch&&(g=!1),h.operator==="<"||h.operator==="<="){if(l=NY(s,h,t),l===h&&l!==s)return!1}else if(s.operator==="<="&&!wd(s.semver,String(h),t))return!1}if(!h.operator&&(s||n)&&o!==0)return!1}return!(n&&c&&!s&&o!==0||s&&u&&!n&&o!==0||f||g)},FY=(r,e,t)=>{if(!r)return e;let i=xv(r.semver,e.semver,t);return i>0?r:i<0||e.operator===">"&&r.operator===">="?e:r},NY=(r,e,t)=>{if(!r)return e;let i=xv(r.semver,e.semver,t);return i<0?r:i>0||e.operator==="<"&&r.operator==="<="?e:r};LY.exports=hEe});var Xr=w((_$e,OY)=>{var Pv=uc();OY.exports={re:Pv.re,src:Pv.src,tokens:Pv.t,SEMVER_SPEC_VERSION:gd().SEMVER_SPEC_VERSION,SemVer:Ti(),compareIdentifiers:OI().compareIdentifiers,rcompareIdentifiers:OI().rcompareIdentifiers,parse:gc(),valid:aG(),clean:lG(),inc:uG(),diff:CG(),major:EG(),minor:yG(),patch:BG(),prerelease:bG(),compare:cs(),rcompare:vG(),compareLoose:PG(),compareBuild:HI(),sort:FG(),rsort:LG(),gt:dd(),lt:GI(),eq:KI(),neq:Cv(),gte:YI(),lte:jI(),cmp:mv(),coerce:YG(),Comparator:Ed(),Range:us(),satisfies:yd(),toComparators:lY(),maxSatisfying:uY(),minSatisfying:fY(),minVersion:dY(),validRange:mY(),outside:VI(),gtr:QY(),ltr:SY(),intersects:PY(),simplifyRange:kY(),subset:TY()}});var Dv=w(ZI=>{"use strict";Object.defineProperty(ZI,"__esModule",{value:!0});ZI.VERSION=void 0;ZI.VERSION="9.1.0"});var Gt=w((exports,module)=>{"use strict";var __spreadArray=exports&&exports.__spreadArray||function(r,e,t){if(t||arguments.length===2)for(var i=0,n=e.length,s;i{(function(r,e){typeof define=="function"&&define.amd?define([],e):typeof _I=="object"&&_I.exports?_I.exports=e():r.regexpToAst=e()})(typeof self<"u"?self:MY,function(){function r(){}r.prototype.saveState=function(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}},r.prototype.restoreState=function(p){this.idx=p.idx,this.input=p.input,this.groupIdx=p.groupIdx},r.prototype.pattern=function(p){this.idx=0,this.input=p,this.groupIdx=0,this.consumeChar("/");var C=this.disjunction();this.consumeChar("/");for(var y={type:"Flags",loc:{begin:this.idx,end:p.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};this.isRegExpFlag();)switch(this.popChar()){case"g":o(y,"global");break;case"i":o(y,"ignoreCase");break;case"m":o(y,"multiLine");break;case"u":o(y,"unicode");break;case"y":o(y,"sticky");break}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:y,value:C,loc:this.loc(0)}},r.prototype.disjunction=function(){var p=[],C=this.idx;for(p.push(this.alternative());this.peekChar()==="|";)this.consumeChar("|"),p.push(this.alternative());return{type:"Disjunction",value:p,loc:this.loc(C)}},r.prototype.alternative=function(){for(var p=[],C=this.idx;this.isTerm();)p.push(this.term());return{type:"Alternative",value:p,loc:this.loc(C)}},r.prototype.term=function(){return this.isAssertion()?this.assertion():this.atom()},r.prototype.assertion=function(){var p=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(p)};case"$":return{type:"EndAnchor",loc:this.loc(p)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(p)};case"B":return{type:"NonWordBoundary",loc:this.loc(p)}}throw Error("Invalid Assertion Escape");case"(":this.consumeChar("?");var C;switch(this.popChar()){case"=":C="Lookahead";break;case"!":C="NegativeLookahead";break}a(C);var y=this.disjunction();return this.consumeChar(")"),{type:C,value:y,loc:this.loc(p)}}l()},r.prototype.quantifier=function(p){var C,y=this.idx;switch(this.popChar()){case"*":C={atLeast:0,atMost:1/0};break;case"+":C={atLeast:1,atMost:1/0};break;case"?":C={atLeast:0,atMost:1};break;case"{":var B=this.integerIncludingZero();switch(this.popChar()){case"}":C={atLeast:B,atMost:B};break;case",":var v;this.isDigit()?(v=this.integerIncludingZero(),C={atLeast:B,atMost:v}):C={atLeast:B,atMost:1/0},this.consumeChar("}");break}if(p===!0&&C===void 0)return;a(C);break}if(!(p===!0&&C===void 0))return a(C),this.peekChar(0)==="?"?(this.consumeChar("?"),C.greedy=!1):C.greedy=!0,C.type="Quantifier",C.loc=this.loc(y),C},r.prototype.atom=function(){var p,C=this.idx;switch(this.peekChar()){case".":p=this.dotAll();break;case"\\":p=this.atomEscape();break;case"[":p=this.characterClass();break;case"(":p=this.group();break}return p===void 0&&this.isPatternCharacter()&&(p=this.patternCharacter()),a(p),p.loc=this.loc(C),this.isQuantifier()&&(p.quantifier=this.quantifier()),p},r.prototype.dotAll=function(){return this.consumeChar("."),{type:"Set",complement:!0,value:[n(` +`),n("\r"),n("\u2028"),n("\u2029")]}},r.prototype.atomEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},r.prototype.decimalEscapeAtom=function(){var p=this.positiveInteger();return{type:"GroupBackReference",value:p}},r.prototype.characterClassEscape=function(){var p,C=!1;switch(this.popChar()){case"d":p=u;break;case"D":p=u,C=!0;break;case"s":p=f;break;case"S":p=f,C=!0;break;case"w":p=g;break;case"W":p=g,C=!0;break}return a(p),{type:"Set",value:p,complement:C}},r.prototype.controlEscapeAtom=function(){var p;switch(this.popChar()){case"f":p=n("\f");break;case"n":p=n(` +`);break;case"r":p=n("\r");break;case"t":p=n(" ");break;case"v":p=n("\v");break}return a(p),{type:"Character",value:p}},r.prototype.controlLetterEscapeAtom=function(){this.consumeChar("c");var p=this.popChar();if(/[a-zA-Z]/.test(p)===!1)throw Error("Invalid ");var C=p.toUpperCase().charCodeAt(0)-64;return{type:"Character",value:C}},r.prototype.nulCharacterAtom=function(){return this.consumeChar("0"),{type:"Character",value:n("\0")}},r.prototype.hexEscapeSequenceAtom=function(){return this.consumeChar("x"),this.parseHexDigits(2)},r.prototype.regExpUnicodeEscapeSequenceAtom=function(){return this.consumeChar("u"),this.parseHexDigits(4)},r.prototype.identityEscapeAtom=function(){var p=this.popChar();return{type:"Character",value:n(p)}},r.prototype.classPatternCharacterAtom=function(){switch(this.peekChar()){case` +`:case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:var p=this.popChar();return{type:"Character",value:n(p)}}},r.prototype.characterClass=function(){var p=[],C=!1;for(this.consumeChar("["),this.peekChar(0)==="^"&&(this.consumeChar("^"),C=!0);this.isClassAtom();){var y=this.classAtom(),B=y.type==="Character";if(B&&this.isRangeDash()){this.consumeChar("-");var v=this.classAtom(),D=v.type==="Character";if(D){if(v.value=this.input.length)throw Error("Unexpected end of input");this.idx++},r.prototype.loc=function(p){return{begin:p,end:this.idx}};var e=/[0-9a-fA-F]/,t=/[0-9]/,i=/[1-9]/;function n(p){return p.charCodeAt(0)}function s(p,C){p.length!==void 0?p.forEach(function(y){C.push(y)}):C.push(p)}function o(p,C){if(p[C]===!0)throw"duplicate flag "+C;p[C]=!0}function a(p){if(p===void 0)throw Error("Internal Error - Should never get here!")}function l(){throw Error("Internal Error - Should never get here!")}var c,u=[];for(c=n("0");c<=n("9");c++)u.push(c);var g=[n("_")].concat(u);for(c=n("a");c<=n("z");c++)g.push(c);for(c=n("A");c<=n("Z");c++)g.push(c);var f=[n(" "),n("\f"),n(` +`),n("\r"),n(" "),n("\v"),n(" "),n("\xA0"),n("\u1680"),n("\u2000"),n("\u2001"),n("\u2002"),n("\u2003"),n("\u2004"),n("\u2005"),n("\u2006"),n("\u2007"),n("\u2008"),n("\u2009"),n("\u200A"),n("\u2028"),n("\u2029"),n("\u202F"),n("\u205F"),n("\u3000"),n("\uFEFF")];function h(){}return h.prototype.visitChildren=function(p){for(var C in p){var y=p[C];p.hasOwnProperty(C)&&(y.type!==void 0?this.visit(y):Array.isArray(y)&&y.forEach(function(B){this.visit(B)},this))}},h.prototype.visit=function(p){switch(p.type){case"Pattern":this.visitPattern(p);break;case"Flags":this.visitFlags(p);break;case"Disjunction":this.visitDisjunction(p);break;case"Alternative":this.visitAlternative(p);break;case"StartAnchor":this.visitStartAnchor(p);break;case"EndAnchor":this.visitEndAnchor(p);break;case"WordBoundary":this.visitWordBoundary(p);break;case"NonWordBoundary":this.visitNonWordBoundary(p);break;case"Lookahead":this.visitLookahead(p);break;case"NegativeLookahead":this.visitNegativeLookahead(p);break;case"Character":this.visitCharacter(p);break;case"Set":this.visitSet(p);break;case"Group":this.visitGroup(p);break;case"GroupBackReference":this.visitGroupBackReference(p);break;case"Quantifier":this.visitQuantifier(p);break}this.visitChildren(p)},h.prototype.visitPattern=function(p){},h.prototype.visitFlags=function(p){},h.prototype.visitDisjunction=function(p){},h.prototype.visitAlternative=function(p){},h.prototype.visitStartAnchor=function(p){},h.prototype.visitEndAnchor=function(p){},h.prototype.visitWordBoundary=function(p){},h.prototype.visitNonWordBoundary=function(p){},h.prototype.visitLookahead=function(p){},h.prototype.visitNegativeLookahead=function(p){},h.prototype.visitCharacter=function(p){},h.prototype.visitSet=function(p){},h.prototype.visitGroup=function(p){},h.prototype.visitGroupBackReference=function(p){},h.prototype.visitQuantifier=function(p){},{RegExpParser:r,BaseRegExpVisitor:h,VERSION:"0.5.0"}})});var ty=w(Xg=>{"use strict";Object.defineProperty(Xg,"__esModule",{value:!0});Xg.clearRegExpParserCache=Xg.getRegExpAst=void 0;var dEe=$I(),ey={},CEe=new dEe.RegExpParser;function mEe(r){var e=r.toString();if(ey.hasOwnProperty(e))return ey[e];var t=CEe.pattern(e);return ey[e]=t,t}Xg.getRegExpAst=mEe;function EEe(){ey={}}Xg.clearRegExpParserCache=EEe});var YY=w(dn=>{"use strict";var IEe=dn&&dn.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(dn,"__esModule",{value:!0});dn.canMatchCharCode=dn.firstCharOptimizedIndices=dn.getOptimizedStartCodesIndices=dn.failedOptimizationPrefixMsg=void 0;var KY=$I(),gs=Gt(),HY=ty(),va=Rv(),GY="Complement Sets are not supported for first char optimization";dn.failedOptimizationPrefixMsg=`Unable to use "first char" lexer optimizations: +`;function yEe(r,e){e===void 0&&(e=!1);try{var t=(0,HY.getRegExpAst)(r),i=iy(t.value,{},t.flags.ignoreCase);return i}catch(s){if(s.message===GY)e&&(0,gs.PRINT_WARNING)(""+dn.failedOptimizationPrefixMsg+(" Unable to optimize: < "+r.toString()+` > +`)+` Complement Sets cannot be automatically optimized. + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{var n="";e&&(n=` + This will disable the lexer's first char optimizations. + See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details.`),(0,gs.PRINT_ERROR)(dn.failedOptimizationPrefixMsg+` +`+(" Failed parsing: < "+r.toString()+` > +`)+(" Using the regexp-to-ast library version: "+KY.VERSION+` +`)+" Please open an issue at: https://github.com/bd82/regexp-to-ast/issues"+n)}}return[]}dn.getOptimizedStartCodesIndices=yEe;function iy(r,e,t){switch(r.type){case"Disjunction":for(var i=0;i=va.minOptimizationVal)for(var f=u.from>=va.minOptimizationVal?u.from:va.minOptimizationVal,h=u.to,p=(0,va.charCodeToOptimizedIndex)(f),C=(0,va.charCodeToOptimizedIndex)(h),y=p;y<=C;y++)e[y]=y}}});break;case"Group":iy(o.value,e,t);break;default:throw Error("Non Exhaustive Match")}var a=o.quantifier!==void 0&&o.quantifier.atLeast===0;if(o.type==="Group"&&kv(o)===!1||o.type!=="Group"&&a===!1)break}break;default:throw Error("non exhaustive match!")}return(0,gs.values)(e)}dn.firstCharOptimizedIndices=iy;function ry(r,e,t){var i=(0,va.charCodeToOptimizedIndex)(r);e[i]=i,t===!0&&wEe(r,e)}function wEe(r,e){var t=String.fromCharCode(r),i=t.toUpperCase();if(i!==t){var n=(0,va.charCodeToOptimizedIndex)(i.charCodeAt(0));e[n]=n}else{var s=t.toLowerCase();if(s!==t){var n=(0,va.charCodeToOptimizedIndex)(s.charCodeAt(0));e[n]=n}}}function UY(r,e){return(0,gs.find)(r.value,function(t){if(typeof t=="number")return(0,gs.contains)(e,t);var i=t;return(0,gs.find)(e,function(n){return i.from<=n&&n<=i.to})!==void 0})}function kv(r){return r.quantifier&&r.quantifier.atLeast===0?!0:r.value?(0,gs.isArray)(r.value)?(0,gs.every)(r.value,kv):kv(r.value):!1}var BEe=function(r){IEe(e,r);function e(t){var i=r.call(this)||this;return i.targetCharCodes=t,i.found=!1,i}return e.prototype.visitChildren=function(t){if(this.found!==!0){switch(t.type){case"Lookahead":this.visitLookahead(t);return;case"NegativeLookahead":this.visitNegativeLookahead(t);return}r.prototype.visitChildren.call(this,t)}},e.prototype.visitCharacter=function(t){(0,gs.contains)(this.targetCharCodes,t.value)&&(this.found=!0)},e.prototype.visitSet=function(t){t.complement?UY(t,this.targetCharCodes)===void 0&&(this.found=!0):UY(t,this.targetCharCodes)!==void 0&&(this.found=!0)},e}(KY.BaseRegExpVisitor);function QEe(r,e){if(e instanceof RegExp){var t=(0,HY.getRegExpAst)(e),i=new BEe(r);return i.visit(t),i.found}else return(0,gs.find)(e,function(n){return(0,gs.contains)(r,n.charCodeAt(0))})!==void 0}dn.canMatchCharCode=QEe});var Rv=w(Ve=>{"use strict";var jY=Ve&&Ve.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Ve,"__esModule",{value:!0});Ve.charCodeToOptimizedIndex=Ve.minOptimizationVal=Ve.buildLineBreakIssueMessage=Ve.LineTerminatorOptimizedTester=Ve.isShortPattern=Ve.isCustomPattern=Ve.cloneEmptyGroups=Ve.performWarningRuntimeChecks=Ve.performRuntimeChecks=Ve.addStickyFlag=Ve.addStartOfInput=Ve.findUnreachablePatterns=Ve.findModesThatDoNotExist=Ve.findInvalidGroupType=Ve.findDuplicatePatterns=Ve.findUnsupportedFlags=Ve.findStartOfInputAnchor=Ve.findEmptyMatchRegExps=Ve.findEndOfInputAnchor=Ve.findInvalidPatterns=Ve.findMissingPatterns=Ve.validatePatterns=Ve.analyzeTokenTypes=Ve.enableSticky=Ve.disableSticky=Ve.SUPPORT_STICKY=Ve.MODES=Ve.DEFAULT_MODE=void 0;var qY=$I(),ir=Bd(),xe=Gt(),Zg=YY(),JY=ty(),Do="PATTERN";Ve.DEFAULT_MODE="defaultMode";Ve.MODES="modes";Ve.SUPPORT_STICKY=typeof new RegExp("(?:)").sticky=="boolean";function bEe(){Ve.SUPPORT_STICKY=!1}Ve.disableSticky=bEe;function SEe(){Ve.SUPPORT_STICKY=!0}Ve.enableSticky=SEe;function vEe(r,e){e=(0,xe.defaults)(e,{useSticky:Ve.SUPPORT_STICKY,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r",` +`],tracer:function(v,D){return D()}});var t=e.tracer;t("initCharCodeToOptimizedIndexMap",function(){OEe()});var i;t("Reject Lexer.NA",function(){i=(0,xe.reject)(r,function(v){return v[Do]===ir.Lexer.NA})});var n=!1,s;t("Transform Patterns",function(){n=!1,s=(0,xe.map)(i,function(v){var D=v[Do];if((0,xe.isRegExp)(D)){var L=D.source;return L.length===1&&L!=="^"&&L!=="$"&&L!=="."&&!D.ignoreCase?L:L.length===2&&L[0]==="\\"&&!(0,xe.contains)(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],L[1])?L[1]:e.useSticky?Lv(D):Nv(D)}else{if((0,xe.isFunction)(D))return n=!0,{exec:D};if((0,xe.has)(D,"exec"))return n=!0,D;if(typeof D=="string"){if(D.length===1)return D;var H=D.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),j=new RegExp(H);return e.useSticky?Lv(j):Nv(j)}else throw Error("non exhaustive match")}})});var o,a,l,c,u;t("misc mapping",function(){o=(0,xe.map)(i,function(v){return v.tokenTypeIdx}),a=(0,xe.map)(i,function(v){var D=v.GROUP;if(D!==ir.Lexer.SKIPPED){if((0,xe.isString)(D))return D;if((0,xe.isUndefined)(D))return!1;throw Error("non exhaustive match")}}),l=(0,xe.map)(i,function(v){var D=v.LONGER_ALT;if(D){var L=(0,xe.isArray)(D)?(0,xe.map)(D,function(H){return(0,xe.indexOf)(i,H)}):[(0,xe.indexOf)(i,D)];return L}}),c=(0,xe.map)(i,function(v){return v.PUSH_MODE}),u=(0,xe.map)(i,function(v){return(0,xe.has)(v,"POP_MODE")})});var g;t("Line Terminator Handling",function(){var v=oj(e.lineTerminatorCharacters);g=(0,xe.map)(i,function(D){return!1}),e.positionTracking!=="onlyOffset"&&(g=(0,xe.map)(i,function(D){if((0,xe.has)(D,"LINE_BREAKS"))return D.LINE_BREAKS;if(nj(D,v)===!1)return(0,Zg.canMatchCharCode)(v,D.PATTERN)}))});var f,h,p,C;t("Misc Mapping #2",function(){f=(0,xe.map)(i,Ov),h=(0,xe.map)(s,ij),p=(0,xe.reduce)(i,function(v,D){var L=D.GROUP;return(0,xe.isString)(L)&&L!==ir.Lexer.SKIPPED&&(v[L]=[]),v},{}),C=(0,xe.map)(s,function(v,D){return{pattern:s[D],longerAlt:l[D],canLineTerminator:g[D],isCustom:f[D],short:h[D],group:a[D],push:c[D],pop:u[D],tokenTypeIdx:o[D],tokenType:i[D]}})});var y=!0,B=[];return e.safeMode||t("First Char Optimization",function(){B=(0,xe.reduce)(i,function(v,D,L){if(typeof D.PATTERN=="string"){var H=D.PATTERN.charCodeAt(0),j=Tv(H);Fv(v,j,C[L])}else if((0,xe.isArray)(D.START_CHARS_HINT)){var $;(0,xe.forEach)(D.START_CHARS_HINT,function(W){var _=typeof W=="string"?W.charCodeAt(0):W,A=Tv(_);$!==A&&($=A,Fv(v,A,C[L]))})}else if((0,xe.isRegExp)(D.PATTERN))if(D.PATTERN.unicode)y=!1,e.ensureOptimizations&&(0,xe.PRINT_ERROR)(""+Zg.failedOptimizationPrefixMsg+(" Unable to analyze < "+D.PATTERN.toString()+` > pattern. +`)+` The regexp unicode flag is not currently supported by the regexp-to-ast library. + This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{var V=(0,Zg.getOptimizedStartCodesIndices)(D.PATTERN,e.ensureOptimizations);(0,xe.isEmpty)(V)&&(y=!1),(0,xe.forEach)(V,function(W){Fv(v,W,C[L])})}else e.ensureOptimizations&&(0,xe.PRINT_ERROR)(""+Zg.failedOptimizationPrefixMsg+(" TokenType: <"+D.name+`> is using a custom token pattern without providing parameter. +`)+` This will disable the lexer's first char optimizations. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),y=!1;return v},[])}),t("ArrayPacking",function(){B=(0,xe.packArray)(B)}),{emptyGroups:p,patternIdxToConfig:C,charCodeToPatternIdxToConfig:B,hasCustom:n,canBeOptimized:y}}Ve.analyzeTokenTypes=vEe;function xEe(r,e){var t=[],i=WY(r);t=t.concat(i.errors);var n=zY(i.valid),s=n.valid;return t=t.concat(n.errors),t=t.concat(PEe(s)),t=t.concat(ej(s)),t=t.concat(tj(s,e)),t=t.concat(rj(s)),t}Ve.validatePatterns=xEe;function PEe(r){var e=[],t=(0,xe.filter)(r,function(i){return(0,xe.isRegExp)(i[Do])});return e=e.concat(VY(t)),e=e.concat(ZY(t)),e=e.concat(_Y(t)),e=e.concat($Y(t)),e=e.concat(XY(t)),e}function WY(r){var e=(0,xe.filter)(r,function(n){return!(0,xe.has)(n,Do)}),t=(0,xe.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- missing static 'PATTERN' property",type:ir.LexerDefinitionErrorType.MISSING_PATTERN,tokenTypes:[n]}}),i=(0,xe.difference)(r,e);return{errors:t,valid:i}}Ve.findMissingPatterns=WY;function zY(r){var e=(0,xe.filter)(r,function(n){var s=n[Do];return!(0,xe.isRegExp)(s)&&!(0,xe.isFunction)(s)&&!(0,xe.has)(s,"exec")&&!(0,xe.isString)(s)}),t=(0,xe.map)(e,function(n){return{message:"Token Type: ->"+n.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:ir.LexerDefinitionErrorType.INVALID_PATTERN,tokenTypes:[n]}}),i=(0,xe.difference)(r,e);return{errors:t,valid:i}}Ve.findInvalidPatterns=zY;var DEe=/[^\\][\$]/;function VY(r){var e=function(n){jY(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitEndAnchor=function(o){this.found=!0},s}(qY.BaseRegExpVisitor),t=(0,xe.filter)(r,function(n){var s=n[Do];try{var o=(0,JY.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch{return DEe.test(s.source)}}),i=(0,xe.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain end of input anchor '$' + See chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:ir.LexerDefinitionErrorType.EOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ve.findEndOfInputAnchor=VY;function XY(r){var e=(0,xe.filter)(r,function(i){var n=i[Do];return n.test("")}),t=(0,xe.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' must not match an empty string",type:ir.LexerDefinitionErrorType.EMPTY_MATCH_PATTERN,tokenTypes:[i]}});return t}Ve.findEmptyMatchRegExps=XY;var kEe=/[^\\[][\^]|^\^/;function ZY(r){var e=function(n){jY(s,n);function s(){var o=n!==null&&n.apply(this,arguments)||this;return o.found=!1,o}return s.prototype.visitStartAnchor=function(o){this.found=!0},s}(qY.BaseRegExpVisitor),t=(0,xe.filter)(r,function(n){var s=n[Do];try{var o=(0,JY.getRegExpAst)(s),a=new e;return a.visit(o),a.found}catch{return kEe.test(s.source)}}),i=(0,xe.map)(t,function(n){return{message:`Unexpected RegExp Anchor Error: + Token Type: ->`+n.name+`<- static 'PATTERN' cannot contain start of input anchor '^' + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS for details.`,type:ir.LexerDefinitionErrorType.SOI_ANCHOR_FOUND,tokenTypes:[n]}});return i}Ve.findStartOfInputAnchor=ZY;function _Y(r){var e=(0,xe.filter)(r,function(i){var n=i[Do];return n instanceof RegExp&&(n.multiline||n.global)}),t=(0,xe.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:ir.LexerDefinitionErrorType.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[i]}});return t}Ve.findUnsupportedFlags=_Y;function $Y(r){var e=[],t=(0,xe.map)(r,function(s){return(0,xe.reduce)(r,function(o,a){return s.PATTERN.source===a.PATTERN.source&&!(0,xe.contains)(e,a)&&a.PATTERN!==ir.Lexer.NA&&(e.push(a),o.push(a)),o},[])});t=(0,xe.compact)(t);var i=(0,xe.filter)(t,function(s){return s.length>1}),n=(0,xe.map)(i,function(s){var o=(0,xe.map)(s,function(l){return l.name}),a=(0,xe.first)(s).PATTERN;return{message:"The same RegExp pattern ->"+a+"<-"+("has been used in all of the following Token Types: "+o.join(", ")+" <-"),type:ir.LexerDefinitionErrorType.DUPLICATE_PATTERNS_FOUND,tokenTypes:s}});return n}Ve.findDuplicatePatterns=$Y;function ej(r){var e=(0,xe.filter)(r,function(i){if(!(0,xe.has)(i,"GROUP"))return!1;var n=i.GROUP;return n!==ir.Lexer.SKIPPED&&n!==ir.Lexer.NA&&!(0,xe.isString)(n)}),t=(0,xe.map)(e,function(i){return{message:"Token Type: ->"+i.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:ir.LexerDefinitionErrorType.INVALID_GROUP_TYPE_FOUND,tokenTypes:[i]}});return t}Ve.findInvalidGroupType=ej;function tj(r,e){var t=(0,xe.filter)(r,function(n){return n.PUSH_MODE!==void 0&&!(0,xe.contains)(e,n.PUSH_MODE)}),i=(0,xe.map)(t,function(n){var s="Token Type: ->"+n.name+"<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->"+n.PUSH_MODE+"<-which does not exist";return{message:s,type:ir.LexerDefinitionErrorType.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[n]}});return i}Ve.findModesThatDoNotExist=tj;function rj(r){var e=[],t=(0,xe.reduce)(r,function(i,n,s){var o=n.PATTERN;return o===ir.Lexer.NA||((0,xe.isString)(o)?i.push({str:o,idx:s,tokenType:n}):(0,xe.isRegExp)(o)&&FEe(o)&&i.push({str:o.source,idx:s,tokenType:n})),i},[]);return(0,xe.forEach)(r,function(i,n){(0,xe.forEach)(t,function(s){var o=s.str,a=s.idx,l=s.tokenType;if(n"+i.name+"<-")+`in the lexer's definition. +See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;e.push({message:c,type:ir.LexerDefinitionErrorType.UNREACHABLE_PATTERN,tokenTypes:[i,l]})}})}),e}Ve.findUnreachablePatterns=rj;function REe(r,e){if((0,xe.isRegExp)(e)){var t=e.exec(r);return t!==null&&t.index===0}else{if((0,xe.isFunction)(e))return e(r,0,[],{});if((0,xe.has)(e,"exec"))return e.exec(r,0,[],{});if(typeof e=="string")return e===r;throw Error("non exhaustive match")}}function FEe(r){var e=[".","\\","[","]","|","^","$","(",")","?","*","+","{"];return(0,xe.find)(e,function(t){return r.source.indexOf(t)!==-1})===void 0}function Nv(r){var e=r.ignoreCase?"i":"";return new RegExp("^(?:"+r.source+")",e)}Ve.addStartOfInput=Nv;function Lv(r){var e=r.ignoreCase?"iy":"y";return new RegExp(""+r.source,e)}Ve.addStickyFlag=Lv;function NEe(r,e,t){var i=[];return(0,xe.has)(r,Ve.DEFAULT_MODE)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ve.DEFAULT_MODE+`> property in its definition +`,type:ir.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),(0,xe.has)(r,Ve.MODES)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+Ve.MODES+`> property in its definition +`,type:ir.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),(0,xe.has)(r,Ve.MODES)&&(0,xe.has)(r,Ve.DEFAULT_MODE)&&!(0,xe.has)(r.modes,r.defaultMode)&&i.push({message:"A MultiMode Lexer cannot be initialized with a "+Ve.DEFAULT_MODE+": <"+r.defaultMode+`>which does not exist +`,type:ir.LexerDefinitionErrorType.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),(0,xe.has)(r,Ve.MODES)&&(0,xe.forEach)(r.modes,function(n,s){(0,xe.forEach)(n,function(o,a){(0,xe.isUndefined)(o)&&i.push({message:"A Lexer cannot be initialized using an undefined Token Type. Mode:"+("<"+s+"> at index: <"+a+`> +`),type:ir.LexerDefinitionErrorType.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED})})}),i}Ve.performRuntimeChecks=NEe;function LEe(r,e,t){var i=[],n=!1,s=(0,xe.compact)((0,xe.flatten)((0,xe.mapValues)(r.modes,function(l){return l}))),o=(0,xe.reject)(s,function(l){return l[Do]===ir.Lexer.NA}),a=oj(t);return e&&(0,xe.forEach)(o,function(l){var c=nj(l,a);if(c!==!1){var u=sj(l,c),g={message:u,type:c.issue,tokenType:l};i.push(g)}else(0,xe.has)(l,"LINE_BREAKS")?l.LINE_BREAKS===!0&&(n=!0):(0,Zg.canMatchCharCode)(a,l.PATTERN)&&(n=!0)}),e&&!n&&i.push({message:`Warning: No LINE_BREAKS Found. + This Lexer has been defined to track line and column information, + But none of the Token Types can be identified as matching a line terminator. + See https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS + for details.`,type:ir.LexerDefinitionErrorType.NO_LINE_BREAKS_FLAGS}),i}Ve.performWarningRuntimeChecks=LEe;function TEe(r){var e={},t=(0,xe.keys)(r);return(0,xe.forEach)(t,function(i){var n=r[i];if((0,xe.isArray)(n))e[i]=[];else throw Error("non exhaustive match")}),e}Ve.cloneEmptyGroups=TEe;function Ov(r){var e=r.PATTERN;if((0,xe.isRegExp)(e))return!1;if((0,xe.isFunction)(e))return!0;if((0,xe.has)(e,"exec"))return!0;if((0,xe.isString)(e))return!1;throw Error("non exhaustive match")}Ve.isCustomPattern=Ov;function ij(r){return(0,xe.isString)(r)&&r.length===1?r.charCodeAt(0):!1}Ve.isShortPattern=ij;Ve.LineTerminatorOptimizedTester={test:function(r){for(var e=r.length,t=this.lastIndex;t Token Type +`)+(" Root cause: "+e.errMsg+`. +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR";if(e.issue===ir.LexerDefinitionErrorType.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the option. +`+(" The problem is in the <"+r.name+`> Token Type +`)+" For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK";throw Error("non exhaustive match")}Ve.buildLineBreakIssueMessage=sj;function oj(r){var e=(0,xe.map)(r,function(t){return(0,xe.isString)(t)&&t.length>0?t.charCodeAt(0):t});return e}function Fv(r,e,t){r[e]===void 0?r[e]=[t]:r[e].push(t)}Ve.minOptimizationVal=256;var ny=[];function Tv(r){return r255?255+~~(r/255):r}}});var _g=w(Nt=>{"use strict";Object.defineProperty(Nt,"__esModule",{value:!0});Nt.isTokenType=Nt.hasExtendingTokensTypesMapProperty=Nt.hasExtendingTokensTypesProperty=Nt.hasCategoriesProperty=Nt.hasShortKeyProperty=Nt.singleAssignCategoriesToksMap=Nt.assignCategoriesMapProp=Nt.assignCategoriesTokensProp=Nt.assignTokenDefaultProps=Nt.expandCategories=Nt.augmentTokenTypes=Nt.tokenIdxToClass=Nt.tokenShortNameIdx=Nt.tokenStructuredMatcherNoCategories=Nt.tokenStructuredMatcher=void 0;var Zr=Gt();function MEe(r,e){var t=r.tokenTypeIdx;return t===e.tokenTypeIdx?!0:e.isParent===!0&&e.categoryMatchesMap[t]===!0}Nt.tokenStructuredMatcher=MEe;function UEe(r,e){return r.tokenTypeIdx===e.tokenTypeIdx}Nt.tokenStructuredMatcherNoCategories=UEe;Nt.tokenShortNameIdx=1;Nt.tokenIdxToClass={};function KEe(r){var e=aj(r);Aj(e),cj(e),lj(e),(0,Zr.forEach)(e,function(t){t.isParent=t.categoryMatches.length>0})}Nt.augmentTokenTypes=KEe;function aj(r){for(var e=(0,Zr.cloneArr)(r),t=r,i=!0;i;){t=(0,Zr.compact)((0,Zr.flatten)((0,Zr.map)(t,function(s){return s.CATEGORIES})));var n=(0,Zr.difference)(t,e);e=e.concat(n),(0,Zr.isEmpty)(n)?i=!1:t=n}return e}Nt.expandCategories=aj;function Aj(r){(0,Zr.forEach)(r,function(e){uj(e)||(Nt.tokenIdxToClass[Nt.tokenShortNameIdx]=e,e.tokenTypeIdx=Nt.tokenShortNameIdx++),Mv(e)&&!(0,Zr.isArray)(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),Mv(e)||(e.CATEGORIES=[]),gj(e)||(e.categoryMatches=[]),fj(e)||(e.categoryMatchesMap={})})}Nt.assignTokenDefaultProps=Aj;function lj(r){(0,Zr.forEach)(r,function(e){e.categoryMatches=[],(0,Zr.forEach)(e.categoryMatchesMap,function(t,i){e.categoryMatches.push(Nt.tokenIdxToClass[i].tokenTypeIdx)})})}Nt.assignCategoriesTokensProp=lj;function cj(r){(0,Zr.forEach)(r,function(e){Uv([],e)})}Nt.assignCategoriesMapProp=cj;function Uv(r,e){(0,Zr.forEach)(r,function(t){e.categoryMatchesMap[t.tokenTypeIdx]=!0}),(0,Zr.forEach)(e.CATEGORIES,function(t){var i=r.concat(e);(0,Zr.contains)(i,t)||Uv(i,t)})}Nt.singleAssignCategoriesToksMap=Uv;function uj(r){return(0,Zr.has)(r,"tokenTypeIdx")}Nt.hasShortKeyProperty=uj;function Mv(r){return(0,Zr.has)(r,"CATEGORIES")}Nt.hasCategoriesProperty=Mv;function gj(r){return(0,Zr.has)(r,"categoryMatches")}Nt.hasExtendingTokensTypesProperty=gj;function fj(r){return(0,Zr.has)(r,"categoryMatchesMap")}Nt.hasExtendingTokensTypesMapProperty=fj;function HEe(r){return(0,Zr.has)(r,"tokenTypeIdx")}Nt.isTokenType=HEe});var Kv=w(sy=>{"use strict";Object.defineProperty(sy,"__esModule",{value:!0});sy.defaultLexerErrorProvider=void 0;sy.defaultLexerErrorProvider={buildUnableToPopLexerModeMessage:function(r){return"Unable to pop Lexer Mode after encountering Token ->"+r.image+"<- The Mode Stack is empty"},buildUnexpectedCharactersMessage:function(r,e,t,i,n){return"unexpected character: ->"+r.charAt(e)+"<- at offset: "+e+","+(" skipped "+t+" characters.")}}});var Bd=w(Cc=>{"use strict";Object.defineProperty(Cc,"__esModule",{value:!0});Cc.Lexer=Cc.LexerDefinitionErrorType=void 0;var _s=Rv(),nr=Gt(),GEe=_g(),YEe=Kv(),jEe=ty(),qEe;(function(r){r[r.MISSING_PATTERN=0]="MISSING_PATTERN",r[r.INVALID_PATTERN=1]="INVALID_PATTERN",r[r.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",r[r.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",r[r.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",r[r.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",r[r.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",r[r.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",r[r.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",r[r.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",r[r.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",r[r.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",r[r.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",r[r.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",r[r.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",r[r.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",r[r.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK"})(qEe=Cc.LexerDefinitionErrorType||(Cc.LexerDefinitionErrorType={}));var Qd={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:[` +`,"\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:YEe.defaultLexerErrorProvider,traceInitPerf:!1,skipValidations:!1};Object.freeze(Qd);var JEe=function(){function r(e,t){var i=this;if(t===void 0&&(t=Qd),this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.config=void 0,this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},typeof t=="boolean")throw Error(`The second argument to the Lexer constructor is now an ILexerConfig Object. +a boolean 2nd argument is no longer supported`);this.config=(0,nr.merge)(Qd,t);var n=this.config.traceInitPerf;n===!0?(this.traceInitMaxIdent=1/0,this.traceInitPerf=!0):typeof n=="number"&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",function(){var s,o=!0;i.TRACE_INIT("Lexer Config handling",function(){if(i.config.lineTerminatorsPattern===Qd.lineTerminatorsPattern)i.config.lineTerminatorsPattern=_s.LineTerminatorOptimizedTester;else if(i.config.lineTerminatorCharacters===Qd.lineTerminatorCharacters)throw Error(`Error: Missing property on the Lexer config. + For details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS`);if(t.safeMode&&t.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');i.trackStartLines=/full|onlyStart/i.test(i.config.positionTracking),i.trackEndLines=/full/i.test(i.config.positionTracking),(0,nr.isArray)(e)?(s={modes:{}},s.modes[_s.DEFAULT_MODE]=(0,nr.cloneArr)(e),s[_s.DEFAULT_MODE]=_s.DEFAULT_MODE):(o=!1,s=(0,nr.cloneObj)(e))}),i.config.skipValidations===!1&&(i.TRACE_INIT("performRuntimeChecks",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,_s.performRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))}),i.TRACE_INIT("performWarningRuntimeChecks",function(){i.lexerDefinitionWarning=i.lexerDefinitionWarning.concat((0,_s.performWarningRuntimeChecks)(s,i.trackStartLines,i.config.lineTerminatorCharacters))})),s.modes=s.modes?s.modes:{},(0,nr.forEach)(s.modes,function(u,g){s.modes[g]=(0,nr.reject)(u,function(f){return(0,nr.isUndefined)(f)})});var a=(0,nr.keys)(s.modes);if((0,nr.forEach)(s.modes,function(u,g){i.TRACE_INIT("Mode: <"+g+"> processing",function(){if(i.modes.push(g),i.config.skipValidations===!1&&i.TRACE_INIT("validatePatterns",function(){i.lexerDefinitionErrors=i.lexerDefinitionErrors.concat((0,_s.validatePatterns)(u,a))}),(0,nr.isEmpty)(i.lexerDefinitionErrors)){(0,GEe.augmentTokenTypes)(u);var f;i.TRACE_INIT("analyzeTokenTypes",function(){f=(0,_s.analyzeTokenTypes)(u,{lineTerminatorCharacters:i.config.lineTerminatorCharacters,positionTracking:t.positionTracking,ensureOptimizations:t.ensureOptimizations,safeMode:t.safeMode,tracer:i.TRACE_INIT.bind(i)})}),i.patternIdxToConfig[g]=f.patternIdxToConfig,i.charCodeToPatternIdxToConfig[g]=f.charCodeToPatternIdxToConfig,i.emptyGroups=(0,nr.merge)(i.emptyGroups,f.emptyGroups),i.hasCustom=f.hasCustom||i.hasCustom,i.canModeBeOptimized[g]=f.canBeOptimized}})}),i.defaultMode=s.defaultMode,!(0,nr.isEmpty)(i.lexerDefinitionErrors)&&!i.config.deferDefinitionErrorsHandling){var l=(0,nr.map)(i.lexerDefinitionErrors,function(u){return u.message}),c=l.join(`----------------------- +`);throw new Error(`Errors detected in definition of Lexer: +`+c)}(0,nr.forEach)(i.lexerDefinitionWarning,function(u){(0,nr.PRINT_WARNING)(u.message)}),i.TRACE_INIT("Choosing sub-methods implementations",function(){if(_s.SUPPORT_STICKY?(i.chopInput=nr.IDENTITY,i.match=i.matchWithTest):(i.updateLastIndex=nr.NOOP,i.match=i.matchWithExec),o&&(i.handleModes=nr.NOOP),i.trackStartLines===!1&&(i.computeNewColumn=nr.IDENTITY),i.trackEndLines===!1&&(i.updateTokenEndLineColumnLocation=nr.NOOP),/full/i.test(i.config.positionTracking))i.createTokenInstance=i.createFullToken;else if(/onlyStart/i.test(i.config.positionTracking))i.createTokenInstance=i.createStartOnlyToken;else if(/onlyOffset/i.test(i.config.positionTracking))i.createTokenInstance=i.createOffsetOnlyToken;else throw Error('Invalid config option: "'+i.config.positionTracking+'"');i.hasCustom?(i.addToken=i.addTokenUsingPush,i.handlePayload=i.handlePayloadWithCustom):(i.addToken=i.addTokenUsingMemberAccess,i.handlePayload=i.handlePayloadNoCustom)}),i.TRACE_INIT("Failed Optimization Warnings",function(){var u=(0,nr.reduce)(i.canModeBeOptimized,function(g,f,h){return f===!1&&g.push(h),g},[]);if(t.ensureOptimizations&&!(0,nr.isEmpty)(u))throw Error("Lexer Modes: < "+u.join(", ")+` > cannot be optimized. + Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode. + Or inspect the console log for details on how to resolve these issues.`)}),i.TRACE_INIT("clearRegExpParserCache",function(){(0,jEe.clearRegExpParserCache)()}),i.TRACE_INIT("toFastProperties",function(){(0,nr.toFastProperties)(i)})})}return r.prototype.tokenize=function(e,t){if(t===void 0&&(t=this.defaultMode),!(0,nr.isEmpty)(this.lexerDefinitionErrors)){var i=(0,nr.map)(this.lexerDefinitionErrors,function(o){return o.message}),n=i.join(`----------------------- +`);throw new Error(`Unable to Tokenize because Errors detected in definition of Lexer: +`+n)}var s=this.tokenizeInternal(e,t);return s},r.prototype.tokenizeInternal=function(e,t){var i=this,n,s,o,a,l,c,u,g,f,h,p,C,y,B,v,D,L=e,H=L.length,j=0,$=0,V=this.hasCustom?0:Math.floor(e.length/10),W=new Array(V),_=[],A=this.trackStartLines?1:void 0,Ae=this.trackStartLines?1:void 0,ge=(0,_s.cloneEmptyGroups)(this.emptyGroups),re=this.trackStartLines,O=this.config.lineTerminatorsPattern,F=0,ue=[],pe=[],ke=[],Fe=[];Object.freeze(Fe);var Ne=void 0;function oe(){return ue}function le(pr){var Ii=(0,_s.charCodeToOptimizedIndex)(pr),rs=pe[Ii];return rs===void 0?Fe:rs}var Be=function(pr){if(ke.length===1&&pr.tokenType.PUSH_MODE===void 0){var Ii=i.config.errorMessageProvider.buildUnableToPopLexerModeMessage(pr);_.push({offset:pr.startOffset,line:pr.startLine!==void 0?pr.startLine:void 0,column:pr.startColumn!==void 0?pr.startColumn:void 0,length:pr.image.length,message:Ii})}else{ke.pop();var rs=(0,nr.last)(ke);ue=i.patternIdxToConfig[rs],pe=i.charCodeToPatternIdxToConfig[rs],F=ue.length;var ga=i.canModeBeOptimized[rs]&&i.config.safeMode===!1;pe&&ga?Ne=le:Ne=oe}};function fe(pr){ke.push(pr),pe=this.charCodeToPatternIdxToConfig[pr],ue=this.patternIdxToConfig[pr],F=ue.length,F=ue.length;var Ii=this.canModeBeOptimized[pr]&&this.config.safeMode===!1;pe&&Ii?Ne=le:Ne=oe}fe.call(this,t);for(var ae;jc.length){c=a,u=g,ae=_e;break}}}break}}if(c!==null){if(f=c.length,h=ae.group,h!==void 0&&(p=ae.tokenTypeIdx,C=this.createTokenInstance(c,j,p,ae.tokenType,A,Ae,f),this.handlePayload(C,u),h===!1?$=this.addToken(W,$,C):ge[h].push(C)),e=this.chopInput(e,f),j=j+f,Ae=this.computeNewColumn(Ae,f),re===!0&&ae.canLineTerminator===!0){var It=0,Or=void 0,ii=void 0;O.lastIndex=0;do Or=O.test(c),Or===!0&&(ii=O.lastIndex-1,It++);while(Or===!0);It!==0&&(A=A+It,Ae=f-ii,this.updateTokenEndLineColumnLocation(C,h,ii,It,A,Ae,f))}this.handleModes(ae,Be,fe,C)}else{for(var gi=j,hr=A,fi=Ae,ni=!1;!ni&&j <"+e+">");var n=(0,nr.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r.SKIPPED="This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.",r.NA=/NOT_APPLICABLE/,r}();Cc.Lexer=JEe});var LA=w(bi=>{"use strict";Object.defineProperty(bi,"__esModule",{value:!0});bi.tokenMatcher=bi.createTokenInstance=bi.EOF=bi.createToken=bi.hasTokenLabel=bi.tokenName=bi.tokenLabel=void 0;var $s=Gt(),WEe=Bd(),Hv=_g();function zEe(r){return wj(r)?r.LABEL:r.name}bi.tokenLabel=zEe;function VEe(r){return r.name}bi.tokenName=VEe;function wj(r){return(0,$s.isString)(r.LABEL)&&r.LABEL!==""}bi.hasTokenLabel=wj;var XEe="parent",hj="categories",pj="label",dj="group",Cj="push_mode",mj="pop_mode",Ej="longer_alt",Ij="line_breaks",yj="start_chars_hint";function Bj(r){return ZEe(r)}bi.createToken=Bj;function ZEe(r){var e=r.pattern,t={};if(t.name=r.name,(0,$s.isUndefined)(e)||(t.PATTERN=e),(0,$s.has)(r,XEe))throw`The parent property is no longer supported. +See: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.`;return(0,$s.has)(r,hj)&&(t.CATEGORIES=r[hj]),(0,Hv.augmentTokenTypes)([t]),(0,$s.has)(r,pj)&&(t.LABEL=r[pj]),(0,$s.has)(r,dj)&&(t.GROUP=r[dj]),(0,$s.has)(r,mj)&&(t.POP_MODE=r[mj]),(0,$s.has)(r,Cj)&&(t.PUSH_MODE=r[Cj]),(0,$s.has)(r,Ej)&&(t.LONGER_ALT=r[Ej]),(0,$s.has)(r,Ij)&&(t.LINE_BREAKS=r[Ij]),(0,$s.has)(r,yj)&&(t.START_CHARS_HINT=r[yj]),t}bi.EOF=Bj({name:"EOF",pattern:WEe.Lexer.NA});(0,Hv.augmentTokenTypes)([bi.EOF]);function _Ee(r,e,t,i,n,s,o,a){return{image:e,startOffset:t,endOffset:i,startLine:n,endLine:s,startColumn:o,endColumn:a,tokenTypeIdx:r.tokenTypeIdx,tokenType:r}}bi.createTokenInstance=_Ee;function $Ee(r,e){return(0,Hv.tokenStructuredMatcher)(r,e)}bi.tokenMatcher=$Ee});var Cn=w(zt=>{"use strict";var xa=zt&&zt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(zt,"__esModule",{value:!0});zt.serializeProduction=zt.serializeGrammar=zt.Terminal=zt.Alternation=zt.RepetitionWithSeparator=zt.Repetition=zt.RepetitionMandatoryWithSeparator=zt.RepetitionMandatory=zt.Option=zt.Alternative=zt.Rule=zt.NonTerminal=zt.AbstractProduction=void 0;var Ar=Gt(),eIe=LA(),ko=function(){function r(e){this._definition=e}return Object.defineProperty(r.prototype,"definition",{get:function(){return this._definition},set:function(e){this._definition=e},enumerable:!1,configurable:!0}),r.prototype.accept=function(e){e.visit(this),(0,Ar.forEach)(this.definition,function(t){t.accept(e)})},r}();zt.AbstractProduction=ko;var Qj=function(r){xa(e,r);function e(t){var i=r.call(this,[])||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this.referencedRule!==void 0?this.referencedRule.definition:[]},set:function(t){},enumerable:!1,configurable:!0}),e.prototype.accept=function(t){t.visit(this)},e}(ko);zt.NonTerminal=Qj;var bj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.orgText="",(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.Rule=bj;var Sj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.ignoreAmbiguities=!1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.Alternative=Sj;var vj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.Option=vj;var xj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.RepetitionMandatory=xj;var Pj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.RepetitionMandatoryWithSeparator=Pj;var Dj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.Repetition=Dj;var kj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return e}(ko);zt.RepetitionWithSeparator=kj;var Rj=function(r){xa(e,r);function e(t){var i=r.call(this,t.definition)||this;return i.idx=1,i.ignoreAmbiguities=!1,i.hasPredicates=!1,(0,Ar.assign)(i,(0,Ar.pick)(t,function(n){return n!==void 0})),i}return Object.defineProperty(e.prototype,"definition",{get:function(){return this._definition},set:function(t){this._definition=t},enumerable:!1,configurable:!0}),e}(ko);zt.Alternation=Rj;var oy=function(){function r(e){this.idx=1,(0,Ar.assign)(this,(0,Ar.pick)(e,function(t){return t!==void 0}))}return r.prototype.accept=function(e){e.visit(this)},r}();zt.Terminal=oy;function tIe(r){return(0,Ar.map)(r,bd)}zt.serializeGrammar=tIe;function bd(r){function e(s){return(0,Ar.map)(s,bd)}if(r instanceof Qj){var t={type:"NonTerminal",name:r.nonTerminalName,idx:r.idx};return(0,Ar.isString)(r.label)&&(t.label=r.label),t}else{if(r instanceof Sj)return{type:"Alternative",definition:e(r.definition)};if(r instanceof vj)return{type:"Option",idx:r.idx,definition:e(r.definition)};if(r instanceof xj)return{type:"RepetitionMandatory",idx:r.idx,definition:e(r.definition)};if(r instanceof Pj)return{type:"RepetitionMandatoryWithSeparator",idx:r.idx,separator:bd(new oy({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof kj)return{type:"RepetitionWithSeparator",idx:r.idx,separator:bd(new oy({terminalType:r.separator})),definition:e(r.definition)};if(r instanceof Dj)return{type:"Repetition",idx:r.idx,definition:e(r.definition)};if(r instanceof Rj)return{type:"Alternation",idx:r.idx,definition:e(r.definition)};if(r instanceof oy){var i={type:"Terminal",name:r.terminalType.name,label:(0,eIe.tokenLabel)(r.terminalType),idx:r.idx};(0,Ar.isString)(r.label)&&(i.terminalLabel=r.label);var n=r.terminalType.PATTERN;return r.terminalType.PATTERN&&(i.pattern=(0,Ar.isRegExp)(n)?n.source:n),i}else{if(r instanceof bj)return{type:"Rule",name:r.name,orgText:r.orgText,definition:e(r.definition)};throw Error("non exhaustive match")}}}zt.serializeProduction=bd});var Ay=w(ay=>{"use strict";Object.defineProperty(ay,"__esModule",{value:!0});ay.RestWalker=void 0;var Gv=Gt(),mn=Cn(),rIe=function(){function r(){}return r.prototype.walk=function(e,t){var i=this;t===void 0&&(t=[]),(0,Gv.forEach)(e.definition,function(n,s){var o=(0,Gv.drop)(e.definition,s+1);if(n instanceof mn.NonTerminal)i.walkProdRef(n,o,t);else if(n instanceof mn.Terminal)i.walkTerminal(n,o,t);else if(n instanceof mn.Alternative)i.walkFlat(n,o,t);else if(n instanceof mn.Option)i.walkOption(n,o,t);else if(n instanceof mn.RepetitionMandatory)i.walkAtLeastOne(n,o,t);else if(n instanceof mn.RepetitionMandatoryWithSeparator)i.walkAtLeastOneSep(n,o,t);else if(n instanceof mn.RepetitionWithSeparator)i.walkManySep(n,o,t);else if(n instanceof mn.Repetition)i.walkMany(n,o,t);else if(n instanceof mn.Alternation)i.walkOr(n,o,t);else throw Error("non exhaustive match")})},r.prototype.walkTerminal=function(e,t,i){},r.prototype.walkProdRef=function(e,t,i){},r.prototype.walkFlat=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkOption=function(e,t,i){var n=t.concat(i);this.walk(e,n)},r.prototype.walkAtLeastOne=function(e,t,i){var n=[new mn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkAtLeastOneSep=function(e,t,i){var n=Fj(e,t,i);this.walk(e,n)},r.prototype.walkMany=function(e,t,i){var n=[new mn.Option({definition:e.definition})].concat(t,i);this.walk(e,n)},r.prototype.walkManySep=function(e,t,i){var n=Fj(e,t,i);this.walk(e,n)},r.prototype.walkOr=function(e,t,i){var n=this,s=t.concat(i);(0,Gv.forEach)(e.definition,function(o){var a=new mn.Alternative({definition:[o]});n.walk(a,s)})},r}();ay.RestWalker=rIe;function Fj(r,e,t){var i=[new mn.Option({definition:[new mn.Terminal({terminalType:r.separator})].concat(r.definition)})],n=i.concat(e,t);return n}});var $g=w(ly=>{"use strict";Object.defineProperty(ly,"__esModule",{value:!0});ly.GAstVisitor=void 0;var Ro=Cn(),iIe=function(){function r(){}return r.prototype.visit=function(e){var t=e;switch(t.constructor){case Ro.NonTerminal:return this.visitNonTerminal(t);case Ro.Alternative:return this.visitAlternative(t);case Ro.Option:return this.visitOption(t);case Ro.RepetitionMandatory:return this.visitRepetitionMandatory(t);case Ro.RepetitionMandatoryWithSeparator:return this.visitRepetitionMandatoryWithSeparator(t);case Ro.RepetitionWithSeparator:return this.visitRepetitionWithSeparator(t);case Ro.Repetition:return this.visitRepetition(t);case Ro.Alternation:return this.visitAlternation(t);case Ro.Terminal:return this.visitTerminal(t);case Ro.Rule:return this.visitRule(t);default:throw Error("non exhaustive match")}},r.prototype.visitNonTerminal=function(e){},r.prototype.visitAlternative=function(e){},r.prototype.visitOption=function(e){},r.prototype.visitRepetition=function(e){},r.prototype.visitRepetitionMandatory=function(e){},r.prototype.visitRepetitionMandatoryWithSeparator=function(e){},r.prototype.visitRepetitionWithSeparator=function(e){},r.prototype.visitAlternation=function(e){},r.prototype.visitTerminal=function(e){},r.prototype.visitRule=function(e){},r}();ly.GAstVisitor=iIe});var vd=w(Mi=>{"use strict";var nIe=Mi&&Mi.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Mi,"__esModule",{value:!0});Mi.collectMethods=Mi.DslMethodsCollectorVisitor=Mi.getProductionDslName=Mi.isBranchingProd=Mi.isOptionalProd=Mi.isSequenceProd=void 0;var Sd=Gt(),Qr=Cn(),sIe=$g();function oIe(r){return r instanceof Qr.Alternative||r instanceof Qr.Option||r instanceof Qr.Repetition||r instanceof Qr.RepetitionMandatory||r instanceof Qr.RepetitionMandatoryWithSeparator||r instanceof Qr.RepetitionWithSeparator||r instanceof Qr.Terminal||r instanceof Qr.Rule}Mi.isSequenceProd=oIe;function Yv(r,e){e===void 0&&(e=[]);var t=r instanceof Qr.Option||r instanceof Qr.Repetition||r instanceof Qr.RepetitionWithSeparator;return t?!0:r instanceof Qr.Alternation?(0,Sd.some)(r.definition,function(i){return Yv(i,e)}):r instanceof Qr.NonTerminal&&(0,Sd.contains)(e,r)?!1:r instanceof Qr.AbstractProduction?(r instanceof Qr.NonTerminal&&e.push(r),(0,Sd.every)(r.definition,function(i){return Yv(i,e)})):!1}Mi.isOptionalProd=Yv;function aIe(r){return r instanceof Qr.Alternation}Mi.isBranchingProd=aIe;function AIe(r){if(r instanceof Qr.NonTerminal)return"SUBRULE";if(r instanceof Qr.Option)return"OPTION";if(r instanceof Qr.Alternation)return"OR";if(r instanceof Qr.RepetitionMandatory)return"AT_LEAST_ONE";if(r instanceof Qr.RepetitionMandatoryWithSeparator)return"AT_LEAST_ONE_SEP";if(r instanceof Qr.RepetitionWithSeparator)return"MANY_SEP";if(r instanceof Qr.Repetition)return"MANY";if(r instanceof Qr.Terminal)return"CONSUME";throw Error("non exhaustive match")}Mi.getProductionDslName=AIe;var Nj=function(r){nIe(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.separator="-",t.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]},t}return e.prototype.reset=function(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}},e.prototype.visitTerminal=function(t){var i=t.terminalType.name+this.separator+"Terminal";(0,Sd.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitNonTerminal=function(t){var i=t.nonTerminalName+this.separator+"Terminal";(0,Sd.has)(this.dslMethods,i)||(this.dslMethods[i]=[]),this.dslMethods[i].push(t)},e.prototype.visitOption=function(t){this.dslMethods.option.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.dslMethods.repetitionWithSeparator.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.dslMethods.repetitionMandatory.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.dslMethods.repetitionMandatoryWithSeparator.push(t)},e.prototype.visitRepetition=function(t){this.dslMethods.repetition.push(t)},e.prototype.visitAlternation=function(t){this.dslMethods.alternation.push(t)},e}(sIe.GAstVisitor);Mi.DslMethodsCollectorVisitor=Nj;var cy=new Nj;function lIe(r){cy.reset(),r.accept(cy);var e=cy.dslMethods;return cy.reset(),e}Mi.collectMethods=lIe});var qv=w(Fo=>{"use strict";Object.defineProperty(Fo,"__esModule",{value:!0});Fo.firstForTerminal=Fo.firstForBranching=Fo.firstForSequence=Fo.first=void 0;var uy=Gt(),Lj=Cn(),jv=vd();function gy(r){if(r instanceof Lj.NonTerminal)return gy(r.referencedRule);if(r instanceof Lj.Terminal)return Mj(r);if((0,jv.isSequenceProd)(r))return Tj(r);if((0,jv.isBranchingProd)(r))return Oj(r);throw Error("non exhaustive match")}Fo.first=gy;function Tj(r){for(var e=[],t=r.definition,i=0,n=t.length>i,s,o=!0;n&&o;)s=t[i],o=(0,jv.isOptionalProd)(s),e=e.concat(gy(s)),i=i+1,n=t.length>i;return(0,uy.uniq)(e)}Fo.firstForSequence=Tj;function Oj(r){var e=(0,uy.map)(r.definition,function(t){return gy(t)});return(0,uy.uniq)((0,uy.flatten)(e))}Fo.firstForBranching=Oj;function Mj(r){return[r.terminalType]}Fo.firstForTerminal=Mj});var Jv=w(fy=>{"use strict";Object.defineProperty(fy,"__esModule",{value:!0});fy.IN=void 0;fy.IN="_~IN~_"});var Yj=w(fs=>{"use strict";var cIe=fs&&fs.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(fs,"__esModule",{value:!0});fs.buildInProdFollowPrefix=fs.buildBetweenProdsFollowPrefix=fs.computeAllProdsFollows=fs.ResyncFollowsWalker=void 0;var uIe=Ay(),gIe=qv(),Uj=Gt(),Kj=Jv(),fIe=Cn(),Hj=function(r){cIe(e,r);function e(t){var i=r.call(this)||this;return i.topProd=t,i.follows={},i}return e.prototype.startWalking=function(){return this.walk(this.topProd),this.follows},e.prototype.walkTerminal=function(t,i,n){},e.prototype.walkProdRef=function(t,i,n){var s=Gj(t.referencedRule,t.idx)+this.topProd.name,o=i.concat(n),a=new fIe.Alternative({definition:o}),l=(0,gIe.first)(a);this.follows[s]=l},e}(uIe.RestWalker);fs.ResyncFollowsWalker=Hj;function hIe(r){var e={};return(0,Uj.forEach)(r,function(t){var i=new Hj(t).startWalking();(0,Uj.assign)(e,i)}),e}fs.computeAllProdsFollows=hIe;function Gj(r,e){return r.name+e+Kj.IN}fs.buildBetweenProdsFollowPrefix=Gj;function pIe(r){var e=r.terminalType.name;return e+r.idx+Kj.IN}fs.buildInProdFollowPrefix=pIe});var xd=w(Pa=>{"use strict";Object.defineProperty(Pa,"__esModule",{value:!0});Pa.defaultGrammarValidatorErrorProvider=Pa.defaultGrammarResolverErrorProvider=Pa.defaultParserErrorProvider=void 0;var ef=LA(),dIe=Gt(),eo=Gt(),Wv=Cn(),jj=vd();Pa.defaultParserErrorProvider={buildMismatchTokenMessage:function(r){var e=r.expected,t=r.actual,i=r.previous,n=r.ruleName,s=(0,ef.hasTokenLabel)(e),o=s?"--> "+(0,ef.tokenLabel)(e)+" <--":"token of type --> "+e.name+" <--",a="Expecting "+o+" but found --> '"+t.image+"' <--";return a},buildNotAllInputParsedMessage:function(r){var e=r.firstRedundant,t=r.ruleName;return"Redundant input, expecting EOF but found: "+e.image},buildNoViableAltMessage:function(r){var e=r.expectedPathsPerAlt,t=r.actual,i=r.previous,n=r.customUserDescription,s=r.ruleName,o="Expecting: ",a=(0,eo.first)(t).image,l=` +but found: '`+a+"'";if(n)return o+n+l;var c=(0,eo.reduce)(e,function(h,p){return h.concat(p)},[]),u=(0,eo.map)(c,function(h){return"["+(0,eo.map)(h,function(p){return(0,ef.tokenLabel)(p)}).join(", ")+"]"}),g=(0,eo.map)(u,function(h,p){return" "+(p+1)+". "+h}),f=`one of these possible Token sequences: +`+g.join(` +`);return o+f+l},buildEarlyExitMessage:function(r){var e=r.expectedIterationPaths,t=r.actual,i=r.customUserDescription,n=r.ruleName,s="Expecting: ",o=(0,eo.first)(t).image,a=` +but found: '`+o+"'";if(i)return s+i+a;var l=(0,eo.map)(e,function(u){return"["+(0,eo.map)(u,function(g){return(0,ef.tokenLabel)(g)}).join(",")+"]"}),c=`expecting at least one iteration which starts with one of these possible Token sequences:: + `+("<"+l.join(" ,")+">");return s+c+a}};Object.freeze(Pa.defaultParserErrorProvider);Pa.defaultGrammarResolverErrorProvider={buildRuleNotFoundError:function(r,e){var t="Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+`<- +inside top level rule: ->`+r.name+"<-";return t}};Pa.defaultGrammarValidatorErrorProvider={buildDuplicateFoundError:function(r,e){function t(u){return u instanceof Wv.Terminal?u.terminalType.name:u instanceof Wv.NonTerminal?u.nonTerminalName:""}var i=r.name,n=(0,eo.first)(e),s=n.idx,o=(0,jj.getProductionDslName)(n),a=t(n),l=s>0,c="->"+o+(l?s:"")+"<- "+(a?"with argument: ->"+a+"<-":"")+` + appears more than once (`+e.length+" times) in the top level rule: ->"+i+`<-. + For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES + `;return c=c.replace(/[ \t]+/g," "),c=c.replace(/\s\s+/g,` +`),c},buildNamespaceConflictError:function(r){var e=`Namespace conflict found in grammar. +`+("The grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <"+r.name+`>. +`)+`To resolve this make sure each Terminal and Non-Terminal names are unique +This is easy to accomplish by using the convention that Terminal names start with an uppercase letter +and Non-Terminal names start with a lower case letter.`;return e},buildAlternationPrefixAmbiguityError:function(r){var e=(0,eo.map)(r.prefixPath,function(n){return(0,ef.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous alternatives: <"+r.ambiguityIndices.join(" ,")+`> due to common lookahead prefix +`+("in inside <"+r.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`)+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX +For Further details.`;return i},buildAlternationAmbiguityError:function(r){var e=(0,eo.map)(r.prefixPath,function(n){return(0,ef.tokenLabel)(n)}).join(", "),t=r.alternation.idx===0?"":r.alternation.idx,i="Ambiguous Alternatives Detected: <"+r.ambiguityIndices.join(" ,")+"> in "+(" inside <"+r.topLevelRule.name+`> Rule, +`)+("<"+e+`> may appears as a prefix path in all these alternatives. +`);return i=i+`See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES +For Further details.`,i},buildEmptyRepetitionError:function(r){var e=(0,jj.getProductionDslName)(r.repetition);r.repetition.idx!==0&&(e+=r.repetition.idx);var t="The repetition <"+e+"> within Rule <"+r.topLevelRule.name+`> can never consume any tokens. +This could lead to an infinite loop.`;return t},buildTokenNameError:function(r){return"deprecated"},buildEmptyAlternationError:function(r){var e="Ambiguous empty alternative: <"+(r.emptyChoiceIdx+1)+">"+(" in inside <"+r.topLevelRule.name+`> Rule. +`)+"Only the last alternative may be an empty alternative.";return e},buildTooManyAlternativesError:function(r){var e=`An Alternation cannot have more than 256 alternatives: +`+(" inside <"+r.topLevelRule.name+`> Rule. + has `+(r.alternation.definition.length+1)+" alternatives.");return e},buildLeftRecursionError:function(r){var e=r.topLevelRule.name,t=dIe.map(r.leftRecursionPath,function(s){return s.name}),i=e+" --> "+t.concat([e]).join(" --> "),n=`Left Recursion found in grammar. +`+("rule: <"+e+`> can be invoked from itself (directly or indirectly) +`)+(`without consuming any Tokens. The grammar path that causes this is: + `+i+` +`)+` To fix this refactor your grammar to remove the left recursion. +see: https://en.wikipedia.org/wiki/LL_parser#Left_Factoring.`;return n},buildInvalidRuleNameError:function(r){return"deprecated"},buildDuplicateRuleNameError:function(r){var e;r.topLevelRule instanceof Wv.Rule?e=r.topLevelRule.name:e=r.topLevelRule;var t="Duplicate definition, rule: ->"+e+"<- is already defined in the grammar: ->"+r.grammarName+"<-";return t}}});var Wj=w(TA=>{"use strict";var CIe=TA&&TA.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(TA,"__esModule",{value:!0});TA.GastRefResolverVisitor=TA.resolveGrammar=void 0;var mIe=Yn(),qj=Gt(),EIe=$g();function IIe(r,e){var t=new Jj(r,e);return t.resolveRefs(),t.errors}TA.resolveGrammar=IIe;var Jj=function(r){CIe(e,r);function e(t,i){var n=r.call(this)||this;return n.nameToTopRule=t,n.errMsgProvider=i,n.errors=[],n}return e.prototype.resolveRefs=function(){var t=this;(0,qj.forEach)((0,qj.values)(this.nameToTopRule),function(i){t.currTopLevel=i,i.accept(t)})},e.prototype.visitNonTerminal=function(t){var i=this.nameToTopRule[t.nonTerminalName];if(i)t.referencedRule=i;else{var n=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,t);this.errors.push({message:n,type:mIe.ParserDefinitionErrorType.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:t.nonTerminalName})}},e}(EIe.GAstVisitor);TA.GastRefResolverVisitor=Jj});var Dd=w(Nr=>{"use strict";var mc=Nr&&Nr.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Nr,"__esModule",{value:!0});Nr.nextPossibleTokensAfter=Nr.possiblePathsFrom=Nr.NextTerminalAfterAtLeastOneSepWalker=Nr.NextTerminalAfterAtLeastOneWalker=Nr.NextTerminalAfterManySepWalker=Nr.NextTerminalAfterManyWalker=Nr.AbstractNextTerminalAfterProductionWalker=Nr.NextAfterTokenWalker=Nr.AbstractNextPossibleTokensWalker=void 0;var zj=Ay(),Ut=Gt(),yIe=qv(),kt=Cn(),Vj=function(r){mc(e,r);function e(t,i){var n=r.call(this)||this;return n.topProd=t,n.path=i,n.possibleTokTypes=[],n.nextProductionName="",n.nextProductionOccurrence=0,n.found=!1,n.isAtEndOfPath=!1,n}return e.prototype.startWalking=function(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=(0,Ut.cloneArr)(this.path.ruleStack).reverse(),this.occurrenceStack=(0,Ut.cloneArr)(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes},e.prototype.walk=function(t,i){i===void 0&&(i=[]),this.found||r.prototype.walk.call(this,t,i)},e.prototype.walkProdRef=function(t,i,n){if(t.referencedRule.name===this.nextProductionName&&t.idx===this.nextProductionOccurrence){var s=i.concat(n);this.updateExpectedNext(),this.walk(t.referencedRule,s)}},e.prototype.updateExpectedNext=function(){(0,Ut.isEmpty)(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())},e}(zj.RestWalker);Nr.AbstractNextPossibleTokensWalker=Vj;var wIe=function(r){mc(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.path=i,n.nextTerminalName="",n.nextTerminalOccurrence=0,n.nextTerminalName=n.path.lastTok.name,n.nextTerminalOccurrence=n.path.lastTokOccurrence,n}return e.prototype.walkTerminal=function(t,i,n){if(this.isAtEndOfPath&&t.terminalType.name===this.nextTerminalName&&t.idx===this.nextTerminalOccurrence&&!this.found){var s=i.concat(n),o=new kt.Alternative({definition:s});this.possibleTokTypes=(0,yIe.first)(o),this.found=!0}},e}(Vj);Nr.NextAfterTokenWalker=wIe;var Pd=function(r){mc(e,r);function e(t,i){var n=r.call(this)||this;return n.topRule=t,n.occurrence=i,n.result={token:void 0,occurrence:void 0,isEndOfRule:void 0},n}return e.prototype.startWalking=function(){return this.walk(this.topRule),this.result},e}(zj.RestWalker);Nr.AbstractNextTerminalAfterProductionWalker=Pd;var BIe=function(r){mc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkMany=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkMany.call(this,t,i,n)},e}(Pd);Nr.NextTerminalAfterManyWalker=BIe;var QIe=function(r){mc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkManySep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkManySep.call(this,t,i,n)},e}(Pd);Nr.NextTerminalAfterManySepWalker=QIe;var bIe=function(r){mc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOne=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOne.call(this,t,i,n)},e}(Pd);Nr.NextTerminalAfterAtLeastOneWalker=bIe;var SIe=function(r){mc(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.prototype.walkAtLeastOneSep=function(t,i,n){if(t.idx===this.occurrence){var s=(0,Ut.first)(i.concat(n));this.result.isEndOfRule=s===void 0,s instanceof kt.Terminal&&(this.result.token=s.terminalType,this.result.occurrence=s.idx)}else r.prototype.walkAtLeastOneSep.call(this,t,i,n)},e}(Pd);Nr.NextTerminalAfterAtLeastOneSepWalker=SIe;function Xj(r,e,t){t===void 0&&(t=[]),t=(0,Ut.cloneArr)(t);var i=[],n=0;function s(c){return c.concat((0,Ut.drop)(r,n+1))}function o(c){var u=Xj(s(c),e,t);return i.concat(u)}for(;t.length=0;ge--){var re=B.definition[ge],O={idx:p,def:re.definition.concat((0,Ut.drop)(h)),ruleStack:C,occurrenceStack:y};g.push(O),g.push(o)}else if(B instanceof kt.Alternative)g.push({idx:p,def:B.definition.concat((0,Ut.drop)(h)),ruleStack:C,occurrenceStack:y});else if(B instanceof kt.Rule)g.push(xIe(B,p,C,y));else throw Error("non exhaustive match")}}return u}Nr.nextPossibleTokensAfter=vIe;function xIe(r,e,t,i){var n=(0,Ut.cloneArr)(t);n.push(r.name);var s=(0,Ut.cloneArr)(i);return s.push(1),{idx:e,def:r.definition,ruleStack:n,occurrenceStack:s}}});var kd=w(Zt=>{"use strict";var $j=Zt&&Zt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Zt,"__esModule",{value:!0});Zt.areTokenCategoriesNotUsed=Zt.isStrictPrefixOfPath=Zt.containsPath=Zt.getLookaheadPathsForOptionalProd=Zt.getLookaheadPathsForOr=Zt.lookAheadSequenceFromAlternatives=Zt.buildSingleAlternativeLookaheadFunction=Zt.buildAlternativesLookAheadFunc=Zt.buildLookaheadFuncForOptionalProd=Zt.buildLookaheadFuncForOr=Zt.getProdType=Zt.PROD_TYPE=void 0;var sr=Gt(),Zj=Dd(),PIe=Ay(),hy=_g(),OA=Cn(),DIe=$g(),oi;(function(r){r[r.OPTION=0]="OPTION",r[r.REPETITION=1]="REPETITION",r[r.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",r[r.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",r[r.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",r[r.ALTERNATION=5]="ALTERNATION"})(oi=Zt.PROD_TYPE||(Zt.PROD_TYPE={}));function kIe(r){if(r instanceof OA.Option)return oi.OPTION;if(r instanceof OA.Repetition)return oi.REPETITION;if(r instanceof OA.RepetitionMandatory)return oi.REPETITION_MANDATORY;if(r instanceof OA.RepetitionMandatoryWithSeparator)return oi.REPETITION_MANDATORY_WITH_SEPARATOR;if(r instanceof OA.RepetitionWithSeparator)return oi.REPETITION_WITH_SEPARATOR;if(r instanceof OA.Alternation)return oi.ALTERNATION;throw Error("non exhaustive match")}Zt.getProdType=kIe;function RIe(r,e,t,i,n,s){var o=tq(r,e,t),a=Xv(o)?hy.tokenStructuredMatcherNoCategories:hy.tokenStructuredMatcher;return s(o,i,a,n)}Zt.buildLookaheadFuncForOr=RIe;function FIe(r,e,t,i,n,s){var o=rq(r,e,n,t),a=Xv(o)?hy.tokenStructuredMatcherNoCategories:hy.tokenStructuredMatcher;return s(o[0],a,i)}Zt.buildLookaheadFuncForOptionalProd=FIe;function NIe(r,e,t,i){var n=r.length,s=(0,sr.every)(r,function(l){return(0,sr.every)(l,function(c){return c.length===1})});if(e)return function(l){for(var c=(0,sr.map)(l,function(D){return D.GATE}),u=0;u{"use strict";var Zv=Vt&&Vt.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(Vt,"__esModule",{value:!0});Vt.checkPrefixAlternativesAmbiguities=Vt.validateSomeNonEmptyLookaheadPath=Vt.validateTooManyAlts=Vt.RepetionCollector=Vt.validateAmbiguousAlternationAlternatives=Vt.validateEmptyOrAlternative=Vt.getFirstNoneTerminal=Vt.validateNoLeftRecursion=Vt.validateRuleIsOverridden=Vt.validateRuleDoesNotAlreadyExist=Vt.OccurrenceValidationCollector=Vt.identifyProductionForDuplicates=Vt.validateGrammar=void 0;var er=Gt(),br=Gt(),No=Yn(),_v=vd(),tf=kd(),UIe=Dd(),to=Cn(),$v=$g();function KIe(r,e,t,i,n){var s=er.map(r,function(h){return HIe(h,i)}),o=er.map(r,function(h){return ex(h,h,i)}),a=[],l=[],c=[];(0,br.every)(o,br.isEmpty)&&(a=(0,br.map)(r,function(h){return Aq(h,i)}),l=(0,br.map)(r,function(h){return lq(h,e,i)}),c=gq(r,e,i));var u=jIe(r,t,i),g=(0,br.map)(r,function(h){return uq(h,i)}),f=(0,br.map)(r,function(h){return aq(h,r,n,i)});return er.flatten(s.concat(c,o,a,l,u,g,f))}Vt.validateGrammar=KIe;function HIe(r,e){var t=new oq;r.accept(t);var i=t.allProductions,n=er.groupBy(i,nq),s=er.pick(n,function(a){return a.length>1}),o=er.map(er.values(s),function(a){var l=er.first(a),c=e.buildDuplicateFoundError(r,a),u=(0,_v.getProductionDslName)(l),g={message:c,type:No.ParserDefinitionErrorType.DUPLICATE_PRODUCTIONS,ruleName:r.name,dslName:u,occurrence:l.idx},f=sq(l);return f&&(g.parameter=f),g});return o}function nq(r){return(0,_v.getProductionDslName)(r)+"_#_"+r.idx+"_#_"+sq(r)}Vt.identifyProductionForDuplicates=nq;function sq(r){return r instanceof to.Terminal?r.terminalType.name:r instanceof to.NonTerminal?r.nonTerminalName:""}var oq=function(r){Zv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitNonTerminal=function(t){this.allProductions.push(t)},e.prototype.visitOption=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e.prototype.visitAlternation=function(t){this.allProductions.push(t)},e.prototype.visitTerminal=function(t){this.allProductions.push(t)},e}($v.GAstVisitor);Vt.OccurrenceValidationCollector=oq;function aq(r,e,t,i){var n=[],s=(0,br.reduce)(e,function(a,l){return l.name===r.name?a+1:a},0);if(s>1){var o=i.buildDuplicateRuleNameError({topLevelRule:r,grammarName:t});n.push({message:o,type:No.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:r.name})}return n}Vt.validateRuleDoesNotAlreadyExist=aq;function GIe(r,e,t){var i=[],n;return er.contains(e,r)||(n="Invalid rule override, rule: ->"+r+"<- cannot be overridden in the grammar: ->"+t+"<-as it is not defined in any of the super grammars ",i.push({message:n,type:No.ParserDefinitionErrorType.INVALID_RULE_OVERRIDE,ruleName:r})),i}Vt.validateRuleIsOverridden=GIe;function ex(r,e,t,i){i===void 0&&(i=[]);var n=[],s=Rd(e.definition);if(er.isEmpty(s))return[];var o=r.name,a=er.contains(s,r);a&&n.push({message:t.buildLeftRecursionError({topLevelRule:r,leftRecursionPath:i}),type:No.ParserDefinitionErrorType.LEFT_RECURSION,ruleName:o});var l=er.difference(s,i.concat([r])),c=er.map(l,function(u){var g=er.cloneArr(i);return g.push(u),ex(r,u,t,g)});return n.concat(er.flatten(c))}Vt.validateNoLeftRecursion=ex;function Rd(r){var e=[];if(er.isEmpty(r))return e;var t=er.first(r);if(t instanceof to.NonTerminal)e.push(t.referencedRule);else if(t instanceof to.Alternative||t instanceof to.Option||t instanceof to.RepetitionMandatory||t instanceof to.RepetitionMandatoryWithSeparator||t instanceof to.RepetitionWithSeparator||t instanceof to.Repetition)e=e.concat(Rd(t.definition));else if(t instanceof to.Alternation)e=er.flatten(er.map(t.definition,function(o){return Rd(o.definition)}));else if(!(t instanceof to.Terminal))throw Error("non exhaustive match");var i=(0,_v.isOptionalProd)(t),n=r.length>1;if(i&&n){var s=er.drop(r);return e.concat(Rd(s))}else return e}Vt.getFirstNoneTerminal=Rd;var tx=function(r){Zv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.alternations=[],t}return e.prototype.visitAlternation=function(t){this.alternations.push(t)},e}($v.GAstVisitor);function Aq(r,e){var t=new tx;r.accept(t);var i=t.alternations,n=er.reduce(i,function(s,o){var a=er.dropRight(o.definition),l=er.map(a,function(c,u){var g=(0,UIe.nextPossibleTokensAfter)([c],[],null,1);return er.isEmpty(g)?{message:e.buildEmptyAlternationError({topLevelRule:r,alternation:o,emptyChoiceIdx:u}),type:No.ParserDefinitionErrorType.NONE_LAST_EMPTY_ALT,ruleName:r.name,occurrence:o.idx,alternative:u+1}:null});return s.concat(er.compact(l))},[]);return n}Vt.validateEmptyOrAlternative=Aq;function lq(r,e,t){var i=new tx;r.accept(i);var n=i.alternations;n=(0,br.reject)(n,function(o){return o.ignoreAmbiguities===!0});var s=er.reduce(n,function(o,a){var l=a.idx,c=a.maxLookahead||e,u=(0,tf.getLookaheadPathsForOr)(l,r,c,a),g=YIe(u,a,r,t),f=fq(u,a,r,t);return o.concat(g,f)},[]);return s}Vt.validateAmbiguousAlternationAlternatives=lq;var cq=function(r){Zv(e,r);function e(){var t=r!==null&&r.apply(this,arguments)||this;return t.allProductions=[],t}return e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e}($v.GAstVisitor);Vt.RepetionCollector=cq;function uq(r,e){var t=new tx;r.accept(t);var i=t.alternations,n=er.reduce(i,function(s,o){return o.definition.length>255&&s.push({message:e.buildTooManyAlternativesError({topLevelRule:r,alternation:o}),type:No.ParserDefinitionErrorType.TOO_MANY_ALTS,ruleName:r.name,occurrence:o.idx}),s},[]);return n}Vt.validateTooManyAlts=uq;function gq(r,e,t){var i=[];return(0,br.forEach)(r,function(n){var s=new cq;n.accept(s);var o=s.allProductions;(0,br.forEach)(o,function(a){var l=(0,tf.getProdType)(a),c=a.maxLookahead||e,u=a.idx,g=(0,tf.getLookaheadPathsForOptionalProd)(u,n,l,c),f=g[0];if((0,br.isEmpty)((0,br.flatten)(f))){var h=t.buildEmptyRepetitionError({topLevelRule:n,repetition:a});i.push({message:h,type:No.ParserDefinitionErrorType.NO_NON_EMPTY_LOOKAHEAD,ruleName:n.name})}})}),i}Vt.validateSomeNonEmptyLookaheadPath=gq;function YIe(r,e,t,i){var n=[],s=(0,br.reduce)(r,function(a,l,c){return e.definition[c].ignoreAmbiguities===!0||(0,br.forEach)(l,function(u){var g=[c];(0,br.forEach)(r,function(f,h){c!==h&&(0,tf.containsPath)(f,u)&&e.definition[h].ignoreAmbiguities!==!0&&g.push(h)}),g.length>1&&!(0,tf.containsPath)(n,u)&&(n.push(u),a.push({alts:g,path:u}))}),a},[]),o=er.map(s,function(a){var l=(0,br.map)(a.alts,function(u){return u+1}),c=i.buildAlternationAmbiguityError({topLevelRule:t,alternation:e,ambiguityIndices:l,prefixPath:a.path});return{message:c,type:No.ParserDefinitionErrorType.AMBIGUOUS_ALTS,ruleName:t.name,occurrence:e.idx,alternatives:[a.alts]}});return o}function fq(r,e,t,i){var n=[],s=(0,br.reduce)(r,function(o,a,l){var c=(0,br.map)(a,function(u){return{idx:l,path:u}});return o.concat(c)},[]);return(0,br.forEach)(s,function(o){var a=e.definition[o.idx];if(a.ignoreAmbiguities!==!0){var l=o.idx,c=o.path,u=(0,br.findAll)(s,function(f){return e.definition[f.idx].ignoreAmbiguities!==!0&&f.idx{"use strict";Object.defineProperty(rf,"__esModule",{value:!0});rf.validateGrammar=rf.resolveGrammar=void 0;var ix=Gt(),qIe=Wj(),JIe=rx(),hq=xd();function WIe(r){r=(0,ix.defaults)(r,{errMsgProvider:hq.defaultGrammarResolverErrorProvider});var e={};return(0,ix.forEach)(r.rules,function(t){e[t.name]=t}),(0,qIe.resolveGrammar)(e,r.errMsgProvider)}rf.resolveGrammar=WIe;function zIe(r){return r=(0,ix.defaults)(r,{errMsgProvider:hq.defaultGrammarValidatorErrorProvider}),(0,JIe.validateGrammar)(r.rules,r.maxLookahead,r.tokenTypes,r.errMsgProvider,r.grammarName)}rf.validateGrammar=zIe});var nf=w(En=>{"use strict";var Fd=En&&En.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(En,"__esModule",{value:!0});En.EarlyExitException=En.NotAllInputParsedException=En.NoViableAltException=En.MismatchedTokenException=En.isRecognitionException=void 0;var VIe=Gt(),dq="MismatchedTokenException",Cq="NoViableAltException",mq="EarlyExitException",Eq="NotAllInputParsedException",Iq=[dq,Cq,mq,Eq];Object.freeze(Iq);function XIe(r){return(0,VIe.contains)(Iq,r.name)}En.isRecognitionException=XIe;var py=function(r){Fd(e,r);function e(t,i){var n=this.constructor,s=r.call(this,t)||this;return s.token=i,s.resyncedTokens=[],Object.setPrototypeOf(s,n.prototype),Error.captureStackTrace&&Error.captureStackTrace(s,s.constructor),s}return e}(Error),ZIe=function(r){Fd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=dq,s}return e}(py);En.MismatchedTokenException=ZIe;var _Ie=function(r){Fd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=Cq,s}return e}(py);En.NoViableAltException=_Ie;var $Ie=function(r){Fd(e,r);function e(t,i){var n=r.call(this,t,i)||this;return n.name=Eq,n}return e}(py);En.NotAllInputParsedException=$Ie;var eye=function(r){Fd(e,r);function e(t,i,n){var s=r.call(this,t,i)||this;return s.previousToken=n,s.name=mq,s}return e}(py);En.EarlyExitException=eye});var sx=w(Ui=>{"use strict";Object.defineProperty(Ui,"__esModule",{value:!0});Ui.attemptInRepetitionRecovery=Ui.Recoverable=Ui.InRuleRecoveryException=Ui.IN_RULE_RECOVERY_EXCEPTION=Ui.EOF_FOLLOW_KEY=void 0;var dy=LA(),hs=Gt(),tye=nf(),rye=Jv(),iye=Yn();Ui.EOF_FOLLOW_KEY={};Ui.IN_RULE_RECOVERY_EXCEPTION="InRuleRecoveryException";function nx(r){this.name=Ui.IN_RULE_RECOVERY_EXCEPTION,this.message=r}Ui.InRuleRecoveryException=nx;nx.prototype=Error.prototype;var nye=function(){function r(){}return r.prototype.initRecoverable=function(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=(0,hs.has)(e,"recoveryEnabled")?e.recoveryEnabled:iye.DEFAULT_PARSER_CONFIG.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=yq)},r.prototype.getTokenToInsert=function(e){var t=(0,dy.createTokenInstance)(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return t.isInsertedInRecovery=!0,t},r.prototype.canTokenTypeBeInsertedInRecovery=function(e){return!0},r.prototype.tryInRepetitionRecovery=function(e,t,i,n){for(var s=this,o=this.findReSyncTokenType(),a=this.exportLexerState(),l=[],c=!1,u=this.LA(1),g=this.LA(1),f=function(){var h=s.LA(0),p=s.errorMessageProvider.buildMismatchTokenMessage({expected:n,actual:u,previous:h,ruleName:s.getCurrRuleFullName()}),C=new tye.MismatchedTokenException(p,u,s.LA(0));C.resyncedTokens=(0,hs.dropRight)(l),s.SAVE_ERROR(C)};!c;)if(this.tokenMatcher(g,n)){f();return}else if(i.call(this)){f(),e.apply(this,t);return}else this.tokenMatcher(g,o)?c=!0:(g=this.SKIP_TOKEN(),this.addToResyncTokens(g,l));this.importLexerState(a)},r.prototype.shouldInRepetitionRecoveryBeTried=function(e,t,i){return!(i===!1||e===void 0||t===void 0||this.tokenMatcher(this.LA(1),e)||this.isBackTracking()||this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,t)))},r.prototype.getFollowsForInRuleRecovery=function(e,t){var i=this.getCurrentGrammarPath(e,t),n=this.getNextPossibleTokenTypes(i);return n},r.prototype.tryInRuleRecovery=function(e,t){if(this.canRecoverWithSingleTokenInsertion(e,t)){var i=this.getTokenToInsert(e);return i}if(this.canRecoverWithSingleTokenDeletion(e)){var n=this.SKIP_TOKEN();return this.consumeToken(),n}throw new nx("sad sad panda")},r.prototype.canPerformInRuleRecovery=function(e,t){return this.canRecoverWithSingleTokenInsertion(e,t)||this.canRecoverWithSingleTokenDeletion(e)},r.prototype.canRecoverWithSingleTokenInsertion=function(e,t){var i=this;if(!this.canTokenTypeBeInsertedInRecovery(e)||(0,hs.isEmpty)(t))return!1;var n=this.LA(1),s=(0,hs.find)(t,function(o){return i.tokenMatcher(n,o)})!==void 0;return s},r.prototype.canRecoverWithSingleTokenDeletion=function(e){var t=this.tokenMatcher(this.LA(2),e);return t},r.prototype.isInCurrentRuleReSyncSet=function(e){var t=this.getCurrFollowKey(),i=this.getFollowSetFromFollowKey(t);return(0,hs.contains)(i,e)},r.prototype.findReSyncTokenType=function(){for(var e=this.flattenFollowSet(),t=this.LA(1),i=2;;){var n=t.tokenType;if((0,hs.contains)(e,n))return n;t=this.LA(i),i++}},r.prototype.getCurrFollowKey=function(){if(this.RULE_STACK.length===1)return Ui.EOF_FOLLOW_KEY;var e=this.getLastExplicitRuleShortName(),t=this.getLastExplicitRuleOccurrenceIndex(),i=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:t,inRule:this.shortRuleNameToFullName(i)}},r.prototype.buildFullFollowKeyStack=function(){var e=this,t=this.RULE_STACK,i=this.RULE_OCCURRENCE_STACK;return(0,hs.map)(t,function(n,s){return s===0?Ui.EOF_FOLLOW_KEY:{ruleName:e.shortRuleNameToFullName(n),idxInCallingRule:i[s],inRule:e.shortRuleNameToFullName(t[s-1])}})},r.prototype.flattenFollowSet=function(){var e=this,t=(0,hs.map)(this.buildFullFollowKeyStack(),function(i){return e.getFollowSetFromFollowKey(i)});return(0,hs.flatten)(t)},r.prototype.getFollowSetFromFollowKey=function(e){if(e===Ui.EOF_FOLLOW_KEY)return[dy.EOF];var t=e.ruleName+e.idxInCallingRule+rye.IN+e.inRule;return this.resyncFollows[t]},r.prototype.addToResyncTokens=function(e,t){return this.tokenMatcher(e,dy.EOF)||t.push(e),t},r.prototype.reSyncTo=function(e){for(var t=[],i=this.LA(1);this.tokenMatcher(i,e)===!1;)i=this.SKIP_TOKEN(),this.addToResyncTokens(i,t);return(0,hs.dropRight)(t)},r.prototype.attemptInRepetitionRecovery=function(e,t,i,n,s,o,a){},r.prototype.getCurrentGrammarPath=function(e,t){var i=this.getHumanReadableRuleStack(),n=(0,hs.cloneArr)(this.RULE_OCCURRENCE_STACK),s={ruleStack:i,occurrenceStack:n,lastTok:e,lastTokOccurrence:t};return s},r.prototype.getHumanReadableRuleStack=function(){var e=this;return(0,hs.map)(this.RULE_STACK,function(t){return e.shortRuleNameToFullName(t)})},r}();Ui.Recoverable=nye;function yq(r,e,t,i,n,s,o){var a=this.getKeyForAutomaticLookahead(i,n),l=this.firstAfterRepMap[a];if(l===void 0){var c=this.getCurrRuleFullName(),u=this.getGAstProductions()[c],g=new s(u,n);l=g.startWalking(),this.firstAfterRepMap[a]=l}var f=l.token,h=l.occurrence,p=l.isEndOfRule;this.RULE_STACK.length===1&&p&&f===void 0&&(f=dy.EOF,h=1),this.shouldInRepetitionRecoveryBeTried(f,h,o)&&this.tryInRepetitionRecovery(r,e,t,f)}Ui.attemptInRepetitionRecovery=yq});var Cy=w(Jt=>{"use strict";Object.defineProperty(Jt,"__esModule",{value:!0});Jt.getKeyForAutomaticLookahead=Jt.AT_LEAST_ONE_SEP_IDX=Jt.MANY_SEP_IDX=Jt.AT_LEAST_ONE_IDX=Jt.MANY_IDX=Jt.OPTION_IDX=Jt.OR_IDX=Jt.BITS_FOR_ALT_IDX=Jt.BITS_FOR_RULE_IDX=Jt.BITS_FOR_OCCURRENCE_IDX=Jt.BITS_FOR_METHOD_TYPE=void 0;Jt.BITS_FOR_METHOD_TYPE=4;Jt.BITS_FOR_OCCURRENCE_IDX=8;Jt.BITS_FOR_RULE_IDX=12;Jt.BITS_FOR_ALT_IDX=8;Jt.OR_IDX=1<{"use strict";Object.defineProperty(my,"__esModule",{value:!0});my.LooksAhead=void 0;var Da=kd(),ro=Gt(),wq=Yn(),ka=Cy(),Ec=vd(),oye=function(){function r(){}return r.prototype.initLooksAhead=function(e){this.dynamicTokensEnabled=(0,ro.has)(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:wq.DEFAULT_PARSER_CONFIG.dynamicTokensEnabled,this.maxLookahead=(0,ro.has)(e,"maxLookahead")?e.maxLookahead:wq.DEFAULT_PARSER_CONFIG.maxLookahead,this.lookAheadFuncsCache=(0,ro.isES2015MapSupported)()?new Map:[],(0,ro.isES2015MapSupported)()?(this.getLaFuncFromCache=this.getLaFuncFromMap,this.setLaFuncCache=this.setLaFuncCacheUsingMap):(this.getLaFuncFromCache=this.getLaFuncFromObj,this.setLaFuncCache=this.setLaFuncUsingObj)},r.prototype.preComputeLookaheadFunctions=function(e){var t=this;(0,ro.forEach)(e,function(i){t.TRACE_INIT(i.name+" Rule Lookahead",function(){var n=(0,Ec.collectMethods)(i),s=n.alternation,o=n.repetition,a=n.option,l=n.repetitionMandatory,c=n.repetitionMandatoryWithSeparator,u=n.repetitionWithSeparator;(0,ro.forEach)(s,function(g){var f=g.idx===0?"":g.idx;t.TRACE_INIT(""+(0,Ec.getProductionDslName)(g)+f,function(){var h=(0,Da.buildLookaheadFuncForOr)(g.idx,i,g.maxLookahead||t.maxLookahead,g.hasPredicates,t.dynamicTokensEnabled,t.lookAheadBuilderForAlternatives),p=(0,ka.getKeyForAutomaticLookahead)(t.fullRuleNameToShort[i.name],ka.OR_IDX,g.idx);t.setLaFuncCache(p,h)})}),(0,ro.forEach)(o,function(g){t.computeLookaheadFunc(i,g.idx,ka.MANY_IDX,Da.PROD_TYPE.REPETITION,g.maxLookahead,(0,Ec.getProductionDslName)(g))}),(0,ro.forEach)(a,function(g){t.computeLookaheadFunc(i,g.idx,ka.OPTION_IDX,Da.PROD_TYPE.OPTION,g.maxLookahead,(0,Ec.getProductionDslName)(g))}),(0,ro.forEach)(l,function(g){t.computeLookaheadFunc(i,g.idx,ka.AT_LEAST_ONE_IDX,Da.PROD_TYPE.REPETITION_MANDATORY,g.maxLookahead,(0,Ec.getProductionDslName)(g))}),(0,ro.forEach)(c,function(g){t.computeLookaheadFunc(i,g.idx,ka.AT_LEAST_ONE_SEP_IDX,Da.PROD_TYPE.REPETITION_MANDATORY_WITH_SEPARATOR,g.maxLookahead,(0,Ec.getProductionDslName)(g))}),(0,ro.forEach)(u,function(g){t.computeLookaheadFunc(i,g.idx,ka.MANY_SEP_IDX,Da.PROD_TYPE.REPETITION_WITH_SEPARATOR,g.maxLookahead,(0,Ec.getProductionDslName)(g))})})})},r.prototype.computeLookaheadFunc=function(e,t,i,n,s,o){var a=this;this.TRACE_INIT(""+o+(t===0?"":t),function(){var l=(0,Da.buildLookaheadFuncForOptionalProd)(t,e,s||a.maxLookahead,a.dynamicTokensEnabled,n,a.lookAheadBuilderForOptional),c=(0,ka.getKeyForAutomaticLookahead)(a.fullRuleNameToShort[e.name],i,t);a.setLaFuncCache(c,l)})},r.prototype.lookAheadBuilderForOptional=function(e,t,i){return(0,Da.buildSingleAlternativeLookaheadFunction)(e,t,i)},r.prototype.lookAheadBuilderForAlternatives=function(e,t,i,n){return(0,Da.buildAlternativesLookAheadFunc)(e,t,i,n)},r.prototype.getKeyForAutomaticLookahead=function(e,t){var i=this.getLastExplicitRuleShortName();return(0,ka.getKeyForAutomaticLookahead)(i,e,t)},r.prototype.getLaFuncFromCache=function(e){},r.prototype.getLaFuncFromMap=function(e){return this.lookAheadFuncsCache.get(e)},r.prototype.getLaFuncFromObj=function(e){return this.lookAheadFuncsCache[e]},r.prototype.setLaFuncCache=function(e,t){},r.prototype.setLaFuncCacheUsingMap=function(e,t){this.lookAheadFuncsCache.set(e,t)},r.prototype.setLaFuncUsingObj=function(e,t){this.lookAheadFuncsCache[e]=t},r}();my.LooksAhead=oye});var Qq=w(Lo=>{"use strict";Object.defineProperty(Lo,"__esModule",{value:!0});Lo.addNoneTerminalToCst=Lo.addTerminalToCst=Lo.setNodeLocationFull=Lo.setNodeLocationOnlyOffset=void 0;function aye(r,e){isNaN(r.startOffset)===!0?(r.startOffset=e.startOffset,r.endOffset=e.endOffset):r.endOffset{"use strict";Object.defineProperty(MA,"__esModule",{value:!0});MA.defineNameProp=MA.functionName=MA.classNameFromInstance=void 0;var uye=Gt();function gye(r){return Sq(r.constructor)}MA.classNameFromInstance=gye;var bq="name";function Sq(r){var e=r.name;return e||"anonymous"}MA.functionName=Sq;function fye(r,e){var t=Object.getOwnPropertyDescriptor(r,bq);return(0,uye.isUndefined)(t)||t.configurable?(Object.defineProperty(r,bq,{enumerable:!1,configurable:!0,writable:!1,value:e}),!0):!1}MA.defineNameProp=fye});var kq=w(Si=>{"use strict";Object.defineProperty(Si,"__esModule",{value:!0});Si.validateRedundantMethods=Si.validateMissingCstMethods=Si.validateVisitor=Si.CstVisitorDefinitionError=Si.createBaseVisitorConstructorWithDefaults=Si.createBaseSemanticVisitorConstructor=Si.defaultVisit=void 0;var ps=Gt(),Nd=ox();function vq(r,e){for(var t=(0,ps.keys)(r),i=t.length,n=0;n: + `+(""+s.join(` + +`).replace(/\n/g,` + `)))}}};return t.prototype=i,t.prototype.constructor=t,t._RULE_NAMES=e,t}Si.createBaseSemanticVisitorConstructor=hye;function pye(r,e,t){var i=function(){};(0,Nd.defineNameProp)(i,r+"BaseSemanticsWithDefaults");var n=Object.create(t.prototype);return(0,ps.forEach)(e,function(s){n[s]=vq}),i.prototype=n,i.prototype.constructor=i,i}Si.createBaseVisitorConstructorWithDefaults=pye;var ax;(function(r){r[r.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",r[r.MISSING_METHOD=1]="MISSING_METHOD"})(ax=Si.CstVisitorDefinitionError||(Si.CstVisitorDefinitionError={}));function xq(r,e){var t=Pq(r,e),i=Dq(r,e);return t.concat(i)}Si.validateVisitor=xq;function Pq(r,e){var t=(0,ps.map)(e,function(i){if(!(0,ps.isFunction)(r[i]))return{msg:"Missing visitor method: <"+i+"> on "+(0,Nd.functionName)(r.constructor)+" CST Visitor.",type:ax.MISSING_METHOD,methodName:i}});return(0,ps.compact)(t)}Si.validateMissingCstMethods=Pq;var dye=["constructor","visit","validateVisitor"];function Dq(r,e){var t=[];for(var i in r)(0,ps.isFunction)(r[i])&&!(0,ps.contains)(dye,i)&&!(0,ps.contains)(e,i)&&t.push({msg:"Redundant visitor method: <"+i+"> on "+(0,Nd.functionName)(r.constructor)+` CST Visitor +There is no Grammar Rule corresponding to this method's name. +`,type:ax.REDUNDANT_METHOD,methodName:i});return t}Si.validateRedundantMethods=Dq});var Fq=w(Ey=>{"use strict";Object.defineProperty(Ey,"__esModule",{value:!0});Ey.TreeBuilder=void 0;var sf=Qq(),_r=Gt(),Rq=kq(),Cye=Yn(),mye=function(){function r(){}return r.prototype.initTreeBuilder=function(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=(0,_r.has)(e,"nodeLocationTracking")?e.nodeLocationTracking:Cye.DEFAULT_PARSER_CONFIG.nodeLocationTracking,!this.outputCst)this.cstInvocationStateUpdate=_r.NOOP,this.cstFinallyStateUpdate=_r.NOOP,this.cstPostTerminal=_r.NOOP,this.cstPostNonTerminal=_r.NOOP,this.cstPostRule=_r.NOOP;else if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=sf.setNodeLocationFull,this.setNodeLocationFromNode=sf.setNodeLocationFull,this.cstPostRule=_r.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=_r.NOOP,this.setNodeLocationFromNode=_r.NOOP,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=sf.setNodeLocationOnlyOffset,this.setNodeLocationFromNode=sf.setNodeLocationOnlyOffset,this.cstPostRule=_r.NOOP,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=_r.NOOP,this.setNodeLocationFromNode=_r.NOOP,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else if(/none/i.test(this.nodeLocationTracking))this.setNodeLocationFromToken=_r.NOOP,this.setNodeLocationFromNode=_r.NOOP,this.cstPostRule=_r.NOOP,this.setInitialNodeLocation=_r.NOOP;else throw Error('Invalid config option: "'+e.nodeLocationTracking+'"')},r.prototype.setInitialNodeLocationOnlyOffsetRecovery=function(e){e.location={startOffset:NaN,endOffset:NaN}},r.prototype.setInitialNodeLocationOnlyOffsetRegular=function(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}},r.prototype.setInitialNodeLocationFullRecovery=function(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.setInitialNodeLocationFullRegular=function(e){var t=this.LA(1);e.location={startOffset:t.startOffset,startLine:t.startLine,startColumn:t.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}},r.prototype.cstInvocationStateUpdate=function(e,t){var i={name:e,children:{}};this.setInitialNodeLocation(i),this.CST_STACK.push(i)},r.prototype.cstFinallyStateUpdate=function(){this.CST_STACK.pop()},r.prototype.cstPostRuleFull=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?(i.endOffset=t.endOffset,i.endLine=t.endLine,i.endColumn=t.endColumn):(i.startOffset=NaN,i.startLine=NaN,i.startColumn=NaN)},r.prototype.cstPostRuleOnlyOffset=function(e){var t=this.LA(0),i=e.location;i.startOffset<=t.startOffset?i.endOffset=t.endOffset:i.startOffset=NaN},r.prototype.cstPostTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,sf.addTerminalToCst)(i,t,e),this.setNodeLocationFromToken(i.location,t)},r.prototype.cstPostNonTerminal=function(e,t){var i=this.CST_STACK[this.CST_STACK.length-1];(0,sf.addNoneTerminalToCst)(i,t,e),this.setNodeLocationFromNode(i.location,e.location)},r.prototype.getBaseCstVisitorConstructor=function(){if((0,_r.isUndefined)(this.baseCstVisitorConstructor)){var e=(0,Rq.createBaseSemanticVisitorConstructor)(this.className,(0,_r.keys)(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor},r.prototype.getBaseCstVisitorConstructorWithDefaults=function(){if((0,_r.isUndefined)(this.baseCstVisitorWithDefaultsConstructor)){var e=(0,Rq.createBaseVisitorConstructorWithDefaults)(this.className,(0,_r.keys)(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor},r.prototype.getLastExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-1]},r.prototype.getPreviousExplicitRuleShortName=function(){var e=this.RULE_STACK;return e[e.length-2]},r.prototype.getLastExplicitRuleOccurrenceIndex=function(){var e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]},r}();Ey.TreeBuilder=mye});var Lq=w(Iy=>{"use strict";Object.defineProperty(Iy,"__esModule",{value:!0});Iy.LexerAdapter=void 0;var Nq=Yn(),Eye=function(){function r(){}return r.prototype.initLexerAdapter=function(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1},Object.defineProperty(r.prototype,"input",{get:function(){return this.tokVector},set:function(e){if(this.selfAnalysisDone!==!0)throw Error("Missing invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length},enumerable:!1,configurable:!0}),r.prototype.SKIP_TOKEN=function(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):Nq.END_OF_FILE},r.prototype.LA=function(e){var t=this.currIdx+e;return t<0||this.tokVectorLength<=t?Nq.END_OF_FILE:this.tokVector[t]},r.prototype.consumeToken=function(){this.currIdx++},r.prototype.exportLexerState=function(){return this.currIdx},r.prototype.importLexerState=function(e){this.currIdx=e},r.prototype.resetLexerState=function(){this.currIdx=-1},r.prototype.moveToTerminatedState=function(){this.currIdx=this.tokVector.length-1},r.prototype.getLexerPosition=function(){return this.exportLexerState()},r}();Iy.LexerAdapter=Eye});var Oq=w(yy=>{"use strict";Object.defineProperty(yy,"__esModule",{value:!0});yy.RecognizerApi=void 0;var Tq=Gt(),Iye=nf(),Ax=Yn(),yye=xd(),wye=rx(),Bye=Cn(),Qye=function(){function r(){}return r.prototype.ACTION=function(e){return e.call(this)},r.prototype.consume=function(e,t,i){return this.consumeInternal(t,e,i)},r.prototype.subrule=function(e,t,i){return this.subruleInternal(t,e,i)},r.prototype.option=function(e,t){return this.optionInternal(t,e)},r.prototype.or=function(e,t){return this.orInternal(t,e)},r.prototype.many=function(e,t){return this.manyInternal(e,t)},r.prototype.atLeastOne=function(e,t){return this.atLeastOneInternal(e,t)},r.prototype.CONSUME=function(e,t){return this.consumeInternal(e,0,t)},r.prototype.CONSUME1=function(e,t){return this.consumeInternal(e,1,t)},r.prototype.CONSUME2=function(e,t){return this.consumeInternal(e,2,t)},r.prototype.CONSUME3=function(e,t){return this.consumeInternal(e,3,t)},r.prototype.CONSUME4=function(e,t){return this.consumeInternal(e,4,t)},r.prototype.CONSUME5=function(e,t){return this.consumeInternal(e,5,t)},r.prototype.CONSUME6=function(e,t){return this.consumeInternal(e,6,t)},r.prototype.CONSUME7=function(e,t){return this.consumeInternal(e,7,t)},r.prototype.CONSUME8=function(e,t){return this.consumeInternal(e,8,t)},r.prototype.CONSUME9=function(e,t){return this.consumeInternal(e,9,t)},r.prototype.SUBRULE=function(e,t){return this.subruleInternal(e,0,t)},r.prototype.SUBRULE1=function(e,t){return this.subruleInternal(e,1,t)},r.prototype.SUBRULE2=function(e,t){return this.subruleInternal(e,2,t)},r.prototype.SUBRULE3=function(e,t){return this.subruleInternal(e,3,t)},r.prototype.SUBRULE4=function(e,t){return this.subruleInternal(e,4,t)},r.prototype.SUBRULE5=function(e,t){return this.subruleInternal(e,5,t)},r.prototype.SUBRULE6=function(e,t){return this.subruleInternal(e,6,t)},r.prototype.SUBRULE7=function(e,t){return this.subruleInternal(e,7,t)},r.prototype.SUBRULE8=function(e,t){return this.subruleInternal(e,8,t)},r.prototype.SUBRULE9=function(e,t){return this.subruleInternal(e,9,t)},r.prototype.OPTION=function(e){return this.optionInternal(e,0)},r.prototype.OPTION1=function(e){return this.optionInternal(e,1)},r.prototype.OPTION2=function(e){return this.optionInternal(e,2)},r.prototype.OPTION3=function(e){return this.optionInternal(e,3)},r.prototype.OPTION4=function(e){return this.optionInternal(e,4)},r.prototype.OPTION5=function(e){return this.optionInternal(e,5)},r.prototype.OPTION6=function(e){return this.optionInternal(e,6)},r.prototype.OPTION7=function(e){return this.optionInternal(e,7)},r.prototype.OPTION8=function(e){return this.optionInternal(e,8)},r.prototype.OPTION9=function(e){return this.optionInternal(e,9)},r.prototype.OR=function(e){return this.orInternal(e,0)},r.prototype.OR1=function(e){return this.orInternal(e,1)},r.prototype.OR2=function(e){return this.orInternal(e,2)},r.prototype.OR3=function(e){return this.orInternal(e,3)},r.prototype.OR4=function(e){return this.orInternal(e,4)},r.prototype.OR5=function(e){return this.orInternal(e,5)},r.prototype.OR6=function(e){return this.orInternal(e,6)},r.prototype.OR7=function(e){return this.orInternal(e,7)},r.prototype.OR8=function(e){return this.orInternal(e,8)},r.prototype.OR9=function(e){return this.orInternal(e,9)},r.prototype.MANY=function(e){this.manyInternal(0,e)},r.prototype.MANY1=function(e){this.manyInternal(1,e)},r.prototype.MANY2=function(e){this.manyInternal(2,e)},r.prototype.MANY3=function(e){this.manyInternal(3,e)},r.prototype.MANY4=function(e){this.manyInternal(4,e)},r.prototype.MANY5=function(e){this.manyInternal(5,e)},r.prototype.MANY6=function(e){this.manyInternal(6,e)},r.prototype.MANY7=function(e){this.manyInternal(7,e)},r.prototype.MANY8=function(e){this.manyInternal(8,e)},r.prototype.MANY9=function(e){this.manyInternal(9,e)},r.prototype.MANY_SEP=function(e){this.manySepFirstInternal(0,e)},r.prototype.MANY_SEP1=function(e){this.manySepFirstInternal(1,e)},r.prototype.MANY_SEP2=function(e){this.manySepFirstInternal(2,e)},r.prototype.MANY_SEP3=function(e){this.manySepFirstInternal(3,e)},r.prototype.MANY_SEP4=function(e){this.manySepFirstInternal(4,e)},r.prototype.MANY_SEP5=function(e){this.manySepFirstInternal(5,e)},r.prototype.MANY_SEP6=function(e){this.manySepFirstInternal(6,e)},r.prototype.MANY_SEP7=function(e){this.manySepFirstInternal(7,e)},r.prototype.MANY_SEP8=function(e){this.manySepFirstInternal(8,e)},r.prototype.MANY_SEP9=function(e){this.manySepFirstInternal(9,e)},r.prototype.AT_LEAST_ONE=function(e){this.atLeastOneInternal(0,e)},r.prototype.AT_LEAST_ONE1=function(e){return this.atLeastOneInternal(1,e)},r.prototype.AT_LEAST_ONE2=function(e){this.atLeastOneInternal(2,e)},r.prototype.AT_LEAST_ONE3=function(e){this.atLeastOneInternal(3,e)},r.prototype.AT_LEAST_ONE4=function(e){this.atLeastOneInternal(4,e)},r.prototype.AT_LEAST_ONE5=function(e){this.atLeastOneInternal(5,e)},r.prototype.AT_LEAST_ONE6=function(e){this.atLeastOneInternal(6,e)},r.prototype.AT_LEAST_ONE7=function(e){this.atLeastOneInternal(7,e)},r.prototype.AT_LEAST_ONE8=function(e){this.atLeastOneInternal(8,e)},r.prototype.AT_LEAST_ONE9=function(e){this.atLeastOneInternal(9,e)},r.prototype.AT_LEAST_ONE_SEP=function(e){this.atLeastOneSepFirstInternal(0,e)},r.prototype.AT_LEAST_ONE_SEP1=function(e){this.atLeastOneSepFirstInternal(1,e)},r.prototype.AT_LEAST_ONE_SEP2=function(e){this.atLeastOneSepFirstInternal(2,e)},r.prototype.AT_LEAST_ONE_SEP3=function(e){this.atLeastOneSepFirstInternal(3,e)},r.prototype.AT_LEAST_ONE_SEP4=function(e){this.atLeastOneSepFirstInternal(4,e)},r.prototype.AT_LEAST_ONE_SEP5=function(e){this.atLeastOneSepFirstInternal(5,e)},r.prototype.AT_LEAST_ONE_SEP6=function(e){this.atLeastOneSepFirstInternal(6,e)},r.prototype.AT_LEAST_ONE_SEP7=function(e){this.atLeastOneSepFirstInternal(7,e)},r.prototype.AT_LEAST_ONE_SEP8=function(e){this.atLeastOneSepFirstInternal(8,e)},r.prototype.AT_LEAST_ONE_SEP9=function(e){this.atLeastOneSepFirstInternal(9,e)},r.prototype.RULE=function(e,t,i){if(i===void 0&&(i=Ax.DEFAULT_RULE_CONFIG),(0,Tq.contains)(this.definedRulesNames,e)){var n=yye.defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),s={message:n,type:Ax.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(s)}this.definedRulesNames.push(e);var o=this.defineRule(e,t,i);return this[e]=o,o},r.prototype.OVERRIDE_RULE=function(e,t,i){i===void 0&&(i=Ax.DEFAULT_RULE_CONFIG);var n=[];n=n.concat((0,wye.validateRuleIsOverridden)(e,this.definedRulesNames,this.className)),this.definitionErrors=this.definitionErrors.concat(n);var s=this.defineRule(e,t,i);return this[e]=s,s},r.prototype.BACKTRACK=function(e,t){return function(){this.isBackTrackingStack.push(1);var i=this.saveRecogState();try{return e.apply(this,t),!0}catch(n){if((0,Iye.isRecognitionException)(n))return!1;throw n}finally{this.reloadRecogState(i),this.isBackTrackingStack.pop()}}},r.prototype.getGAstProductions=function(){return this.gastProductionsCache},r.prototype.getSerializedGastProductions=function(){return(0,Bye.serializeGrammar)((0,Tq.values)(this.gastProductionsCache))},r}();yy.RecognizerApi=Qye});var Hq=w(By=>{"use strict";Object.defineProperty(By,"__esModule",{value:!0});By.RecognizerEngine=void 0;var Pr=Gt(),jn=Cy(),wy=nf(),Mq=kd(),of=Dd(),Uq=Yn(),bye=sx(),Kq=LA(),Ld=_g(),Sye=ox(),vye=function(){function r(){}return r.prototype.initRecognizerEngine=function(e,t){if(this.className=(0,Sye.classNameFromInstance)(this),this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=Ld.tokenStructuredMatcherNoCategories,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},(0,Pr.has)(t,"serializedGrammar"))throw Error(`The Parser's configuration can no longer contain a property. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0 + For Further details.`);if((0,Pr.isArray)(e)){if((0,Pr.isEmpty)(e))throw Error(`A Token Vocabulary cannot be empty. + Note that the first argument for the parser constructor + is no longer a Token vector (since v4.0).`);if(typeof e[0].startOffset=="number")throw Error(`The Parser constructor no longer accepts a token vector as the first argument. + See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0 + For Further details.`)}if((0,Pr.isArray)(e))this.tokensMap=(0,Pr.reduce)(e,function(o,a){return o[a.name]=a,o},{});else if((0,Pr.has)(e,"modes")&&(0,Pr.every)((0,Pr.flatten)((0,Pr.values)(e.modes)),Ld.isTokenType)){var i=(0,Pr.flatten)((0,Pr.values)(e.modes)),n=(0,Pr.uniq)(i);this.tokensMap=(0,Pr.reduce)(n,function(o,a){return o[a.name]=a,o},{})}else if((0,Pr.isObject)(e))this.tokensMap=(0,Pr.cloneObj)(e);else throw new Error(" argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap.EOF=Kq.EOF;var s=(0,Pr.every)((0,Pr.values)(e),function(o){return(0,Pr.isEmpty)(o.categoryMatches)});this.tokenMatcher=s?Ld.tokenStructuredMatcherNoCategories:Ld.tokenStructuredMatcher,(0,Ld.augmentTokenTypes)((0,Pr.values)(this.tokensMap))},r.prototype.defineRule=function(e,t,i){if(this.selfAnalysisDone)throw Error("Grammar rule <"+e+`> may not be defined after the 'performSelfAnalysis' method has been called' +Make sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);var n=(0,Pr.has)(i,"resyncEnabled")?i.resyncEnabled:Uq.DEFAULT_RULE_CONFIG.resyncEnabled,s=(0,Pr.has)(i,"recoveryValueFunc")?i.recoveryValueFunc:Uq.DEFAULT_RULE_CONFIG.recoveryValueFunc,o=this.ruleShortNameIdx<t},r.prototype.orInternal=function(e,t){var i=this.getKeyForAutomaticLookahead(jn.OR_IDX,t),n=(0,Pr.isArray)(e)?e:e.DEF,s=this.getLaFuncFromCache(i),o=s.call(this,n);if(o!==void 0){var a=n[o];return a.ALT.call(this)}this.raiseNoAltException(t,e.ERR_MSG)},r.prototype.ruleFinallyStateUpdate=function(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),this.RULE_STACK.length===0&&this.isAtEndOfInput()===!1){var e=this.LA(1),t=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new wy.NotAllInputParsedException(t,e))}},r.prototype.subruleInternal=function(e,t,i){var n;try{var s=i!==void 0?i.ARGS:void 0;return n=e.call(this,t,s),this.cstPostNonTerminal(n,i!==void 0&&i.LABEL!==void 0?i.LABEL:e.ruleName),n}catch(o){this.subruleInternalError(o,i,e.ruleName)}},r.prototype.subruleInternalError=function(e,t,i){throw(0,wy.isRecognitionException)(e)&&e.partialCstResult!==void 0&&(this.cstPostNonTerminal(e.partialCstResult,t!==void 0&&t.LABEL!==void 0?t.LABEL:i),delete e.partialCstResult),e},r.prototype.consumeInternal=function(e,t,i){var n;try{var s=this.LA(1);this.tokenMatcher(s,e)===!0?(this.consumeToken(),n=s):this.consumeInternalError(e,s,i)}catch(o){n=this.consumeInternalRecovery(e,t,o)}return this.cstPostTerminal(i!==void 0&&i.LABEL!==void 0?i.LABEL:e.name,n),n},r.prototype.consumeInternalError=function(e,t,i){var n,s=this.LA(0);throw i!==void 0&&i.ERR_MSG?n=i.ERR_MSG:n=this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:t,previous:s,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new wy.MismatchedTokenException(n,t,s))},r.prototype.consumeInternalRecovery=function(e,t,i){if(this.recoveryEnabled&&i.name==="MismatchedTokenException"&&!this.isBackTracking()){var n=this.getFollowsForInRuleRecovery(e,t);try{return this.tryInRuleRecovery(e,n)}catch(s){throw s.name===bye.IN_RULE_RECOVERY_EXCEPTION?i:s}}else throw i},r.prototype.saveRecogState=function(){var e=this.errors,t=(0,Pr.cloneArr)(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:t,CST_STACK:this.CST_STACK}},r.prototype.reloadRecogState=function(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK},r.prototype.ruleInvocationStateUpdate=function(e,t,i){this.RULE_OCCURRENCE_STACK.push(i),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(t,e)},r.prototype.isBackTracking=function(){return this.isBackTrackingStack.length!==0},r.prototype.getCurrRuleFullName=function(){var e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]},r.prototype.shortRuleNameToFullName=function(e){return this.shortRuleNameToFull[e]},r.prototype.isAtEndOfInput=function(){return this.tokenMatcher(this.LA(1),Kq.EOF)},r.prototype.reset=function(){this.resetLexerState(),this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]},r}();By.RecognizerEngine=vye});var Yq=w(Qy=>{"use strict";Object.defineProperty(Qy,"__esModule",{value:!0});Qy.ErrorHandler=void 0;var lx=nf(),cx=Gt(),Gq=kd(),xye=Yn(),Pye=function(){function r(){}return r.prototype.initErrorHandler=function(e){this._errors=[],this.errorMessageProvider=(0,cx.has)(e,"errorMessageProvider")?e.errorMessageProvider:xye.DEFAULT_PARSER_CONFIG.errorMessageProvider},r.prototype.SAVE_ERROR=function(e){if((0,lx.isRecognitionException)(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:(0,cx.cloneArr)(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")},Object.defineProperty(r.prototype,"errors",{get:function(){return(0,cx.cloneArr)(this._errors)},set:function(e){this._errors=e},enumerable:!1,configurable:!0}),r.prototype.raiseEarlyExitException=function(e,t,i){for(var n=this.getCurrRuleFullName(),s=this.getGAstProductions()[n],o=(0,Gq.getLookaheadPathsForOptionalProd)(e,s,t,this.maxLookahead),a=o[0],l=[],c=1;c<=this.maxLookahead;c++)l.push(this.LA(c));var u=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:a,actual:l,previous:this.LA(0),customUserDescription:i,ruleName:n});throw this.SAVE_ERROR(new lx.EarlyExitException(u,this.LA(1),this.LA(0)))},r.prototype.raiseNoAltException=function(e,t){for(var i=this.getCurrRuleFullName(),n=this.getGAstProductions()[i],s=(0,Gq.getLookaheadPathsForOr)(e,n,this.maxLookahead),o=[],a=1;a<=this.maxLookahead;a++)o.push(this.LA(a));var l=this.LA(0),c=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:s,actual:o,previous:l,customUserDescription:t,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new lx.NoViableAltException(c,this.LA(1),l))},r}();Qy.ErrorHandler=Pye});var Jq=w(by=>{"use strict";Object.defineProperty(by,"__esModule",{value:!0});by.ContentAssist=void 0;var jq=Dd(),qq=Gt(),Dye=function(){function r(){}return r.prototype.initContentAssist=function(){},r.prototype.computeContentAssist=function(e,t){var i=this.gastProductionsCache[e];if((0,qq.isUndefined)(i))throw Error("Rule ->"+e+"<- does not exist in this grammar.");return(0,jq.nextPossibleTokensAfter)([i],t,this.tokenMatcher,this.maxLookahead)},r.prototype.getNextPossibleTokenTypes=function(e){var t=(0,qq.first)(e.ruleStack),i=this.getGAstProductions(),n=i[t],s=new jq.NextAfterTokenWalker(n,e).startWalking();return s},r}();by.ContentAssist=Dye});var eJ=w(xy=>{"use strict";Object.defineProperty(xy,"__esModule",{value:!0});xy.GastRecorder=void 0;var In=Gt(),To=Cn(),kye=Bd(),Xq=_g(),Zq=LA(),Rye=Yn(),Fye=Cy(),vy={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(vy);var Wq=!0,zq=Math.pow(2,Fye.BITS_FOR_OCCURRENCE_IDX)-1,_q=(0,Zq.createToken)({name:"RECORDING_PHASE_TOKEN",pattern:kye.Lexer.NA});(0,Xq.augmentTokenTypes)([_q]);var $q=(0,Zq.createTokenInstance)(_q,`This IToken indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,-1,-1,-1,-1,-1,-1);Object.freeze($q);var Nye={name:`This CSTNode indicates the Parser is in Recording Phase + See: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details`,children:{}},Lye=function(){function r(){}return r.prototype.initGastRecorder=function(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1},r.prototype.enableRecording=function(){var e=this;this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",function(){for(var t=function(n){var s=n>0?n:"";e["CONSUME"+s]=function(o,a){return this.consumeInternalRecord(o,n,a)},e["SUBRULE"+s]=function(o,a){return this.subruleInternalRecord(o,n,a)},e["OPTION"+s]=function(o){return this.optionInternalRecord(o,n)},e["OR"+s]=function(o){return this.orInternalRecord(o,n)},e["MANY"+s]=function(o){this.manyInternalRecord(n,o)},e["MANY_SEP"+s]=function(o){this.manySepFirstInternalRecord(n,o)},e["AT_LEAST_ONE"+s]=function(o){this.atLeastOneInternalRecord(n,o)},e["AT_LEAST_ONE_SEP"+s]=function(o){this.atLeastOneSepFirstInternalRecord(n,o)}},i=0;i<10;i++)t(i);e.consume=function(n,s,o){return this.consumeInternalRecord(s,n,o)},e.subrule=function(n,s,o){return this.subruleInternalRecord(s,n,o)},e.option=function(n,s){return this.optionInternalRecord(s,n)},e.or=function(n,s){return this.orInternalRecord(s,n)},e.many=function(n,s){this.manyInternalRecord(n,s)},e.atLeastOne=function(n,s){this.atLeastOneInternalRecord(n,s)},e.ACTION=e.ACTION_RECORD,e.BACKTRACK=e.BACKTRACK_RECORD,e.LA=e.LA_RECORD})},r.prototype.disableRecording=function(){var e=this;this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",function(){for(var t=0;t<10;t++){var i=t>0?t:"";delete e["CONSUME"+i],delete e["SUBRULE"+i],delete e["OPTION"+i],delete e["OR"+i],delete e["MANY"+i],delete e["MANY_SEP"+i],delete e["AT_LEAST_ONE"+i],delete e["AT_LEAST_ONE_SEP"+i]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA})},r.prototype.ACTION_RECORD=function(e){},r.prototype.BACKTRACK_RECORD=function(e,t){return function(){return!0}},r.prototype.LA_RECORD=function(e){return Rye.END_OF_FILE},r.prototype.topLevelRuleRecord=function(e,t){try{var i=new To.Rule({definition:[],name:e});return i.name=e,this.recordingProdStack.push(i),t.call(this),this.recordingProdStack.pop(),i}catch(n){if(n.KNOWN_RECORDER_ERROR!==!0)try{n.message=n.message+` + This error was thrown during the "grammar recording phase" For more info see: + https://chevrotain.io/docs/guide/internals.html#grammar-recording`}catch{throw n}throw n}},r.prototype.optionInternalRecord=function(e,t){return Td.call(this,To.Option,e,t)},r.prototype.atLeastOneInternalRecord=function(e,t){Td.call(this,To.RepetitionMandatory,t,e)},r.prototype.atLeastOneSepFirstInternalRecord=function(e,t){Td.call(this,To.RepetitionMandatoryWithSeparator,t,e,Wq)},r.prototype.manyInternalRecord=function(e,t){Td.call(this,To.Repetition,t,e)},r.prototype.manySepFirstInternalRecord=function(e,t){Td.call(this,To.RepetitionWithSeparator,t,e,Wq)},r.prototype.orInternalRecord=function(e,t){return Tye.call(this,e,t)},r.prototype.subruleInternalRecord=function(e,t,i){if(Sy(t),!e||(0,In.has)(e,"ruleName")===!1){var n=new Error(" argument is invalid"+(" expecting a Parser method reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,In.peek)(this.recordingProdStack),o=e.ruleName,a=new To.NonTerminal({idx:t,nonTerminalName:o,label:i==null?void 0:i.LABEL,referencedRule:void 0});return s.definition.push(a),this.outputCst?Nye:vy},r.prototype.consumeInternalRecord=function(e,t,i){if(Sy(t),!(0,Xq.hasShortKeyProperty)(e)){var n=new Error(" argument is invalid"+(" expecting a TokenType reference but got: <"+JSON.stringify(e)+">")+(` + inside top level rule: <`+this.recordingProdStack[0].name+">"));throw n.KNOWN_RECORDER_ERROR=!0,n}var s=(0,In.peek)(this.recordingProdStack),o=new To.Terminal({idx:t,terminalType:e,label:i==null?void 0:i.LABEL});return s.definition.push(o),$q},r}();xy.GastRecorder=Lye;function Td(r,e,t,i){i===void 0&&(i=!1),Sy(t);var n=(0,In.peek)(this.recordingProdStack),s=(0,In.isFunction)(e)?e:e.DEF,o=new r({definition:[],idx:t});return i&&(o.separator=e.SEP),(0,In.has)(e,"MAX_LOOKAHEAD")&&(o.maxLookahead=e.MAX_LOOKAHEAD),this.recordingProdStack.push(o),s.call(this),n.definition.push(o),this.recordingProdStack.pop(),vy}function Tye(r,e){var t=this;Sy(e);var i=(0,In.peek)(this.recordingProdStack),n=(0,In.isArray)(r)===!1,s=n===!1?r:r.DEF,o=new To.Alternation({definition:[],idx:e,ignoreAmbiguities:n&&r.IGNORE_AMBIGUITIES===!0});(0,In.has)(r,"MAX_LOOKAHEAD")&&(o.maxLookahead=r.MAX_LOOKAHEAD);var a=(0,In.some)(s,function(l){return(0,In.isFunction)(l.GATE)});return o.hasPredicates=a,i.definition.push(o),(0,In.forEach)(s,function(l){var c=new To.Alternative({definition:[]});o.definition.push(c),(0,In.has)(l,"IGNORE_AMBIGUITIES")?c.ignoreAmbiguities=l.IGNORE_AMBIGUITIES:(0,In.has)(l,"GATE")&&(c.ignoreAmbiguities=!0),t.recordingProdStack.push(c),l.ALT.call(t),t.recordingProdStack.pop()}),vy}function Vq(r){return r===0?"":""+r}function Sy(r){if(r<0||r>zq){var e=new Error("Invalid DSL Method idx value: <"+r+`> + `+("Idx value must be a none negative value smaller than "+(zq+1)));throw e.KNOWN_RECORDER_ERROR=!0,e}}});var rJ=w(Py=>{"use strict";Object.defineProperty(Py,"__esModule",{value:!0});Py.PerformanceTracer=void 0;var tJ=Gt(),Oye=Yn(),Mye=function(){function r(){}return r.prototype.initPerformanceTracer=function(e){if((0,tJ.has)(e,"traceInitPerf")){var t=e.traceInitPerf,i=typeof t=="number";this.traceInitMaxIdent=i?t:1/0,this.traceInitPerf=i?t>0:t}else this.traceInitMaxIdent=0,this.traceInitPerf=Oye.DEFAULT_PARSER_CONFIG.traceInitPerf;this.traceInitIndent=-1},r.prototype.TRACE_INIT=function(e,t){if(this.traceInitPerf===!0){this.traceInitIndent++;var i=new Array(this.traceInitIndent+1).join(" ");this.traceInitIndent <"+e+">");var n=(0,tJ.timer)(t),s=n.time,o=n.value,a=s>10?console.warn:console.log;return this.traceInitIndent time: "+s+"ms"),this.traceInitIndent--,o}else return t()},r}();Py.PerformanceTracer=Mye});var iJ=w(Dy=>{"use strict";Object.defineProperty(Dy,"__esModule",{value:!0});Dy.applyMixins=void 0;function Uye(r,e){e.forEach(function(t){var i=t.prototype;Object.getOwnPropertyNames(i).forEach(function(n){if(n!=="constructor"){var s=Object.getOwnPropertyDescriptor(i,n);s&&(s.get||s.set)?Object.defineProperty(r.prototype,n,s):r.prototype[n]=t.prototype[n]}})})}Dy.applyMixins=Uye});var Yn=w(dr=>{"use strict";var oJ=dr&&dr.__extends||function(){var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(i,n){i.__proto__=n}||function(i,n){for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(i[s]=n[s])},r(e,t)};return function(e,t){if(typeof t!="function"&&t!==null)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");r(e,t);function i(){this.constructor=e}e.prototype=t===null?Object.create(t):(i.prototype=t.prototype,new i)}}();Object.defineProperty(dr,"__esModule",{value:!0});dr.EmbeddedActionsParser=dr.CstParser=dr.Parser=dr.EMPTY_ALT=dr.ParserDefinitionErrorType=dr.DEFAULT_RULE_CONFIG=dr.DEFAULT_PARSER_CONFIG=dr.END_OF_FILE=void 0;var $i=Gt(),Kye=Yj(),nJ=LA(),aJ=xd(),sJ=pq(),Hye=sx(),Gye=Bq(),Yye=Fq(),jye=Lq(),qye=Oq(),Jye=Hq(),Wye=Yq(),zye=Jq(),Vye=eJ(),Xye=rJ(),Zye=iJ();dr.END_OF_FILE=(0,nJ.createTokenInstance)(nJ.EOF,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(dr.END_OF_FILE);dr.DEFAULT_PARSER_CONFIG=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:aJ.defaultParserErrorProvider,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1});dr.DEFAULT_RULE_CONFIG=Object.freeze({recoveryValueFunc:function(){},resyncEnabled:!0});var _ye;(function(r){r[r.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",r[r.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",r[r.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",r[r.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",r[r.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",r[r.LEFT_RECURSION=5]="LEFT_RECURSION",r[r.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",r[r.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",r[r.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",r[r.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",r[r.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",r[r.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",r[r.TOO_MANY_ALTS=12]="TOO_MANY_ALTS"})(_ye=dr.ParserDefinitionErrorType||(dr.ParserDefinitionErrorType={}));function $ye(r){return r===void 0&&(r=void 0),function(){return r}}dr.EMPTY_ALT=$ye;var ky=function(){function r(e,t){this.definitionErrors=[],this.selfAnalysisDone=!1;var i=this;if(i.initErrorHandler(t),i.initLexerAdapter(),i.initLooksAhead(t),i.initRecognizerEngine(e,t),i.initRecoverable(t),i.initTreeBuilder(t),i.initContentAssist(),i.initGastRecorder(t),i.initPerformanceTracer(t),(0,$i.has)(t,"ignoredIssues"))throw new Error(`The IParserConfig property has been deprecated. + Please use the flag on the relevant DSL method instead. + See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES + For further details.`);this.skipValidations=(0,$i.has)(t,"skipValidations")?t.skipValidations:dr.DEFAULT_PARSER_CONFIG.skipValidations}return r.performSelfAnalysis=function(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated. \nUse the **instance** method with the same name instead.")},r.prototype.performSelfAnalysis=function(){var e=this;this.TRACE_INIT("performSelfAnalysis",function(){var t;e.selfAnalysisDone=!0;var i=e.className;e.TRACE_INIT("toFastProps",function(){(0,$i.toFastProperties)(e)}),e.TRACE_INIT("Grammar Recording",function(){try{e.enableRecording(),(0,$i.forEach)(e.definedRulesNames,function(s){var o=e[s],a=o.originalGrammarAction,l=void 0;e.TRACE_INIT(s+" Rule",function(){l=e.topLevelRuleRecord(s,a)}),e.gastProductionsCache[s]=l})}finally{e.disableRecording()}});var n=[];if(e.TRACE_INIT("Grammar Resolving",function(){n=(0,sJ.resolveGrammar)({rules:(0,$i.values)(e.gastProductionsCache)}),e.definitionErrors=e.definitionErrors.concat(n)}),e.TRACE_INIT("Grammar Validations",function(){if((0,$i.isEmpty)(n)&&e.skipValidations===!1){var s=(0,sJ.validateGrammar)({rules:(0,$i.values)(e.gastProductionsCache),maxLookahead:e.maxLookahead,tokenTypes:(0,$i.values)(e.tokensMap),errMsgProvider:aJ.defaultGrammarValidatorErrorProvider,grammarName:i});e.definitionErrors=e.definitionErrors.concat(s)}}),(0,$i.isEmpty)(e.definitionErrors)&&(e.recoveryEnabled&&e.TRACE_INIT("computeAllProdsFollows",function(){var s=(0,Kye.computeAllProdsFollows)((0,$i.values)(e.gastProductionsCache));e.resyncFollows=s}),e.TRACE_INIT("ComputeLookaheadFunctions",function(){e.preComputeLookaheadFunctions((0,$i.values)(e.gastProductionsCache))})),!r.DEFER_DEFINITION_ERRORS_HANDLING&&!(0,$i.isEmpty)(e.definitionErrors))throw t=(0,$i.map)(e.definitionErrors,function(s){return s.message}),new Error(`Parser Definition Errors detected: + `+t.join(` +------------------------------- +`))})},r.DEFER_DEFINITION_ERRORS_HANDLING=!1,r}();dr.Parser=ky;(0,Zye.applyMixins)(ky,[Hye.Recoverable,Gye.LooksAhead,Yye.TreeBuilder,jye.LexerAdapter,Jye.RecognizerEngine,qye.RecognizerApi,Wye.ErrorHandler,zye.ContentAssist,Vye.GastRecorder,Xye.PerformanceTracer]);var ewe=function(r){oJ(e,r);function e(t,i){i===void 0&&(i=dr.DEFAULT_PARSER_CONFIG);var n=this,s=(0,$i.cloneObj)(i);return s.outputCst=!0,n=r.call(this,t,s)||this,n}return e}(ky);dr.CstParser=ewe;var twe=function(r){oJ(e,r);function e(t,i){i===void 0&&(i=dr.DEFAULT_PARSER_CONFIG);var n=this,s=(0,$i.cloneObj)(i);return s.outputCst=!1,n=r.call(this,t,s)||this,n}return e}(ky);dr.EmbeddedActionsParser=twe});var lJ=w(Ry=>{"use strict";Object.defineProperty(Ry,"__esModule",{value:!0});Ry.createSyntaxDiagramsCode=void 0;var AJ=Dv();function rwe(r,e){var t=e===void 0?{}:e,i=t.resourceBase,n=i===void 0?"https://unpkg.com/chevrotain@"+AJ.VERSION+"/diagrams/":i,s=t.css,o=s===void 0?"https://unpkg.com/chevrotain@"+AJ.VERSION+"/diagrams/diagrams.css":s,a=` + + + + + +`,l=` + +`,c=` +