diff --git a/.bazelrc b/.bazelrc index 2816269e3..25f27d3c2 100644 --- a/.bazelrc +++ b/.bazelrc @@ -22,7 +22,8 @@ build --@rules_rust//rust/toolchain/channel=nightly # --- Rust validation (replaces cargo clippy/nextest in CI) -------------------- # Mirrors cargo semantics: crates with `[lints] workspace = true` (pi-ast, -# pi-iso, pi-natives, pi-shell, pi-walker) get the strict workspace policy +# pi-iso, pi-natives, pi-shell, pi-voice, pi-walker) get the strict workspace +# policy # (clippy-strict; bazel/clippy.bazelrc is generated from Cargo.toml); everything # else gets default clippy + -Dwarnings (clippy). build:clippy --aspects=@rules_rust//rust:defs.bzl%rust_clippy_aspect diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml new file mode 100644 index 000000000..73bd0da5a --- /dev/null +++ b/.github/actionlint.yaml @@ -0,0 +1,6 @@ +# actionlint only knows GitHub-hosted labels; register the self-hosted ARC +# runner scale set (infra/docs/04-arc-and-caching.md) so `runs-on: omp-kata` +# lints clean. +self-hosted-runner: + labels: + - omp-kata diff --git a/.github/actions/bazel-cache/action.yml b/.github/actions/bazel-cache/action.yml index 6d3239fcc..6247e2c9f 100644 --- a/.github/actions/bazel-cache/action.yml +++ b/.github/actions/bazel-cache/action.yml @@ -12,11 +12,17 @@ description: > The v3 key is -: config covers toolchain and build settings, source covers crates/** + BUILD.bazel. Restores fall - back to the config-scoped prefix, so a source generation the exact key - has never seen still seeds from the previous generation's archive, and - the refreshed archive is saved after the build (an exact hit suppresses + back to the config-scoped prefix, then to a bare scope+os+arch prefix: + the config hash covers Cargo.toml/Cargo.lock, which every release + version bump rewrites, so without the bare fallback each release built + the darwin addons fully cold (~40-50 min on macos-15-intel; CI run + 30357804722). A stale-config archive is safe — bazel keys every + action by content digest, so mismatched entries just miss — and the + refreshed archive is saved after the build (an exact hit suppresses the save — without the source component the first archive for a config - generation would permanently shadow newer source states). + generation would permanently shadow newer source states). Restored + entries untouched for 14 days are pruned before the build so + ever-seeding archives don't grow without bound. inputs: scope: @@ -58,10 +64,12 @@ runs: fi key="bazel-disk-v3-${{ inputs.scope }}-${{ runner.os }}-${{ runner.arch }}-$CONFIG_HASH-$SOURCE_HASH" prefix="bazel-disk-v3-${{ inputs.scope }}-${{ runner.os }}-${{ runner.arch }}-$CONFIG_HASH-" + bare_prefix="bazel-disk-v3-${{ inputs.scope }}-${{ runner.os }}-${{ runner.arch }}-" { echo "remote=$remote" echo "cache-key=$key" echo "cache-prefix=$prefix" + echo "cache-bare-prefix=$bare_prefix" } >> "$GITHUB_OUTPUT" - name: Restore bazel disk cache @@ -69,10 +77,23 @@ runs: if: steps.backend.outputs.remote != 'true' uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: - path: ~/.cache/omp-bazel-disk + # Both caches ride one archive: the action cache AND the repository + # cache (downloads + extracted repo contents at repo/contents, which + # reproducible repo rules reuse across output bases). Without the + # repo half, every hosted job re-downloaded and re-extracted the + # rust/LLVM/zig toolchains. Save sites must list the same paths. + path: | + ~/.cache/omp-bazel-disk + ~/.cache/omp-bazel-repo key: ${{ steps.backend.outputs.cache-key }} + # Order matters: exact key, same-config prefix, then any archive for + # this scope+os+arch. The bare fallback is what keeps release version + # bumps (Cargo.toml/Cargo.lock churn -> new CONFIG_HASH) from going + # fully cold; bazel's content-addressed action keys make a + # stale-config archive a partial hit, never a wrong output. restore-keys: | ${{ steps.backend.outputs.cache-prefix }} + ${{ steps.backend.outputs.cache-bare-prefix }} - name: Compose cache config id: compose @@ -112,6 +133,14 @@ runs: } > "$rc" else mkdir -p "$HOME/.cache/omp-bazel-disk" "$HOME/.cache/omp-bazel-repo" + # Seeding from stale archives means entries dead source + # generations wrote would otherwise ride along forever; drop + # anything untouched for 14 days (tar preserves mtimes across + # the actions/cache round trip, so age survives restores). + # Covers the repo download/contents cache too — bazel's own + # contents-cache GC only runs on idle servers, which short-lived + # CI invocations never have. + find "$HOME/.cache/omp-bazel-disk" "$HOME/.cache/omp-bazel-repo" -type f -mtime +14 -delete 2>/dev/null || true { echo "common --config=ci" echo "common --disk_cache=$HOME/.cache/omp-bazel-disk" diff --git a/.github/actions/bazel-natives/action.yml b/.github/actions/bazel-natives/action.yml index 8dfbf9457..408548d1e 100644 --- a/.github/actions/bazel-natives/action.yml +++ b/.github/actions/bazel-natives/action.yml @@ -43,5 +43,8 @@ runs: if: steps.cache.outputs.save-needed == 'true' uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: - path: ~/.cache/omp-bazel-disk + # Must mirror the restore path list in the bazel-cache action. + path: | + ~/.cache/omp-bazel-disk + ~/.cache/omp-bazel-repo key: ${{ steps.cache.outputs.cache-key }} \ No newline at end of file diff --git a/.github/actions/bun-install/action.yml b/.github/actions/bun-install/action.yml index 54f2ddeab..752907a76 100644 --- a/.github/actions/bun-install/action.yml +++ b/.github/actions/bun-install/action.yml @@ -42,13 +42,25 @@ runs: curl -fsSL https://bun.sh/install | bash -s "bun-v1.3.14" echo "${BUN_INSTALL}/bin" >> "$GITHUB_PATH" - # Off-infra (GitHub-hosted): stock actions/cache for the bun store. - - name: Cache bun store (GitHub cache) + # Off-infra (GitHub-hosted): actions/cache for the bun store, split into + # restore + save. actions/cache entries are scoped per ref but count + # against the shared 10 GB repo quota — letting every PR branch save its + # own copy of the ~500 MB store duplicated it 19x, evicting the far more + # valuable bazel disk-cache archives (which is why release darwin builds + # kept going cold). PRs only restore; non-PR runs (main pushes, releases, + # dispatches) produce the shared entry every PR can see. + - name: Restore bun store (GitHub cache) + id: bun-cache if: steps.env.outputs.cache == 'gha' - uses: actions/cache@v4 + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: ~/.bun/install/cache key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} + # A lockfile change seeds from the previous store: entries are + # content-hash-named tarballs, so stale extras waste only space and + # bun downloads just the delta. + restore-keys: | + bun-${{ runner.os }}- # On-infra (omp-kata): the pod mounts a shared PVC at bun's store path. - name: Prepare mounted bun store @@ -75,3 +87,12 @@ runs: echo "::warning title=bun install retry::shared bun store install failed; retrying with a clean job-local cache" retry_cache="$(mktemp -d "${RUNNER_TEMP:-/tmp}/bun-cache-retry.XXXXXX")" bun install --frozen-lockfile --cache-dir="$retry_cache" + + # Producer half of the split cache: only non-PR runs save, so the store + # exists once per lockfile generation instead of once per PR ref. + - name: Save bun store (GitHub cache) + if: steps.env.outputs.cache == 'gha' && github.event_name != 'pull_request' && steps.bun-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} diff --git a/.github/actions/native-inputs/action.yml b/.github/actions/native-inputs/action.yml deleted file mode 100644 index 52d65ffe8..000000000 --- a/.github/actions/native-inputs/action.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: "Native inputs: change detection + artifact cache key" -description: > - Single source of truth for what counts as a native-affecting change. - - `rust` gates Rust validation (tests, clippy, rustfmt); `cache-key` - addresses the prebuilt Linux x64 addon pair published by trusted main - builds. The detector pathspec and the hashed file set MUST cover the same - inputs — drift means a native change could ship without validation or be - tested against stale addons. The key embeds a schema version, OS, arch, - target pair, and build profile so a future target/profile change can - never resolve valid-but-wrong .node files under the same source hash. - -outputs: - rust: - description: Whether the event touches native inputs (always true off pull_request) - value: ${{ steps.changes.outputs.rust }} - source-hash: - description: 16-hex fingerprint over every native build input - value: ${{ steps.hash.outputs.source-hash }} - cache-key: - description: Exact actions/cache key for the prebuilt Linux x64 addon pair - value: ${{ steps.hash.outputs.cache-key }} - -runs: - using: composite - steps: - - name: Detect native-affecting changes - id: changes - shell: bash - env: - GH_TOKEN: ${{ github.token }} - run: | - set -euo pipefail - if [ "${{ github.event_name }}" != "pull_request" ]; then - echo "rust=true" >> "$GITHUB_OUTPUT" - exit 0 - fi - # Write the diff to a file before matching: in a pipeline, an API - # failure is indistinguishable from "no native changes" (skips - # validation — fail-open), and grep -q can close the pipe early so - # gh dies on SIGPIPE and pipefail flips a MATCH to rust=false. - changed_files="$RUNNER_TEMP/native-changed-files" - gh pr diff ${{ github.event.pull_request.number }} --name-only > "$changed_files" - if grep -qE '^(crates/|bazel/|Cargo\.(toml|lock)|MODULE\.bazel(\.lock)?|BUILD\.bazel|\.bazelrc|\.bazelignore|\.bazelversion|rust-toolchain\.toml|rustfmt\.toml|scripts/bazel-natives\.ts|\.github/actions/(bazel-cache|bazel-natives|native-artifacts|native-inputs)/|\.github/workflows/ci\.yml)' "$changed_files"; then - echo "rust=true" >> "$GITHUB_OUTPUT" - else - echo "No native-affecting changes; skipping Rust validation." - echo "rust=false" >> "$GITHUB_OUTPUT" - fi - - # Content-addresses the addon bytes from git index entries (mode, - # blob identity, path) — `git ls-files -s` covers the executable bit - # and never follows symlinks into worktree bytes. `--error-unmatch` - # fails the step loudly when a listed path disappears instead of - # silently narrowing the key. - - name: Compute native source hash - id: hash - shell: bash - run: | - set -euo pipefail - source_hash=$(git ls-files -s -z --error-unmatch -- \ - crates bazel \ - Cargo.toml Cargo.lock \ - MODULE.bazel MODULE.bazel.lock BUILD.bazel \ - .bazelrc .bazelignore .bazelversion \ - rust-toolchain.toml rustfmt.toml \ - scripts/bazel-natives.ts \ - .github/actions/bazel-cache .github/actions/bazel-natives \ - .github/actions/native-artifacts .github/actions/native-inputs \ - .github/workflows/ci.yml \ - | sort -z \ - | sha256sum \ - | cut -c1-16) - { - echo "source-hash=$source_hash" - echo "cache-key=native-addons-v1-linux-x64-baseline+modern-opt-$source_hash" - } >> "$GITHUB_OUTPUT" - echo "Native source hash: $source_hash" diff --git a/.github/workflows/bazel-cache-warm.yml b/.github/workflows/bazel-cache-warm.yml index adc722996..3d61a3cb9 100644 --- a/.github/workflows/bazel-cache-warm.yml +++ b/.github/workflows/bazel-cache-warm.yml @@ -1,24 +1,38 @@ name: Warm bazel disk cache -# GitHub-hosted PR runners cannot use the cluster remote cache and only see -# actions/cache entries created on the default branch. Bazel action keys do -# not transfer across runner environments (a kata-produced disk cache misses -# every action on ubuntu-22.04), so seed the disk cache from the same image -# PR jobs run on. Runs the full hosted action set — Rust validation (test, -# clippy, rustfmt) plus the native addons — so one exact-key archive covers -# both rust_validate and native_addons for this source generation. The v3 -# key embeds a crates/** source fingerprint, so a native change on main -# means an exact miss: the build seeds from the previous generation via the -# config-scoped prefix and the refreshed archive is saved. An exact hit -# makes every invocation a cache replay and saves nothing. +# GitHub-hosted runners cannot use the cluster remote cache and only see +# actions/cache entries created on the default branch, and bazel action keys +# do not transfer across runner environments (a kata-produced disk cache +# misses every action on a hosted image) — so seed each hosted consumer from +# the same image it runs on: +# +# warm_darwin (macos-*) -> scopes `release-darwin-*`, consumed by the +# release_binary darwin jobs. Releases are the +# only other producers for these scopes and a +# release always changes CONFIG_HASH (version +# bump rewrites Cargo.toml/Cargo.lock), so +# without warming here every release rebuilt the +# darwin addons cold (~40-50 min on +# macos-15-intel — run 30357804722). +# warm_bun (ubuntu-22.04)-> the shared `bun--` store entry. +# PR jobs restore it but never save (per-PR-ref +# copies of the ~500 MB store once ate ~9.4 GB of +# the 10 GB repo cache quota and evicted every +# bazel archive). +# +# The v3 key embeds a crates/** source fingerprint, so a native change on +# main means an exact miss: the build seeds from a previous generation via +# the prefix/bare restore keys and the refreshed archive is saved. An exact +# hit makes every invocation a cache replay and saves nothing. +# +# Paths mirror the cache-key inputs (bazel-cache action) plus bun.lock — a +# packages/** push cannot change any archive, so it does not trigger a warm. on: push: branches: [main] paths: - - "packages/**" - "crates/**" - - "scripts/**" - "bazel/**" - "MODULE.bazel" - "MODULE.bazel.lock" @@ -30,50 +44,54 @@ on: - "Cargo.lock" - "rust-toolchain.toml" - "rustfmt.toml" + - "bun.lock" - ".github/**" workflow_dispatch: permissions: contents: read +# No cancel-in-progress: a cancelled warm saves nothing, and the first darwin +# warm on a cold runner takes long enough that back-to-back native pushes +# would cancel it forever. Superseded queued runs still collapse to the +# newest one, and staleness is harmless — consumers seed via prefix keys. concurrency: group: bazel-cache-warm - cancel-in-progress: true + cancel-in-progress: false jobs: - warm: - name: Seed hosted bazel disk cache + # Keeps the release_binary darwin scopes seeded near HEAD so a release's + # bazel build is the version-bump delta, not a cold graph. Scope, runner + # image, and target must stay in lockstep with the release_binary matrix + # in ci.yml — a mismatched scope warms an archive nobody restores. + warm_darwin: + name: "Seed darwin release bazel cache: ${{ matrix.target }}" + strategy: + fail-fast: false + matrix: + include: + - { os: macos-15-intel, target: darwin-x64-baseline, scope: release-darwin-x64 } + - { os: macos-14, target: darwin-arm64, scope: release-darwin-arm64 } + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: "1.3" + # scripts/bazel-natives.ts is dependency-free (node builtins only), so + # no `bun install` is needed; the bazel-natives action restores, + # builds, and saves the scope's disk cache. + - uses: ./.github/actions/bazel-natives + with: + targets: ${{ matrix.target }} + cache-scope: ${{ matrix.scope }} + + # Produces the shared bun store entry PR jobs restore. bun-install's save + # half only runs on non-PR events, and main CI jobs run on omp-kata (PVC + # store, no GitHub cache), so this is the sole hosted-runner producer. + warm_bun: + name: Seed bun store cache runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - - id: cache - uses: ./.github/actions/bazel-cache - with: - scope: linux - # Invocation set mirrors the hosted CI jobs (rust_validate + - # native_addons) so the saved archive serves both. - - name: Rust tests - run: | - set -euo pipefail - if [ "$(ulimit -Sn)" != unlimited ] && [ "$(ulimit -Sn)" -lt 65536 ]; then ulimit -Sn 65536 || true; fi - bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" test //crates/... - - name: Clippy (workspace lint policy on opted-in crates) - run: | - bazelisk query "kind('rust_library|rust_shared_library', //crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...)" \ - | xargs bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=clippy-strict -- - - name: Clippy (default lints elsewhere) - run: | - bazelisk query "kind('rust_library|rust_shared_library', //crates/... - (//crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...) - //crates/vendor/brush-core/... - //crates/vendor/brush-builtins/...)" \ - | xargs bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=clippy -- - - name: Rustfmt - run: bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=rustfmt //crates/... - - name: Build native addons - run: | - set -euo pipefail - bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build //:natives-linux-x64-baseline //:natives-linux-x64-modern - - name: Save bazel disk cache - if: steps.cache.outputs.save-needed == 'true' - uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: ~/.cache/omp-bazel-disk - key: ${{ steps.cache.outputs.cache-key }} + - uses: ./.github/actions/bun-install diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 910fec12b..84bc2e397 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,13 @@ on: - "Cargo.lock" - "rust-toolchain.toml" - "rustfmt.toml" + # A root dependency change (lockfile/catalog/patches) affects every + # job; without these a lockfile-only push shipped untested — and a + # release retagged onto such a commit never triggered its run. + - "bun.lock" + - "bunfig.toml" + - "package.json" + - "patches/**" - ".github/**" pull_request: branches: [main] @@ -36,6 +43,10 @@ on: - "Cargo.lock" - "rust-toolchain.toml" - "rustfmt.toml" + - "bun.lock" + - "bunfig.toml" + - "package.json" + - "patches/**" - ".github/**" workflow_dispatch: inputs: @@ -75,7 +86,10 @@ jobs: # ref (or from a tagged main HEAD) is also treated as a release. release_metadata: name: Resolve release metadata - runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} + # Hosted, not omp-kata: this ~20 s git-tag probe gates the whole release + # chain, and queueing it behind the 4-runner kata pool adds dead minutes + # to the darwin critical path. + runs-on: ubuntu-22.04 outputs: is-release: ${{ steps.detect.outputs.is-release }} release-tag: ${{ steps.detect.outputs.release-tag }} @@ -124,26 +138,23 @@ jobs: - name: Build collab web run: bun run collab:web:build - # Rust validation (tests, clippy, rustfmt) and native addon production are - # separate jobs: TS test shards wait only on the addons, and on - # native-changing PRs validation no longer delays artifact production. + # Rust validation (tests, clippy, rustfmt) runs on non-PR events only. + # Native-changing PRs are rare enough that they do not warrant PR-side + # Rust validation or a PR-side addon build (see native_addons): Rust is + # validated post-merge on main (kata remote cache, warm) and again at + # release. A skipped required check still satisfies branch protection. rust_validate: name: Validate Rust workspace (bazel) - runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} + if: github.event_name != 'pull_request' + runs-on: omp-kata steps: - uses: actions/checkout@v4 - - id: inputs - uses: ./.github/actions/native-inputs - # TS-only PRs skip Rust validation entirely. - - if: steps.inputs.outputs.rust == 'true' - uses: ./.github/actions/bun-install + - uses: ./.github/actions/bun-install - id: cache - if: steps.inputs.outputs.rust == 'true' uses: ./.github/actions/bazel-cache with: scope: linux - name: Rust tests - if: steps.inputs.outputs.rust == 'true' # The ulimit guard runs in the step that launches the bazel server # (limits are per-process and the server persists across steps). run: | @@ -154,67 +165,49 @@ jobs: # `[lints] workspace = true` get the workspace policy, the vendored # brush fork is exempt (same as run-rs-task.ts's cargo excludes). - name: Clippy (workspace lint policy on opted-in crates) - if: steps.inputs.outputs.rust == 'true' run: | - bazelisk query "kind('rust_library|rust_shared_library', //crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...)" \ + bazelisk query "kind('rust_library|rust_shared_library', //crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-voice/... + //crates/pi-walker/...)" \ | xargs bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=clippy-strict -- - name: Clippy (default lints elsewhere) - if: steps.inputs.outputs.rust == 'true' run: | - bazelisk query "kind('rust_library|rust_shared_library', //crates/... - (//crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...) - //crates/vendor/brush-core/... - //crates/vendor/brush-builtins/...)" \ + bazelisk query "kind('rust_library|rust_shared_library', //crates/... - (//crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-voice/... + //crates/pi-walker/...) - //crates/vendor/brush-core/... - //crates/vendor/brush-builtins/...)" \ | xargs bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=clippy -- - name: Rustfmt - if: steps.inputs.outputs.rust == 'true' run: bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build --config=rustfmt //crates/... - # No disk-cache save here: native_addons saves this same key - # concurrently, and an immutable archive can have only one producer - # per key — a validation-only archive winning the race would - # suppress the addon half on every later exact hit. Validation - # actions are seeded by the main cache warmer's combined archive. - # Builds the native addons every downstream job installs. TS-only PRs - # restore the prebuilt Linux x64 pair published by trusted main builds - # (exact content-addressed key, smoke-loaded before use) and skip Bazel - # entirely; anything else builds with bazel. Main builds all Linux-hosted - # targets, pull requests only the x64 pair tests require. + # Provides the native addons every downstream TS job installs. PRs never + # build: they fetch the latest release's Linux x64 pair from the + # @oh-my-pi/pi-natives-linux-x64 npm leaf instead. The workspace loader + # skips its version sentinel for workspace loads, so release addons load + # fine under a newer checkout; a PR whose TS tests depend on changed + # native behavior fails visibly and the native side lands via main. + # Main (kata, cluster remote cache) builds all Linux-hosted targets with + # bazel. Job name says "bazel" for continuity with required checks. native_addons: name: Build native addons (bazel) runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'omp-kata' }} steps: - uses: actions/checkout@v4 - - id: inputs - uses: ./.github/actions/native-inputs - # Trusted fast path. Exact-key restores only — a prefix fallback - # could resolve valid-but-wrong .node files under a changed - # target/profile (the key embeds schema + os/arch + target pair + - # build profile + input hash; see native-inputs action). - - name: Restore prebuilt native addons - id: prebuilt + + # ---- PR path: latest release addons from npm ---- + - name: Fetch release native addons (npm) if: github.event_name == 'pull_request' - uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: ~/.cache/omp-native-addons - key: ${{ steps.inputs.outputs.cache-key }} - - name: Stage cached addons - if: steps.prebuilt.outputs.cache-hit == 'true' shell: bash - # Canonical filenames come from the target map in - # scripts/bazel-natives.ts; staging reproduces the bazel-bin - # layout the artifact upload below globs. run: | set -euo pipefail + tarball="$(npm view @oh-my-pi/pi-natives-linux-x64@latest dist.tarball)" + echo "Fetching $tarball" + curl -fsSL --retry 3 "$tarball" | tar -xz -C "$RUNNER_TEMP" mkdir -p bazel-bin/natives-linux-x64-baseline bazel-bin/natives-linux-x64-modern - cp ~/.cache/omp-native-addons/pi_natives.linux-x64-baseline.node bazel-bin/natives-linux-x64-baseline/ - cp ~/.cache/omp-native-addons/pi_natives.linux-x64-modern.node bazel-bin/natives-linux-x64-modern/ - # A poisoned cache entry must not ship: load both addons before - # trusting them. Failure falls back to a full build (loudly) rather - # than failing the PR. - - name: Smoke cached addons - id: smoke - if: steps.prebuilt.outputs.cache-hit == 'true' + cp "$RUNNER_TEMP/package/pi_natives.linux-x64-baseline.node" bazel-bin/natives-linux-x64-baseline/ + cp "$RUNNER_TEMP/package/pi_natives.linux-x64-modern.node" bazel-bin/natives-linux-x64-modern/ + # A corrupt download must fail here, not as a confusing dlopen error + # in every downstream test shard. + - name: Smoke release addons + if: github.event_name == 'pull_request' shell: bash run: | - set -uo pipefail + set -euo pipefail # NOTE: `bun -e 'require("./x.node")'` swallows dlopen failures # (exit 0 on a bogus addon); a script file enforces them in # both bun and node. Verified against a corrupt .node fixture. @@ -229,50 +222,40 @@ jobs: EOF loader=node if command -v bun >/dev/null 2>&1; then loader=bun; fi - if "$loader" "$RUNNER_TEMP/smoke-addons.js" \ - "$PWD/bazel-bin/natives-linux-x64-baseline/pi_natives.linux-x64-baseline.node" \ - "$PWD/bazel-bin/natives-linux-x64-modern/pi_natives.linux-x64-modern.node"; then - echo "ok=true" >> "$GITHUB_OUTPUT" - else - echo "::warning::cached native addons failed to load; falling back to a full bazel build" - rm -rf bazel-bin - echo "ok=false" >> "$GITHUB_OUTPUT" - fi - - name: Decide build path - id: decide + "$loader" "$RUNNER_TEMP/smoke-addons.js" \ + "$PWD/bazel-bin/natives-linux-x64-baseline/pi_natives.linux-x64-baseline.node" \ + "$PWD/bazel-bin/natives-linux-x64-modern/pi_natives.linux-x64-modern.node" + # Make the policy visible on the rare native-touching PR instead of + # leaving a reviewer to wonder which addons the tests exercised. + # Best-effort: a diff-API failure must not fail the job over a notice. + - name: Note native changes tested against release addons + if: github.event_name == 'pull_request' shell: bash env: - HIT: ${{ steps.prebuilt.outputs.cache-hit }} - SMOKE: ${{ steps.smoke.outputs.ok }} + GH_TOKEN: ${{ github.token }} run: | - if [ "$HIT" = "true" ] && [ "$SMOKE" = "true" ]; then - echo "Prebuilt addons restored and verified; skipping bazel." - echo "needed=false" >> "$GITHUB_OUTPUT" - else - echo "needed=true" >> "$GITHUB_OUTPUT" + if gh pr diff ${{ github.event.pull_request.number }} --name-only 2>/dev/null \ + | grep -qE '^(crates/|bazel/|Cargo\.(toml|lock)|MODULE\.bazel(\.lock)?|BUILD\.bazel|\.bazelrc|\.bazelignore|\.bazelversion|rust-toolchain\.toml|rustfmt\.toml)'; then + echo "::notice title=Native sources changed::PR CI tests against the latest release addons by design; native changes are validated post-merge on main and at release." fi + + # ---- main path: bazel build of all Linux-hosted targets ---- - id: cache - if: steps.decide.outputs.needed == 'true' + if: github.event_name != 'pull_request' uses: ./.github/actions/bazel-cache with: scope: linux - name: Build native addons once - if: steps.decide.outputs.needed == 'true' - env: - EVENT_NAME: ${{ github.event_name }} + if: github.event_name != 'pull_request' run: | set -eo pipefail if [ "$(ulimit -Sn)" != unlimited ] && [ "$(ulimit -Sn)" -lt 65536 ]; then ulimit -Sn 65536 || true; fi - targets=(//:natives-linux-x64-baseline //:natives-linux-x64-modern) - if [ "$EVENT_NAME" != "pull_request" ]; then - targets=(//:natives-linux-all) - fi - bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build "${targets[@]}" 2>&1 | tee "$RUNNER_TEMP/bazel-build.log" + bazelisk --bazelrc="${{ steps.cache.outputs.rc }}" build //:natives-linux-all 2>&1 | tee "$RUNNER_TEMP/bazel-build.log" # Cache-hit visibility: a supposedly warm build that executes # thousands of actions is the failure mode that made CI slow — make # it visible in the run summary instead of discovering it weeks in. - name: Report bazel cache stats - if: steps.decide.outputs.needed == 'true' + if: github.event_name != 'pull_request' shell: bash run: | # Bazel runs with --color=yes (config=ci); strip ANSI before @@ -280,57 +263,7 @@ jobs: # the raw log. summary=$(sed -E 's/\x1b\[[0-9;]*m//g' "$RUNNER_TEMP/bazel-build.log" | grep -E '[0-9]+ processes:' | tail -1 || true) echo "::notice title=Bazel build summary::${summary:-no process summary found}" - - name: Save Bazel disk cache - if: steps.cache.outputs.save-needed == 'true' - uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: ~/.cache/omp-bazel-disk - key: ${{ steps.cache.outputs.cache-key }} - # Producer side of the fast path: trusted main builds publish the - # x64 pair under the content-addressed key. Smoke-load before save — - # an exact-key archive is never overwritten, so bad bytes would - # poison every TS-only PR until manual eviction. - - name: Stage built addons for cache - if: github.event_name != 'pull_request' - shell: bash - run: | - set -euo pipefail - mkdir -p ~/.cache/omp-native-addons - cp bazel-bin/natives-linux-x64-baseline/pi_natives.linux-x64-baseline.node \ - bazel-bin/natives-linux-x64-modern/pi_natives.linux-x64-modern.node \ - ~/.cache/omp-native-addons/ - - name: Smoke addons before caching - if: github.event_name != 'pull_request' - shell: bash - run: | - set -euo pipefail - cd ~/.cache/omp-native-addons - cat > "$RUNNER_TEMP/smoke-addons.js" <<'EOF' - for (const f of process.argv.slice(2)) { - const m = require(f); - if (!m || Object.keys(m).length === 0) { - console.error(`addon failed to load: ${f}`); - process.exit(1); - } - } - EOF - bun "$RUNNER_TEMP/smoke-addons.js" \ - "$PWD/pi_natives.linux-x64-baseline.node" \ - "$PWD/pi_natives.linux-x64-modern.node" - - name: Look up native addon cache - id: addon-cache - if: github.event_name != 'pull_request' - uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: ~/.cache/omp-native-addons - key: ${{ steps.inputs.outputs.cache-key }} - lookup-only: true - - name: Save native addon cache - if: github.event_name != 'pull_request' && steps.addon-cache.outputs.cache-hit != 'true' - uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 - with: - path: ~/.cache/omp-native-addons - key: ${{ steps.inputs.outputs.cache-key }} + - name: Upload native addon artifacts uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: @@ -482,8 +415,11 @@ jobs: OMP_INSTALL_TEST_SKIP_NATIVE_BUILD: "1" run: bun run ci:test:install-methods - release_binary: - name: "Release binary: ${{ matrix.target_id }}" + # Aggregates every validation job so publish-side release jobs gate on one + # result. Binary BUILDS deliberately do not wait for this gate — they run + # in parallel with the test fan-out and only publishing is held back. + release_gate: + name: Release validation gate if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && needs.rust_validate.result == 'success' && needs.native_addons.result == 'success' && @@ -496,6 +432,20 @@ jobs: needs.test_smoke.result == 'success' && needs.check.result == 'success' && needs.install_methods.result == 'success' }} needs: [release_metadata, check, rust_validate, native_addons, test_workspace, test_coding_agent_singleton, test_ts_native, test_coding_agent_ui, test_coding_agent_runtime, test_coding_agent_native, test_smoke, install_methods] + runs-on: ubuntu-22.04 + steps: + - run: echo "release validation green" + + # Builds (does not publish) the Linux-hosted release binaries in parallel + # with the test fan-out; the single need is native_addons, whose artifact + # supplies their addons. Darwin builds live in release_binary_darwin so + # they start at release_metadata time instead. Publishing (npm leaves, + # GitHub release, core npm) is gated on release_gate downstream. + release_binary: + name: "Release binary: ${{ matrix.target_id }}" + if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && + needs.native_addons.result == 'success' }} + needs: [release_metadata, native_addons] strategy: fail-fast: false matrix: @@ -534,22 +484,6 @@ jobs: binary_path: packages/coding-agent/binaries/omp-linux-musl-arm64, native_targets: linux-musl-arm64, } - - { - os: macos-15-intel, - platform: darwin, - arch: x64, - target_id: darwin-x64, - binary_path: packages/coding-agent/binaries/omp-darwin-x64, - native_targets: darwin-x64-baseline, - } - - { - os: macos-14, - platform: darwin, - arch: arm64, - target_id: darwin-arm64, - binary_path: packages/coding-agent/binaries/omp-darwin-arm64, - native_targets: darwin-arm64, - } - { os: ubuntu-22.04, platform: win32, @@ -561,60 +495,25 @@ jobs: runs-on: ${{ matrix.os }} permissions: contents: read - id-token: write - env: - MACOS_SIGNING: ${{ secrets.APPLE_CERTIFICATE_P12 != '' && secrets.APPLE_CERTIFICATE_PASSWORD != '' && secrets.APPLE_API_KEY_ID != '' && secrets.APPLE_API_ISSUER_ID != '' && secrets.APPLE_API_KEY != '' }} steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 with: bun-version: "1.3" - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - with: - node-version: "24" - registry-url: "https://registry.npmjs.org" - # npm runs under Bun when invoked by the release script; npm 12 - # requires a newer emulated Node version than Bun 1.3 provides. - - name: Ensure npm supports trusted publishing - if: ${{ !inputs.skip_npm }} - run: npm install -g npm@11.17.0 - name: Cache bun dependencies uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 with: path: ~/.bun/install/cache key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} - run: bun install --frozen-lockfile - # Linux and Windows addons come from the native_addons job. Darwin runners - # build only their own architecture because cross-hosted artifacts do - # not exist for macOS. - name: Install prebuilt native addon(s) - if: matrix.platform != 'darwin' uses: ./.github/actions/native-artifacts with: targets: ${{ matrix.native_targets }} - - name: Build native addon (bazel) - if: matrix.platform == 'darwin' - uses: ./.github/actions/bazel-natives - with: - targets: ${{ matrix.native_targets }} - cache-scope: release-${{ matrix.target_id }} - name: Build release binary env: RELEASE_TARGETS: ${{ matrix.target_id }} run: bun run ci:release:build-binaries - - name: Sign and notarize macOS binary (Developer ID) - # Replaces the ad-hoc signature with a Developer ID + hardened-runtime - # one (+JIT/library-validation entitlements; omp dlopens its - # runtime-extracted native addon, which has a different Team ID) and - # notarizes. Auto-skips until the APPLE_* secrets are configured. - if: matrix.platform == 'darwin' && env.MACOS_SIGNING == 'true' - env: - APPLE_CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} - APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }} - APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} - run: bash scripts/ci-macos-sign.sh "${{ matrix.binary_path }}" # Windows binary is cross-built on Linux, so we have no Windows runner # to smoke it on. Cross-build correctness is verified via the bun # `--compile --target=bun-windows-x64-*` cross-compile. Musl binaries @@ -638,25 +537,168 @@ jobs: HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" omp --version HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" omp --smoke-test ' - - name: Publish native addon package - if: ${{ !inputs.skip_npm && matrix.libc != 'musl' }} - env: - # Fallback auth: setup-node wrote an .npmrc referencing - # NODE_AUTH_TOKEN; npm uses it only when OIDC has no trusted - # publisher for the package (or on a first publish). - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - run: bun run ci:release:publish-native-leaf ${{ matrix.target_id }} - name: Upload release binary artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: omp-binary-${{ matrix.target_id }} path: ${{ matrix.binary_path }} + # Darwin release builds are the longest leg of a release (bazel-built + # addons on macOS runners), build their own addons, and touch nothing from + # native_addons — so they gate on release_metadata alone and start the + # moment the release run is detected, fully overlapped with the tests. + release_binary_darwin: + name: "Release binary: ${{ matrix.target_id }}" + if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() }} + needs: [release_metadata] + strategy: + fail-fast: false + matrix: + include: + - { + os: macos-15-intel, + target_id: darwin-x64, + binary_path: packages/coding-agent/binaries/omp-darwin-x64, + native_targets: darwin-x64-baseline, + } + - { + os: macos-14, + target_id: darwin-arm64, + binary_path: packages/coding-agent/binaries/omp-darwin-arm64, + native_targets: darwin-arm64, + } + runs-on: ${{ matrix.os }} + permissions: + contents: read + env: + MACOS_SIGNING: ${{ secrets.APPLE_CERTIFICATE_P12 != '' && secrets.APPLE_CERTIFICATE_PASSWORD != '' && secrets.APPLE_API_KEY_ID != '' && secrets.APPLE_API_ISSUER_ID != '' && secrets.APPLE_API_KEY != '' }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: "1.3" + - name: Cache bun dependencies + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} + - run: bun install --frozen-lockfile + # Darwin runners build their own architecture; cross-hosted artifacts + # do not exist for macOS. The warm workflow keeps these scopes seeded + # near HEAD, so this is normally the version-bump delta. + - name: Build native addon (bazel) + uses: ./.github/actions/bazel-natives + with: + targets: ${{ matrix.native_targets }} + cache-scope: release-${{ matrix.target_id }} + - name: Build release binary + env: + RELEASE_TARGETS: ${{ matrix.target_id }} + run: bun run ci:release:build-binaries + - name: Sign and notarize macOS binary (Developer ID) + # Replaces the ad-hoc signature with a Developer ID + hardened-runtime + # one (+JIT/library-validation entitlements; omp dlopens its + # runtime-extracted native addon, which has a different Team ID) and + # notarizes. Auto-skips until the APPLE_* secrets are configured. + if: env.MACOS_SIGNING == 'true' + env: + APPLE_CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} + APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }} + APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} + run: bash scripts/ci-macos-sign.sh "${{ matrix.binary_path }}" + - name: Smoke release binary + run: | + runtime_dir="$(mktemp -d)" + HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" "${{ matrix.binary_path }}" --version + HOME="$runtime_dir/home" XDG_DATA_HOME="$runtime_dir/xdg" "${{ matrix.binary_path }}" --smoke-test + # Darwin addons exist only on these runners; export them so + # release_native_leaves can publish every leaf package after the + # validation gate. Non-darwin leaves reuse the native-addons artifact. + - name: Upload darwin native addon artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: native-addons-${{ matrix.target_id }} + path: packages/natives/native/pi_natives.${{ matrix.target_id }}*.node + if-no-files-found: error + retention-days: 1 + - name: Upload release binary artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: omp-binary-${{ matrix.target_id }} + path: ${{ matrix.binary_path }} + + # Publishes the five @oh-my-pi/pi-natives- leaf packages once + # validation passes and every binary built. Runs on one linux runner: leaf + # publishing is platform-agnostic file packaging (gen-npm-packages reads + # packages/natives/native), so no per-platform runners are needed. + release_native_leaves: + name: Publish native leaf packages + if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && + needs.release_gate.result == 'success' && + needs.release_binary.result == 'success' && + needs.release_binary_darwin.result == 'success' && + !inputs.skip_npm }} + needs: [release_metadata, release_gate, release_binary, release_binary_darwin] + runs-on: ubuntu-22.04 + # id-token lets npm mint the OIDC token for trusted publishing; the + # NODE_AUTH_TOKEN below is the fallback for unconfigured packages. + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: "1.3" + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: "24" + registry-url: "https://registry.npmjs.org" + # npm runs under Bun when invoked by the release script; npm 12 + # requires a newer emulated Node version than Bun 1.3 provides. + - name: Ensure npm supports trusted publishing + run: npm install -g npm@11.17.0 + - name: Cache bun dependencies + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: ~/.bun/install/cache + key: bun-${{ runner.os }}-${{ hashFiles('**/bun.lock') }} + - run: bun install --frozen-lockfile + # Linux + win32 addons from the native_addons artifact (gnu targets + # only — musl reuses the linux filenames and has no leaf package). + - name: Install linux and win32 native addons + uses: ./.github/actions/native-artifacts + with: + targets: linux-x64-baseline linux-x64-modern linux-arm64 win32-x64-baseline + # Darwin addons come flat (canonical filenames) from the + # release_binary_darwin legs. + - name: Install darwin native addons + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + pattern: native-addons-darwin-* + path: packages/natives/native + merge-multiple: true + - name: Publish native leaf packages + env: + # Fallback auth: setup-node wrote an .npmrc referencing + # NODE_AUTH_TOKEN; npm uses it only when OIDC has no trusted + # publisher for the package (or on a first publish). + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + set -euo pipefail + for tag in linux-x64 linux-arm64 darwin-x64 darwin-arm64 win32-x64; do + bun run ci:release:publish-native-leaf "$tag" + done + release_github: name: Publish GitHub release if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && - needs.release_binary.result == 'success' }} - needs: [release_metadata, release_binary] + needs.release_gate.result == 'success' && + needs.release_binary.result == 'success' && + needs.release_binary_darwin.result == 'success' }} + needs: [release_metadata, release_gate, release_binary, release_binary_darwin] runs-on: ubuntu-22.04 permissions: contents: write @@ -727,9 +769,14 @@ jobs: name: Publish to npm if: ${{ needs.release_metadata.outputs.is-release == 'true' && !cancelled() && needs.release_binary.result == 'success' && + needs.release_binary_darwin.result == 'success' && needs.release_github_verify.result == 'success' && + needs.release_native_leaves.result == 'success' && !inputs.skip_npm }} - needs: [release_metadata, release_binary, release_github_verify] + # release_native_leaves must finish first: the core package lists the + # leaf packages as lockstep-versioned optionalDependencies, so installs + # resolve them the moment the core version is live. + needs: [release_metadata, release_binary, release_binary_darwin, release_github_verify, release_native_leaves] runs-on: ubuntu-22.04 # `id-token: write` lets npm mint the GitHub OIDC token it exchanges for a # short-lived publish token (trusted publishing + provenance). When a diff --git a/.gitignore b/.gitignore index c9968f970..3266d9634 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,8 @@ target/ # OS *.tmp +# Bun compile temp artifacts, left in cwd if a `Bun.build({ compile })` run is killed mid-write +*.bun-build .DS_Store # Logs & profiling diff --git a/Cargo.lock b/Cargo.lock index 0d26b34a2..b179f4520 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1065,9 +1065,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.8.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" dependencies = [ "glob", "libc", @@ -1439,9 +1439,9 @@ dependencies = [ [[package]] name = "ctor" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9bb72bb94fdc1bd619f4c18cc91ecf6302aeb333d31b3c6ec0bb841cd920209" +checksum = "2d83cb7e7a873830708d6b02a78cd36a592c6fa14bf267b68725103b85c0d77f" [[package]] name = "ctr" @@ -1692,13 +1692,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] @@ -2202,9 +2202,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fontdue" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e57e16b3fe8ff4364c0661fdaac543fb38b29ea9bc9c2f45612d90adf931d2b" +checksum = "7894823fa221401399e2598f8b63f81ac77ff5c63248b7656779bff1632d7d3d" dependencies = [ "ttf-parser", ] @@ -4732,7 +4732,7 @@ dependencies = [ [[package]] name = "pi-ast" -version = "17.1.8" +version = "17.2.0" dependencies = [ "anyhow", "ast-grep-core", @@ -4801,7 +4801,7 @@ dependencies = [ [[package]] name = "pi-iso" -version = "17.1.8" +version = "17.2.0" dependencies = [ "async-trait", "libc", @@ -4813,14 +4813,12 @@ dependencies = [ [[package]] name = "pi-natives" -version = "17.1.8" +version = "17.2.0" dependencies = [ "anyhow", "arboard", "ast-grep-core", - "audiopus_sys", "base64", - "bytes", "clap", "clipboard-win", "core-graphics", @@ -4838,17 +4836,16 @@ dependencies = [ "image", "inferno", "libc", - "maudio", "napi", "napi-build", "napi-derive", - "opus", "parking_lot", "phf 0.13.1", "pi-ast", "pi-iso", "pi-shell", "pi-uutils-ctx", + "pi-voice", "pi-walker", "png", "portable-pty", @@ -4865,7 +4862,6 @@ dependencies = [ "toml", "unicode-segmentation", "unicode-width 0.2.2", - "webrtc", "windows-sys 0.61.2", "winreg 0.56.0", "x11rb", @@ -4876,7 +4872,7 @@ dependencies = [ [[package]] name = "pi-shell" -version = "17.1.8" +version = "17.2.0" dependencies = [ "anyhow", "brush-builtins", @@ -4961,9 +4957,23 @@ dependencies = [ "libc", ] +[[package]] +name = "pi-voice" +version = "17.2.0" +dependencies = [ + "audiopus_sys", + "bytes", + "flume", + "maudio", + "opus", + "parking_lot", + "tokio", + "webrtc", +] + [[package]] name = "pi-walker" -version = "17.1.8" +version = "17.2.0" dependencies = [ "dashmap", "globset", @@ -5758,9 +5768,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.42" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ "once_cell", "ring", @@ -6513,13 +6523,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] @@ -6542,9 +6552,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.3+spec-1.1.0" +version = "1.1.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c" +checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5" dependencies = [ "indexmap", "serde_core", @@ -6749,9 +6759,9 @@ dependencies = [ [[package]] name = "tree-sitter-elisp" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e2e9a6ab3cebf24ca41cdc1f985549b9b33f7ef25c19ac7d18e53a4ee24da09" +checksum = "5d68ec866ff7af14f1514f11b0eba7aa837adf2ad1837fa9b30c360461bff481" dependencies = [ "cc", "tree-sitter-language", @@ -7223,9 +7233,12 @@ checksum = "b40688ea6389c8171614b25491f71d4a27946e0c7ce2da1c6de27e25abf1a0ae" [[package]] name = "ttf-parser" -version = "0.21.1" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +dependencies = [ + "core_maths", +] [[package]] name = "turn" diff --git a/Cargo.toml b/Cargo.toml index 0aec4ace9..03d5bc81e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/pi-*", "crates/vendor/*"] resolver = "3" [workspace.package] -version = "17.1.8" +version = "17.2.0" edition = "2024" license = "MIT" authors = ["Can Boluk"] @@ -177,6 +177,7 @@ too_many_lines = "allow" # Arbitrary limits don't account for necessary comp pi-ast = { path = "crates/pi-ast" } pi-iso = { path = "crates/pi-iso" } pi-shell = { path = "crates/pi-shell" } +pi-voice = { path = "crates/pi-voice" } pi-walker = { path = "crates/pi-walker" } brush-core = { path = "crates/vendor/brush-core" } brush-builtins = { path = "crates/vendor/brush-builtins" } diff --git a/MODULE.bazel b/MODULE.bazel index 7846ae953..74c8ed707 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -37,6 +37,45 @@ rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") rust.toolchain( edition = "2024", versions = ["nightly/2026-04-29"], + # Pinned archive checksums for every toolchain component. Not (only) a + # supply-chain nicety: rules_rust marks a toolchain-tools repo as + # reproducible — and therefore eligible for Bazel's repo contents cache — + # only when every sha256 it needs was predeclared here (repositories.bzl: + # `reproducible = sha256s == dict(ctx.attr.sha256s)`). Without these, + # every fresh output base (= every ephemeral CI pod) re-downloaded and + # re-extracted ~5 rustc toolchains (~20 s each). Regenerate after a + # version bump: for each `-nightly-` below, take the value + # from https://static.rust-lang.org/dist//.tar.xz.sha256. + sha256s = { + "2026-04-29/cargo-nightly-aarch64-apple-darwin.tar.xz": "9165010618ad581a90bd3e74a36cab092e6f509c8e7ffdcfe00293257cafabb7", + "2026-04-29/cargo-nightly-aarch64-unknown-linux-gnu.tar.xz": "f9b463c3eadaf040b5028590c3d3072c8b0893f9863ed25138dfc54c254388e1", + "2026-04-29/cargo-nightly-x86_64-apple-darwin.tar.xz": "03cf3edb1d0b9564fd466553092ccec5c37be729c35df1d77f7c5a9206801638", + "2026-04-29/cargo-nightly-x86_64-unknown-linux-gnu.tar.xz": "0ae6ed5a9e262d082003d5804cd7fc6977057cfa3df721451e356347962f391f", + "2026-04-29/clippy-nightly-aarch64-apple-darwin.tar.xz": "84b933f8a2837c81adca3e3a44fed971ec0de27673e2c56f122f6d2b35ef9371", + "2026-04-29/clippy-nightly-aarch64-unknown-linux-gnu.tar.xz": "827c90b264a716475e85f51bd1999344af14648882cdd5a6d517a73c7e4c02c4", + "2026-04-29/clippy-nightly-x86_64-apple-darwin.tar.xz": "2c749f10bb18c752323b489e056c55f2e6e04ff3939d16444f4f0d960463d2d2", + "2026-04-29/clippy-nightly-x86_64-unknown-linux-gnu.tar.xz": "36a9409a58b3ac16ce9823d4e705055cad8144dd7f18464c028e3a06ae5d87c8", + "2026-04-29/llvm-tools-nightly-aarch64-apple-darwin.tar.xz": "c6a5cfd0c6133e1fae913a624bef2387a1b9c1e2e75316f9d9b6872a592a8b2c", + "2026-04-29/llvm-tools-nightly-aarch64-unknown-linux-gnu.tar.xz": "7e51dc58df2d0d9e263d629e6b149785bb61b716e267cc841556a4641ed52a50", + "2026-04-29/llvm-tools-nightly-x86_64-apple-darwin.tar.xz": "ab6cd3bae1c979fd807982b8c39e911227f9344dab5051d45f612b440dad13ff", + "2026-04-29/llvm-tools-nightly-x86_64-unknown-linux-gnu.tar.xz": "0fb4bed6714359d9505b870c8bd67c722266c5a3894f66523bc231b9c479db31", + "2026-04-29/rust-src-nightly.tar.xz": "2a9c5ae7696a808e30fc5169ddfea20d69571a11997f142944c022a0d30af48b", + "2026-04-29/rust-std-nightly-aarch64-apple-darwin.tar.xz": "cd9e231f3e343b4ed5cff5c384c813cecba13fca94ef767fa8dc4aa0ff58a171", + "2026-04-29/rust-std-nightly-aarch64-unknown-linux-gnu.tar.xz": "80dceec313e144e3cfc5d67326826d85c664e762a27b53fea018a96d537a2942", + "2026-04-29/rust-std-nightly-aarch64-unknown-linux-musl.tar.xz": "9d5cb99d5678b2310bd69b2b654e9dcbbc3c5a50f9b66d03a21745cff4444927", + "2026-04-29/rust-std-nightly-x86_64-apple-darwin.tar.xz": "4992887472dfdea66a7f96c85b81104b543974204f91722742bbe5453bce8ec1", + "2026-04-29/rust-std-nightly-x86_64-pc-windows-msvc.tar.xz": "890d91c1b86e482aaee32d793b366ee3889a9326143cd7f82a2b7507a4f4d592", + "2026-04-29/rust-std-nightly-x86_64-unknown-linux-gnu.tar.xz": "09774060c01c82005a2ae4e4b46a899c5e6157d6cc7188dfbb750c0a0f7c52cf", + "2026-04-29/rust-std-nightly-x86_64-unknown-linux-musl.tar.xz": "de5936933a2994ebff227b62fe41fca5707496d13da33563f2bfee3049e7b122", + "2026-04-29/rustc-nightly-aarch64-apple-darwin.tar.xz": "61fc2a3fd11637fbe9f961319aa16d84615d2a033de46909742000448290c687", + "2026-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "d8c9d9117a0499b6891e4622c55c7be9568e6b0cbed4f53540e51459ab514633", + "2026-04-29/rustc-nightly-x86_64-apple-darwin.tar.xz": "66efb8a2fb4155cd010bafda3382f643d87f337b646542f7830eda36cf1571a4", + "2026-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "b0db9dc4957c0f12ff8be0a30d22b411d4e2a7f434d747d767156be80d782f1d", + "2026-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "56dcf5ac72bcf663687273b0b9cdf953537081f38a4592d3577e9a6502707b4b", + "2026-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "b495726b0f311dcb53a8cf5325c61ef321f110a3739247536bc87109d428a3cc", + "2026-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "9c64403758b4b631b60057f6ed4a93b02f19286a59a60f8ea235b4f7d4e1ba4c", + "2026-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "397e4ead440f29a1fc10903388a377f5607a1d404c29dc3e3a979d2bc813a801", + }, extra_target_triples = [ "x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu", diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 6074ca2f6..7a0a4e221 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -479,11 +479,11 @@ "REPO_MAPPING:rules_rust+,bazel_skylib bazel_skylib+", "REPO_MAPPING:rules_rust+,bazel_tools bazel_tools", "REPO_MAPPING:rules_rust+,rules_cc rules_cc+", - "FILE:@@//Cargo.lock 2f6175327e3eda9efe339c2763039c5f6d6b0eb819e5c03f7f30a23043f7fceb", - "FILE:@@//Cargo.toml 87e9784018cdcabbe49ea960b2bf2fb5b7023e94f5d13248fad93b03d2945a13", + "FILE:@@//Cargo.lock e4832f453a923b7f3dd3f1f5e1c43d4f6b583003085e129074e870ca8498fbfe", + "FILE:@@//Cargo.toml 71321e61d1afb06e31359b4d1936d07133ddda97ad1b02a5416ef23a208e3ce4", "FILE:@@//crates/pi-ast/Cargo.toml 4467b5854e91088ad1669756f7a0aaec3c2208fc28057a29982ccc902ecaf356", "FILE:@@//crates/pi-iso/Cargo.toml 1cd7ed7e5e8cbe9b1683f38f1250d475d6bec29cd84c757af817eb5a79cffdb2", - "FILE:@@//crates/pi-natives/Cargo.toml 2fac3e444359f388843cc26e2cb70902490e9e5dd3e97e1c7410c18f85518e57", + "FILE:@@//crates/pi-natives/Cargo.toml 1d575044e37ceabd9dd029f273b56c50012da463833333298535232fa88a94b8", "FILE:@@//crates/pi-shell/Cargo.toml dff7badd2729fe8ba492500bab6119cb994f3d0bb21d559587b2c6a17168408a", "FILE:@@//crates/vendor/brush-builtins/Cargo.toml 9799575fe609133927291fbca4c4e190e0378c7efe20aa9f66bb0ae6a08cb6ef", "FILE:@@//crates/vendor/brush-core/Cargo.toml a15b65352d399a599153c739a69064c82c12170fd989bf96adeaee87bed98c2c", @@ -537,16 +537,17 @@ "FILE:@@//crates/vendor/uu-wc/Cargo.toml 9af4d9fe9f1bb66a4b838e0ac7d51d6f331e39576e86b0836f39cbe9a3432a92", "FILE:@@//crates/vendor/uu-whoami/Cargo.toml 4d2e3cd67fc1408641dca3f77c754dfc245777d5c3f1260014694632e4c48540", "FILE:@@//crates/vendor/uu-xargs/Cargo.toml ecd2699904131db4fac1592793816a1e063f57100d5e599da095adcf919b27ef", - "FILE:@@//crates/vendor/uu-yes/Cargo.toml 6a717ee1ec2f45d388858c3e2333e315532f8cbc4e30805ad5cece19cb59a4dc" + "FILE:@@//crates/vendor/uu-yes/Cargo.toml 6a717ee1ec2f45d388858c3e2333e315532f8cbc4e30805ad5cece19cb59a4dc", + "FILE:@@//crates/pi-voice/Cargo.toml 688e136b939a030ae8d8ddac9adaff0513db4c038477550cbfb9f6a97a71176e" ], "generatedRepoSpecs": { "crates": { "repoRuleId": "@@rules_rust+//crate_universe/private:crates_vendor.bzl%crates_vendor_remote_repository", "attributes": { "contents": { - "BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files(\n [\n \"cargo-bazel.json\",\n \"crates.bzl\",\n \"defs.bzl\",\n ] + glob(\n allow_empty = True,\n include = [\"*.bazel\"],\n ),\n)\n\nfilegroup(\n name = \"srcs\",\n srcs = glob(\n allow_empty = True,\n include = [\n \"*.bazel\",\n \"*.bzl\",\n ],\n ),\n)\n\n# Workspace Member Dependencies\nalias(\n name = \"ansi-width-0.1.0\",\n actual = \"@crates__ansi-width-0.1.0//:ansi_width\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ansi-width\",\n actual = \"@crates__ansi-width-0.1.0//:ansi_width\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"anyhow-1.0.104\",\n actual = \"@crates__anyhow-1.0.104//:anyhow\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"anyhow\",\n actual = \"@crates__anyhow-1.0.104//:anyhow\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"arboard-3.6.1\",\n actual = \"@crates__arboard-3.6.1//:arboard\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"arboard\",\n actual = \"@crates__arboard-3.6.1//:arboard\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"argmax-0.3.1\",\n actual = \"@crates__argmax-0.3.1//:argmax\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"argmax\",\n actual = \"@crates__argmax-0.3.1//:argmax\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ast-grep-core-0.39.9\",\n actual = \"@crates__ast-grep-core-0.39.9//:ast_grep_core\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ast-grep-core\",\n actual = \"@crates__ast-grep-core-0.39.9//:ast_grep_core\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"async-recursion-1.1.1\",\n actual = \"@crates__async-recursion-1.1.1//:async_recursion\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"async-recursion\",\n actual = \"@crates__async-recursion-1.1.1//:async_recursion\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"async-trait-0.1.91\",\n actual = \"@crates__async-trait-0.1.91//:async_trait\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"async-trait\",\n actual = \"@crates__async-trait-0.1.91//:async_trait\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"audiopus_sys-0.2.2\",\n actual = \"@crates__audiopus_sys-0.2.2//:audiopus_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"audiopus_sys\",\n actual = \"@crates__audiopus_sys-0.2.2//:audiopus_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"base64-0.22.1\",\n actual = \"@crates__base64-0.22.1//:base64\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"base64\",\n actual = \"@crates__base64-0.22.1//:base64\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"base64-simd-0.8.0\",\n actual = \"@crates__base64-simd-0.8.0//:base64_simd\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"base64-simd\",\n actual = \"@crates__base64-simd-0.8.0//:base64_simd\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bigdecimal-0.4.10\",\n actual = \"@crates__bigdecimal-0.4.10//:bigdecimal\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bigdecimal\",\n actual = \"@crates__bigdecimal-0.4.10//:bigdecimal\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"binary-heap-plus-0.5.0\",\n actual = \"@crates__binary-heap-plus-0.5.0//:binary_heap_plus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"binary-heap-plus\",\n actual = \"@crates__binary-heap-plus-0.5.0//:binary_heap_plus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bon-3.9.3\",\n actual = \"@crates__bon-3.9.3//:bon\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bon\",\n actual = \"@crates__bon-3.9.3//:bon\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"brush-parser-0.3.0\",\n actual = \"@crates__brush-parser-0.3.0//:brush_parser\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"brush-parser-0.4.0\",\n actual = \"@crates__brush-parser-0.4.0//:brush_parser\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bstr-1.13.0\",\n actual = \"@crates__bstr-1.13.0//:bstr\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bstr\",\n actual = \"@crates__bstr-1.13.0//:bstr\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bytecount-0.6.9\",\n actual = \"@crates__bytecount-0.6.9//:bytecount\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bytecount\",\n actual = \"@crates__bytecount-0.6.9//:bytecount\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bytes-1.12.1\",\n actual = \"@crates__bytes-1.12.1//:bytes\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bytes\",\n actual = \"@crates__bytes-1.12.1//:bytes\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"cached-0.59.0\",\n actual = \"@crates__cached-0.59.0//:cached\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"cached\",\n actual = \"@crates__cached-0.59.0//:cached\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"cfg-if-1.0.4\",\n actual = \"@crates__cfg-if-1.0.4//:cfg_if\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"cfg-if\",\n actual = \"@crates__cfg-if-1.0.4//:cfg_if\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"check_elevation-0.2.7\",\n actual = \"@crates__check_elevation-0.2.7//:check_elevation\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"check_elevation\",\n actual = \"@crates__check_elevation-0.2.7//:check_elevation\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"chrono-0.4.45\",\n actual = \"@crates__chrono-0.4.45//:chrono\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"chrono\",\n actual = \"@crates__chrono-0.4.45//:chrono\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clap-4.6.4\",\n actual = \"@crates__clap-4.6.4//:clap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clap\",\n actual = \"@crates__clap-4.6.4//:clap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clipboard-win-5.4.1\",\n actual = \"@crates__clipboard-win-5.4.1//:clipboard_win\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clipboard-win\",\n actual = \"@crates__clipboard-win-5.4.1//:clipboard_win\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"codesnake-0.2.1\",\n actual = \"@crates__codesnake-0.2.1//:codesnake\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"codesnake\",\n actual = \"@crates__codesnake-0.2.1//:codesnake\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"color-print-0.3.7\",\n actual = \"@crates__color-print-0.3.7//:color_print\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"color-print\",\n actual = \"@crates__color-print-0.3.7//:color_print\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"command-fds-0.3.3\",\n actual = \"@crates__command-fds-0.3.3//:command_fds\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"command-fds\",\n actual = \"@crates__command-fds-0.3.3//:command_fds\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"compare-0.1.0\",\n actual = \"@crates__compare-0.1.0//:compare\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"compare\",\n actual = \"@crates__compare-0.1.0//:compare\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"core-graphics-0.25.0\",\n actual = \"@crates__core-graphics-0.25.0//:core_graphics\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"core-graphics\",\n actual = \"@crates__core-graphics-0.25.0//:core_graphics\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dashmap-6.2.1\",\n actual = \"@crates__dashmap-6.2.1//:dashmap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dashmap\",\n actual = \"@crates__dashmap-6.2.1//:dashmap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dns-lookup-3.0.1\",\n actual = \"@crates__dns-lookup-3.0.1//:dns_lookup\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dns-lookup\",\n actual = \"@crates__dns-lookup-3.0.1//:dns_lookup\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"enigo-0.6.1\",\n actual = \"@crates__enigo-0.6.1//:enigo\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"enigo\",\n actual = \"@crates__enigo-0.6.1//:enigo\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"faccess-0.2.4\",\n actual = \"@crates__faccess-0.2.4//:faccess\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"faccess\",\n actual = \"@crates__faccess-0.2.4//:faccess\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fancy-regex-0.17.0\",\n actual = \"@crates__fancy-regex-0.17.0//:fancy_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fancy-regex-0.18.0\",\n actual = \"@crates__fancy-regex-0.18.0//:fancy_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"filetime-0.2.29\",\n actual = \"@crates__filetime-0.2.29//:filetime\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"filetime\",\n actual = \"@crates__filetime-0.2.29//:filetime\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"flume-0.11.1\",\n actual = \"@crates__flume-0.11.1//:flume\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"flume\",\n actual = \"@crates__flume-0.11.1//:flume\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"foldhash-0.2.0\",\n actual = \"@crates__foldhash-0.2.0//:foldhash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"foldhash\",\n actual = \"@crates__foldhash-0.2.0//:foldhash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fontdue-0.9.3\",\n actual = \"@crates__fontdue-0.9.3//:fontdue\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fontdue\",\n actual = \"@crates__fontdue-0.9.3//:fontdue\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fs_extra-1.3.0\",\n actual = \"@crates__fs_extra-1.3.0//:fs_extra\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fs_extra\",\n actual = \"@crates__fs_extra-1.3.0//:fs_extra\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"futures-0.3.33\",\n actual = \"@crates__futures-0.3.33//:futures\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"futures\",\n actual = \"@crates__futures-0.3.33//:futures\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"getrandom-0.4.3\",\n actual = \"@crates__getrandom-0.4.3//:getrandom\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"getrandom\",\n actual = \"@crates__getrandom-0.4.3//:getrandom\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"glob-0.3.4\",\n actual = \"@crates__glob-0.3.4//:glob\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"glob\",\n actual = \"@crates__glob-0.3.4//:glob\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"globset-0.4.19\",\n actual = \"@crates__globset-0.4.19//:globset\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"globset\",\n actual = \"@crates__globset-0.4.19//:globset\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-cli-0.1.12\",\n actual = \"@crates__grep-cli-0.1.12//:grep_cli\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-cli\",\n actual = \"@crates__grep-cli-0.1.12//:grep_cli\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-matcher-0.1.9\",\n actual = \"@crates__grep-matcher-0.1.9//:grep_matcher\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-matcher\",\n actual = \"@crates__grep-matcher-0.1.9//:grep_matcher\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-pcre2-0.1.10\",\n actual = \"@crates__grep-pcre2-0.1.10//:grep_pcre2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-pcre2\",\n actual = \"@crates__grep-pcre2-0.1.10//:grep_pcre2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-printer-0.3.1\",\n actual = \"@crates__grep-printer-0.3.1//:grep_printer\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-printer\",\n actual = \"@crates__grep-printer-0.3.1//:grep_printer\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-regex-0.1.14\",\n actual = \"@crates__grep-regex-0.1.14//:grep_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-regex\",\n actual = \"@crates__grep-regex-0.1.14//:grep_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-searcher-0.1.17\",\n actual = \"@crates__grep-searcher-0.1.17//:grep_searcher\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-searcher\",\n actual = \"@crates__grep-searcher-0.1.17//:grep_searcher\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hex-0.4.3\",\n actual = \"@crates__hex-0.4.3//:hex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hex\",\n actual = \"@crates__hex-0.4.3//:hex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hifijson-0.2.3\",\n actual = \"@crates__hifijson-0.2.3//:hifijson\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hifijson\",\n actual = \"@crates__hifijson-0.2.3//:hifijson\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hostname-0.4.2\",\n actual = \"@crates__hostname-0.4.2//:hostname\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hostname\",\n actual = \"@crates__hostname-0.4.2//:hostname\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"html-to-markdown-rs-2.30.0\",\n actual = \"@crates__html-to-markdown-rs-2.30.0//:html_to_markdown_rs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"html-to-markdown-rs\",\n actual = \"@crates__html-to-markdown-rs-2.30.0//:html_to_markdown_rs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"icy_sixel-0.5.0\",\n actual = \"@crates__icy_sixel-0.5.0//:icy_sixel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"icy_sixel\",\n actual = \"@crates__icy_sixel-0.5.0//:icy_sixel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ignore-0.4.31\",\n actual = \"@crates__ignore-0.4.31//:ignore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ignore\",\n actual = \"@crates__ignore-0.4.31//:ignore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"image-0.25.10\",\n actual = \"@crates__image-0.25.10//:image\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"image\",\n actual = \"@crates__image-0.25.10//:image\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"indicatif-0.18.6\",\n actual = \"@crates__indicatif-0.18.6//:indicatif\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"indicatif\",\n actual = \"@crates__indicatif-0.18.6//:indicatif\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"inferno-0.12.8\",\n actual = \"@crates__inferno-0.12.8//:inferno\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"inferno\",\n actual = \"@crates__inferno-0.12.8//:inferno\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"inherent-1.0.14\",\n actual = \"@crates__inherent-1.0.14//:inherent\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"inherent\",\n actual = \"@crates__inherent-1.0.14//:inherent\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"itertools-0.14.0\",\n actual = \"@crates__itertools-0.14.0//:itertools\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"itertools\",\n actual = \"@crates__itertools-0.14.0//:itertools\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-core-2.2.1\",\n actual = \"@crates__jaq-core-2.2.1//:jaq_core\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-core\",\n actual = \"@crates__jaq-core-2.2.1//:jaq_core\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-json-1.1.3\",\n actual = \"@crates__jaq-json-1.1.3//:jaq_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-json\",\n actual = \"@crates__jaq-json-1.1.3//:jaq_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-std-2.1.2\",\n actual = \"@crates__jaq-std-2.1.2//:jaq_std\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-std\",\n actual = \"@crates__jaq-std-2.1.2//:jaq_std\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jiff-0.2.35\",\n actual = \"@crates__jiff-0.2.35//:jiff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jiff\",\n actual = \"@crates__jiff-0.2.35//:jiff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc-0.2.189\",\n actual = \"@crates__libc-0.2.189//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc\",\n actual = \"@crates__libc-0.2.189//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"lscolors-0.21.0\",\n actual = \"@crates__lscolors-0.21.0//:lscolors\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"lscolors\",\n actual = \"@crates__lscolors-0.21.0//:lscolors\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"maudio-0.1.6\",\n actual = \"@crates__maudio-0.1.6//:maudio\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"maudio\",\n actual = \"@crates__maudio-0.1.6//:maudio\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"memchr-2.8.3\",\n actual = \"@crates__memchr-2.8.3//:memchr\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"memchr\",\n actual = \"@crates__memchr-2.8.3//:memchr\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"memmap2-0.9.11\",\n actual = \"@crates__memmap2-0.9.11//:memmap2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"memmap2\",\n actual = \"@crates__memmap2-0.9.11//:memmap2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-3.11.0\",\n actual = \"@crates__napi-3.11.0//:napi\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi\",\n actual = \"@crates__napi-3.11.0//:napi\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-build-2.3.2\",\n actual = \"@crates__napi-build-2.3.2//:napi_build\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-build\",\n actual = \"@crates__napi-build-2.3.2//:napi_build\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-derive-3.6.0\",\n actual = \"@crates__napi-derive-3.6.0//:napi_derive\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-derive\",\n actual = \"@crates__napi-derive-3.6.0//:napi_derive\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"nix-0.29.0\",\n actual = \"@crates__nix-0.29.0//:nix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"nix-0.31.3\",\n actual = \"@crates__nix-0.31.3//:nix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"nom-8.0.0\",\n actual = \"@crates__nom-8.0.0//:nom\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"nom\",\n actual = \"@crates__nom-8.0.0//:nom\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"normalize-path-0.2.1\",\n actual = \"@crates__normalize-path-0.2.1//:normalize_path\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"normalize-path\",\n actual = \"@crates__normalize-path-0.2.1//:normalize_path\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"notify-8.2.0\",\n actual = \"@crates__notify-8.2.0//:notify\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"notify\",\n actual = \"@crates__notify-8.2.0//:notify\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"num-bigint-0.4.8\",\n actual = \"@crates__num-bigint-0.4.8//:num_bigint\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"num-bigint\",\n actual = \"@crates__num-bigint-0.4.8//:num_bigint\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"num-traits-0.2.19\",\n actual = \"@crates__num-traits-0.2.19//:num_traits\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"num-traits\",\n actual = \"@crates__num-traits-0.2.19//:num_traits\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"onig-6.5.3\",\n actual = \"@crates__onig-6.5.3//:onig\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"onig\",\n actual = \"@crates__onig-6.5.3//:onig\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"opus-0.3.1\",\n actual = \"@crates__opus-0.3.1//:opus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"opus\",\n actual = \"@crates__opus-0.3.1//:opus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"os_display-0.1.4\",\n actual = \"@crates__os_display-0.1.4//:os_display\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"os_display\",\n actual = \"@crates__os_display-0.1.4//:os_display\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"os_pipe-1.2.3\",\n actual = \"@crates__os_pipe-1.2.3//:os_pipe\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"os_pipe\",\n actual = \"@crates__os_pipe-1.2.3//:os_pipe\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot-0.12.5\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parse_datetime-0.14.0\",\n actual = \"@crates__parse_datetime-0.14.0//:parse_datetime\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parse_datetime\",\n actual = \"@crates__parse_datetime-0.14.0//:parse_datetime\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"phf-0.13.1\",\n actual = \"@crates__phf-0.13.1//:phf\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"phf\",\n actual = \"@crates__phf-0.13.1//:phf\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pi-shell-17.1.7\",\n actual = \"@crates__pi-shell-17.1.7//:pi_shell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pi-shell\",\n actual = \"@crates__pi-shell-17.1.7//:pi_shell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"platform-info-2.1.0\",\n actual = \"@crates__platform-info-2.1.0//:platform_info\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"platform-info\",\n actual = \"@crates__platform-info-2.1.0//:platform_info\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"png-0.18.1\",\n actual = \"@crates__png-0.18.1//:png\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"png\",\n actual = \"@crates__png-0.18.1//:png\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"portable-pty-0.9.0\",\n actual = \"@crates__portable-pty-0.9.0//:portable_pty\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"portable-pty\",\n actual = \"@crates__portable-pty-0.9.0//:portable_pty\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pretty_assertions-1.4.1\",\n actual = \"@crates__pretty_assertions-1.4.1//:pretty_assertions\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pretty_assertions\",\n actual = \"@crates__pretty_assertions-1.4.1//:pretty_assertions\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"procfs-0.18.0\",\n actual = \"@crates__procfs-0.18.0//:procfs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"procfs\",\n actual = \"@crates__procfs-0.18.0//:procfs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rand-0.10.2\",\n actual = \"@crates__rand-0.10.2//:rand\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rand\",\n actual = \"@crates__rand-0.10.2//:rand\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rayon-1.12.0\",\n actual = \"@crates__rayon-1.12.0//:rayon\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rayon\",\n actual = \"@crates__rayon-1.12.0//:rayon\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"regex-1.13.1\",\n actual = \"@crates__regex-1.13.1//:regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"regex\",\n actual = \"@crates__regex-1.13.1//:regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rlimit-0.11.0\",\n actual = \"@crates__rlimit-0.11.0//:rlimit\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rlimit\",\n actual = \"@crates__rlimit-0.11.0//:rlimit\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rpds-1.2.1\",\n actual = \"@crates__rpds-1.2.1//:rpds\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rpds\",\n actual = \"@crates__rpds-1.2.1//:rpds\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rstest-0.26.1\",\n actual = \"@crates__rstest-0.26.1//:rstest\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rstest\",\n actual = \"@crates__rstest-0.26.1//:rstest\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rustc-hash-2.1.3\",\n actual = \"@crates__rustc-hash-2.1.3//:rustc_hash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rustc-hash\",\n actual = \"@crates__rustc-hash-2.1.3//:rustc_hash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rustix-1.1.4\",\n actual = \"@crates__rustix-1.1.4//:rustix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rustix\",\n actual = \"@crates__rustix-1.1.4//:rustix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"self_cell-1.3.0\",\n actual = \"@crates__self_cell-1.3.0//:self_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"self_cell\",\n actual = \"@crates__self_cell-1.3.0//:self_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde-1.0.229\",\n actual = \"@crates__serde-1.0.229//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde\",\n actual = \"@crates__serde-1.0.229//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json-1.0.151\",\n actual = \"@crates__serde_json-1.0.151//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json\",\n actual = \"@crates__serde_json-1.0.151//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"similar-3.1.1\",\n actual = \"@crates__similar-3.1.1//:similar\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"similar\",\n actual = \"@crates__similar-3.1.1//:similar\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"smallvec-1.15.2\",\n actual = \"@crates__smallvec-1.15.2//:smallvec\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"smallvec\",\n actual = \"@crates__smallvec-1.15.2//:smallvec\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strum-0.28.0\",\n actual = \"@crates__strum-0.28.0//:strum\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strum\",\n actual = \"@crates__strum-0.28.0//:strum\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strum_macros-0.28.0\",\n actual = \"@crates__strum_macros-0.28.0//:strum_macros\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strum_macros\",\n actual = \"@crates__strum_macros-0.28.0//:strum_macros\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"syntect-5.3.0\",\n actual = \"@crates__syntect-5.3.0//:syntect\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"syntect\",\n actual = \"@crates__syntect-5.3.0//:syntect\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile-3.27.0\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"terminfo-0.9.0\",\n actual = \"@crates__terminfo-0.9.0//:terminfo\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"terminfo\",\n actual = \"@crates__terminfo-0.9.0//:terminfo\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"thiserror-2.0.19\",\n actual = \"@crates__thiserror-2.0.19//:thiserror\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"thiserror\",\n actual = \"@crates__thiserror-2.0.19//:thiserror\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tiktoken-rs-0.11.0\",\n actual = \"@crates__tiktoken-rs-0.11.0//:tiktoken_rs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tiktoken-rs\",\n actual = \"@crates__tiktoken-rs-0.11.0//:tiktoken_rs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tokio-1.53.1\",\n actual = \"@crates__tokio-1.53.1//:tokio\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tokio\",\n actual = \"@crates__tokio-1.53.1//:tokio\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tokio-util-0.7.19\",\n actual = \"@crates__tokio-util-0.7.19//:tokio_util\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tokio-util\",\n actual = \"@crates__tokio-util-0.7.19//:tokio_util\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml-1.1.3+spec-1.1.0\",\n actual = \"@crates__toml-1.1.3-spec-1.1.0//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml\",\n actual = \"@crates__toml-1.1.3-spec-1.1.0//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tracing-0.1.44\",\n actual = \"@crates__tracing-0.1.44//:tracing\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tracing\",\n actual = \"@crates__tracing-0.1.44//:tracing\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-0.25.10\",\n actual = \"@crates__tree-sitter-0.25.10//:tree_sitter\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter\",\n actual = \"@crates__tree-sitter-0.25.10//:tree_sitter\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-astro-next-0.1.1\",\n actual = \"@crates__tree-sitter-astro-next-0.1.1//:tree_sitter_astro_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_astro-0.1.1\",\n actual = \"@crates__tree-sitter-astro-next-0.1.1//:tree_sitter_astro_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_astro\",\n actual = \"@crates__tree-sitter-astro-next-0.1.1//:tree_sitter_astro_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-bash-0.25.1\",\n actual = \"@crates__tree-sitter-bash-0.25.1//:tree_sitter_bash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-bash\",\n actual = \"@crates__tree-sitter-bash-0.25.1//:tree_sitter_bash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-c-0.24.2\",\n actual = \"@crates__tree-sitter-c-0.24.2//:tree_sitter_c\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-c\",\n actual = \"@crates__tree-sitter-c-0.24.2//:tree_sitter_c\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-c-sharp-0.23.5\",\n actual = \"@crates__tree-sitter-c-sharp-0.23.5//:tree_sitter_c_sharp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-c-sharp\",\n actual = \"@crates__tree-sitter-c-sharp-0.23.5//:tree_sitter_c_sharp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-clojure-0.1.0\",\n actual = \"@crates__tree-sitter-clojure-0.1.0//:tree_sitter_clojure\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-clojure\",\n actual = \"@crates__tree-sitter-clojure-0.1.0//:tree_sitter_clojure\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-cmake-0.7.4\",\n actual = \"@crates__tree-sitter-cmake-0.7.4//:tree_sitter_cmake\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-cmake\",\n actual = \"@crates__tree-sitter-cmake-0.7.4//:tree_sitter_cmake\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-cpp-0.23.4\",\n actual = \"@crates__tree-sitter-cpp-0.23.4//:tree_sitter_cpp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-cpp\",\n actual = \"@crates__tree-sitter-cpp-0.23.4//:tree_sitter_cpp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-css-0.25.0\",\n actual = \"@crates__tree-sitter-css-0.25.0//:tree_sitter_css\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-css\",\n actual = \"@crates__tree-sitter-css-0.25.0//:tree_sitter_css\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-dart-0.2.0\",\n actual = \"@crates__tree-sitter-dart-0.2.0//:tree_sitter_dart\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-dart\",\n actual = \"@crates__tree-sitter-dart-0.2.0//:tree_sitter_dart\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-diff-0.1.0\",\n actual = \"@crates__tree-sitter-diff-0.1.0//:tree_sitter_diff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-diff\",\n actual = \"@crates__tree-sitter-diff-0.1.0//:tree_sitter_diff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-dockerfile-updated-0.2.0\",\n actual = \"@crates__tree-sitter-dockerfile-updated-0.2.0//:tree_sitter_dockerfile_updated\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_dockerfile-0.2.0\",\n actual = \"@crates__tree-sitter-dockerfile-updated-0.2.0//:tree_sitter_dockerfile_updated\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_dockerfile\",\n actual = \"@crates__tree-sitter-dockerfile-updated-0.2.0//:tree_sitter_dockerfile_updated\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-elisp-1.6.1\",\n actual = \"@crates__tree-sitter-elisp-1.6.1//:tree_sitter_elisp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-elisp\",\n actual = \"@crates__tree-sitter-elisp-1.6.1//:tree_sitter_elisp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-elixir-0.3.5\",\n actual = \"@crates__tree-sitter-elixir-0.3.5//:tree_sitter_elixir\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-elixir\",\n actual = \"@crates__tree-sitter-elixir-0.3.5//:tree_sitter_elixir\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-erlang-0.16.0\",\n actual = \"@crates__tree-sitter-erlang-0.16.0//:tree_sitter_erlang\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-erlang\",\n actual = \"@crates__tree-sitter-erlang-0.16.0//:tree_sitter_erlang\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-fortran-0.6.0\",\n actual = \"@crates__tree-sitter-fortran-0.6.0//:tree_sitter_fortran\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-fortran\",\n actual = \"@crates__tree-sitter-fortran-0.6.0//:tree_sitter_fortran\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-go-0.25.0\",\n actual = \"@crates__tree-sitter-go-0.25.0//:tree_sitter_go\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-go\",\n actual = \"@crates__tree-sitter-go-0.25.0//:tree_sitter_go\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-graphql-0.1.0\",\n actual = \"@crates__tree-sitter-graphql-0.1.0//:tree_sitter_graphql\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-graphql\",\n actual = \"@crates__tree-sitter-graphql-0.1.0//:tree_sitter_graphql\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-haskell-0.23.1\",\n actual = \"@crates__tree-sitter-haskell-0.23.1//:tree_sitter_haskell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-haskell\",\n actual = \"@crates__tree-sitter-haskell-0.23.1//:tree_sitter_haskell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-hcl-1.1.0\",\n actual = \"@crates__tree-sitter-hcl-1.1.0//:tree_sitter_hcl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-hcl\",\n actual = \"@crates__tree-sitter-hcl-1.1.0//:tree_sitter_hcl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-html-0.23.2\",\n actual = \"@crates__tree-sitter-html-0.23.2//:tree_sitter_html\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-html\",\n actual = \"@crates__tree-sitter-html-0.23.2//:tree_sitter_html\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ini-1.4.0\",\n actual = \"@crates__tree-sitter-ini-1.4.0//:tree_sitter_ini\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ini\",\n actual = \"@crates__tree-sitter-ini-1.4.0//:tree_sitter_ini\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-java-0.23.5\",\n actual = \"@crates__tree-sitter-java-0.23.5//:tree_sitter_java\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-java\",\n actual = \"@crates__tree-sitter-java-0.23.5//:tree_sitter_java\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-javascript-0.25.0\",\n actual = \"@crates__tree-sitter-javascript-0.25.0//:tree_sitter_javascript\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-javascript\",\n actual = \"@crates__tree-sitter-javascript-0.25.0//:tree_sitter_javascript\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-json-0.24.8\",\n actual = \"@crates__tree-sitter-json-0.24.8//:tree_sitter_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-json\",\n actual = \"@crates__tree-sitter-json-0.24.8//:tree_sitter_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-julia-0.23.1\",\n actual = \"@crates__tree-sitter-julia-0.23.1//:tree_sitter_julia\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-julia\",\n actual = \"@crates__tree-sitter-julia-0.23.1//:tree_sitter_julia\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-just-0.2.0\",\n actual = \"@crates__tree-sitter-just-0.2.0//:tree_sitter_just\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-just\",\n actual = \"@crates__tree-sitter-just-0.2.0//:tree_sitter_just\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-kotlin-sg-0.4.1\",\n actual = \"@crates__tree-sitter-kotlin-sg-0.4.1//:tree_sitter_kotlin_sg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_kotlin-0.4.1\",\n actual = \"@crates__tree-sitter-kotlin-sg-0.4.1//:tree_sitter_kotlin_sg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_kotlin\",\n actual = \"@crates__tree-sitter-kotlin-sg-0.4.1//:tree_sitter_kotlin_sg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-lua-0.5.0\",\n actual = \"@crates__tree-sitter-lua-0.5.0//:tree_sitter_lua\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-lua\",\n actual = \"@crates__tree-sitter-lua-0.5.0//:tree_sitter_lua\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-make-1.1.1\",\n actual = \"@crates__tree-sitter-make-1.1.1//:tree_sitter_make\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-make\",\n actual = \"@crates__tree-sitter-make-1.1.1//:tree_sitter_make\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-md-0.5.3\",\n actual = \"@crates__tree-sitter-md-0.5.3//:tree_sitter_md\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-md\",\n actual = \"@crates__tree-sitter-md-0.5.3//:tree_sitter_md\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-nix-0.3.0\",\n actual = \"@crates__tree-sitter-nix-0.3.0//:tree_sitter_nix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-nix\",\n actual = \"@crates__tree-sitter-nix-0.3.0//:tree_sitter_nix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-objc-3.0.2\",\n actual = \"@crates__tree-sitter-objc-3.0.2//:tree_sitter_objc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-objc\",\n actual = \"@crates__tree-sitter-objc-3.0.2//:tree_sitter_objc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ocaml-0.24.2\",\n actual = \"@crates__tree-sitter-ocaml-0.24.2//:tree_sitter_ocaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ocaml\",\n actual = \"@crates__tree-sitter-ocaml-0.24.2//:tree_sitter_ocaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-odin-1.3.0\",\n actual = \"@crates__tree-sitter-odin-1.3.0//:tree_sitter_odin\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-odin\",\n actual = \"@crates__tree-sitter-odin-1.3.0//:tree_sitter_odin\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-php-0.24.2\",\n actual = \"@crates__tree-sitter-php-0.24.2//:tree_sitter_php\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-php\",\n actual = \"@crates__tree-sitter-php-0.24.2//:tree_sitter_php\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-powershell-0.26.4\",\n actual = \"@crates__tree-sitter-powershell-0.26.4//:tree_sitter_powershell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-powershell\",\n actual = \"@crates__tree-sitter-powershell-0.26.4//:tree_sitter_powershell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-proto-0.4.0\",\n actual = \"@crates__tree-sitter-proto-0.4.0//:tree_sitter_proto\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-proto\",\n actual = \"@crates__tree-sitter-proto-0.4.0//:tree_sitter_proto\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-python-0.25.0\",\n actual = \"@crates__tree-sitter-python-0.25.0//:tree_sitter_python\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-python\",\n actual = \"@crates__tree-sitter-python-0.25.0//:tree_sitter_python\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-r-1.3.0\",\n actual = \"@crates__tree-sitter-r-1.3.0//:tree_sitter_r\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-r\",\n actual = \"@crates__tree-sitter-r-1.3.0//:tree_sitter_r\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-regex-0.25.0\",\n actual = \"@crates__tree-sitter-regex-0.25.0//:tree_sitter_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-regex\",\n actual = \"@crates__tree-sitter-regex-0.25.0//:tree_sitter_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ruby-0.23.1\",\n actual = \"@crates__tree-sitter-ruby-0.23.1//:tree_sitter_ruby\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ruby\",\n actual = \"@crates__tree-sitter-ruby-0.23.1//:tree_sitter_ruby\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-rust-0.24.2\",\n actual = \"@crates__tree-sitter-rust-0.24.2//:tree_sitter_rust\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-rust\",\n actual = \"@crates__tree-sitter-rust-0.24.2//:tree_sitter_rust\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-scala-0.26.0\",\n actual = \"@crates__tree-sitter-scala-0.26.0//:tree_sitter_scala\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-scala\",\n actual = \"@crates__tree-sitter-scala-0.26.0//:tree_sitter_scala\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-sequel-0.3.11\",\n actual = \"@crates__tree-sitter-sequel-0.3.11//:tree_sitter_sequel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_sql-0.3.11\",\n actual = \"@crates__tree-sitter-sequel-0.3.11//:tree_sitter_sequel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_sql\",\n actual = \"@crates__tree-sitter-sequel-0.3.11//:tree_sitter_sequel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-solidity-1.2.13\",\n actual = \"@crates__tree-sitter-solidity-1.2.13//:tree_sitter_solidity\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-solidity\",\n actual = \"@crates__tree-sitter-solidity-1.2.13//:tree_sitter_solidity\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-starlark-1.3.0\",\n actual = \"@crates__tree-sitter-starlark-1.3.0//:tree_sitter_starlark\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-starlark\",\n actual = \"@crates__tree-sitter-starlark-1.3.0//:tree_sitter_starlark\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-svelte-next-0.1.1\",\n actual = \"@crates__tree-sitter-svelte-next-0.1.1//:tree_sitter_svelte_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_svelte-0.1.1\",\n actual = \"@crates__tree-sitter-svelte-next-0.1.1//:tree_sitter_svelte_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_svelte\",\n actual = \"@crates__tree-sitter-svelte-next-0.1.1//:tree_sitter_svelte_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-swift-0.7.3\",\n actual = \"@crates__tree-sitter-swift-0.7.3//:tree_sitter_swift\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-swift\",\n actual = \"@crates__tree-sitter-swift-0.7.3//:tree_sitter_swift\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-tlaplus-1.5.0\",\n actual = \"@crates__tree-sitter-tlaplus-1.5.0//:tree_sitter_tlaplus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-tlaplus\",\n actual = \"@crates__tree-sitter-tlaplus-1.5.0//:tree_sitter_tlaplus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-toml-ng-0.7.0\",\n actual = \"@crates__tree-sitter-toml-ng-0.7.0//:tree_sitter_toml_ng\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-toml-ng\",\n actual = \"@crates__tree-sitter-toml-ng-0.7.0//:tree_sitter_toml_ng\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-typescript-0.23.2\",\n actual = \"@crates__tree-sitter-typescript-0.23.2//:tree_sitter_typescript\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-typescript\",\n actual = \"@crates__tree-sitter-typescript-0.23.2//:tree_sitter_typescript\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-verilog-1.0.3\",\n actual = \"@crates__tree-sitter-verilog-1.0.3//:tree_sitter_verilog\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-verilog\",\n actual = \"@crates__tree-sitter-verilog-1.0.3//:tree_sitter_verilog\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-vue-next-0.1.0\",\n actual = \"@crates__tree-sitter-vue-next-0.1.0//:tree_sitter_vue_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_vue-0.1.0\",\n actual = \"@crates__tree-sitter-vue-next-0.1.0//:tree_sitter_vue_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_vue\",\n actual = \"@crates__tree-sitter-vue-next-0.1.0//:tree_sitter_vue_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-xml-0.7.0\",\n actual = \"@crates__tree-sitter-xml-0.7.0//:tree_sitter_xml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-xml\",\n actual = \"@crates__tree-sitter-xml-0.7.0//:tree_sitter_xml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-yaml-0.7.2\",\n actual = \"@crates__tree-sitter-yaml-0.7.2//:tree_sitter_yaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-yaml\",\n actual = \"@crates__tree-sitter-yaml-0.7.2//:tree_sitter_yaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-zig-1.1.2\",\n actual = \"@crates__tree-sitter-zig-1.1.2//:tree_sitter_zig\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-zig\",\n actual = \"@crates__tree-sitter-zig-1.1.2//:tree_sitter_zig\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"unicode-segmentation-1.13.3\",\n actual = \"@crates__unicode-segmentation-1.13.3//:unicode_segmentation\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"unicode-segmentation\",\n actual = \"@crates__unicode-segmentation-1.13.3//:unicode_segmentation\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"unicode-width-0.1.14\",\n actual = \"@crates__unicode-width-0.1.14//:unicode_width\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"unicode-width-0.2.2\",\n actual = \"@crates__unicode-width-0.2.2//:unicode_width\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uucore-0.0.30\",\n actual = \"@crates__uucore-0.0.30//:uucore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uucore-0.8.0\",\n actual = \"@crates__uucore-0.8.0//:uucore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uucore-0.9.0\",\n actual = \"@crates__uucore-0.9.0//:uucore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uuid-1.24.0\",\n actual = \"@crates__uuid-1.24.0//:uuid\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uuid\",\n actual = \"@crates__uuid-1.24.0//:uuid\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uutils_term_grid-0.8.0\",\n actual = \"@crates__uutils_term_grid-0.8.0//:term_grid\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uutils_term_grid\",\n actual = \"@crates__uutils_term_grid-0.8.0//:term_grid\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uzers-0.12.2\",\n actual = \"@crates__uzers-0.12.2//:uzers\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uzers\",\n actual = \"@crates__uzers-0.12.2//:uzers\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"webrtc-0.17.2\",\n actual = \"@crates__webrtc-0.17.2//:webrtc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"webrtc\",\n actual = \"@crates__webrtc-0.17.2//:webrtc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"whoami-2.1.2\",\n actual = \"@crates__whoami-2.1.2//:whoami\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"whoami\",\n actual = \"@crates__whoami-2.1.2//:whoami\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"windows-sys-0.59.0\",\n actual = \"@crates__windows-sys-0.59.0//:windows_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"windows-sys-0.61.2\",\n actual = \"@crates__windows-sys-0.61.2//:windows_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"winreg-0.56.0\",\n actual = \"@crates__winreg-0.56.0//:winreg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"winreg\",\n actual = \"@crates__winreg-0.56.0//:winreg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"x11rb-0.13.2\",\n actual = \"@crates__x11rb-0.13.2//:x11rb\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"x11rb\",\n actual = \"@crates__x11rb-0.13.2//:x11rb\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xcap-0.9.6\",\n actual = \"@crates__xcap-0.9.6//:xcap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xcap\",\n actual = \"@crates__xcap-0.9.6//:xcap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xkeysym-0.2.1\",\n actual = \"@crates__xkeysym-0.2.1//:xkeysym\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xkeysym\",\n actual = \"@crates__xkeysym-0.2.1//:xkeysym\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xxhash-rust-0.8.18\",\n actual = \"@crates__xxhash-rust-0.8.18//:xxhash_rust\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xxhash-rust\",\n actual = \"@crates__xxhash-rust-0.8.18//:xxhash_rust\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"yansi-1.0.1\",\n actual = \"@crates__yansi-1.0.1//:yansi\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"yansi\",\n actual = \"@crates__yansi-1.0.1//:yansi\",\n tags = [\"manual\"],\n)\n", + "BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files(\n [\n \"cargo-bazel.json\",\n \"crates.bzl\",\n \"defs.bzl\",\n ] + glob(\n allow_empty = True,\n include = [\"*.bazel\"],\n ),\n)\n\nfilegroup(\n name = \"srcs\",\n srcs = glob(\n allow_empty = True,\n include = [\n \"*.bazel\",\n \"*.bzl\",\n ],\n ),\n)\n\n# Workspace Member Dependencies\nalias(\n name = \"ansi-width-0.1.0\",\n actual = \"@crates__ansi-width-0.1.0//:ansi_width\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ansi-width\",\n actual = \"@crates__ansi-width-0.1.0//:ansi_width\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"anyhow-1.0.104\",\n actual = \"@crates__anyhow-1.0.104//:anyhow\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"anyhow\",\n actual = \"@crates__anyhow-1.0.104//:anyhow\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"arboard-3.6.1\",\n actual = \"@crates__arboard-3.6.1//:arboard\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"arboard\",\n actual = \"@crates__arboard-3.6.1//:arboard\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"argmax-0.3.1\",\n actual = \"@crates__argmax-0.3.1//:argmax\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"argmax\",\n actual = \"@crates__argmax-0.3.1//:argmax\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ast-grep-core-0.39.9\",\n actual = \"@crates__ast-grep-core-0.39.9//:ast_grep_core\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ast-grep-core\",\n actual = \"@crates__ast-grep-core-0.39.9//:ast_grep_core\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"async-recursion-1.1.1\",\n actual = \"@crates__async-recursion-1.1.1//:async_recursion\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"async-recursion\",\n actual = \"@crates__async-recursion-1.1.1//:async_recursion\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"async-trait-0.1.91\",\n actual = \"@crates__async-trait-0.1.91//:async_trait\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"async-trait\",\n actual = \"@crates__async-trait-0.1.91//:async_trait\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"audiopus_sys-0.2.2\",\n actual = \"@crates__audiopus_sys-0.2.2//:audiopus_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"audiopus_sys\",\n actual = \"@crates__audiopus_sys-0.2.2//:audiopus_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"base64-0.22.1\",\n actual = \"@crates__base64-0.22.1//:base64\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"base64\",\n actual = \"@crates__base64-0.22.1//:base64\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"base64-simd-0.8.0\",\n actual = \"@crates__base64-simd-0.8.0//:base64_simd\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"base64-simd\",\n actual = \"@crates__base64-simd-0.8.0//:base64_simd\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bigdecimal-0.4.10\",\n actual = \"@crates__bigdecimal-0.4.10//:bigdecimal\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bigdecimal\",\n actual = \"@crates__bigdecimal-0.4.10//:bigdecimal\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"binary-heap-plus-0.5.0\",\n actual = \"@crates__binary-heap-plus-0.5.0//:binary_heap_plus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"binary-heap-plus\",\n actual = \"@crates__binary-heap-plus-0.5.0//:binary_heap_plus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bon-3.9.3\",\n actual = \"@crates__bon-3.9.3//:bon\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bon\",\n actual = \"@crates__bon-3.9.3//:bon\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"brush-parser-0.3.0\",\n actual = \"@crates__brush-parser-0.3.0//:brush_parser\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"brush-parser-0.4.0\",\n actual = \"@crates__brush-parser-0.4.0//:brush_parser\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bstr-1.13.0\",\n actual = \"@crates__bstr-1.13.0//:bstr\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bstr\",\n actual = \"@crates__bstr-1.13.0//:bstr\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bytecount-0.6.9\",\n actual = \"@crates__bytecount-0.6.9//:bytecount\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bytecount\",\n actual = \"@crates__bytecount-0.6.9//:bytecount\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bytes-1.12.1\",\n actual = \"@crates__bytes-1.12.1//:bytes\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"bytes\",\n actual = \"@crates__bytes-1.12.1//:bytes\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"cached-0.59.0\",\n actual = \"@crates__cached-0.59.0//:cached\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"cached\",\n actual = \"@crates__cached-0.59.0//:cached\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"cfg-if-1.0.4\",\n actual = \"@crates__cfg-if-1.0.4//:cfg_if\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"cfg-if\",\n actual = \"@crates__cfg-if-1.0.4//:cfg_if\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"check_elevation-0.2.7\",\n actual = \"@crates__check_elevation-0.2.7//:check_elevation\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"check_elevation\",\n actual = \"@crates__check_elevation-0.2.7//:check_elevation\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"chrono-0.4.45\",\n actual = \"@crates__chrono-0.4.45//:chrono\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"chrono\",\n actual = \"@crates__chrono-0.4.45//:chrono\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clap-4.6.4\",\n actual = \"@crates__clap-4.6.4//:clap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clap\",\n actual = \"@crates__clap-4.6.4//:clap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clipboard-win-5.4.1\",\n actual = \"@crates__clipboard-win-5.4.1//:clipboard_win\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clipboard-win\",\n actual = \"@crates__clipboard-win-5.4.1//:clipboard_win\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"codesnake-0.2.1\",\n actual = \"@crates__codesnake-0.2.1//:codesnake\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"codesnake\",\n actual = \"@crates__codesnake-0.2.1//:codesnake\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"color-print-0.3.7\",\n actual = \"@crates__color-print-0.3.7//:color_print\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"color-print\",\n actual = \"@crates__color-print-0.3.7//:color_print\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"command-fds-0.3.3\",\n actual = \"@crates__command-fds-0.3.3//:command_fds\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"command-fds\",\n actual = \"@crates__command-fds-0.3.3//:command_fds\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"compare-0.1.0\",\n actual = \"@crates__compare-0.1.0//:compare\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"compare\",\n actual = \"@crates__compare-0.1.0//:compare\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"core-graphics-0.25.0\",\n actual = \"@crates__core-graphics-0.25.0//:core_graphics\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"core-graphics\",\n actual = \"@crates__core-graphics-0.25.0//:core_graphics\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dashmap-6.2.1\",\n actual = \"@crates__dashmap-6.2.1//:dashmap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dashmap\",\n actual = \"@crates__dashmap-6.2.1//:dashmap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dns-lookup-3.0.1\",\n actual = \"@crates__dns-lookup-3.0.1//:dns_lookup\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"dns-lookup\",\n actual = \"@crates__dns-lookup-3.0.1//:dns_lookup\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"enigo-0.6.1\",\n actual = \"@crates__enigo-0.6.1//:enigo\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"enigo\",\n actual = \"@crates__enigo-0.6.1//:enigo\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"faccess-0.2.4\",\n actual = \"@crates__faccess-0.2.4//:faccess\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"faccess\",\n actual = \"@crates__faccess-0.2.4//:faccess\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fancy-regex-0.17.0\",\n actual = \"@crates__fancy-regex-0.17.0//:fancy_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fancy-regex-0.18.0\",\n actual = \"@crates__fancy-regex-0.18.0//:fancy_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"filetime-0.2.29\",\n actual = \"@crates__filetime-0.2.29//:filetime\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"filetime\",\n actual = \"@crates__filetime-0.2.29//:filetime\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"flume-0.11.1\",\n actual = \"@crates__flume-0.11.1//:flume\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"flume\",\n actual = \"@crates__flume-0.11.1//:flume\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"foldhash-0.2.0\",\n actual = \"@crates__foldhash-0.2.0//:foldhash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"foldhash\",\n actual = \"@crates__foldhash-0.2.0//:foldhash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fontdue-0.9.3\",\n actual = \"@crates__fontdue-0.9.3//:fontdue\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fontdue\",\n actual = \"@crates__fontdue-0.9.3//:fontdue\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fs_extra-1.3.0\",\n actual = \"@crates__fs_extra-1.3.0//:fs_extra\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"fs_extra\",\n actual = \"@crates__fs_extra-1.3.0//:fs_extra\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"futures-0.3.33\",\n actual = \"@crates__futures-0.3.33//:futures\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"futures\",\n actual = \"@crates__futures-0.3.33//:futures\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"getrandom-0.4.3\",\n actual = \"@crates__getrandom-0.4.3//:getrandom\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"getrandom\",\n actual = \"@crates__getrandom-0.4.3//:getrandom\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"glob-0.3.4\",\n actual = \"@crates__glob-0.3.4//:glob\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"glob\",\n actual = \"@crates__glob-0.3.4//:glob\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"globset-0.4.19\",\n actual = \"@crates__globset-0.4.19//:globset\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"globset\",\n actual = \"@crates__globset-0.4.19//:globset\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-cli-0.1.12\",\n actual = \"@crates__grep-cli-0.1.12//:grep_cli\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-cli\",\n actual = \"@crates__grep-cli-0.1.12//:grep_cli\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-matcher-0.1.9\",\n actual = \"@crates__grep-matcher-0.1.9//:grep_matcher\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-matcher\",\n actual = \"@crates__grep-matcher-0.1.9//:grep_matcher\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-pcre2-0.1.10\",\n actual = \"@crates__grep-pcre2-0.1.10//:grep_pcre2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-pcre2\",\n actual = \"@crates__grep-pcre2-0.1.10//:grep_pcre2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-printer-0.3.1\",\n actual = \"@crates__grep-printer-0.3.1//:grep_printer\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-printer\",\n actual = \"@crates__grep-printer-0.3.1//:grep_printer\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-regex-0.1.14\",\n actual = \"@crates__grep-regex-0.1.14//:grep_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-regex\",\n actual = \"@crates__grep-regex-0.1.14//:grep_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-searcher-0.1.17\",\n actual = \"@crates__grep-searcher-0.1.17//:grep_searcher\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"grep-searcher\",\n actual = \"@crates__grep-searcher-0.1.17//:grep_searcher\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hex-0.4.3\",\n actual = \"@crates__hex-0.4.3//:hex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hex\",\n actual = \"@crates__hex-0.4.3//:hex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hifijson-0.2.3\",\n actual = \"@crates__hifijson-0.2.3//:hifijson\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hifijson\",\n actual = \"@crates__hifijson-0.2.3//:hifijson\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hostname-0.4.2\",\n actual = \"@crates__hostname-0.4.2//:hostname\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"hostname\",\n actual = \"@crates__hostname-0.4.2//:hostname\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"html-to-markdown-rs-2.30.0\",\n actual = \"@crates__html-to-markdown-rs-2.30.0//:html_to_markdown_rs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"html-to-markdown-rs\",\n actual = \"@crates__html-to-markdown-rs-2.30.0//:html_to_markdown_rs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"icy_sixel-0.5.0\",\n actual = \"@crates__icy_sixel-0.5.0//:icy_sixel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"icy_sixel\",\n actual = \"@crates__icy_sixel-0.5.0//:icy_sixel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ignore-0.4.31\",\n actual = \"@crates__ignore-0.4.31//:ignore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"ignore\",\n actual = \"@crates__ignore-0.4.31//:ignore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"image-0.25.10\",\n actual = \"@crates__image-0.25.10//:image\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"image\",\n actual = \"@crates__image-0.25.10//:image\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"indicatif-0.18.6\",\n actual = \"@crates__indicatif-0.18.6//:indicatif\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"indicatif\",\n actual = \"@crates__indicatif-0.18.6//:indicatif\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"inferno-0.12.8\",\n actual = \"@crates__inferno-0.12.8//:inferno\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"inferno\",\n actual = \"@crates__inferno-0.12.8//:inferno\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"inherent-1.0.14\",\n actual = \"@crates__inherent-1.0.14//:inherent\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"inherent\",\n actual = \"@crates__inherent-1.0.14//:inherent\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"itertools-0.14.0\",\n actual = \"@crates__itertools-0.14.0//:itertools\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"itertools\",\n actual = \"@crates__itertools-0.14.0//:itertools\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-core-2.2.1\",\n actual = \"@crates__jaq-core-2.2.1//:jaq_core\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-core\",\n actual = \"@crates__jaq-core-2.2.1//:jaq_core\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-json-1.1.3\",\n actual = \"@crates__jaq-json-1.1.3//:jaq_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-json\",\n actual = \"@crates__jaq-json-1.1.3//:jaq_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-std-2.1.2\",\n actual = \"@crates__jaq-std-2.1.2//:jaq_std\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jaq-std\",\n actual = \"@crates__jaq-std-2.1.2//:jaq_std\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jiff-0.2.35\",\n actual = \"@crates__jiff-0.2.35//:jiff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"jiff\",\n actual = \"@crates__jiff-0.2.35//:jiff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc-0.2.189\",\n actual = \"@crates__libc-0.2.189//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libc\",\n actual = \"@crates__libc-0.2.189//:libc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"lscolors-0.21.0\",\n actual = \"@crates__lscolors-0.21.0//:lscolors\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"lscolors\",\n actual = \"@crates__lscolors-0.21.0//:lscolors\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"maudio-0.1.6\",\n actual = \"@crates__maudio-0.1.6//:maudio\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"maudio\",\n actual = \"@crates__maudio-0.1.6//:maudio\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"memchr-2.8.3\",\n actual = \"@crates__memchr-2.8.3//:memchr\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"memchr\",\n actual = \"@crates__memchr-2.8.3//:memchr\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"memmap2-0.9.11\",\n actual = \"@crates__memmap2-0.9.11//:memmap2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"memmap2\",\n actual = \"@crates__memmap2-0.9.11//:memmap2\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-3.12.0\",\n actual = \"@crates__napi-3.12.0//:napi\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi\",\n actual = \"@crates__napi-3.12.0//:napi\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-build-2.4.0\",\n actual = \"@crates__napi-build-2.4.0//:napi_build\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-build\",\n actual = \"@crates__napi-build-2.4.0//:napi_build\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-derive-3.6.1\",\n actual = \"@crates__napi-derive-3.6.1//:napi_derive\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"napi-derive\",\n actual = \"@crates__napi-derive-3.6.1//:napi_derive\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"nix-0.29.0\",\n actual = \"@crates__nix-0.29.0//:nix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"nix-0.31.3\",\n actual = \"@crates__nix-0.31.3//:nix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"nom-8.0.0\",\n actual = \"@crates__nom-8.0.0//:nom\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"nom\",\n actual = \"@crates__nom-8.0.0//:nom\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"normalize-path-0.2.1\",\n actual = \"@crates__normalize-path-0.2.1//:normalize_path\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"normalize-path\",\n actual = \"@crates__normalize-path-0.2.1//:normalize_path\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"notify-8.2.0\",\n actual = \"@crates__notify-8.2.0//:notify\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"notify\",\n actual = \"@crates__notify-8.2.0//:notify\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"num-bigint-0.4.8\",\n actual = \"@crates__num-bigint-0.4.8//:num_bigint\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"num-bigint\",\n actual = \"@crates__num-bigint-0.4.8//:num_bigint\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"num-traits-0.2.19\",\n actual = \"@crates__num-traits-0.2.19//:num_traits\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"num-traits\",\n actual = \"@crates__num-traits-0.2.19//:num_traits\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"onig-6.5.3\",\n actual = \"@crates__onig-6.5.3//:onig\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"onig\",\n actual = \"@crates__onig-6.5.3//:onig\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"opus-0.3.1\",\n actual = \"@crates__opus-0.3.1//:opus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"opus\",\n actual = \"@crates__opus-0.3.1//:opus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"os_display-0.1.4\",\n actual = \"@crates__os_display-0.1.4//:os_display\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"os_display\",\n actual = \"@crates__os_display-0.1.4//:os_display\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"os_pipe-1.2.3\",\n actual = \"@crates__os_pipe-1.2.3//:os_pipe\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"os_pipe\",\n actual = \"@crates__os_pipe-1.2.3//:os_pipe\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot-0.12.5\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parking_lot\",\n actual = \"@crates__parking_lot-0.12.5//:parking_lot\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parse_datetime-0.14.0\",\n actual = \"@crates__parse_datetime-0.14.0//:parse_datetime\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"parse_datetime\",\n actual = \"@crates__parse_datetime-0.14.0//:parse_datetime\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"phf-0.13.1\",\n actual = \"@crates__phf-0.13.1//:phf\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"phf\",\n actual = \"@crates__phf-0.13.1//:phf\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pi-shell-17.1.8\",\n actual = \"@crates__pi-shell-17.1.8//:pi_shell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pi-shell\",\n actual = \"@crates__pi-shell-17.1.8//:pi_shell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"platform-info-2.1.0\",\n actual = \"@crates__platform-info-2.1.0//:platform_info\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"platform-info\",\n actual = \"@crates__platform-info-2.1.0//:platform_info\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"png-0.18.1\",\n actual = \"@crates__png-0.18.1//:png\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"png\",\n actual = \"@crates__png-0.18.1//:png\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"portable-pty-0.9.0\",\n actual = \"@crates__portable-pty-0.9.0//:portable_pty\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"portable-pty\",\n actual = \"@crates__portable-pty-0.9.0//:portable_pty\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pretty_assertions-1.4.1\",\n actual = \"@crates__pretty_assertions-1.4.1//:pretty_assertions\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pretty_assertions\",\n actual = \"@crates__pretty_assertions-1.4.1//:pretty_assertions\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"procfs-0.18.0\",\n actual = \"@crates__procfs-0.18.0//:procfs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"procfs\",\n actual = \"@crates__procfs-0.18.0//:procfs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rand-0.10.2\",\n actual = \"@crates__rand-0.10.2//:rand\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rand\",\n actual = \"@crates__rand-0.10.2//:rand\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rayon-1.12.0\",\n actual = \"@crates__rayon-1.12.0//:rayon\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rayon\",\n actual = \"@crates__rayon-1.12.0//:rayon\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"regex-1.13.1\",\n actual = \"@crates__regex-1.13.1//:regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"regex\",\n actual = \"@crates__regex-1.13.1//:regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rlimit-0.11.0\",\n actual = \"@crates__rlimit-0.11.0//:rlimit\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rlimit\",\n actual = \"@crates__rlimit-0.11.0//:rlimit\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rpds-1.2.1\",\n actual = \"@crates__rpds-1.2.1//:rpds\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rpds\",\n actual = \"@crates__rpds-1.2.1//:rpds\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rstest-0.26.1\",\n actual = \"@crates__rstest-0.26.1//:rstest\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rstest\",\n actual = \"@crates__rstest-0.26.1//:rstest\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rustc-hash-2.1.3\",\n actual = \"@crates__rustc-hash-2.1.3//:rustc_hash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rustc-hash\",\n actual = \"@crates__rustc-hash-2.1.3//:rustc_hash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rustix-1.1.4\",\n actual = \"@crates__rustix-1.1.4//:rustix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"rustix\",\n actual = \"@crates__rustix-1.1.4//:rustix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"self_cell-1.3.0\",\n actual = \"@crates__self_cell-1.3.0//:self_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"self_cell\",\n actual = \"@crates__self_cell-1.3.0//:self_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde-1.0.229\",\n actual = \"@crates__serde-1.0.229//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde\",\n actual = \"@crates__serde-1.0.229//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json-1.0.151\",\n actual = \"@crates__serde_json-1.0.151//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json\",\n actual = \"@crates__serde_json-1.0.151//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"similar-3.1.1\",\n actual = \"@crates__similar-3.1.1//:similar\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"similar\",\n actual = \"@crates__similar-3.1.1//:similar\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"smallvec-1.15.2\",\n actual = \"@crates__smallvec-1.15.2//:smallvec\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"smallvec\",\n actual = \"@crates__smallvec-1.15.2//:smallvec\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strum-0.28.0\",\n actual = \"@crates__strum-0.28.0//:strum\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strum\",\n actual = \"@crates__strum-0.28.0//:strum\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strum_macros-0.28.0\",\n actual = \"@crates__strum_macros-0.28.0//:strum_macros\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strum_macros\",\n actual = \"@crates__strum_macros-0.28.0//:strum_macros\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"syntect-5.3.0\",\n actual = \"@crates__syntect-5.3.0//:syntect\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"syntect\",\n actual = \"@crates__syntect-5.3.0//:syntect\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile-3.27.0\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tempfile\",\n actual = \"@crates__tempfile-3.27.0//:tempfile\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"terminfo-0.9.0\",\n actual = \"@crates__terminfo-0.9.0//:terminfo\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"terminfo\",\n actual = \"@crates__terminfo-0.9.0//:terminfo\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"thiserror-2.0.19\",\n actual = \"@crates__thiserror-2.0.19//:thiserror\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"thiserror\",\n actual = \"@crates__thiserror-2.0.19//:thiserror\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tiktoken-rs-0.11.0\",\n actual = \"@crates__tiktoken-rs-0.11.0//:tiktoken_rs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tiktoken-rs\",\n actual = \"@crates__tiktoken-rs-0.11.0//:tiktoken_rs\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tokio-1.53.1\",\n actual = \"@crates__tokio-1.53.1//:tokio\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tokio\",\n actual = \"@crates__tokio-1.53.1//:tokio\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tokio-util-0.7.19\",\n actual = \"@crates__tokio-util-0.7.19//:tokio_util\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tokio-util\",\n actual = \"@crates__tokio-util-0.7.19//:tokio_util\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml-1.1.3+spec-1.1.0\",\n actual = \"@crates__toml-1.1.3-spec-1.1.0//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"toml\",\n actual = \"@crates__toml-1.1.3-spec-1.1.0//:toml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tracing-0.1.44\",\n actual = \"@crates__tracing-0.1.44//:tracing\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tracing\",\n actual = \"@crates__tracing-0.1.44//:tracing\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-0.25.10\",\n actual = \"@crates__tree-sitter-0.25.10//:tree_sitter\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter\",\n actual = \"@crates__tree-sitter-0.25.10//:tree_sitter\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-astro-next-0.1.1\",\n actual = \"@crates__tree-sitter-astro-next-0.1.1//:tree_sitter_astro_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_astro-0.1.1\",\n actual = \"@crates__tree-sitter-astro-next-0.1.1//:tree_sitter_astro_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_astro\",\n actual = \"@crates__tree-sitter-astro-next-0.1.1//:tree_sitter_astro_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-bash-0.25.1\",\n actual = \"@crates__tree-sitter-bash-0.25.1//:tree_sitter_bash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-bash\",\n actual = \"@crates__tree-sitter-bash-0.25.1//:tree_sitter_bash\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-c-0.24.2\",\n actual = \"@crates__tree-sitter-c-0.24.2//:tree_sitter_c\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-c\",\n actual = \"@crates__tree-sitter-c-0.24.2//:tree_sitter_c\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-c-sharp-0.23.5\",\n actual = \"@crates__tree-sitter-c-sharp-0.23.5//:tree_sitter_c_sharp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-c-sharp\",\n actual = \"@crates__tree-sitter-c-sharp-0.23.5//:tree_sitter_c_sharp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-clojure-0.1.0\",\n actual = \"@crates__tree-sitter-clojure-0.1.0//:tree_sitter_clojure\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-clojure\",\n actual = \"@crates__tree-sitter-clojure-0.1.0//:tree_sitter_clojure\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-cmake-0.7.4\",\n actual = \"@crates__tree-sitter-cmake-0.7.4//:tree_sitter_cmake\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-cmake\",\n actual = \"@crates__tree-sitter-cmake-0.7.4//:tree_sitter_cmake\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-cpp-0.23.4\",\n actual = \"@crates__tree-sitter-cpp-0.23.4//:tree_sitter_cpp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-cpp\",\n actual = \"@crates__tree-sitter-cpp-0.23.4//:tree_sitter_cpp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-css-0.25.0\",\n actual = \"@crates__tree-sitter-css-0.25.0//:tree_sitter_css\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-css\",\n actual = \"@crates__tree-sitter-css-0.25.0//:tree_sitter_css\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-dart-0.2.0\",\n actual = \"@crates__tree-sitter-dart-0.2.0//:tree_sitter_dart\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-dart\",\n actual = \"@crates__tree-sitter-dart-0.2.0//:tree_sitter_dart\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-diff-0.1.0\",\n actual = \"@crates__tree-sitter-diff-0.1.0//:tree_sitter_diff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-diff\",\n actual = \"@crates__tree-sitter-diff-0.1.0//:tree_sitter_diff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-dockerfile-updated-0.2.0\",\n actual = \"@crates__tree-sitter-dockerfile-updated-0.2.0//:tree_sitter_dockerfile_updated\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_dockerfile-0.2.0\",\n actual = \"@crates__tree-sitter-dockerfile-updated-0.2.0//:tree_sitter_dockerfile_updated\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_dockerfile\",\n actual = \"@crates__tree-sitter-dockerfile-updated-0.2.0//:tree_sitter_dockerfile_updated\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-elisp-1.6.1\",\n actual = \"@crates__tree-sitter-elisp-1.6.1//:tree_sitter_elisp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-elisp\",\n actual = \"@crates__tree-sitter-elisp-1.6.1//:tree_sitter_elisp\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-elixir-0.3.5\",\n actual = \"@crates__tree-sitter-elixir-0.3.5//:tree_sitter_elixir\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-elixir\",\n actual = \"@crates__tree-sitter-elixir-0.3.5//:tree_sitter_elixir\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-erlang-0.16.0\",\n actual = \"@crates__tree-sitter-erlang-0.16.0//:tree_sitter_erlang\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-erlang\",\n actual = \"@crates__tree-sitter-erlang-0.16.0//:tree_sitter_erlang\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-fortran-0.6.0\",\n actual = \"@crates__tree-sitter-fortran-0.6.0//:tree_sitter_fortran\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-fortran\",\n actual = \"@crates__tree-sitter-fortran-0.6.0//:tree_sitter_fortran\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-go-0.25.0\",\n actual = \"@crates__tree-sitter-go-0.25.0//:tree_sitter_go\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-go\",\n actual = \"@crates__tree-sitter-go-0.25.0//:tree_sitter_go\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-graphql-0.1.0\",\n actual = \"@crates__tree-sitter-graphql-0.1.0//:tree_sitter_graphql\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-graphql\",\n actual = \"@crates__tree-sitter-graphql-0.1.0//:tree_sitter_graphql\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-haskell-0.23.1\",\n actual = \"@crates__tree-sitter-haskell-0.23.1//:tree_sitter_haskell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-haskell\",\n actual = \"@crates__tree-sitter-haskell-0.23.1//:tree_sitter_haskell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-hcl-1.1.0\",\n actual = \"@crates__tree-sitter-hcl-1.1.0//:tree_sitter_hcl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-hcl\",\n actual = \"@crates__tree-sitter-hcl-1.1.0//:tree_sitter_hcl\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-html-0.23.2\",\n actual = \"@crates__tree-sitter-html-0.23.2//:tree_sitter_html\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-html\",\n actual = \"@crates__tree-sitter-html-0.23.2//:tree_sitter_html\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ini-1.4.0\",\n actual = \"@crates__tree-sitter-ini-1.4.0//:tree_sitter_ini\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ini\",\n actual = \"@crates__tree-sitter-ini-1.4.0//:tree_sitter_ini\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-java-0.23.5\",\n actual = \"@crates__tree-sitter-java-0.23.5//:tree_sitter_java\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-java\",\n actual = \"@crates__tree-sitter-java-0.23.5//:tree_sitter_java\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-javascript-0.25.0\",\n actual = \"@crates__tree-sitter-javascript-0.25.0//:tree_sitter_javascript\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-javascript\",\n actual = \"@crates__tree-sitter-javascript-0.25.0//:tree_sitter_javascript\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-json-0.24.8\",\n actual = \"@crates__tree-sitter-json-0.24.8//:tree_sitter_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-json\",\n actual = \"@crates__tree-sitter-json-0.24.8//:tree_sitter_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-julia-0.23.1\",\n actual = \"@crates__tree-sitter-julia-0.23.1//:tree_sitter_julia\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-julia\",\n actual = \"@crates__tree-sitter-julia-0.23.1//:tree_sitter_julia\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-just-0.2.0\",\n actual = \"@crates__tree-sitter-just-0.2.0//:tree_sitter_just\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-just\",\n actual = \"@crates__tree-sitter-just-0.2.0//:tree_sitter_just\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-kotlin-sg-0.4.1\",\n actual = \"@crates__tree-sitter-kotlin-sg-0.4.1//:tree_sitter_kotlin_sg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_kotlin-0.4.1\",\n actual = \"@crates__tree-sitter-kotlin-sg-0.4.1//:tree_sitter_kotlin_sg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_kotlin\",\n actual = \"@crates__tree-sitter-kotlin-sg-0.4.1//:tree_sitter_kotlin_sg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-lua-0.5.0\",\n actual = \"@crates__tree-sitter-lua-0.5.0//:tree_sitter_lua\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-lua\",\n actual = \"@crates__tree-sitter-lua-0.5.0//:tree_sitter_lua\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-make-1.1.1\",\n actual = \"@crates__tree-sitter-make-1.1.1//:tree_sitter_make\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-make\",\n actual = \"@crates__tree-sitter-make-1.1.1//:tree_sitter_make\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-md-0.5.3\",\n actual = \"@crates__tree-sitter-md-0.5.3//:tree_sitter_md\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-md\",\n actual = \"@crates__tree-sitter-md-0.5.3//:tree_sitter_md\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-nix-0.3.0\",\n actual = \"@crates__tree-sitter-nix-0.3.0//:tree_sitter_nix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-nix\",\n actual = \"@crates__tree-sitter-nix-0.3.0//:tree_sitter_nix\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-objc-3.0.2\",\n actual = \"@crates__tree-sitter-objc-3.0.2//:tree_sitter_objc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-objc\",\n actual = \"@crates__tree-sitter-objc-3.0.2//:tree_sitter_objc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ocaml-0.24.2\",\n actual = \"@crates__tree-sitter-ocaml-0.24.2//:tree_sitter_ocaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ocaml\",\n actual = \"@crates__tree-sitter-ocaml-0.24.2//:tree_sitter_ocaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-odin-1.3.0\",\n actual = \"@crates__tree-sitter-odin-1.3.0//:tree_sitter_odin\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-odin\",\n actual = \"@crates__tree-sitter-odin-1.3.0//:tree_sitter_odin\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-php-0.24.2\",\n actual = \"@crates__tree-sitter-php-0.24.2//:tree_sitter_php\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-php\",\n actual = \"@crates__tree-sitter-php-0.24.2//:tree_sitter_php\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-powershell-0.26.4\",\n actual = \"@crates__tree-sitter-powershell-0.26.4//:tree_sitter_powershell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-powershell\",\n actual = \"@crates__tree-sitter-powershell-0.26.4//:tree_sitter_powershell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-proto-0.4.0\",\n actual = \"@crates__tree-sitter-proto-0.4.0//:tree_sitter_proto\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-proto\",\n actual = \"@crates__tree-sitter-proto-0.4.0//:tree_sitter_proto\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-python-0.25.0\",\n actual = \"@crates__tree-sitter-python-0.25.0//:tree_sitter_python\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-python\",\n actual = \"@crates__tree-sitter-python-0.25.0//:tree_sitter_python\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-r-1.3.0\",\n actual = \"@crates__tree-sitter-r-1.3.0//:tree_sitter_r\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-r\",\n actual = \"@crates__tree-sitter-r-1.3.0//:tree_sitter_r\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-regex-0.25.0\",\n actual = \"@crates__tree-sitter-regex-0.25.0//:tree_sitter_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-regex\",\n actual = \"@crates__tree-sitter-regex-0.25.0//:tree_sitter_regex\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ruby-0.23.1\",\n actual = \"@crates__tree-sitter-ruby-0.23.1//:tree_sitter_ruby\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-ruby\",\n actual = \"@crates__tree-sitter-ruby-0.23.1//:tree_sitter_ruby\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-rust-0.24.2\",\n actual = \"@crates__tree-sitter-rust-0.24.2//:tree_sitter_rust\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-rust\",\n actual = \"@crates__tree-sitter-rust-0.24.2//:tree_sitter_rust\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-scala-0.26.0\",\n actual = \"@crates__tree-sitter-scala-0.26.0//:tree_sitter_scala\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-scala\",\n actual = \"@crates__tree-sitter-scala-0.26.0//:tree_sitter_scala\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-sequel-0.3.11\",\n actual = \"@crates__tree-sitter-sequel-0.3.11//:tree_sitter_sequel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_sql-0.3.11\",\n actual = \"@crates__tree-sitter-sequel-0.3.11//:tree_sitter_sequel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_sql\",\n actual = \"@crates__tree-sitter-sequel-0.3.11//:tree_sitter_sequel\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-solidity-1.2.13\",\n actual = \"@crates__tree-sitter-solidity-1.2.13//:tree_sitter_solidity\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-solidity\",\n actual = \"@crates__tree-sitter-solidity-1.2.13//:tree_sitter_solidity\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-starlark-1.3.0\",\n actual = \"@crates__tree-sitter-starlark-1.3.0//:tree_sitter_starlark\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-starlark\",\n actual = \"@crates__tree-sitter-starlark-1.3.0//:tree_sitter_starlark\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-svelte-next-0.1.1\",\n actual = \"@crates__tree-sitter-svelte-next-0.1.1//:tree_sitter_svelte_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_svelte-0.1.1\",\n actual = \"@crates__tree-sitter-svelte-next-0.1.1//:tree_sitter_svelte_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_svelte\",\n actual = \"@crates__tree-sitter-svelte-next-0.1.1//:tree_sitter_svelte_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-swift-0.7.3\",\n actual = \"@crates__tree-sitter-swift-0.7.3//:tree_sitter_swift\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-swift\",\n actual = \"@crates__tree-sitter-swift-0.7.3//:tree_sitter_swift\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-tlaplus-1.5.0\",\n actual = \"@crates__tree-sitter-tlaplus-1.5.0//:tree_sitter_tlaplus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-tlaplus\",\n actual = \"@crates__tree-sitter-tlaplus-1.5.0//:tree_sitter_tlaplus\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-toml-ng-0.7.0\",\n actual = \"@crates__tree-sitter-toml-ng-0.7.0//:tree_sitter_toml_ng\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-toml-ng\",\n actual = \"@crates__tree-sitter-toml-ng-0.7.0//:tree_sitter_toml_ng\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-typescript-0.23.2\",\n actual = \"@crates__tree-sitter-typescript-0.23.2//:tree_sitter_typescript\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-typescript\",\n actual = \"@crates__tree-sitter-typescript-0.23.2//:tree_sitter_typescript\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-verilog-1.0.3\",\n actual = \"@crates__tree-sitter-verilog-1.0.3//:tree_sitter_verilog\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-verilog\",\n actual = \"@crates__tree-sitter-verilog-1.0.3//:tree_sitter_verilog\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-vue-next-0.1.0\",\n actual = \"@crates__tree-sitter-vue-next-0.1.0//:tree_sitter_vue_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_vue-0.1.0\",\n actual = \"@crates__tree-sitter-vue-next-0.1.0//:tree_sitter_vue_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree_sitter_vue\",\n actual = \"@crates__tree-sitter-vue-next-0.1.0//:tree_sitter_vue_next\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-xml-0.7.0\",\n actual = \"@crates__tree-sitter-xml-0.7.0//:tree_sitter_xml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-xml\",\n actual = \"@crates__tree-sitter-xml-0.7.0//:tree_sitter_xml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-yaml-0.7.2\",\n actual = \"@crates__tree-sitter-yaml-0.7.2//:tree_sitter_yaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-yaml\",\n actual = \"@crates__tree-sitter-yaml-0.7.2//:tree_sitter_yaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-zig-1.1.2\",\n actual = \"@crates__tree-sitter-zig-1.1.2//:tree_sitter_zig\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"tree-sitter-zig\",\n actual = \"@crates__tree-sitter-zig-1.1.2//:tree_sitter_zig\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"unicode-segmentation-1.13.3\",\n actual = \"@crates__unicode-segmentation-1.13.3//:unicode_segmentation\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"unicode-segmentation\",\n actual = \"@crates__unicode-segmentation-1.13.3//:unicode_segmentation\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"unicode-width-0.1.14\",\n actual = \"@crates__unicode-width-0.1.14//:unicode_width\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"unicode-width-0.2.2\",\n actual = \"@crates__unicode-width-0.2.2//:unicode_width\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uucore-0.0.30\",\n actual = \"@crates__uucore-0.0.30//:uucore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uucore-0.8.0\",\n actual = \"@crates__uucore-0.8.0//:uucore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uucore-0.9.0\",\n actual = \"@crates__uucore-0.9.0//:uucore\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uuid-1.24.0\",\n actual = \"@crates__uuid-1.24.0//:uuid\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uuid\",\n actual = \"@crates__uuid-1.24.0//:uuid\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uutils_term_grid-0.8.0\",\n actual = \"@crates__uutils_term_grid-0.8.0//:term_grid\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uutils_term_grid\",\n actual = \"@crates__uutils_term_grid-0.8.0//:term_grid\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uzers-0.12.2\",\n actual = \"@crates__uzers-0.12.2//:uzers\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"uzers\",\n actual = \"@crates__uzers-0.12.2//:uzers\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"webrtc-0.17.2\",\n actual = \"@crates__webrtc-0.17.2//:webrtc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"webrtc\",\n actual = \"@crates__webrtc-0.17.2//:webrtc\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"whoami-2.1.2\",\n actual = \"@crates__whoami-2.1.2//:whoami\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"whoami\",\n actual = \"@crates__whoami-2.1.2//:whoami\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"windows-sys-0.59.0\",\n actual = \"@crates__windows-sys-0.59.0//:windows_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"windows-sys-0.61.2\",\n actual = \"@crates__windows-sys-0.61.2//:windows_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"winreg-0.56.0\",\n actual = \"@crates__winreg-0.56.0//:winreg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"winreg\",\n actual = \"@crates__winreg-0.56.0//:winreg\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"x11rb-0.13.2\",\n actual = \"@crates__x11rb-0.13.2//:x11rb\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"x11rb\",\n actual = \"@crates__x11rb-0.13.2//:x11rb\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xcap-0.9.6\",\n actual = \"@crates__xcap-0.9.6//:xcap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xcap\",\n actual = \"@crates__xcap-0.9.6//:xcap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xkeysym-0.2.1\",\n actual = \"@crates__xkeysym-0.2.1//:xkeysym\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xkeysym\",\n actual = \"@crates__xkeysym-0.2.1//:xkeysym\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xxhash-rust-0.8.18\",\n actual = \"@crates__xxhash-rust-0.8.18//:xxhash_rust\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"xxhash-rust\",\n actual = \"@crates__xxhash-rust-0.8.18//:xxhash_rust\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"yansi-1.0.1\",\n actual = \"@crates__yansi-1.0.1//:yansi\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"yansi\",\n actual = \"@crates__yansi-1.0.1//:yansi\",\n tags = [\"manual\"],\n)\n", "alias_rules.bzl": "\"\"\"Alias that transitions its target to `compilation_mode=opt`. Use `transition_alias=\"opt\"` to enable.\"\"\"\n\nload(\"@rules_cc//cc:defs.bzl\", \"CcInfo\")\nload(\"@rules_rust//rust:rust_common.bzl\", \"COMMON_PROVIDERS\")\n\ndef _transition_alias_impl(ctx):\n # `ctx.attr.actual` is a list of 1 item due to the transition\n providers = [ctx.attr.actual[0][provider] for provider in COMMON_PROVIDERS]\n if CcInfo in ctx.attr.actual[0]:\n providers.append(ctx.attr.actual[0][CcInfo])\n return providers\n\ndef _change_compilation_mode(compilation_mode):\n def _change_compilation_mode_impl(_settings, _attr):\n return {\n \"//command_line_option:compilation_mode\": compilation_mode,\n }\n\n return transition(\n implementation = _change_compilation_mode_impl,\n inputs = [],\n outputs = [\n \"//command_line_option:compilation_mode\",\n ],\n )\n\ndef _transition_alias_rule(compilation_mode):\n return rule(\n implementation = _transition_alias_impl,\n provides = COMMON_PROVIDERS,\n attrs = {\n \"actual\": attr.label(\n mandatory = True,\n doc = \"`rust_library()` target to transition to `compilation_mode=opt`.\",\n providers = COMMON_PROVIDERS,\n cfg = _change_compilation_mode(compilation_mode),\n ),\n \"_allowlist_function_transition\": attr.label(\n default = \"@bazel_tools//tools/allowlists/function_transition_allowlist\",\n ),\n },\n doc = \"Transitions a Rust library crate to the `compilation_mode=opt`.\",\n )\n\ntransition_alias_dbg = _transition_alias_rule(\"dbg\")\ntransition_alias_fastbuild = _transition_alias_rule(\"fastbuild\")\ntransition_alias_opt = _transition_alias_rule(\"opt\")\n", - "crates.bzl": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\"\"\"\n# `crates_repository` API\n\n- [aliases](#aliases)\n- [crate_edition](#crate_edition)\n- [crate_deps](#crate_deps)\n- [all_crate_deps](#all_crate_deps)\n- [crate_repositories](#crate_repositories)\n\n\"\"\"\n\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"git_repository\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@rules_rust//crate_universe:defs.bzl\", \"crates_vendor_remote_repository\", \"local_crate_mirror\")\n\n###############################################################################\n# MACROS API\n###############################################################################\n\n# An identifier that represent common dependencies (unconditional).\n_COMMON_CONDITION = \"\"\n\ndef _flatten_dependency_maps(all_dependency_maps):\n \"\"\"Flatten a list of dependency maps into one dictionary.\n\n Dependency maps have the following structure:\n\n ```python\n DEPENDENCIES_MAP = {\n # The first key in the map is a Bazel package\n # name of the workspace this file is defined in.\n \"workspace_member_package\": {\n\n # Not all dependencies are supported for all platforms.\n # the condition key is the condition required to be true\n # on the host platform.\n \"condition\": {\n\n # An alias to a crate target. # The label of the crate target the\n # Aliases are only crate names. # package name refers to.\n \"package_name\": \"@full//:label\",\n }\n }\n }\n ```\n\n Args:\n all_dependency_maps (list): A list of dicts as described above\n\n Returns:\n dict: A dictionary as described above\n \"\"\"\n dependencies = {}\n\n for workspace_deps_map in all_dependency_maps:\n for pkg_name, conditional_deps_map in workspace_deps_map.items():\n if pkg_name not in dependencies:\n non_frozen_map = dict()\n for key, values in conditional_deps_map.items():\n non_frozen_map.update({key: dict(values.items())})\n dependencies.setdefault(pkg_name, non_frozen_map)\n continue\n\n for condition, deps_map in conditional_deps_map.items():\n # If the condition has not been recorded, do so and continue\n if condition not in dependencies[pkg_name]:\n dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))\n continue\n\n # Alert on any miss-matched dependencies\n inconsistent_entries = []\n for crate_name, crate_label in deps_map.items():\n existing = dependencies[pkg_name][condition].get(crate_name)\n if existing and existing != crate_label:\n inconsistent_entries.append((crate_name, existing, crate_label))\n dependencies[pkg_name][condition].update({crate_name: crate_label})\n\n return dependencies\n\ndef crate_deps(deps, package_name = None):\n \"\"\"Finds the fully qualified label of the requested crates for the package where this macro is called.\n\n Args:\n deps (list): The desired list of crate targets.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()`.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if not deps:\n return []\n\n if package_name == None:\n package_name = native.package_name()\n\n # Join both sets of dependencies\n dependencies = _flatten_dependency_maps([\n _NORMAL_DEPENDENCIES,\n _NORMAL_DEV_DEPENDENCIES,\n _PROC_MACRO_DEPENDENCIES,\n _PROC_MACRO_DEV_DEPENDENCIES,\n _BUILD_DEPENDENCIES,\n _BUILD_PROC_MACRO_DEPENDENCIES,\n ]).pop(package_name, {})\n\n # Combine all conditional packages so we can easily index over a flat list\n # TODO: Perhaps this should actually return select statements and maintain\n # the conditionals of the dependencies\n flat_deps = {}\n for deps_set in dependencies.values():\n for crate_name, crate_label in deps_set.items():\n flat_deps.update({crate_name: crate_label})\n\n missing_crates = []\n crate_targets = []\n for crate_target in deps:\n if crate_target not in flat_deps:\n missing_crates.append(crate_target)\n else:\n crate_targets.append(flat_deps[crate_target])\n\n if missing_crates:\n fail(\"Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`\".format(\n missing_crates,\n package_name,\n dependencies,\n ))\n\n return crate_targets\n\ndef crate_edition(package_name = None):\n \"\"\"Finds the Rust edition for the package where this macro is called.\n\n Args:\n package_name (str, optional): The package name whose edition should be\n looked up. Defaults to `native.package_name()` when unset.\n\n Returns:\n str: The Rust edition declared by the package's Cargo.toml file.\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n if package_name not in _CRATE_EDITIONS:\n fail(\"Tried to get crate_edition for package \" + package_name + \" but that package had no Cargo.toml file\")\n\n return _CRATE_EDITIONS[package_name]\n\ndef all_crate_deps(\n normal = False, \n normal_dev = False, \n proc_macro = False, \n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Finds the fully qualified label of all requested direct crate dependencies \\\n for the package where this macro is called.\n\n If no parameters are set, all normal dependencies are returned. Setting any one flag will\n otherwise impact the contents of the returned list.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list.\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_dependency_maps = []\n if normal:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n if normal_dev:\n all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)\n if proc_macro:\n all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)\n if proc_macro_dev:\n all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)\n if build:\n all_dependency_maps.append(_BUILD_DEPENDENCIES)\n if build_proc_macro:\n all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)\n\n # Default to always using normal dependencies\n if not all_dependency_maps:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n\n dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)\n\n if not dependencies:\n if dependencies == None:\n fail(\"Tried to get all_crate_deps for package \" + package_name + \" but that package had no Cargo.toml file\")\n else:\n return []\n\n crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())\n for condition, deps in dependencies.items():\n crate_deps += selects.with_or({\n tuple(_CONDITIONS[condition]): deps.values(),\n \"//conditions:default\": [],\n })\n\n return crate_deps\n\ndef aliases(\n normal = False,\n normal_dev = False,\n proc_macro = False,\n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Produces a map of Crate alias names to their original label\n\n If no dependency kinds are specified, `normal` and `proc_macro` are used by default.\n Setting any one flag will otherwise determine the contents of the returned dict.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list..\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n dict: The aliases of all associated packages\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_aliases_maps = []\n if normal:\n all_aliases_maps.append(_NORMAL_ALIASES)\n if normal_dev:\n all_aliases_maps.append(_NORMAL_DEV_ALIASES)\n if proc_macro:\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n if proc_macro_dev:\n all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)\n if build:\n all_aliases_maps.append(_BUILD_ALIASES)\n if build_proc_macro:\n all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)\n\n # Default to always using normal aliases\n if not all_aliases_maps:\n all_aliases_maps.append(_NORMAL_ALIASES)\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n\n aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)\n\n if not aliases:\n return dict()\n\n common_items = aliases.pop(_COMMON_CONDITION, {}).items()\n\n # If there are only common items in the dictionary, immediately return them\n if not len(aliases.keys()) == 1:\n return dict(common_items)\n\n # Build a single select statement where each conditional has accounted for the\n # common set of aliases.\n crate_aliases = {\"//conditions:default\": dict(common_items)}\n for condition, deps in aliases.items():\n condition_triples = _CONDITIONS[condition]\n for triple in condition_triples:\n if triple in crate_aliases:\n crate_aliases[triple].update(deps)\n else:\n crate_aliases.update({triple: dict(deps.items() + common_items)})\n\n return select(crate_aliases)\n\n###############################################################################\n# WORKSPACE MEMBER DEPS, ALIASES, AND EDITIONS\n###############################################################################\n\n_CRATE_EDITIONS = {\n \"crates/vendor/brush-builtins\": \"2024\",\n \"crates/vendor/brush-core\": \"2024\",\n \"crates/vendor/jaq\": \"2024\",\n \"crates/pi-ast\": \"2024\",\n \"crates/pi-iso\": \"2024\",\n \"crates/pi-natives\": \"2024\",\n \"crates/pi-shell\": \"2024\",\n \"crates/pi-uutils-ctx\": \"2024\",\n \"crates/pi-walker\": \"2024\",\n \"crates/pi-uu-diff\": \"2024\",\n \"crates/pi-uu-grep\": \"2024\",\n \"crates/vendor/uu-b2sum\": \"2024\",\n \"crates/vendor/uu-base32\": \"2024\",\n \"crates/vendor/uu-base64\": \"2024\",\n \"crates/vendor/uu-basename\": \"2024\",\n \"crates/vendor/uu-cat\": \"2024\",\n \"crates/vendor/uu-checksum-common\": \"2024\",\n \"crates/vendor/uu-comm\": \"2024\",\n \"crates/vendor/uu-cut\": \"2024\",\n \"crates/vendor/uu-date\": \"2024\",\n \"crates/vendor/uu-dirname\": \"2024\",\n \"crates/vendor/uu-find\": \"2024\",\n \"crates/vendor/uu-head\": \"2024\",\n \"crates/vendor/uu-hostname\": \"2024\",\n \"crates/vendor/uu-ln\": \"2024\",\n \"crates/vendor/uu-ls\": \"2024\",\n \"crates/vendor/uu-md5sum\": \"2024\",\n \"crates/vendor/uu-mkdir\": \"2024\",\n \"crates/vendor/uu-mktemp\": \"2024\",\n \"crates/vendor/uu-mv\": \"2024\",\n \"crates/vendor/uu-nproc\": \"2024\",\n \"crates/vendor/uu-paste\": \"2024\",\n \"crates/vendor/uu-printenv\": \"2024\",\n \"crates/vendor/uu-readlink\": \"2024\",\n \"crates/vendor/uu-realpath\": \"2024\",\n \"crates/vendor/uu-rm\": \"2024\",\n \"crates/vendor/uu-sed\": \"2024\",\n \"crates/vendor/uu-seq\": \"2024\",\n \"crates/vendor/uu-sha1sum\": \"2024\",\n \"crates/vendor/uu-sha224sum\": \"2024\",\n \"crates/vendor/uu-sha256sum\": \"2024\",\n \"crates/vendor/uu-sha384sum\": \"2024\",\n \"crates/vendor/uu-sha512sum\": \"2024\",\n \"crates/vendor/uu-sort\": \"2024\",\n \"crates/vendor/uu-stat\": \"2024\",\n \"crates/vendor/uu-tac\": \"2024\",\n \"crates/vendor/uu-tail\": \"2024\",\n \"crates/vendor/uu-tee\": \"2024\",\n \"crates/vendor/uu-touch\": \"2024\",\n \"crates/vendor/uu-tr\": \"2024\",\n \"crates/vendor/uu-truncate\": \"2024\",\n \"crates/vendor/uu-uname\": \"2024\",\n \"crates/vendor/uu-uniq\": \"2024\",\n \"crates/vendor/uu-wc\": \"2024\",\n \"crates/vendor/uu-whoami\": \"2024\",\n \"crates/vendor/uu-xargs\": \"2024\",\n \"crates/vendor/uu-yes\": \"2024\",\n}\n\n_NORMAL_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n \"brush-parser\": Label(\"//brush-parser-0.4.0\"),\n \"cfg-if\": Label(\"//cfg-if-1.0.4\"),\n \"chrono\": Label(\"//chrono-0.4.45\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"fancy-regex\": Label(\"//fancy-regex-0.17.0\"),\n \"futures\": Label(\"//futures-0.3.33\"),\n \"itertools\": Label(\"//itertools-0.14.0\"),\n \"strum\": Label(\"//strum-0.28.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"tracing\": Label(\"//tracing-0.1.44\"),\n },\n \"cfg(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"))\": {\n \"procfs\": Label(\"//procfs-0.18.0\"),\n },\n \"cfg(any(unix, windows))\": {\n \"tokio\": Label(\"//tokio-1.53.1\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(target_family = \\\"wasm\\\")\": {\n \"tokio\": Label(\"//tokio-1.53.1\"),\n },\n \"cfg(unix)\": {\n \"nix\": Label(\"//nix-0.31.3\"),\n \"rlimit\": Label(\"//rlimit-0.11.0\"),\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n \"bon\": Label(\"//bon-3.9.3\"),\n \"brush-parser\": Label(\"//brush-parser-0.4.0\"),\n \"cached\": Label(\"//cached-0.59.0\"),\n \"cfg-if\": Label(\"//cfg-if-1.0.4\"),\n \"chrono\": Label(\"//chrono-0.4.45\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"color-print\": Label(\"//color-print-0.3.7\"),\n \"fancy-regex\": Label(\"//fancy-regex-0.17.0\"),\n \"futures\": Label(\"//futures-0.3.33\"),\n \"itertools\": Label(\"//itertools-0.14.0\"),\n \"normalize-path\": Label(\"//normalize-path-0.2.1\"),\n \"rand\": Label(\"//rand-0.10.2\"),\n \"rpds\": Label(\"//rpds-1.2.1\"),\n \"strum\": Label(\"//strum-0.28.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"tokio-util\": Label(\"//tokio-util-0.7.19\"),\n \"tracing\": Label(\"//tracing-0.1.44\"),\n },\n \"cfg(any(unix, windows))\": {\n \"hostname\": Label(\"//hostname-0.4.2\"),\n \"tokio\": Label(\"//tokio-1.53.1\"),\n },\n \"cfg(target_family = \\\"wasm\\\")\": {\n \"tokio\": Label(\"//tokio-1.53.1\"),\n },\n \"cfg(unix)\": {\n \"command-fds\": Label(\"//command-fds-0.3.3\"),\n \"libc\": Label(\"//libc-0.2.189\"),\n \"nix\": Label(\"//nix-0.31.3\"),\n \"terminfo\": Label(\"//terminfo-0.9.0\"),\n \"uzers\": Label(\"//uzers-0.12.2\"),\n },\n \"cfg(windows)\": {\n \"check_elevation\": Label(\"//check_elevation-0.2.7\"),\n \"whoami\": Label(\"//whoami-2.1.2\"),\n \"windows-sys\": Label(\"//windows-sys-0.59.0\"),\n },\n \"wasm32-unknown-unknown\": {\n \"getrandom\": Label(\"//getrandom-0.4.3\"),\n \"uuid\": Label(\"//uuid-1.24.0\"),\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n \"codesnake\": Label(\"//codesnake-0.2.1\"),\n \"hifijson\": Label(\"//hifijson-0.2.3\"),\n \"jaq-core\": Label(\"//jaq-core-2.2.1\"),\n \"jaq-json\": Label(\"//jaq-json-1.1.3\"),\n \"jaq-std\": Label(\"//jaq-std-2.1.2\"),\n \"memmap2\": Label(\"//memmap2-0.9.11\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n \"unicode-width\": Label(\"//unicode-width-0.1.14\"),\n \"yansi\": Label(\"//yansi-1.0.1\"),\n },\n },\n \"crates/pi-ast\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"ast-grep-core\": Label(\"//ast-grep-core-0.39.9\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"phf\": Label(\"//phf-0.13.1\"),\n \"serde\": Label(\"//serde-1.0.229\"),\n \"tree-sitter\": Label(\"//tree-sitter-0.25.10\"),\n \"tree_sitter_astro\": Label(\"//tree-sitter-astro-next-0.1.1\"),\n \"tree-sitter-bash\": Label(\"//tree-sitter-bash-0.25.1\"),\n \"tree-sitter-c\": Label(\"//tree-sitter-c-0.24.2\"),\n \"tree-sitter-c-sharp\": Label(\"//tree-sitter-c-sharp-0.23.5\"),\n \"tree-sitter-clojure\": Label(\"//tree-sitter-clojure-0.1.0\"),\n \"tree-sitter-cmake\": Label(\"//tree-sitter-cmake-0.7.4\"),\n \"tree-sitter-cpp\": Label(\"//tree-sitter-cpp-0.23.4\"),\n \"tree-sitter-css\": Label(\"//tree-sitter-css-0.25.0\"),\n \"tree-sitter-dart\": Label(\"//tree-sitter-dart-0.2.0\"),\n \"tree-sitter-diff\": Label(\"//tree-sitter-diff-0.1.0\"),\n \"tree_sitter_dockerfile\": Label(\"//tree-sitter-dockerfile-updated-0.2.0\"),\n \"tree-sitter-elisp\": Label(\"//tree-sitter-elisp-1.6.1\"),\n \"tree-sitter-elixir\": Label(\"//tree-sitter-elixir-0.3.5\"),\n \"tree-sitter-erlang\": Label(\"//tree-sitter-erlang-0.16.0\"),\n \"tree-sitter-fortran\": Label(\"//tree-sitter-fortran-0.6.0\"),\n \"tree-sitter-go\": Label(\"//tree-sitter-go-0.25.0\"),\n \"tree-sitter-graphql\": Label(\"//tree-sitter-graphql-0.1.0\"),\n \"tree-sitter-haskell\": Label(\"//tree-sitter-haskell-0.23.1\"),\n \"tree-sitter-hcl\": Label(\"//tree-sitter-hcl-1.1.0\"),\n \"tree-sitter-html\": Label(\"//tree-sitter-html-0.23.2\"),\n \"tree-sitter-ini\": Label(\"//tree-sitter-ini-1.4.0\"),\n \"tree-sitter-java\": Label(\"//tree-sitter-java-0.23.5\"),\n \"tree-sitter-javascript\": Label(\"//tree-sitter-javascript-0.25.0\"),\n \"tree-sitter-json\": Label(\"//tree-sitter-json-0.24.8\"),\n \"tree-sitter-julia\": Label(\"//tree-sitter-julia-0.23.1\"),\n \"tree-sitter-just\": Label(\"//tree-sitter-just-0.2.0\"),\n \"tree_sitter_kotlin\": Label(\"//tree-sitter-kotlin-sg-0.4.1\"),\n \"tree-sitter-lua\": Label(\"//tree-sitter-lua-0.5.0\"),\n \"tree-sitter-make\": Label(\"//tree-sitter-make-1.1.1\"),\n \"tree-sitter-md\": Label(\"//tree-sitter-md-0.5.3\"),\n \"tree-sitter-nix\": Label(\"//tree-sitter-nix-0.3.0\"),\n \"tree-sitter-objc\": Label(\"//tree-sitter-objc-3.0.2\"),\n \"tree-sitter-ocaml\": Label(\"//tree-sitter-ocaml-0.24.2\"),\n \"tree-sitter-odin\": Label(\"//tree-sitter-odin-1.3.0\"),\n \"tree-sitter-php\": Label(\"//tree-sitter-php-0.24.2\"),\n \"tree-sitter-powershell\": Label(\"//tree-sitter-powershell-0.26.4\"),\n \"tree-sitter-proto\": Label(\"//tree-sitter-proto-0.4.0\"),\n \"tree-sitter-python\": Label(\"//tree-sitter-python-0.25.0\"),\n \"tree-sitter-r\": Label(\"//tree-sitter-r-1.3.0\"),\n \"tree-sitter-regex\": Label(\"//tree-sitter-regex-0.25.0\"),\n \"tree-sitter-ruby\": Label(\"//tree-sitter-ruby-0.23.1\"),\n \"tree-sitter-rust\": Label(\"//tree-sitter-rust-0.24.2\"),\n \"tree-sitter-scala\": Label(\"//tree-sitter-scala-0.26.0\"),\n \"tree_sitter_sql\": Label(\"//tree-sitter-sequel-0.3.11\"),\n \"tree-sitter-solidity\": Label(\"//tree-sitter-solidity-1.2.13\"),\n \"tree-sitter-starlark\": Label(\"//tree-sitter-starlark-1.3.0\"),\n \"tree_sitter_svelte\": Label(\"//tree-sitter-svelte-next-0.1.1\"),\n \"tree-sitter-swift\": Label(\"//tree-sitter-swift-0.7.3\"),\n \"tree-sitter-tlaplus\": Label(\"//tree-sitter-tlaplus-1.5.0\"),\n \"tree-sitter-toml-ng\": Label(\"//tree-sitter-toml-ng-0.7.0\"),\n \"tree-sitter-typescript\": Label(\"//tree-sitter-typescript-0.23.2\"),\n \"tree-sitter-verilog\": Label(\"//tree-sitter-verilog-1.0.3\"),\n \"tree_sitter_vue\": Label(\"//tree-sitter-vue-next-0.1.0\"),\n \"tree-sitter-xml\": Label(\"//tree-sitter-xml-0.7.0\"),\n \"tree-sitter-yaml\": Label(\"//tree-sitter-yaml-0.7.2\"),\n \"tree-sitter-zig\": Label(\"//tree-sitter-zig-1.1.2\"),\n },\n },\n \"crates/pi-iso\": {\n _COMMON_CONDITION: {\n \"similar\": Label(\"//similar-3.1.1\"),\n \"tokio\": Label(\"//tokio-1.53.1\"),\n },\n \"cfg(target_os = \\\"linux\\\")\": {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"arboard\": Label(\"//arboard-3.6.1\"),\n \"ast-grep-core\": Label(\"//ast-grep-core-0.39.9\"),\n \"audiopus_sys\": Label(\"//audiopus_sys-0.2.2\"),\n \"base64\": Label(\"//base64-0.22.1\"),\n \"bytes\": Label(\"//bytes-1.12.1\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"flume\": Label(\"//flume-0.11.1\"),\n \"fontdue\": Label(\"//fontdue-0.9.3\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"grep-matcher\": Label(\"//grep-matcher-0.1.9\"),\n \"grep-pcre2\": Label(\"//grep-pcre2-0.1.10\"),\n \"grep-regex\": Label(\"//grep-regex-0.1.14\"),\n \"grep-searcher\": Label(\"//grep-searcher-0.1.17\"),\n \"html-to-markdown-rs\": Label(\"//html-to-markdown-rs-2.30.0\"),\n \"icy_sixel\": Label(\"//icy_sixel-0.5.0\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"image\": Label(\"//image-0.25.10\"),\n \"inferno\": Label(\"//inferno-0.12.8\"),\n \"maudio\": Label(\"//maudio-0.1.6\"),\n \"napi\": Label(\"//napi-3.11.0\"),\n \"opus\": Label(\"//opus-0.3.1\"),\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"phf\": Label(\"//phf-0.13.1\"),\n \"png\": Label(\"//png-0.18.1\"),\n \"portable-pty\": Label(\"//portable-pty-0.9.0\"),\n \"rayon\": Label(\"//rayon-1.12.0\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"serde\": Label(\"//serde-1.0.229\"),\n \"serde_json\": Label(\"//serde_json-1.0.151\"),\n \"smallvec\": Label(\"//smallvec-1.15.2\"),\n \"syntect\": Label(\"//syntect-5.3.0\"),\n \"tiktoken-rs\": Label(\"//tiktoken-rs-0.11.0\"),\n \"tokio\": Label(\"//tokio-1.53.1\"),\n \"tokio-util\": Label(\"//tokio-util-0.7.19\"),\n \"toml\": Label(\"//toml-1.1.3+spec-1.1.0\"),\n \"unicode-segmentation\": Label(\"//unicode-segmentation-1.13.3\"),\n \"unicode-width\": Label(\"//unicode-width-0.2.2\"),\n \"webrtc\": Label(\"//webrtc-0.17.2\"),\n \"xxhash-rust\": Label(\"//xxhash-rust-0.8.18\"),\n },\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"windows\\\"))\": {\n \"enigo\": Label(\"//enigo-0.6.1\"),\n \"xcap\": Label(\"//xcap-0.9.6\"),\n },\n \"cfg(target_os = \\\"linux\\\")\": {\n \"x11rb\": Label(\"//x11rb-0.13.2\"),\n \"xkeysym\": Label(\"//xkeysym-0.2.1\"),\n },\n \"cfg(target_os = \\\"macos\\\")\": {\n \"core-graphics\": Label(\"//core-graphics-0.25.0\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"clipboard-win\": Label(\"//clipboard-win-5.4.1\"),\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n \"winreg\": Label(\"//winreg-0.56.0\"),\n },\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"brush-parser\": Label(\"//brush-parser-0.3.0\"),\n \"bytes\": Label(\"//bytes-1.12.1\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"flume\": Label(\"//flume-0.11.1\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"jiff\": Label(\"//jiff-0.2.35\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"os_pipe\": Label(\"//os_pipe-1.2.3\"),\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"serde\": Label(\"//serde-1.0.229\"),\n \"serde_json\": Label(\"//serde_json-1.0.151\"),\n \"tokio\": Label(\"//tokio-1.53.1\"),\n \"tokio-util\": Label(\"//tokio-util-0.7.19\"),\n \"toml\": Label(\"//toml-1.1.3+spec-1.1.0\"),\n \"xxhash-rust\": Label(\"//xxhash-rust-0.8.18\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"smallvec\": Label(\"//smallvec-1.15.2\"),\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n \"winreg\": Label(\"//winreg-0.56.0\"),\n },\n },\n \"crates/pi-uutils-ctx\": {\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n },\n \"crates/pi-walker\": {\n _COMMON_CONDITION: {\n \"dashmap\": Label(\"//dashmap-6.2.1\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"rayon\": Label(\"//rayon-1.12.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"similar\": Label(\"//similar-3.1.1\"),\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"grep-cli\": Label(\"//grep-cli-0.1.12\"),\n \"grep-matcher\": Label(\"//grep-matcher-0.1.9\"),\n \"grep-pcre2\": Label(\"//grep-pcre2-0.1.10\"),\n \"grep-printer\": Label(\"//grep-printer-0.3.1\"),\n \"grep-regex\": Label(\"//grep-regex-0.1.14\"),\n \"grep-searcher\": Label(\"//grep-searcher-0.1.17\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"serde_json\": Label(\"//serde_json-1.0.151\"),\n },\n },\n \"crates/vendor/uu-b2sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-base32\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-basename\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-cat\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-checksum-common\": {\n _COMMON_CONDITION: {\n \"base64-simd\": Label(\"//base64-simd-0.8.0\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"hex\": Label(\"//hex-0.4.3\"),\n \"os_display\": Label(\"//os_display-0.1.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-comm\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-cut\": {\n _COMMON_CONDITION: {\n \"bstr\": Label(\"//bstr-1.13.0\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"jiff\": Label(\"//jiff-0.2.35\"),\n \"parse_datetime\": Label(\"//parse_datetime-0.14.0\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n \"argmax\": Label(\"//argmax-0.3.1\"),\n \"chrono\": Label(\"//chrono-0.4.45\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"faccess\": Label(\"//faccess-0.2.4\"),\n \"nix\": Label(\"//nix-0.29.0\"),\n \"onig\": Label(\"//onig-6.5.3\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"uucore\": Label(\"//uucore-0.0.30\"),\n },\n },\n \"crates/vendor/uu-head\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"hostname\": Label(\"//hostname-0.4.2\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"openbsd\\\"))\": {\n \"dns-lookup\": Label(\"//dns-lookup-3.0.1\"),\n },\n \"cfg(target_os = \\\"windows\\\")\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-ls\": {\n _COMMON_CONDITION: {\n \"ansi-width\": Label(\"//ansi-width-0.1.0\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"glob\": Label(\"//glob-0.3.4\"),\n \"lscolors\": Label(\"//lscolors-0.21.0\"),\n \"rustc-hash\": Label(\"//rustc-hash-2.1.3\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n \"uutils_term_grid\": Label(\"//uutils_term_grid-0.8.0\"),\n },\n \"cfg(not(target_os = \\\"wasi\\\"))\": {\n \"hostname\": Label(\"//hostname-0.4.2\"),\n },\n },\n \"crates/vendor/uu-md5sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-mkdir\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"rand\": Label(\"//rand-0.10.2\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-mv\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"fs_extra\": Label(\"//fs_extra-1.3.0\"),\n \"indicatif\": Label(\"//indicatif-0.18.6\"),\n \"libc\": Label(\"//libc-0.2.189\"),\n \"rustc-hash\": Label(\"//rustc-hash-2.1.3\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"libc\": Label(\"//libc-0.2.189\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-paste\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-rm\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"indicatif\": Label(\"//indicatif-0.18.6\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"fancy-regex\": Label(\"//fancy-regex-0.18.0\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n \"uucore\": Label(\"//uucore-0.9.0\"),\n },\n \"cfg(unix)\": {\n \"memmap2\": Label(\"//memmap2-0.9.11\"),\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n \"bigdecimal\": Label(\"//bigdecimal-0.4.10\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"num-bigint\": Label(\"//num-bigint-0.4.8\"),\n \"num-traits\": Label(\"//num-traits-0.2.19\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha224sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha256sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha384sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha512sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sort\": {\n _COMMON_CONDITION: {\n \"bigdecimal\": Label(\"//bigdecimal-0.4.10\"),\n \"binary-heap-plus\": Label(\"//binary-heap-plus-0.5.0\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"compare\": Label(\"//compare-0.1.0\"),\n \"flume\": Label(\"//flume-0.11.1\"),\n \"foldhash\": Label(\"//foldhash-0.2.0\"),\n \"itertools\": Label(\"//itertools-0.14.0\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"rand\": Label(\"//rand-0.10.2\"),\n \"rayon\": Label(\"//rayon-1.12.0\"),\n \"self_cell\": Label(\"//self_cell-1.3.0\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"nix\": Label(\"//nix-0.31.3\"),\n },\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"memmap2\": Label(\"//memmap2-0.9.11\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(not(target_os = \\\"wasi\\\"))\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n \"notify\": Label(\"//notify-8.2.0\"),\n },\n \"cfg(unix)\": {\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-tee\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"filetime\": Label(\"//filetime-0.2.29\"),\n \"jiff\": Label(\"//jiff-0.2.35\"),\n \"parse_datetime\": Label(\"//parse_datetime-0.14.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-tr\": {\n _COMMON_CONDITION: {\n \"bytecount\": Label(\"//bytecount-0.6.9\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"nom\": Label(\"//nom-8.0.0\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"platform-info\": Label(\"//platform-info-2.1.0\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-uniq\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-wc\": {\n _COMMON_CONDITION: {\n \"bytecount\": Label(\"//bytecount-0.6.9\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"unicode-width\": Label(\"//unicode-width-0.2.2\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(target_os = \\\"windows\\\")\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"itertools\": Label(\"//itertools-0.14.0\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n}\n\n\n_NORMAL_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n },\n \"cfg(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"))\": {\n },\n \"cfg(any(unix, windows))\": {\n },\n \"cfg(target_family = \\\"wasm\\\")\": {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n },\n \"cfg(any(unix, windows))\": {\n },\n \"cfg(target_family = \\\"wasm\\\")\": {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n \"wasm32-unknown-unknown\": {\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-ast\": {\n _COMMON_CONDITION: {\n Label(\"//tree-sitter-astro-next-0.1.1\"): \"tree_sitter_astro\",\n Label(\"//tree-sitter-dockerfile-updated-0.2.0\"): \"tree_sitter_dockerfile\",\n Label(\"//tree-sitter-kotlin-sg-0.4.1\"): \"tree_sitter_kotlin\",\n Label(\"//tree-sitter-sequel-0.3.11\"): \"tree_sitter_sql\",\n Label(\"//tree-sitter-svelte-next-0.1.1\"): \"tree_sitter_svelte\",\n Label(\"//tree-sitter-vue-next-0.1.0\"): \"tree_sitter_vue\",\n },\n },\n \"crates/pi-iso\": {\n _COMMON_CONDITION: {\n },\n \"cfg(target_os = \\\"linux\\\")\": {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n },\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"windows\\\"))\": {\n },\n \"cfg(target_os = \\\"linux\\\")\": {\n },\n \"cfg(target_os = \\\"macos\\\")\": {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/pi-uutils-ctx\": {\n \"cfg(unix)\": {\n },\n },\n \"crates/pi-walker\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-b2sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-base32\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-basename\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-cat\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-checksum-common\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-comm\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-cut\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-head\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n },\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"openbsd\\\"))\": {\n },\n \"cfg(target_os = \\\"windows\\\")\": {\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ls\": {\n _COMMON_CONDITION: {\n },\n \"cfg(not(target_os = \\\"wasi\\\"))\": {\n },\n },\n \"crates/vendor/uu-md5sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-mkdir\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-mv\": {\n _COMMON_CONDITION: {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-paste\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-rm\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha224sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha256sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha384sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha512sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sort\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n },\n \"cfg(not(target_os = \\\"wasi\\\"))\": {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-tee\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-tr\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uniq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-wc\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n },\n \"cfg(target_os = \\\"windows\\\")\": {\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_NORMAL_DEV_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"pretty_assertions\": Label(\"//pretty_assertions-1.4.1\"),\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"pretty_assertions\": Label(\"//pretty_assertions-1.4.1\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n \"filetime\": Label(\"//filetime-0.2.29\"),\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"rstest\": Label(\"//rstest-0.26.1\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n}\n\n\n_NORMAL_DEV_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_PROC_MACRO_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n \"strum_macros\": Label(\"//strum_macros-0.28.0\"),\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n \"async-recursion\": Label(\"//async-recursion-1.1.1\"),\n \"async-trait\": Label(\"//async-trait-0.1.91\"),\n \"inherent\": Label(\"//inherent-1.0.14\"),\n \"strum_macros\": Label(\"//strum_macros-0.28.0\"),\n },\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n _COMMON_CONDITION: {\n \"async-trait\": Label(\"//async-trait-0.1.91\"),\n },\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n \"napi-derive\": Label(\"//napi-derive-3.6.0\"),\n },\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_PROC_MACRO_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_PROC_MACRO_DEV_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_PROC_MACRO_DEV_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_BUILD_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n \"napi-build\": Label(\"//napi-build-2.3.2\"),\n \"serde\": Label(\"//serde-1.0.229\"),\n \"serde_json\": Label(\"//serde_json-1.0.151\"),\n },\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_BUILD_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_CONDITIONS = {\n \"aarch64-apple-darwin\": [\"@@//bazel/triples:aarch64-apple-darwin\"],\n \"aarch64-linux-android\": [],\n \"aarch64-pc-windows-gnullvm\": [],\n \"aarch64-unknown-linux-gnu\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\"],\n \"aarch64-unknown-linux-musl\": [\"@@//bazel/triples:aarch64-unknown-linux-musl\"],\n \"cfg(all(all(target_arch = \\\"aarch64\\\", target_endian = \\\"little\\\"), target_os = \\\"windows\\\"))\": [],\n \"cfg(all(all(target_arch = \\\"aarch64\\\", target_endian = \\\"little\\\"), target_vendor = \\\"apple\\\", any(target_os = \\\"ios\\\", target_os = \\\"macos\\\", target_os = \\\"tvos\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\")))\": [\"@@//bazel/triples:aarch64-apple-darwin\"],\n \"cfg(all(any(all(target_arch = \\\"aarch64\\\", target_endian = \\\"little\\\"), all(target_arch = \\\"arm\\\", target_endian = \\\"little\\\")), any(target_os = \\\"android\\\", target_os = \\\"linux\\\")))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\"],\n \"cfg(all(any(target_arch = \\\"x86_64\\\", target_arch = \\\"arm64ec\\\"), target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(all(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), not(any(all(target_os = \\\"linux\\\", target_env = \\\"\\\"), getrandom_backend = \\\"custom\\\", getrandom_backend = \\\"linux_raw\\\", getrandom_backend = \\\"rdrand\\\", getrandom_backend = \\\"rndr\\\"))))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(not(curve25519_dalek_backend = \\\"fiat\\\"), not(curve25519_dalek_backend = \\\"serial\\\"), target_arch = \\\"x86_64\\\"))\": [\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_os = \\\"android\\\"))\": [],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_os = \\\"linux\\\"))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_vendor = \\\"apple\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\"],\n \"cfg(all(target_arch = \\\"loongarch64\\\", target_os = \\\"linux\\\"))\": [],\n \"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\": [],\n \"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"wasi\\\", target_env = \\\"p2\\\"))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"gnu\\\", not(target_abi = \\\"llvm\\\"), not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"gnu\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"gnu\\\", not(target_abi = \\\"llvm\\\"), not(windows_raw_dylib)))\": [\"@@//bazel/triples:x86_64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\": [],\n \"cfg(all(target_os = \\\"linux\\\", not(target_env = \\\"ohos\\\")))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(target_os = \\\"uefi\\\", getrandom_backend = \\\"efi_rng\\\"))\": [],\n \"cfg(all(unix, not(any(target_os = \\\"macos\\\", target_os = \\\"android\\\", target_os = \\\"emscripten\\\"))))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(unix, not(target_os = \\\"macos\\\")))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any())\": [],\n \"cfg(any(target_arch = \\\"aarch64\\\", target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_arch = \\\"aarch64\\\", target_arch = \\\"x86_64\\\", target_arch = \\\"x86\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\": [\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_arch = \\\"x86_64\\\", target_arch = \\\"x86\\\"))\": [\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\", target_os = \\\"macos\\\", target_os = \\\"hurd\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"hurd\\\", target_os = \\\"illumos\\\", target_os = \\\"cygwin\\\", all(target_os = \\\"horizon\\\", target_arch = \\\"arm\\\")))\": [],\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"dragonfly\\\"))\": [],\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\": [],\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"openbsd\\\"))\": [],\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"openbsd\\\", target_os = \\\"netbsd\\\", target_os = \\\"dragonflybsd\\\", target_os = \\\"ios\\\"))\": [],\n \"cfg(any(target_os = \\\"haiku\\\", target_os = \\\"redox\\\", target_os = \\\"nto\\\", target_os = \\\"aix\\\"))\": [],\n \"cfg(any(target_os = \\\"ios\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\", target_os = \\\"tvos\\\"))\": [],\n \"cfg(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"openbsd\\\", target_os = \\\"vita\\\", target_os = \\\"emscripten\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"windows\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(any(unix, target_os = \\\"fuchsia\\\", target_os = \\\"vxworks\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(unix, target_os = \\\"hermit\\\", target_os = \\\"wasi\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(unix, target_os = \\\"redox\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(unix, target_os = \\\"wasi\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(unix, windows))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(windows, target_os = \\\"linux\\\"))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(curve25519_dalek_backend = \\\"fiat\\\")\": [],\n \"cfg(not(all(target_arch = \\\"arm\\\", target_os = \\\"none\\\")))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(not(any(target_os = \\\"android\\\", target_os = \\\"linux\\\")))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(not(target_has_atomic = \\\"ptr\\\"))\": [],\n \"cfg(not(target_os = \\\"wasi\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(not(target_os = \\\"windows\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(not(windows))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(target_arch = \\\"aarch64\\\")\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\"],\n \"cfg(target_arch = \\\"spirv\\\")\": [],\n \"cfg(target_arch = \\\"x86\\\")\": [],\n \"cfg(target_arch = \\\"x86_64\\\")\": [\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(target_family = \\\"wasm\\\")\": [],\n \"cfg(target_os = \\\"android\\\")\": [],\n \"cfg(target_os = \\\"freebsd\\\")\": [],\n \"cfg(target_os = \\\"haiku\\\")\": [],\n \"cfg(target_os = \\\"hermit\\\")\": [],\n \"cfg(target_os = \\\"linux\\\")\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(target_os = \\\"macos\\\")\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(target_os = \\\"netbsd\\\")\": [],\n \"cfg(target_os = \\\"redox\\\")\": [],\n \"cfg(target_os = \\\"solaris\\\")\": [],\n \"cfg(target_os = \\\"vxworks\\\")\": [],\n \"cfg(target_os = \\\"wasi\\\")\": [],\n \"cfg(target_os = \\\"windows\\\")\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(target_vendor = \\\"apple\\\")\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(unix)\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(windows)\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(windows_raw_dylib)\": [],\n \"i686-pc-windows-gnu\": [],\n \"i686-pc-windows-gnullvm\": [],\n \"wasm32-unknown-unknown\": [],\n \"x86_64-apple-darwin\": [\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"x86_64-pc-windows-gnu\": [],\n \"x86_64-pc-windows-gnullvm\": [],\n \"x86_64-pc-windows-msvc\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"x86_64-unknown-linux-gnu\": [\"@@//bazel/triples:x86_64-unknown-linux-gnu\"],\n \"x86_64-unknown-linux-musl\": [\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n}\n\n###############################################################################\n\ndef crate_repositories():\n \"\"\"A macro for defining repositories for all generated crates.\n\n Returns:\n A list of repos visible to the module through the module extension.\n \"\"\"\n maybe(\n crates_vendor_remote_repository,\n name = \"crates\",\n # Lean interface: just point at `crates.bzl`; the repo rule\n # derives the sibling `BUILD.bazel` and `defs.bzl`.\n crates_module = Label(\"@crates//crates:crates.bzl\"),\n )\n maybe(\n http_archive,\n name = \"crates__adler2-2.0.1\",\n sha256 = \"320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/adler2/2.0.1/download\"],\n strip_prefix = \"adler2-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.adler2-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__aead-0.5.2\",\n sha256 = \"d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aead/0.5.2/download\"],\n strip_prefix = \"aead-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.aead-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__aes-0.8.4\",\n sha256 = \"b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aes/0.8.4/download\"],\n strip_prefix = \"aes-0.8.4\",\n build_file = Label(\"@crates//crates:BUILD.aes-0.8.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__aes-gcm-0.10.3\",\n sha256 = \"831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aes-gcm/0.10.3/download\"],\n strip_prefix = \"aes-gcm-0.10.3\",\n build_file = Label(\"@crates//crates:BUILD.aes-gcm-0.10.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ahash-0.8.12\",\n sha256 = \"5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ahash/0.8.12/download\"],\n strip_prefix = \"ahash-0.8.12\",\n build_file = Label(\"@crates//crates:BUILD.ahash-0.8.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__aho-corasick-1.1.4\",\n sha256 = \"ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aho-corasick/1.1.4/download\"],\n strip_prefix = \"aho-corasick-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.aho-corasick-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__allocator-api2-0.2.21\",\n sha256 = \"683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/allocator-api2/0.2.21/download\"],\n strip_prefix = \"allocator-api2-0.2.21\",\n build_file = Label(\"@crates//crates:BUILD.allocator-api2-0.2.21.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__android_system_properties-0.1.5\",\n sha256 = \"819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/android_system_properties/0.1.5/download\"],\n strip_prefix = \"android_system_properties-0.1.5\",\n build_file = Label(\"@crates//crates:BUILD.android_system_properties-0.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__annotate-snippets-0.11.5\",\n sha256 = \"710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/annotate-snippets/0.11.5/download\"],\n strip_prefix = \"annotate-snippets-0.11.5\",\n build_file = Label(\"@crates//crates:BUILD.annotate-snippets-0.11.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ansi-width-0.1.0\",\n sha256 = \"219e3ce6f2611d83b51ec2098a12702112c29e57203a6b0a0929b2cddb486608\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ansi-width/0.1.0/download\"],\n strip_prefix = \"ansi-width-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.ansi-width-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstream-1.0.0\",\n sha256 = \"824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstream/1.0.0/download\"],\n strip_prefix = \"anstream-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.anstream-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-1.0.14\",\n sha256 = \"940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle/1.0.14/download\"],\n strip_prefix = \"anstyle-1.0.14\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-1.0.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-parse-1.0.0\",\n sha256 = \"52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle-parse/1.0.0/download\"],\n strip_prefix = \"anstyle-parse-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-parse-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-query-1.1.5\",\n sha256 = \"40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle-query/1.1.5/download\"],\n strip_prefix = \"anstyle-query-1.1.5\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-query-1.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-wincon-3.0.11\",\n sha256 = \"291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle-wincon/3.0.11/download\"],\n strip_prefix = \"anstyle-wincon-3.0.11\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-wincon-3.0.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anyhow-1.0.104\",\n sha256 = \"330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anyhow/1.0.104/download\"],\n strip_prefix = \"anyhow-1.0.104\",\n build_file = Label(\"@crates//crates:BUILD.anyhow-1.0.104.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__arboard-3.6.1\",\n sha256 = \"0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/arboard/3.6.1/download\"],\n strip_prefix = \"arboard-3.6.1\",\n build_file = Label(\"@crates//crates:BUILD.arboard-3.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__arc-swap-1.9.2\",\n sha256 = \"c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/arc-swap/1.9.2/download\"],\n strip_prefix = \"arc-swap-1.9.2\",\n build_file = Label(\"@crates//crates:BUILD.arc-swap-1.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__archery-1.2.2\",\n sha256 = \"70e0a5f99dfebb87bb342d0f53bb92c81842e100bbb915223e38349580e5441d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/archery/1.2.2/download\"],\n strip_prefix = \"archery-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.archery-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__argmax-0.3.1\",\n sha256 = \"5b7e3ef5e3a7f2c5e5a49d90ad087c03d38258e75155daac64deb62c50972c66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/argmax/0.3.1/download\"],\n strip_prefix = \"argmax-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.argmax-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__arrayref-0.3.9\",\n sha256 = \"76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/arrayref/0.3.9/download\"],\n strip_prefix = \"arrayref-0.3.9\",\n build_file = Label(\"@crates//crates:BUILD.arrayref-0.3.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__arrayvec-0.7.8\",\n sha256 = \"d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/arrayvec/0.7.8/download\"],\n strip_prefix = \"arrayvec-0.7.8\",\n build_file = Label(\"@crates//crates:BUILD.arrayvec-0.7.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__asn1-rs-0.6.2\",\n sha256 = \"5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/asn1-rs/0.6.2/download\"],\n strip_prefix = \"asn1-rs-0.6.2\",\n build_file = Label(\"@crates//crates:BUILD.asn1-rs-0.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__asn1-rs-derive-0.5.1\",\n sha256 = \"965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/asn1-rs-derive/0.5.1/download\"],\n strip_prefix = \"asn1-rs-derive-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.asn1-rs-derive-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__asn1-rs-impl-0.2.0\",\n sha256 = \"7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/asn1-rs-impl/0.2.0/download\"],\n strip_prefix = \"asn1-rs-impl-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.asn1-rs-impl-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ast-grep-core-0.39.9\",\n sha256 = \"057ae90e7256ebf85f840b1638268df0142c9d19467d500b790631fd301acc27\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ast-grep-core/0.39.9/download\"],\n strip_prefix = \"ast-grep-core-0.39.9\",\n build_file = Label(\"@crates//crates:BUILD.ast-grep-core-0.39.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__astral-tl-0.7.11\",\n sha256 = \"d90933ffb0f97e2fc2e0de21da9d3f20597b804012d199843a6fe7c2810d28f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/astral-tl/0.7.11/download\"],\n strip_prefix = \"astral-tl-0.7.11\",\n build_file = Label(\"@crates//crates:BUILD.astral-tl-0.7.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-broadcast-0.7.2\",\n sha256 = \"435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-broadcast/0.7.2/download\"],\n strip_prefix = \"async-broadcast-0.7.2\",\n build_file = Label(\"@crates//crates:BUILD.async-broadcast-0.7.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-channel-2.5.0\",\n sha256 = \"924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-channel/2.5.0/download\"],\n strip_prefix = \"async-channel-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.async-channel-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-executor-1.14.0\",\n sha256 = \"c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-executor/1.14.0/download\"],\n strip_prefix = \"async-executor-1.14.0\",\n build_file = Label(\"@crates//crates:BUILD.async-executor-1.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-io-2.6.0\",\n sha256 = \"456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-io/2.6.0/download\"],\n strip_prefix = \"async-io-2.6.0\",\n build_file = Label(\"@crates//crates:BUILD.async-io-2.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-lock-3.4.2\",\n sha256 = \"290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-lock/3.4.2/download\"],\n strip_prefix = \"async-lock-3.4.2\",\n build_file = Label(\"@crates//crates:BUILD.async-lock-3.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-process-2.5.0\",\n sha256 = \"fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-process/2.5.0/download\"],\n strip_prefix = \"async-process-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.async-process-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-recursion-1.1.1\",\n sha256 = \"3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-recursion/1.1.1/download\"],\n strip_prefix = \"async-recursion-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.async-recursion-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-signal-0.2.14\",\n sha256 = \"52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-signal/0.2.14/download\"],\n strip_prefix = \"async-signal-0.2.14\",\n build_file = Label(\"@crates//crates:BUILD.async-signal-0.2.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-task-4.7.1\",\n sha256 = \"8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-task/4.7.1/download\"],\n strip_prefix = \"async-task-4.7.1\",\n build_file = Label(\"@crates//crates:BUILD.async-task-4.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-trait-0.1.91\",\n sha256 = \"ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-trait/0.1.91/download\"],\n strip_prefix = \"async-trait-0.1.91\",\n build_file = Label(\"@crates//crates:BUILD.async-trait-0.1.91.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__atomic-waker-1.1.2\",\n sha256 = \"1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/atomic-waker/1.1.2/download\"],\n strip_prefix = \"atomic-waker-1.1.2\",\n build_file = Label(\"@crates//crates:BUILD.atomic-waker-1.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__audiopus_sys-0.2.2\",\n sha256 = \"62314a1546a2064e033665d658e88c620a62904be945f8147e6b16c3db9f8651\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/audiopus_sys/0.2.2/download\"],\n strip_prefix = \"audiopus_sys-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.audiopus_sys-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__autocfg-1.5.1\",\n sha256 = \"f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/autocfg/1.5.1/download\"],\n strip_prefix = \"autocfg-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.autocfg-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base16ct-0.2.0\",\n sha256 = \"4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base16ct/0.2.0/download\"],\n strip_prefix = \"base16ct-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.base16ct-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64-0.22.1\",\n sha256 = \"72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64/0.22.1/download\"],\n strip_prefix = \"base64-0.22.1\",\n build_file = Label(\"@crates//crates:BUILD.base64-0.22.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64-simd-0.8.0\",\n sha256 = \"339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64-simd/0.8.0/download\"],\n strip_prefix = \"base64-simd-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.base64-simd-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64ct-1.8.3\",\n sha256 = \"2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64ct/1.8.3/download\"],\n strip_prefix = \"base64ct-1.8.3\",\n build_file = Label(\"@crates//crates:BUILD.base64ct-1.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bigdecimal-0.4.10\",\n sha256 = \"4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bigdecimal/0.4.10/download\"],\n strip_prefix = \"bigdecimal-0.4.10\",\n build_file = Label(\"@crates//crates:BUILD.bigdecimal-0.4.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__binary-heap-plus-0.5.0\",\n sha256 = \"e4551d8382e911ecc0d0f0ffb602777988669be09447d536ff4388d1def11296\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/binary-heap-plus/0.5.0/download\"],\n strip_prefix = \"binary-heap-plus-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.binary-heap-plus-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bincode-1.3.3\",\n sha256 = \"b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bincode/1.3.3/download\"],\n strip_prefix = \"bincode-1.3.3\",\n build_file = Label(\"@crates//crates:BUILD.bincode-1.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bindgen-0.72.1\",\n sha256 = \"993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bindgen/0.72.1/download\"],\n strip_prefix = \"bindgen-0.72.1\",\n build_file = Label(\"@crates//crates:BUILD.bindgen-0.72.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bit-set-0.8.0\",\n sha256 = \"08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bit-set/0.8.0/download\"],\n strip_prefix = \"bit-set-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.bit-set-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bit-vec-0.8.0\",\n sha256 = \"5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bit-vec/0.8.0/download\"],\n strip_prefix = \"bit-vec-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.bit-vec-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitflags-1.3.2\",\n sha256 = \"bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitflags/1.3.2/download\"],\n strip_prefix = \"bitflags-1.3.2\",\n build_file = Label(\"@crates//crates:BUILD.bitflags-1.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitflags-2.13.1\",\n sha256 = \"b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitflags/2.13.1/download\"],\n strip_prefix = \"bitflags-2.13.1\",\n build_file = Label(\"@crates//crates:BUILD.bitflags-2.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitvec-1.1.1\",\n sha256 = \"ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitvec/1.1.1/download\"],\n strip_prefix = \"bitvec-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.bitvec-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blake2b_simd-1.0.4\",\n sha256 = \"b79834656f71332577234b50bfc009996f7449e0c056884e6a02492ded0ca2f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blake2b_simd/1.0.4/download\"],\n strip_prefix = \"blake2b_simd-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.blake2b_simd-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blake3-1.8.5\",\n sha256 = \"0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blake3/1.8.5/download\"],\n strip_prefix = \"blake3-1.8.5\",\n build_file = Label(\"@crates//crates:BUILD.blake3-1.8.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-buffer-0.10.4\",\n sha256 = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-buffer/0.10.4/download\"],\n strip_prefix = \"block-buffer-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.block-buffer-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-buffer-0.12.1\",\n sha256 = \"d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-buffer/0.12.1/download\"],\n strip_prefix = \"block-buffer-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.block-buffer-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-padding-0.3.3\",\n sha256 = \"a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-padding/0.3.3/download\"],\n strip_prefix = \"block-padding-0.3.3\",\n build_file = Label(\"@crates//crates:BUILD.block-padding-0.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block2-0.6.2\",\n sha256 = \"cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block2/0.6.2/download\"],\n strip_prefix = \"block2-0.6.2\",\n build_file = Label(\"@crates//crates:BUILD.block2-0.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blocking-1.6.2\",\n sha256 = \"e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blocking/1.6.2/download\"],\n strip_prefix = \"blocking-1.6.2\",\n build_file = Label(\"@crates//crates:BUILD.blocking-1.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bon-3.9.3\",\n sha256 = \"a602c73c7b0148ec6d12af6fd5cc7a46e2eacc8878271a999abac56eed12f561\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bon/3.9.3/download\"],\n strip_prefix = \"bon-3.9.3\",\n build_file = Label(\"@crates//crates:BUILD.bon-3.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bon-macros-3.9.3\",\n sha256 = \"6dee98b0db6a962de883bf5d20362dee4d7ca0d12fe39a7c6c73c844e1cd7c1f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bon-macros/3.9.3/download\"],\n strip_prefix = \"bon-macros-3.9.3\",\n build_file = Label(\"@crates//crates:BUILD.bon-macros-3.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__brush-parser-0.3.0\",\n sha256 = \"f7367124d4f38fdcd65f4b815bda7caeb3de377b9cd95ffa1b23627989c93718\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/brush-parser/0.3.0/download\"],\n strip_prefix = \"brush-parser-0.3.0\",\n build_file = Label(\"@crates//crates:BUILD.brush-parser-0.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__brush-parser-0.4.0\",\n sha256 = \"9f64b19efc02f0dd6cac1d462e20a1098f425f09cb13624efbb1b7d63f061735\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/brush-parser/0.4.0/download\"],\n strip_prefix = \"brush-parser-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.brush-parser-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bstr-1.13.0\",\n sha256 = \"1f7dc094d718f2e1c1559ad110e27eeaae14a5465d3d56dd6dbd793079fbd530\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bstr/1.13.0/download\"],\n strip_prefix = \"bstr-1.13.0\",\n build_file = Label(\"@crates//crates:BUILD.bstr-1.13.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bumpalo-3.20.3\",\n sha256 = \"72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bumpalo/3.20.3/download\"],\n strip_prefix = \"bumpalo-3.20.3\",\n build_file = Label(\"@crates//crates:BUILD.bumpalo-3.20.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__by_address-1.2.1\",\n sha256 = \"64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/by_address/1.2.1/download\"],\n strip_prefix = \"by_address-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.by_address-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytecheck-0.8.2\",\n sha256 = \"0caa33a2c0edca0419d15ac723dff03f1956f7978329b1e3b5fdaaaed9d3ca8b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytecheck/0.8.2/download\"],\n strip_prefix = \"bytecheck-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.bytecheck-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytecheck_derive-0.8.2\",\n sha256 = \"89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytecheck_derive/0.8.2/download\"],\n strip_prefix = \"bytecheck_derive-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.bytecheck_derive-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytecount-0.6.9\",\n sha256 = \"175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytecount/0.6.9/download\"],\n strip_prefix = \"bytecount-0.6.9\",\n build_file = Label(\"@crates//crates:BUILD.bytecount-0.6.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytemuck-1.25.2\",\n sha256 = \"95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytemuck/1.25.2/download\"],\n strip_prefix = \"bytemuck-1.25.2\",\n build_file = Label(\"@crates//crates:BUILD.bytemuck-1.25.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytemuck_derive-1.11.0\",\n sha256 = \"f65693059b6b9c588b9f62fed1cedbf0a8b805631457ea162d68f0de186f3de5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytemuck_derive/1.11.0/download\"],\n strip_prefix = \"bytemuck_derive-1.11.0\",\n build_file = Label(\"@crates//crates:BUILD.bytemuck_derive-1.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__byteorder-1.5.0\",\n sha256 = \"1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/byteorder/1.5.0/download\"],\n strip_prefix = \"byteorder-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.byteorder-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__byteorder-lite-0.1.0\",\n sha256 = \"8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/byteorder-lite/0.1.0/download\"],\n strip_prefix = \"byteorder-lite-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.byteorder-lite-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytes-1.12.1\",\n sha256 = \"fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytes/1.12.1/download\"],\n strip_prefix = \"bytes-1.12.1\",\n build_file = Label(\"@crates//crates:BUILD.bytes-1.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached-0.56.0\",\n sha256 = \"801927ee168e17809ab8901d9f01f700cd7d8d6a6527997fee44e4b0327a253c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached/0.56.0/download\"],\n strip_prefix = \"cached-0.56.0\",\n build_file = Label(\"@crates//crates:BUILD.cached-0.56.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached-0.59.0\",\n sha256 = \"53b6f5d101f0f6322c8646a45b7c581a673e476329040d97565815c2461dd0c4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached/0.59.0/download\"],\n strip_prefix = \"cached-0.59.0\",\n build_file = Label(\"@crates//crates:BUILD.cached-0.59.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached_proc_macro-0.25.0\",\n sha256 = \"9225bdcf4e4a9a4c08bf16607908eb2fbf746828d5e0b5e019726dbf6571f201\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached_proc_macro/0.25.0/download\"],\n strip_prefix = \"cached_proc_macro-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.cached_proc_macro-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached_proc_macro-0.27.0\",\n sha256 = \"8ebcf9c75f17a17d55d11afc98e46167d4790a263f428891b8705ab2f793eca3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached_proc_macro/0.27.0/download\"],\n strip_prefix = \"cached_proc_macro-0.27.0\",\n build_file = Label(\"@crates//crates:BUILD.cached_proc_macro-0.27.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached_proc_macro_types-0.1.1\",\n sha256 = \"ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached_proc_macro_types/0.1.1/download\"],\n strip_prefix = \"cached_proc_macro_types-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.cached_proc_macro_types-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__calendrical_calculations-0.2.4\",\n sha256 = \"5abbd6eeda6885048d357edc66748eea6e0268e3dd11f326fff5bd248d779c26\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/calendrical_calculations/0.2.4/download\"],\n strip_prefix = \"calendrical_calculations-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.calendrical_calculations-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cbc-0.1.2\",\n sha256 = \"26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cbc/0.1.2/download\"],\n strip_prefix = \"cbc-0.1.2\",\n build_file = Label(\"@crates//crates:BUILD.cbc-0.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cc-1.2.67\",\n sha256 = \"e17dd265a7d0f31ef544e1b20e03add05d3b45b491b633b10d67145d2acc1a38\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cc/1.2.67/download\"],\n strip_prefix = \"cc-1.2.67\",\n build_file = Label(\"@crates//crates:BUILD.cc-1.2.67.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ccm-0.5.0\",\n sha256 = \"9ae3c82e4355234767756212c570e29833699ab63e6ffd161887314cc5b43847\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ccm/0.5.0/download\"],\n strip_prefix = \"ccm-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.ccm-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cexpr-0.6.0\",\n sha256 = \"6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cexpr/0.6.0/download\"],\n strip_prefix = \"cexpr-0.6.0\",\n build_file = Label(\"@crates//crates:BUILD.cexpr-0.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg-expr-0.20.8\",\n sha256 = \"fb693542bcafa528e198be0ebd9d3632ca5b7c93dbe7237460e199910835997c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg-expr/0.20.8/download\"],\n strip_prefix = \"cfg-expr-0.20.8\",\n build_file = Label(\"@crates//crates:BUILD.cfg-expr-0.20.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg-if-1.0.4\",\n sha256 = \"9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg-if/1.0.4/download\"],\n strip_prefix = \"cfg-if-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.cfg-if-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg_aliases-0.1.1\",\n sha256 = \"fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg_aliases/0.1.1/download\"],\n strip_prefix = \"cfg_aliases-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.cfg_aliases-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg_aliases-0.2.2\",\n sha256 = \"f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg_aliases/0.2.2/download\"],\n strip_prefix = \"cfg_aliases-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.cfg_aliases-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chacha20-0.10.1\",\n sha256 = \"d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chacha20/0.10.1/download\"],\n strip_prefix = \"chacha20-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.chacha20-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chacha20-0.9.1\",\n sha256 = \"c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chacha20/0.9.1/download\"],\n strip_prefix = \"chacha20-0.9.1\",\n build_file = Label(\"@crates//crates:BUILD.chacha20-0.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chacha20poly1305-0.10.1\",\n sha256 = \"10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chacha20poly1305/0.10.1/download\"],\n strip_prefix = \"chacha20poly1305-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.chacha20poly1305-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__check_elevation-0.2.7\",\n sha256 = \"a7fe1fbbd8bd3174109071530f12932ff471eeff30d83e9c485d6ff424ac534b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/check_elevation/0.2.7/download\"],\n strip_prefix = \"check_elevation-0.2.7\",\n build_file = Label(\"@crates//crates:BUILD.check_elevation-0.2.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chrono-0.4.45\",\n sha256 = \"1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chrono/0.4.45/download\"],\n strip_prefix = \"chrono-0.4.45\",\n build_file = Label(\"@crates//crates:BUILD.chrono-0.4.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chrono-tz-0.10.4\",\n sha256 = \"a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chrono-tz/0.10.4/download\"],\n strip_prefix = \"chrono-tz-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.chrono-tz-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cipher-0.4.4\",\n sha256 = \"773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cipher/0.4.4/download\"],\n strip_prefix = \"cipher-0.4.4\",\n build_file = Label(\"@crates//crates:BUILD.cipher-0.4.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clang-sys-1.8.1\",\n sha256 = \"0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clang-sys/1.8.1/download\"],\n strip_prefix = \"clang-sys-1.8.1\",\n build_file = Label(\"@crates//crates:BUILD.clang-sys-1.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap-4.6.4\",\n sha256 = \"d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap/4.6.4/download\"],\n strip_prefix = \"clap-4.6.4\",\n build_file = Label(\"@crates//crates:BUILD.clap-4.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap_builder-4.6.2\",\n sha256 = \"f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap_builder/4.6.2/download\"],\n strip_prefix = \"clap_builder-4.6.2\",\n build_file = Label(\"@crates//crates:BUILD.clap_builder-4.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap_derive-4.6.4\",\n sha256 = \"d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap_derive/4.6.4/download\"],\n strip_prefix = \"clap_derive-4.6.4\",\n build_file = Label(\"@crates//crates:BUILD.clap_derive-4.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap_lex-1.1.0\",\n sha256 = \"c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap_lex/1.1.0/download\"],\n strip_prefix = \"clap_lex-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.clap_lex-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clipboard-win-5.4.1\",\n sha256 = \"bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clipboard-win/5.4.1/download\"],\n strip_prefix = \"clipboard-win-5.4.1\",\n build_file = Label(\"@crates//crates:BUILD.clipboard-win-5.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cmake-0.1.58\",\n sha256 = \"c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cmake/0.1.58/download\"],\n strip_prefix = \"cmake-0.1.58\",\n build_file = Label(\"@crates//crates:BUILD.cmake-0.1.58.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__codesnake-0.2.1\",\n sha256 = \"2205f7f6d3de68ecf4c291c789b3edf07b6569268abd0188819086f71ae42225\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/codesnake/0.2.1/download\"],\n strip_prefix = \"codesnake-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.codesnake-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__color-print-0.3.7\",\n sha256 = \"3aa954171903797d5623e047d9ab69d91b493657917bdfb8c2c80ecaf9cdb6f4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/color-print/0.3.7/download\"],\n strip_prefix = \"color-print-0.3.7\",\n build_file = Label(\"@crates//crates:BUILD.color-print-0.3.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__color-print-proc-macro-0.3.7\",\n sha256 = \"692186b5ebe54007e45a59aea47ece9eb4108e141326c304cdc91699a7118a22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/color-print-proc-macro/0.3.7/download\"],\n strip_prefix = \"color-print-proc-macro-0.3.7\",\n build_file = Label(\"@crates//crates:BUILD.color-print-proc-macro-0.3.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__color_quant-1.1.0\",\n sha256 = \"3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/color_quant/1.1.0/download\"],\n strip_prefix = \"color_quant-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.color_quant-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__colorchoice-1.0.5\",\n sha256 = \"1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/colorchoice/1.0.5/download\"],\n strip_prefix = \"colorchoice-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.colorchoice-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__command-fds-0.3.3\",\n sha256 = \"1b60b5124979fccd9addd89d8b97a1d6eebb4950694520c75ddd722535ea443f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/command-fds/0.3.3/download\"],\n strip_prefix = \"command-fds-0.3.3\",\n build_file = Label(\"@crates//crates:BUILD.command-fds-0.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__compare-0.1.0\",\n sha256 = \"120133d4db2ec47efe2e26502ee984747630c67f51974fca0b6c1340cf2368d3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/compare/0.1.0/download\"],\n strip_prefix = \"compare-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.compare-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__concurrent-queue-2.5.0\",\n sha256 = \"4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/concurrent-queue/2.5.0/download\"],\n strip_prefix = \"concurrent-queue-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.concurrent-queue-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__console-0.16.4\",\n sha256 = \"4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/console/0.16.4/download\"],\n strip_prefix = \"console-0.16.4\",\n build_file = Label(\"@crates//crates:BUILD.console-0.16.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__const-oid-0.10.2\",\n sha256 = \"a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/const-oid/0.10.2/download\"],\n strip_prefix = \"const-oid-0.10.2\",\n build_file = Label(\"@crates//crates:BUILD.const-oid-0.10.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__const-oid-0.9.6\",\n sha256 = \"c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/const-oid/0.9.6/download\"],\n strip_prefix = \"const-oid-0.9.6\",\n build_file = Label(\"@crates//crates:BUILD.const-oid-0.9.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__const-random-0.1.18\",\n sha256 = \"87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/const-random/0.1.18/download\"],\n strip_prefix = \"const-random-0.1.18\",\n build_file = Label(\"@crates//crates:BUILD.const-random-0.1.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__const-random-macro-0.1.16\",\n sha256 = \"f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/const-random-macro/0.1.16/download\"],\n strip_prefix = \"const-random-macro-0.1.16\",\n build_file = Label(\"@crates//crates:BUILD.const-random-macro-0.1.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__constant_time_eq-0.4.2\",\n sha256 = \"3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/constant_time_eq/0.4.2/download\"],\n strip_prefix = \"constant_time_eq-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.constant_time_eq-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__convert_case-0.11.0\",\n sha256 = \"affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/convert_case/0.11.0/download\"],\n strip_prefix = \"convert_case-0.11.0\",\n build_file = Label(\"@crates//crates:BUILD.convert_case-0.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__convert_case-0.8.0\",\n sha256 = \"baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/convert_case/0.8.0/download\"],\n strip_prefix = \"convert_case-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.convert_case-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cookie-factory-0.3.3\",\n sha256 = \"9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cookie-factory/0.3.3/download\"],\n strip_prefix = \"cookie-factory-0.3.3\",\n build_file = Label(\"@crates//crates:BUILD.cookie-factory-0.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core-foundation-0.10.1\",\n sha256 = \"b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core-foundation/0.10.1/download\"],\n strip_prefix = \"core-foundation-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.core-foundation-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core-foundation-sys-0.8.7\",\n sha256 = \"773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core-foundation-sys/0.8.7/download\"],\n strip_prefix = \"core-foundation-sys-0.8.7\",\n build_file = Label(\"@crates//crates:BUILD.core-foundation-sys-0.8.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core-graphics-0.25.0\",\n sha256 = \"064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core-graphics/0.25.0/download\"],\n strip_prefix = \"core-graphics-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.core-graphics-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core-graphics-types-0.2.0\",\n sha256 = \"3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core-graphics-types/0.2.0/download\"],\n strip_prefix = \"core-graphics-types-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.core-graphics-types-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core_maths-0.1.1\",\n sha256 = \"77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core_maths/0.1.1/download\"],\n strip_prefix = \"core_maths-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.core_maths-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cpufeatures-0.2.17\",\n sha256 = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cpufeatures/0.2.17/download\"],\n strip_prefix = \"cpufeatures-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.cpufeatures-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cpufeatures-0.3.0\",\n sha256 = \"8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cpufeatures/0.3.0/download\"],\n strip_prefix = \"cpufeatures-0.3.0\",\n build_file = Label(\"@crates//crates:BUILD.cpufeatures-0.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crc-3.4.0\",\n sha256 = \"5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crc/3.4.0/download\"],\n strip_prefix = \"crc-3.4.0\",\n build_file = Label(\"@crates//crates:BUILD.crc-3.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crc-catalog-2.5.0\",\n sha256 = \"217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crc-catalog/2.5.0/download\"],\n strip_prefix = \"crc-catalog-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.crc-catalog-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crc-fast-1.8.2\",\n sha256 = \"85d9be5297a59f1b7651fd2711a1f4461929f53b182b394df0df15b3a387ef51\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crc-fast/1.8.2/download\"],\n strip_prefix = \"crc-fast-1.8.2\",\n build_file = Label(\"@crates//crates:BUILD.crc-fast-1.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crc32fast-1.5.0\",\n sha256 = \"9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crc32fast/1.5.0/download\"],\n strip_prefix = \"crc32fast-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.crc32fast-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crossbeam-deque-0.8.7\",\n sha256 = \"5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crossbeam-deque/0.8.7/download\"],\n strip_prefix = \"crossbeam-deque-0.8.7\",\n build_file = Label(\"@crates//crates:BUILD.crossbeam-deque-0.8.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crossbeam-epoch-0.9.20\",\n sha256 = \"2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crossbeam-epoch/0.9.20/download\"],\n strip_prefix = \"crossbeam-epoch-0.9.20\",\n build_file = Label(\"@crates//crates:BUILD.crossbeam-epoch-0.9.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crossbeam-utils-0.8.22\",\n sha256 = \"61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crossbeam-utils/0.8.22/download\"],\n strip_prefix = \"crossbeam-utils-0.8.22\",\n build_file = Label(\"@crates//crates:BUILD.crossbeam-utils-0.8.22.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crunchy-0.2.4\",\n sha256 = \"460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crunchy/0.2.4/download\"],\n strip_prefix = \"crunchy-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.crunchy-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-bigint-0.5.5\",\n sha256 = \"0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-bigint/0.5.5/download\"],\n strip_prefix = \"crypto-bigint-0.5.5\",\n build_file = Label(\"@crates//crates:BUILD.crypto-bigint-0.5.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-common-0.1.7\",\n sha256 = \"78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-common/0.1.7/download\"],\n strip_prefix = \"crypto-common-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.crypto-common-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-common-0.2.2\",\n sha256 = \"ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-common/0.2.2/download\"],\n strip_prefix = \"crypto-common-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.crypto-common-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ctor-1.0.11\",\n sha256 = \"e9bb72bb94fdc1bd619f4c18cc91ecf6302aeb333d31b3c6ec0bb841cd920209\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ctor/1.0.11/download\"],\n strip_prefix = \"ctor-1.0.11\",\n build_file = Label(\"@crates//crates:BUILD.ctor-1.0.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ctr-0.9.2\",\n sha256 = \"0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ctr/0.9.2/download\"],\n strip_prefix = \"ctr-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.ctr-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__curve25519-dalek-4.1.3\",\n sha256 = \"97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/curve25519-dalek/4.1.3/download\"],\n strip_prefix = \"curve25519-dalek-4.1.3\",\n build_file = Label(\"@crates//crates:BUILD.curve25519-dalek-4.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__curve25519-dalek-derive-0.1.1\",\n sha256 = \"f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/curve25519-dalek-derive/0.1.1/download\"],\n strip_prefix = \"curve25519-dalek-derive-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.curve25519-dalek-derive-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling-0.20.11\",\n sha256 = \"fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling/0.20.11/download\"],\n strip_prefix = \"darling-0.20.11\",\n build_file = Label(\"@crates//crates:BUILD.darling-0.20.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling-0.23.0\",\n sha256 = \"25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling/0.23.0/download\"],\n strip_prefix = \"darling-0.23.0\",\n build_file = Label(\"@crates//crates:BUILD.darling-0.23.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling_core-0.20.11\",\n sha256 = \"0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling_core/0.20.11/download\"],\n strip_prefix = \"darling_core-0.20.11\",\n build_file = Label(\"@crates//crates:BUILD.darling_core-0.20.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling_core-0.23.0\",\n sha256 = \"9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling_core/0.23.0/download\"],\n strip_prefix = \"darling_core-0.23.0\",\n build_file = Label(\"@crates//crates:BUILD.darling_core-0.23.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling_macro-0.20.11\",\n sha256 = \"fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling_macro/0.20.11/download\"],\n strip_prefix = \"darling_macro-0.20.11\",\n build_file = Label(\"@crates//crates:BUILD.darling_macro-0.20.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling_macro-0.23.0\",\n sha256 = \"ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling_macro/0.23.0/download\"],\n strip_prefix = \"darling_macro-0.23.0\",\n build_file = Label(\"@crates//crates:BUILD.darling_macro-0.23.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dashmap-6.2.1\",\n sha256 = \"e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dashmap/6.2.1/download\"],\n strip_prefix = \"dashmap-6.2.1\",\n build_file = Label(\"@crates//crates:BUILD.dashmap-6.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__data-encoding-2.11.0\",\n sha256 = \"a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/data-encoding/2.11.0/download\"],\n strip_prefix = \"data-encoding-2.11.0\",\n build_file = Label(\"@crates//crates:BUILD.data-encoding-2.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__data-encoding-macro-0.1.20\",\n sha256 = \"3259c913752a86488b501ed8680446a5ed2d5aeac6e596cb23ba3800768ea32c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/data-encoding-macro/0.1.20/download\"],\n strip_prefix = \"data-encoding-macro-0.1.20\",\n build_file = Label(\"@crates//crates:BUILD.data-encoding-macro-0.1.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__data-encoding-macro-internal-0.1.18\",\n sha256 = \"ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/data-encoding-macro-internal/0.1.18/download\"],\n strip_prefix = \"data-encoding-macro-internal-0.1.18\",\n build_file = Label(\"@crates//crates:BUILD.data-encoding-macro-internal-0.1.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__defmt-1.1.1\",\n sha256 = \"e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/defmt/1.1.1/download\"],\n strip_prefix = \"defmt-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.defmt-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__defmt-macros-1.1.1\",\n sha256 = \"bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/defmt-macros/1.1.1/download\"],\n strip_prefix = \"defmt-macros-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.defmt-macros-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__defmt-parser-1.0.0\",\n sha256 = \"10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/defmt-parser/1.0.0/download\"],\n strip_prefix = \"defmt-parser-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.defmt-parser-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__der-0.7.10\",\n sha256 = \"e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/der/0.7.10/download\"],\n strip_prefix = \"der-0.7.10\",\n build_file = Label(\"@crates//crates:BUILD.der-0.7.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__der-parser-9.0.0\",\n sha256 = \"5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/der-parser/9.0.0/download\"],\n strip_prefix = \"der-parser-9.0.0\",\n build_file = Label(\"@crates//crates:BUILD.der-parser-9.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__deranged-0.5.8\",\n sha256 = \"7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/deranged/0.5.8/download\"],\n strip_prefix = \"deranged-0.5.8\",\n build_file = Label(\"@crates//crates:BUILD.deranged-0.5.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__diff-0.1.13\",\n sha256 = \"56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/diff/0.1.13/download\"],\n strip_prefix = \"diff-0.1.13\",\n build_file = Label(\"@crates//crates:BUILD.diff-0.1.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__digest-0.10.7\",\n sha256 = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/digest/0.10.7/download\"],\n strip_prefix = \"digest-0.10.7\",\n build_file = Label(\"@crates//crates:BUILD.digest-0.10.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__digest-0.11.3\",\n sha256 = \"f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/digest/0.11.3/download\"],\n strip_prefix = \"digest-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.digest-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dispatch2-0.3.1\",\n sha256 = \"1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dispatch2/0.3.1/download\"],\n strip_prefix = \"dispatch2-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.dispatch2-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__displaydoc-0.2.6\",\n sha256 = \"1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/displaydoc/0.2.6/download\"],\n strip_prefix = \"displaydoc-0.2.6\",\n build_file = Label(\"@crates//crates:BUILD.displaydoc-0.2.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dlib-0.5.3\",\n sha256 = \"ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dlib/0.5.3/download\"],\n strip_prefix = \"dlib-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.dlib-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dns-lookup-3.0.1\",\n sha256 = \"6e39034cee21a2f5bbb66ba0e3689819c4bb5d00382a282006e802a7ffa6c41d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dns-lookup/3.0.1/download\"],\n strip_prefix = \"dns-lookup-3.0.1\",\n build_file = Label(\"@crates//crates:BUILD.dns-lookup-3.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__downcast-rs-1.2.1\",\n sha256 = \"75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/downcast-rs/1.2.1/download\"],\n strip_prefix = \"downcast-rs-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.downcast-rs-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-0.14.1\",\n sha256 = \"80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm/0.14.1/download\"],\n strip_prefix = \"drm-0.14.1\",\n build_file = Label(\"@crates//crates:BUILD.drm-0.14.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-0.15.0\",\n sha256 = \"7a41816e58f47f49acfd956651055ddcf137c4882c2098c30c448817af21183a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm/0.15.0/download\"],\n strip_prefix = \"drm-0.15.0\",\n build_file = Label(\"@crates//crates:BUILD.drm-0.15.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-ffi-0.9.1\",\n sha256 = \"51a91c9b32ac4e8105dec255e849e0d66e27d7c34d184364fb93e469db08f690\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm-ffi/0.9.1/download\"],\n strip_prefix = \"drm-ffi-0.9.1\",\n build_file = Label(\"@crates//crates:BUILD.drm-ffi-0.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-fourcc-2.2.0\",\n sha256 = \"0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm-fourcc/2.2.0/download\"],\n strip_prefix = \"drm-fourcc-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.drm-fourcc-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-sys-0.8.1\",\n sha256 = \"ecc8e1361066d91f5ffccff060a3c3be9c3ecde15be2959c1937595f7a82a9f8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm-sys/0.8.1/download\"],\n strip_prefix = \"drm-sys-0.8.1\",\n build_file = Label(\"@crates//crates:BUILD.drm-sys-0.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dtls-0.17.2\",\n sha256 = \"01a431e87fc386bd5e02deb554a013f97bc406e47a7d8e97efb7c6366b980e9c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dtls/0.17.2/download\"],\n strip_prefix = \"dtls-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.dtls-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dunce-1.0.5\",\n sha256 = \"92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dunce/1.0.5/download\"],\n strip_prefix = \"dunce-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.dunce-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dyn-clone-1.0.20\",\n sha256 = \"d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dyn-clone/1.0.20/download\"],\n strip_prefix = \"dyn-clone-1.0.20\",\n build_file = Label(\"@crates//crates:BUILD.dyn-clone-1.0.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ecdsa-0.16.9\",\n sha256 = \"ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ecdsa/0.16.9/download\"],\n strip_prefix = \"ecdsa-0.16.9\",\n build_file = Label(\"@crates//crates:BUILD.ecdsa-0.16.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__either-1.17.0\",\n sha256 = \"9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/either/1.17.0/download\"],\n strip_prefix = \"either-1.17.0\",\n build_file = Label(\"@crates//crates:BUILD.either-1.17.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__elliptic-curve-0.13.8\",\n sha256 = \"b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/elliptic-curve/0.13.8/download\"],\n strip_prefix = \"elliptic-curve-0.13.8\",\n build_file = Label(\"@crates//crates:BUILD.elliptic-curve-0.13.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__encode_unicode-1.0.0\",\n sha256 = \"34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/encode_unicode/1.0.0/download\"],\n strip_prefix = \"encode_unicode-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.encode_unicode-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__encoding_rs-0.8.35\",\n sha256 = \"75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/encoding_rs/0.8.35/download\"],\n strip_prefix = \"encoding_rs-0.8.35\",\n build_file = Label(\"@crates//crates:BUILD.encoding_rs-0.8.35.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__encoding_rs_io-0.1.7\",\n sha256 = \"1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/encoding_rs_io/0.1.7/download\"],\n strip_prefix = \"encoding_rs_io-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.encoding_rs_io-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__endi-1.1.1\",\n sha256 = \"66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/endi/1.1.1/download\"],\n strip_prefix = \"endi-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.endi-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__enigo-0.6.1\",\n sha256 = \"71c6c56e50f7acae2906a0dcbb34529ca647e40421119ad5d12e7f8ba6e50010\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/enigo/0.6.1/download\"],\n strip_prefix = \"enigo-0.6.1\",\n build_file = Label(\"@crates//crates:BUILD.enigo-0.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__enumflags2-0.7.12\",\n sha256 = \"1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/enumflags2/0.7.12/download\"],\n strip_prefix = \"enumflags2-0.7.12\",\n build_file = Label(\"@crates//crates:BUILD.enumflags2-0.7.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__enumflags2_derive-0.7.12\",\n sha256 = \"67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/enumflags2_derive/0.7.12/download\"],\n strip_prefix = \"enumflags2_derive-0.7.12\",\n build_file = Label(\"@crates//crates:BUILD.enumflags2_derive-0.7.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__equivalent-1.0.2\",\n sha256 = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/equivalent/1.0.2/download\"],\n strip_prefix = \"equivalent-1.0.2\",\n build_file = Label(\"@crates//crates:BUILD.equivalent-1.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__errno-0.3.14\",\n sha256 = \"39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/errno/0.3.14/download\"],\n strip_prefix = \"errno-0.3.14\",\n build_file = Label(\"@crates//crates:BUILD.errno-0.3.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__error-code-3.3.2\",\n sha256 = \"dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/error-code/3.3.2/download\"],\n strip_prefix = \"error-code-3.3.2\",\n build_file = Label(\"@crates//crates:BUILD.error-code-3.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__event-listener-5.4.2\",\n sha256 = \"5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/event-listener/5.4.2/download\"],\n strip_prefix = \"event-listener-5.4.2\",\n build_file = Label(\"@crates//crates:BUILD.event-listener-5.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__event-listener-strategy-0.5.4\",\n sha256 = \"8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/event-listener-strategy/0.5.4/download\"],\n strip_prefix = \"event-listener-strategy-0.5.4\",\n build_file = Label(\"@crates//crates:BUILD.event-listener-strategy-0.5.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__faccess-0.2.4\",\n sha256 = \"59ae66425802d6a903e268ae1a08b8c38ba143520f227a205edf4e9c7e3e26d5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/faccess/0.2.4/download\"],\n strip_prefix = \"faccess-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.faccess-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fancy-regex-0.16.2\",\n sha256 = \"998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fancy-regex/0.16.2/download\"],\n strip_prefix = \"fancy-regex-0.16.2\",\n build_file = Label(\"@crates//crates:BUILD.fancy-regex-0.16.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fancy-regex-0.17.0\",\n sha256 = \"72cf461f865c862bb7dc573f643dd6a2b6842f7c30b07882b56bd148cc2761b8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fancy-regex/0.17.0/download\"],\n strip_prefix = \"fancy-regex-0.17.0\",\n build_file = Label(\"@crates//crates:BUILD.fancy-regex-0.17.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fancy-regex-0.18.0\",\n sha256 = \"e1e1dacd0d2082dfcf1351c4bdd566bbe89a2b263235a2b50058f1e130a47277\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fancy-regex/0.18.0/download\"],\n strip_prefix = \"fancy-regex-0.18.0\",\n build_file = Label(\"@crates//crates:BUILD.fancy-regex-0.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fast-srgb8-1.0.0\",\n sha256 = \"dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fast-srgb8/1.0.0/download\"],\n strip_prefix = \"fast-srgb8-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.fast-srgb8-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fastrand-2.5.0\",\n sha256 = \"da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fastrand/2.5.0/download\"],\n strip_prefix = \"fastrand-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.fastrand-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fax-0.2.7\",\n sha256 = \"caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fax/0.2.7/download\"],\n strip_prefix = \"fax-0.2.7\",\n build_file = Label(\"@crates//crates:BUILD.fax-0.2.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fdeflate-0.3.7\",\n sha256 = \"1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fdeflate/0.3.7/download\"],\n strip_prefix = \"fdeflate-0.3.7\",\n build_file = Label(\"@crates//crates:BUILD.fdeflate-0.3.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ff-0.13.1\",\n sha256 = \"c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ff/0.13.1/download\"],\n strip_prefix = \"ff-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.ff-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fiat-crypto-0.2.9\",\n sha256 = \"28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fiat-crypto/0.2.9/download\"],\n strip_prefix = \"fiat-crypto-0.2.9\",\n build_file = Label(\"@crates//crates:BUILD.fiat-crypto-0.2.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__filedescriptor-0.8.3\",\n sha256 = \"e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/filedescriptor/0.8.3/download\"],\n strip_prefix = \"filedescriptor-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.filedescriptor-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__filetime-0.2.29\",\n sha256 = \"5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/filetime/0.2.29/download\"],\n strip_prefix = \"filetime-0.2.29\",\n build_file = Label(\"@crates//crates:BUILD.filetime-0.2.29.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__find-msvc-tools-0.1.9\",\n sha256 = \"5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/find-msvc-tools/0.1.9/download\"],\n strip_prefix = \"find-msvc-tools-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.find-msvc-tools-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fixed_decimal-0.7.2\",\n sha256 = \"79c3c892f121fff406e5dd6b28c1b30096b95111c30701a899d4f2b18da6d1bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fixed_decimal/0.7.2/download\"],\n strip_prefix = \"fixed_decimal-0.7.2\",\n build_file = Label(\"@crates//crates:BUILD.fixed_decimal-0.7.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fixedbitset-0.5.7\",\n sha256 = \"1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fixedbitset/0.5.7/download\"],\n strip_prefix = \"fixedbitset-0.5.7\",\n build_file = Label(\"@crates//crates:BUILD.fixedbitset-0.5.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__flate2-1.1.9\",\n sha256 = \"843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/flate2/1.1.9/download\"],\n strip_prefix = \"flate2-1.1.9\",\n build_file = Label(\"@crates//crates:BUILD.flate2-1.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fluent-0.17.0\",\n sha256 = \"8137a6d5a2c50d6b0ebfcb9aaa91a28154e0a70605f112d30cb0cd4a78670477\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fluent/0.17.0/download\"],\n strip_prefix = \"fluent-0.17.0\",\n build_file = Label(\"@crates//crates:BUILD.fluent-0.17.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fluent-bundle-0.16.0\",\n sha256 = \"01203cb8918f5711e73891b347816d932046f95f54207710bda99beaeb423bf4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fluent-bundle/0.16.0/download\"],\n strip_prefix = \"fluent-bundle-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.fluent-bundle-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fluent-langneg-0.13.1\",\n sha256 = \"7eebbe59450baee8282d71676f3bfed5689aeab00b27545e83e5f14b1195e8b0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fluent-langneg/0.13.1/download\"],\n strip_prefix = \"fluent-langneg-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.fluent-langneg-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fluent-syntax-0.12.0\",\n sha256 = \"54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fluent-syntax/0.12.0/download\"],\n strip_prefix = \"fluent-syntax-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.fluent-syntax-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__flume-0.11.1\",\n sha256 = \"da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/flume/0.11.1/download\"],\n strip_prefix = \"flume-0.11.1\",\n build_file = Label(\"@crates//crates:BUILD.flume-0.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fnv-1.0.7\",\n sha256 = \"3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fnv/1.0.7/download\"],\n strip_prefix = \"fnv-1.0.7\",\n build_file = Label(\"@crates//crates:BUILD.fnv-1.0.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foldhash-0.1.5\",\n sha256 = \"d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foldhash/0.1.5/download\"],\n strip_prefix = \"foldhash-0.1.5\",\n build_file = Label(\"@crates//crates:BUILD.foldhash-0.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foldhash-0.2.0\",\n sha256 = \"77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foldhash/0.2.0/download\"],\n strip_prefix = \"foldhash-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.foldhash-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fontdue-0.9.3\",\n sha256 = \"2e57e16b3fe8ff4364c0661fdaac543fb38b29ea9bc9c2f45612d90adf931d2b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fontdue/0.9.3/download\"],\n strip_prefix = \"fontdue-0.9.3\",\n build_file = Label(\"@crates//crates:BUILD.fontdue-0.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-0.5.0\",\n sha256 = \"d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types/0.5.0/download\"],\n strip_prefix = \"foreign-types-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-macros-0.2.4\",\n sha256 = \"ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types-macros/0.2.4/download\"],\n strip_prefix = \"foreign-types-macros-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-macros-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-shared-0.3.1\",\n sha256 = \"aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types-shared/0.3.1/download\"],\n strip_prefix = \"foreign-types-shared-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-shared-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__form_urlencoded-1.2.2\",\n sha256 = \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/form_urlencoded/1.2.2/download\"],\n strip_prefix = \"form_urlencoded-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.form_urlencoded-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fs_extra-1.3.0\",\n sha256 = \"42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fs_extra/1.3.0/download\"],\n strip_prefix = \"fs_extra-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.fs_extra-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fsevent-sys-4.1.0\",\n sha256 = \"76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fsevent-sys/4.1.0/download\"],\n strip_prefix = \"fsevent-sys-4.1.0\",\n build_file = Label(\"@crates//crates:BUILD.fsevent-sys-4.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__funty-2.0.0\",\n sha256 = \"e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/funty/2.0.0/download\"],\n strip_prefix = \"funty-2.0.0\",\n build_file = Label(\"@crates//crates:BUILD.funty-2.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-0.3.33\",\n sha256 = \"a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures/0.3.33/download\"],\n strip_prefix = \"futures-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-channel-0.3.33\",\n sha256 = \"262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-channel/0.3.33/download\"],\n strip_prefix = \"futures-channel-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-channel-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-core-0.3.33\",\n sha256 = \"2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-core/0.3.33/download\"],\n strip_prefix = \"futures-core-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-core-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-executor-0.3.33\",\n sha256 = \"6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-executor/0.3.33/download\"],\n strip_prefix = \"futures-executor-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-executor-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-io-0.3.33\",\n sha256 = \"4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-io/0.3.33/download\"],\n strip_prefix = \"futures-io-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-io-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-lite-2.6.1\",\n sha256 = \"f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-lite/2.6.1/download\"],\n strip_prefix = \"futures-lite-2.6.1\",\n build_file = Label(\"@crates//crates:BUILD.futures-lite-2.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-macro-0.3.33\",\n sha256 = \"2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-macro/0.3.33/download\"],\n strip_prefix = \"futures-macro-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-macro-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-sink-0.3.33\",\n sha256 = \"e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-sink/0.3.33/download\"],\n strip_prefix = \"futures-sink-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-sink-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-task-0.3.33\",\n sha256 = \"b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-task/0.3.33/download\"],\n strip_prefix = \"futures-task-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-task-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-timer-3.0.4\",\n sha256 = \"af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-timer/3.0.4/download\"],\n strip_prefix = \"futures-timer-3.0.4\",\n build_file = Label(\"@crates//crates:BUILD.futures-timer-3.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-util-0.3.33\",\n sha256 = \"a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-util/0.3.33/download\"],\n strip_prefix = \"futures-util-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-util-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gbm-0.18.0\",\n sha256 = \"ce852e998d3ca5e4a97014fb31c940dc5ef344ec7d364984525fd11e8a547e6a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gbm/0.18.0/download\"],\n strip_prefix = \"gbm-0.18.0\",\n build_file = Label(\"@crates//crates:BUILD.gbm-0.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gbm-sys-0.4.0\",\n sha256 = \"c13a5f2acc785d8fb6bf6b7ab6bfb0ef5dad4f4d97e8e70bb8e470722312f76f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gbm-sys/0.4.0/download\"],\n strip_prefix = \"gbm-sys-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.gbm-sys-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__generic-array-0.14.7\",\n sha256 = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/generic-array/0.14.7/download\"],\n strip_prefix = \"generic-array-0.14.7\",\n build_file = Label(\"@crates//crates:BUILD.generic-array-0.14.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gethostname-1.1.0\",\n sha256 = \"1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gethostname/1.1.0/download\"],\n strip_prefix = \"gethostname-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.gethostname-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.2.17\",\n sha256 = \"ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.2.17/download\"],\n strip_prefix = \"getrandom-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.3.4\",\n sha256 = \"899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.3.4/download\"],\n strip_prefix = \"getrandom-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.4.3\",\n sha256 = \"300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.4.3/download\"],\n strip_prefix = \"getrandom-0.4.3\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ghash-0.5.1\",\n sha256 = \"f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ghash/0.5.1/download\"],\n strip_prefix = \"ghash-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.ghash-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gif-0.14.2\",\n sha256 = \"ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gif/0.14.2/download\"],\n strip_prefix = \"gif-0.14.2\",\n build_file = Label(\"@crates//crates:BUILD.gif-0.14.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gl-0.14.0\",\n sha256 = \"a94edab108827d67608095e269cf862e60d920f144a5026d3dbcfd8b877fb404\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gl/0.14.0/download\"],\n strip_prefix = \"gl-0.14.0\",\n build_file = Label(\"@crates//crates:BUILD.gl-0.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gl_generator-0.14.0\",\n sha256 = \"1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gl_generator/0.14.0/download\"],\n strip_prefix = \"gl_generator-0.14.0\",\n build_file = Label(\"@crates//crates:BUILD.gl_generator-0.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__glob-0.3.4\",\n sha256 = \"e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/glob/0.3.4/download\"],\n strip_prefix = \"glob-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.glob-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__globset-0.4.19\",\n sha256 = \"e47d37d2ae4464254884b60ab7071be2b876a9c35b696bd018ddcc76847309cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/globset/0.4.19/download\"],\n strip_prefix = \"globset-0.4.19\",\n build_file = Label(\"@crates//crates:BUILD.globset-0.4.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-cli-0.1.12\",\n sha256 = \"cf32d263c5d5cc2a23ce587097f5ddafdb188492ba2e6fb638eaccdc22453631\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-cli/0.1.12/download\"],\n strip_prefix = \"grep-cli-0.1.12\",\n build_file = Label(\"@crates//crates:BUILD.grep-cli-0.1.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-matcher-0.1.9\",\n sha256 = \"f9417543f4870fc8f1c8e1af870afae2431007626d9e703fce6471c468d33847\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-matcher/0.1.9/download\"],\n strip_prefix = \"grep-matcher-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.grep-matcher-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-pcre2-0.1.10\",\n sha256 = \"b752bb6f57dd3716e55b63a33ca05b5825c3d66cd427468874a5564af6ca365c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-pcre2/0.1.10/download\"],\n strip_prefix = \"grep-pcre2-0.1.10\",\n build_file = Label(\"@crates//crates:BUILD.grep-pcre2-0.1.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-printer-0.3.1\",\n sha256 = \"fd76035e87871f51c1ee5b793e32122b3ccf9c692662d9622ef1686ff5321acb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-printer/0.3.1/download\"],\n strip_prefix = \"grep-printer-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.grep-printer-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-regex-0.1.14\",\n sha256 = \"0ce0c256c3ad82bcc07b812c15a45ec1d398122e8e15124f96695234db7112ef\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-regex/0.1.14/download\"],\n strip_prefix = \"grep-regex-0.1.14\",\n build_file = Label(\"@crates//crates:BUILD.grep-regex-0.1.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-searcher-0.1.17\",\n sha256 = \"72348823a0eafc4bc2e9051064f28b5b42cc100b571b3a35d67918d711efcbc6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-searcher/0.1.17/download\"],\n strip_prefix = \"grep-searcher-0.1.17\",\n build_file = Label(\"@crates//crates:BUILD.grep-searcher-0.1.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__group-0.13.0\",\n sha256 = \"f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/group/0.13.0/download\"],\n strip_prefix = \"group-0.13.0\",\n build_file = Label(\"@crates//crates:BUILD.group-0.13.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__half-2.7.1\",\n sha256 = \"6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/half/2.7.1/download\"],\n strip_prefix = \"half-2.7.1\",\n build_file = Label(\"@crates//crates:BUILD.half-2.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.14.5\",\n sha256 = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.14.5/download\"],\n strip_prefix = \"hashbrown-0.14.5\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.14.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.15.5\",\n sha256 = \"9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.15.5/download\"],\n strip_prefix = \"hashbrown-0.15.5\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.15.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.16.1\",\n sha256 = \"841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.16.1/download\"],\n strip_prefix = \"hashbrown-0.16.1\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.16.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.17.1\",\n sha256 = \"ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.17.1/download\"],\n strip_prefix = \"hashbrown-0.17.1\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.17.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__heck-0.5.0\",\n sha256 = \"2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/heck/0.5.0/download\"],\n strip_prefix = \"heck-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.heck-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hermit-abi-0.5.2\",\n sha256 = \"fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hermit-abi/0.5.2/download\"],\n strip_prefix = \"hermit-abi-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.hermit-abi-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hex-0.4.3\",\n sha256 = \"7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hex/0.4.3/download\"],\n strip_prefix = \"hex-0.4.3\",\n build_file = Label(\"@crates//crates:BUILD.hex-0.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hifijson-0.2.3\",\n sha256 = \"0a7763b98ba8a24f59e698bf9ab197e7676c640d6455d1580b4ce7dc560f0f0d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hifijson/0.2.3/download\"],\n strip_prefix = \"hifijson-0.2.3\",\n build_file = Label(\"@crates//crates:BUILD.hifijson-0.2.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hkdf-0.12.4\",\n sha256 = \"7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hkdf/0.12.4/download\"],\n strip_prefix = \"hkdf-0.12.4\",\n build_file = Label(\"@crates//crates:BUILD.hkdf-0.12.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hmac-0.12.1\",\n sha256 = \"6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hmac/0.12.1/download\"],\n strip_prefix = \"hmac-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.hmac-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hostname-0.4.2\",\n sha256 = \"617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hostname/0.4.2/download\"],\n strip_prefix = \"hostname-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.hostname-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__html-escape-0.2.14\",\n sha256 = \"46c1ff2d1cbf39efe5af0900ced8a069b5e61557a17544eb0c4a50239937389e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/html-escape/0.2.14/download\"],\n strip_prefix = \"html-escape-0.2.14\",\n build_file = Label(\"@crates//crates:BUILD.html-escape-0.2.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__html-to-markdown-rs-2.30.0\",\n sha256 = \"7ea41945a2fd834381642a000ef75b03f0030f3023f3dd3291fc5c372d3dda33\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/html-to-markdown-rs/2.30.0/download\"],\n strip_prefix = \"html-to-markdown-rs-2.30.0\",\n build_file = Label(\"@crates//crates:BUILD.html-to-markdown-rs-2.30.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__html5ever-0.39.0\",\n sha256 = \"46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/html5ever/0.39.0/download\"],\n strip_prefix = \"html5ever-0.39.0\",\n build_file = Label(\"@crates//crates:BUILD.html5ever-0.39.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hybrid-array-0.4.13\",\n sha256 = \"818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hybrid-array/0.4.13/download\"],\n strip_prefix = \"hybrid-array-0.4.13\",\n build_file = Label(\"@crates//crates:BUILD.hybrid-array-0.4.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__iana-time-zone-0.1.65\",\n sha256 = \"e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/iana-time-zone/0.1.65/download\"],\n strip_prefix = \"iana-time-zone-0.1.65\",\n build_file = Label(\"@crates//crates:BUILD.iana-time-zone-0.1.65.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__iana-time-zone-haiku-0.1.2\",\n sha256 = \"f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/iana-time-zone-haiku/0.1.2/download\"],\n strip_prefix = \"iana-time-zone-haiku-0.1.2\",\n build_file = Label(\"@crates//crates:BUILD.iana-time-zone-haiku-0.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_calendar-2.2.1\",\n sha256 = \"a2b2acc6263f494f1df50685b53ff8e57869e47d5c6fe39c23d518ae9a4f3e45\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_calendar/2.2.1/download\"],\n strip_prefix = \"icu_calendar-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_calendar-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_calendar_data-2.2.0\",\n sha256 = \"118577bcf3a0fa7c6ac0a7d6e951814da84ee56b9b1f68fb4d8d10b08cefaf4d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_calendar_data/2.2.0/download\"],\n strip_prefix = \"icu_calendar_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_calendar_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collator-2.2.1\",\n sha256 = \"8bbdf98e5e0aa827770acee171ebb568aaab975a36b56afdb5fd0e2f525750bb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collator/2.2.1/download\"],\n strip_prefix = \"icu_collator-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_collator-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collator_data-2.2.0\",\n sha256 = \"038ed8e5817f2059c2f3efb0945ba78d060d3d25e8f1a1bea5139f821a21a2f0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collator_data/2.2.0/download\"],\n strip_prefix = \"icu_collator_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_collator_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collections-2.2.0\",\n sha256 = \"2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collections/2.2.0/download\"],\n strip_prefix = \"icu_collections-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_collections-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_datetime-2.2.0\",\n sha256 = \"989d56ea5bbc43ae2b4e0388874b002884eaf4ed3a76c84a6c8c5ad575e04d72\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_datetime/2.2.0/download\"],\n strip_prefix = \"icu_datetime-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_datetime-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_datetime_data-2.2.0\",\n sha256 = \"40d3cc1b690d9703202bc319692ac8a1f3a6390686f0930ff40542450fa34f0b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_datetime_data/2.2.0/download\"],\n strip_prefix = \"icu_datetime_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_datetime_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_decimal-2.2.0\",\n sha256 = \"288247df2e32aa776ac54fdd64de552149ac43cb840f2761811f0e8d09719dd4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_decimal/2.2.0/download\"],\n strip_prefix = \"icu_decimal-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_decimal-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_decimal_data-2.2.0\",\n sha256 = \"6f14a5ca9e8af29eef62064f269078424283d90dbaffeac5225addf62aaabc22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_decimal_data/2.2.0/download\"],\n strip_prefix = \"icu_decimal_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_decimal_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locale-2.2.0\",\n sha256 = \"d5a396343c7208121dc86e35623d3dfe19814a7613cfd14964994cdc9c9a2e26\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locale/2.2.0/download\"],\n strip_prefix = \"icu_locale-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locale-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locale_core-2.2.0\",\n sha256 = \"92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locale_core/2.2.0/download\"],\n strip_prefix = \"icu_locale_core-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locale_core-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locale_data-2.2.0\",\n sha256 = \"d5fdcc9ac77c6d74ff5cf6e65ef3181d6af32003b16fce3a77fb451d2f695993\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locale_data/2.2.0/download\"],\n strip_prefix = \"icu_locale_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locale_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer-2.2.0\",\n sha256 = \"c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer/2.2.0/download\"],\n strip_prefix = \"icu_normalizer-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer_data-2.2.0\",\n sha256 = \"da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer_data/2.2.0/download\"],\n strip_prefix = \"icu_normalizer_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_pattern-0.4.2\",\n sha256 = \"1c4c568054ffe735398a9f4c55aec37ad7c768844553cc0978f09cc9b933a1fb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_pattern/0.4.2/download\"],\n strip_prefix = \"icu_pattern-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.icu_pattern-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_plurals-2.2.0\",\n sha256 = \"2a50023f1d49ad5c4333380328a0d4a19e4b9d6d842ec06639affd5ba47c8103\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_plurals/2.2.0/download\"],\n strip_prefix = \"icu_plurals-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_plurals-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_plurals_data-2.2.0\",\n sha256 = \"8485497155dc865f901decb93ecc20d3e467df67bfeceb91e3ba34e2b11e8e1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_plurals_data/2.2.0/download\"],\n strip_prefix = \"icu_plurals_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_plurals_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties-2.2.0\",\n sha256 = \"bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties/2.2.0/download\"],\n strip_prefix = \"icu_properties-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties_data-2.2.0\",\n sha256 = \"8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties_data/2.2.0/download\"],\n strip_prefix = \"icu_properties_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider-2.2.0\",\n sha256 = \"139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider/2.2.0/download\"],\n strip_prefix = \"icu_provider-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_time-2.2.0\",\n sha256 = \"ec3af0c141da0a61d4f6970cd1d5f4b388b17ea22f8124f8f6049d3d5147586a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_time/2.2.0/download\"],\n strip_prefix = \"icu_time-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_time-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_time_data-2.2.1\",\n sha256 = \"2e0ee79a0bb29772465234bfbad6ea04fbc5220bef9fa4f318cc53eb8897070e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_time_data/2.2.1/download\"],\n strip_prefix = \"icu_time_data-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_time_data-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icy_sixel-0.5.0\",\n sha256 = \"85518b9086bf01117761b90e7691c0ef3236fa8adfb1fb44dd248fe5f87215d5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icy_sixel/0.5.0/download\"],\n strip_prefix = \"icy_sixel-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icy_sixel-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ident_case-1.0.1\",\n sha256 = \"b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ident_case/1.0.1/download\"],\n strip_prefix = \"ident_case-1.0.1\",\n build_file = Label(\"@crates//crates:BUILD.ident_case-1.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna-1.1.0\",\n sha256 = \"3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna/1.1.0/download\"],\n strip_prefix = \"idna-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.idna-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna_adapter-1.2.2\",\n sha256 = \"cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna_adapter/1.2.2/download\"],\n strip_prefix = \"idna_adapter-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.idna_adapter-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ignore-0.4.31\",\n sha256 = \"7f8a7b8211e695a1d0cd91cace480d4d0bd57667ab10277cc412c5f7f4884f83\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ignore/0.4.31/download\"],\n strip_prefix = \"ignore-0.4.31\",\n build_file = Label(\"@crates//crates:BUILD.ignore-0.4.31.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__image-0.25.10\",\n sha256 = \"85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/image/0.25.10/download\"],\n strip_prefix = \"image-0.25.10\",\n build_file = Label(\"@crates//crates:BUILD.image-0.25.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__image-webp-0.2.4\",\n sha256 = \"525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/image-webp/0.2.4/download\"],\n strip_prefix = \"image-webp-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.image-webp-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indenter-0.3.4\",\n sha256 = \"964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indenter/0.3.4/download\"],\n strip_prefix = \"indenter-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.indenter-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indexmap-2.14.0\",\n sha256 = \"d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indexmap/2.14.0/download\"],\n strip_prefix = \"indexmap-2.14.0\",\n build_file = Label(\"@crates//crates:BUILD.indexmap-2.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indicatif-0.18.6\",\n sha256 = \"9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indicatif/0.18.6/download\"],\n strip_prefix = \"indicatif-0.18.6\",\n build_file = Label(\"@crates//crates:BUILD.indicatif-0.18.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inferno-0.12.8\",\n sha256 = \"0c460d4fa06223667240720ab69a8045133755ae6dfbe100cf481b95e3a014f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inferno/0.12.8/download\"],\n strip_prefix = \"inferno-0.12.8\",\n build_file = Label(\"@crates//crates:BUILD.inferno-0.12.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inherent-1.0.14\",\n sha256 = \"bee2c455ca60511a054699102d40ce7153621cb2429558f9eaa600e4499b5984\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inherent/1.0.14/download\"],\n strip_prefix = \"inherent-1.0.14\",\n build_file = Label(\"@crates//crates:BUILD.inherent-1.0.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inotify-0.11.4\",\n sha256 = \"153be1941a183ec9ccd095ddbe17a8b8d435ef6c76e9e02451b933c3999af2c8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inotify/0.11.4/download\"],\n strip_prefix = \"inotify-0.11.4\",\n build_file = Label(\"@crates//crates:BUILD.inotify-0.11.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inotify-sys-0.1.8\",\n sha256 = \"c033f80b2c113cdf91ab7a33faa9cbc014726dcad99880c8609af2a370edf37d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inotify-sys/0.1.8/download\"],\n strip_prefix = \"inotify-sys-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.inotify-sys-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inout-0.1.4\",\n sha256 = \"879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inout/0.1.4/download\"],\n strip_prefix = \"inout-0.1.4\",\n build_file = Label(\"@crates//crates:BUILD.inout-0.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__insta-1.48.0\",\n sha256 = \"86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/insta/1.48.0/download\"],\n strip_prefix = \"insta-1.48.0\",\n build_file = Label(\"@crates//crates:BUILD.insta-1.48.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__interceptor-0.17.2\",\n sha256 = \"88c11a956a48159f7fe539b8198f12b4db9b709ae5f94385b840db38f97fed74\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/interceptor/0.17.2/download\"],\n strip_prefix = \"interceptor-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.interceptor-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__intl-memoizer-0.5.3\",\n sha256 = \"310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/intl-memoizer/0.5.3/download\"],\n strip_prefix = \"intl-memoizer-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.intl-memoizer-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__intl_pluralrules-7.0.2\",\n sha256 = \"078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/intl_pluralrules/7.0.2/download\"],\n strip_prefix = \"intl_pluralrules-7.0.2\",\n build_file = Label(\"@crates//crates:BUILD.intl_pluralrules-7.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ipnet-2.12.0\",\n sha256 = \"d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ipnet/2.12.0/download\"],\n strip_prefix = \"ipnet-2.12.0\",\n build_file = Label(\"@crates//crates:BUILD.ipnet-2.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__is_terminal_polyfill-1.70.2\",\n sha256 = \"a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/is_terminal_polyfill/1.70.2/download\"],\n strip_prefix = \"is_terminal_polyfill-1.70.2\",\n build_file = Label(\"@crates//crates:BUILD.is_terminal_polyfill-1.70.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itertools-0.13.0\",\n sha256 = \"413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itertools/0.13.0/download\"],\n strip_prefix = \"itertools-0.13.0\",\n build_file = Label(\"@crates//crates:BUILD.itertools-0.13.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itertools-0.14.0\",\n sha256 = \"2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itertools/0.14.0/download\"],\n strip_prefix = \"itertools-0.14.0\",\n build_file = Label(\"@crates//crates:BUILD.itertools-0.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itoa-1.0.18\",\n sha256 = \"8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itoa/1.0.18/download\"],\n strip_prefix = \"itoa-1.0.18\",\n build_file = Label(\"@crates//crates:BUILD.itoa-1.0.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jaq-core-2.2.1\",\n sha256 = \"77526a72eb79412c29fd141767a6549bbfcb1cb40e00556fe16532d5e878e098\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jaq-core/2.2.1/download\"],\n strip_prefix = \"jaq-core-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.jaq-core-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jaq-json-1.1.3\",\n sha256 = \"01dbdbd07b076e8403abac68ce7744d93e2ecd953bbc44bf77bf00e1e81172bc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jaq-json/1.1.3/download\"],\n strip_prefix = \"jaq-json-1.1.3\",\n build_file = Label(\"@crates//crates:BUILD.jaq-json-1.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jaq-std-2.1.2\",\n sha256 = \"2c264fe397c981705976c71f1bfe020382b9eda52ae950e57fe885e147bdd67d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jaq-std/2.1.2/download\"],\n strip_prefix = \"jaq-std-2.1.2\",\n build_file = Label(\"@crates//crates:BUILD.jaq-std-2.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-0.2.35\",\n sha256 = \"668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff/0.2.35/download\"],\n strip_prefix = \"jiff-0.2.35\",\n build_file = Label(\"@crates//crates:BUILD.jiff-0.2.35.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-core-0.1.0\",\n sha256 = \"7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-core/0.1.0/download\"],\n strip_prefix = \"jiff-core-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.jiff-core-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-icu-0.2.2\",\n sha256 = \"0e67c2beaae8b10a82d849b9aabb698a43a682f32b17bcdc035d5ecadb44d646\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-icu/0.2.2/download\"],\n strip_prefix = \"jiff-icu-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.jiff-icu-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-static-0.2.35\",\n sha256 = \"3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-static/0.2.35/download\"],\n strip_prefix = \"jiff-static-0.2.35\",\n build_file = Label(\"@crates//crates:BUILD.jiff-static-0.2.35.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-tzdb-0.1.8\",\n sha256 = \"142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-tzdb/0.1.8/download\"],\n strip_prefix = \"jiff-tzdb-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.jiff-tzdb-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-tzdb-platform-0.1.3\",\n sha256 = \"875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-tzdb-platform/0.1.3/download\"],\n strip_prefix = \"jiff-tzdb-platform-0.1.3\",\n build_file = Label(\"@crates//crates:BUILD.jiff-tzdb-platform-0.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jobserver-0.1.35\",\n sha256 = \"1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jobserver/0.1.35/download\"],\n strip_prefix = \"jobserver-0.1.35\",\n build_file = Label(\"@crates//crates:BUILD.jobserver-0.1.35.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__js-sys-0.3.103\",\n sha256 = \"53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/js-sys/0.3.103/download\"],\n strip_prefix = \"js-sys-0.3.103\",\n build_file = Label(\"@crates//crates:BUILD.js-sys-0.3.103.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__keccak-0.1.6\",\n sha256 = \"cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/keccak/0.1.6/download\"],\n strip_prefix = \"keccak-0.1.6\",\n build_file = Label(\"@crates//crates:BUILD.keccak-0.1.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__khronos-egl-6.0.0\",\n sha256 = \"6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/khronos-egl/6.0.0/download\"],\n strip_prefix = \"khronos-egl-6.0.0\",\n build_file = Label(\"@crates//crates:BUILD.khronos-egl-6.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__khronos_api-3.1.0\",\n sha256 = \"e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/khronos_api/3.1.0/download\"],\n strip_prefix = \"khronos_api-3.1.0\",\n build_file = Label(\"@crates//crates:BUILD.khronos_api-3.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__kqueue-1.2.0\",\n sha256 = \"273c0752728918e0ac4976f2b275b6fefb9ecd400585dec929419f3844cd87b5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/kqueue/1.2.0/download\"],\n strip_prefix = \"kqueue-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.kqueue-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__kqueue-sys-1.1.2\",\n sha256 = \"07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/kqueue-sys/1.1.2/download\"],\n strip_prefix = \"kqueue-sys-1.1.2\",\n build_file = Label(\"@crates//crates:BUILD.kqueue-sys-1.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lazy_static-1.5.0\",\n sha256 = \"bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lazy_static/1.5.0/download\"],\n strip_prefix = \"lazy_static-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.lazy_static-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libc-0.2.189\",\n sha256 = \"3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libc/0.2.189/download\"],\n strip_prefix = \"libc-0.2.189\",\n build_file = Label(\"@crates//crates:BUILD.libc-0.2.189.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libloading-0.8.9\",\n sha256 = \"d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libloading/0.8.9/download\"],\n strip_prefix = \"libloading-0.8.9\",\n build_file = Label(\"@crates//crates:BUILD.libloading-0.8.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libloading-0.9.0\",\n sha256 = \"754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libloading/0.9.0/download\"],\n strip_prefix = \"libloading-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.libloading-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libm-0.2.16\",\n sha256 = \"b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libm/0.2.16/download\"],\n strip_prefix = \"libm-0.2.16\",\n build_file = Label(\"@crates//crates:BUILD.libm-0.2.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libredox-0.1.18\",\n sha256 = \"c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libredox/0.1.18/download\"],\n strip_prefix = \"libredox-0.1.18\",\n build_file = Label(\"@crates//crates:BUILD.libredox-0.1.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libspa-0.9.2\",\n sha256 = \"b6b8cfa2a7656627b4c92c6b9ef929433acd673d5ab3708cda1b18478ac00df4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libspa/0.9.2/download\"],\n strip_prefix = \"libspa-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.libspa-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libspa-sys-0.9.2\",\n sha256 = \"901049455d2eb6decf9058235d745237952f4804bc584c5fcb41412e6adcc6e0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libspa-sys/0.9.2/download\"],\n strip_prefix = \"libspa-sys-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.libspa-sys-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libwayshot-xcap-0.3.3\",\n sha256 = \"ea8a46e4d016ef464e386e4970f5415fe0939c2d63abe0c2f539c05ef88c5fe5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libwayshot-xcap/0.3.3/download\"],\n strip_prefix = \"libwayshot-xcap-0.3.3\",\n build_file = Label(\"@crates//crates:BUILD.libwayshot-xcap-0.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linked-hash-map-0.5.6\",\n sha256 = \"0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linked-hash-map/0.5.6/download\"],\n strip_prefix = \"linked-hash-map-0.5.6\",\n build_file = Label(\"@crates//crates:BUILD.linked-hash-map-0.5.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.12.1\",\n sha256 = \"32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.12.1/download\"],\n strip_prefix = \"linux-raw-sys-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.4.15\",\n sha256 = \"d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.4.15/download\"],\n strip_prefix = \"linux-raw-sys-0.4.15\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.4.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.9.4\",\n sha256 = \"cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.9.4/download\"],\n strip_prefix = \"linux-raw-sys-0.9.4\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.9.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__litemap-0.8.2\",\n sha256 = \"92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/litemap/0.8.2/download\"],\n strip_prefix = \"litemap-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.litemap-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lock_api-0.4.14\",\n sha256 = \"224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lock_api/0.4.14/download\"],\n strip_prefix = \"lock_api-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.lock_api-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__log-0.4.33\",\n sha256 = \"0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/log/0.4.33/download\"],\n strip_prefix = \"log-0.4.33\",\n build_file = Label(\"@crates//crates:BUILD.log-0.4.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lru-0.16.4\",\n sha256 = \"7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lru/0.16.4/download\"],\n strip_prefix = \"lru-0.16.4\",\n build_file = Label(\"@crates//crates:BUILD.lru-0.16.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lscolors-0.21.0\",\n sha256 = \"d60e266dfb1426eb2d24792602e041131fdc0236bb7007abc0e589acafd60929\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lscolors/0.21.0/download\"],\n strip_prefix = \"lscolors-0.21.0\",\n build_file = Label(\"@crates//crates:BUILD.lscolors-0.21.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__markup5ever-0.39.0\",\n sha256 = \"7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/markup5ever/0.39.0/download\"],\n strip_prefix = \"markup5ever-0.39.0\",\n build_file = Label(\"@crates//crates:BUILD.markup5ever-0.39.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__maudio-0.1.6\",\n sha256 = \"c6ab2d47a7b24f4cf6ab85d335b4a6cc932f650080dfe0819b22bc553aada602\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/maudio/0.1.6/download\"],\n strip_prefix = \"maudio-0.1.6\",\n build_file = Label(\"@crates//crates:BUILD.maudio-0.1.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__maudio-sys-0.1.3\",\n patch_args = [\n \"-p1\",\n ],\n patches = [\n \"@@//bazel/patches:maudio-sys-target-bindings.patch\",\n ],\n sha256 = \"f00ae1969d0a389937161b834623e5cba2d8449752a0970d71382cf9a905bb35\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/maudio-sys/0.1.3/download\"],\n strip_prefix = \"maudio-sys-0.1.3\",\n build_file = Label(\"@crates//crates:BUILD.maudio-sys-0.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__md-5-0.10.6\",\n sha256 = \"d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/md-5/0.10.6/download\"],\n strip_prefix = \"md-5-0.10.6\",\n build_file = Label(\"@crates//crates:BUILD.md-5-0.10.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memchr-2.8.3\",\n sha256 = \"cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memchr/2.8.3/download\"],\n strip_prefix = \"memchr-2.8.3\",\n build_file = Label(\"@crates//crates:BUILD.memchr-2.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memmap2-0.9.11\",\n sha256 = \"d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memmap2/0.9.11/download\"],\n strip_prefix = \"memmap2-0.9.11\",\n build_file = Label(\"@crates//crates:BUILD.memmap2-0.9.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memoffset-0.7.1\",\n sha256 = \"5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memoffset/0.7.1/download\"],\n strip_prefix = \"memoffset-0.7.1\",\n build_file = Label(\"@crates//crates:BUILD.memoffset-0.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memoffset-0.9.1\",\n sha256 = \"488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memoffset/0.9.1/download\"],\n strip_prefix = \"memoffset-0.9.1\",\n build_file = Label(\"@crates//crates:BUILD.memoffset-0.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__minimal-lexical-0.2.1\",\n sha256 = \"68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/minimal-lexical/0.2.1/download\"],\n strip_prefix = \"minimal-lexical-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.minimal-lexical-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__miniz_oxide-0.8.9\",\n sha256 = \"1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/miniz_oxide/0.8.9/download\"],\n strip_prefix = \"miniz_oxide-0.8.9\",\n build_file = Label(\"@crates//crates:BUILD.miniz_oxide-0.8.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__mio-1.2.2\",\n sha256 = \"30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/mio/1.2.2/download\"],\n strip_prefix = \"mio-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.mio-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__moxcms-0.8.1\",\n sha256 = \"bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/moxcms/0.8.1/download\"],\n strip_prefix = \"moxcms-0.8.1\",\n build_file = Label(\"@crates//crates:BUILD.moxcms-0.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__munge-0.4.7\",\n sha256 = \"5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/munge/0.4.7/download\"],\n strip_prefix = \"munge-0.4.7\",\n build_file = Label(\"@crates//crates:BUILD.munge-0.4.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__munge_macro-0.4.7\",\n sha256 = \"4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/munge_macro/0.4.7/download\"],\n strip_prefix = \"munge_macro-0.4.7\",\n build_file = Label(\"@crates//crates:BUILD.munge_macro-0.4.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nanorand-0.7.0\",\n sha256 = \"6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nanorand/0.7.0/download\"],\n strip_prefix = \"nanorand-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.nanorand-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-3.11.0\",\n sha256 = \"de33522036981030a75c231829566bc63414e08101a6f5ff4ac6cef19c8e0941\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi/3.11.0/download\"],\n strip_prefix = \"napi-3.11.0\",\n build_file = Label(\"@crates//crates:BUILD.napi-3.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-build-2.3.2\",\n sha256 = \"c9c366d2c8c60b86fa632df75f745509b52f9128f91a6bad4c796e44abb505e1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi-build/2.3.2/download\"],\n strip_prefix = \"napi-build-2.3.2\",\n build_file = Label(\"@crates//crates:BUILD.napi-build-2.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-derive-3.6.0\",\n sha256 = \"a49c513341a61a16a10af6efcce46b30d0822ba2d4fb197d24d33dfc199c78d5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi-derive/3.6.0/download\"],\n strip_prefix = \"napi-derive-3.6.0\",\n build_file = Label(\"@crates//crates:BUILD.napi-derive-3.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-derive-backend-6.0.0\",\n sha256 = \"4747005fa3e2c9989ac45a723a514c5db2411238b72981a3cda4c701a9dfea17\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi-derive-backend/6.0.0/download\"],\n strip_prefix = \"napi-derive-backend-6.0.0\",\n build_file = Label(\"@crates//crates:BUILD.napi-derive-backend-6.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-sys-3.3.0\",\n sha256 = \"85fbf1fa9f1babfe396d74bbbf52b3643770243e8f5b0b46715d4caf7f0dfc9a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi-sys/3.3.0/download\"],\n strip_prefix = \"napi-sys-3.3.0\",\n build_file = Label(\"@crates//crates:BUILD.napi-sys-3.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__new_debug_unreachable-1.0.6\",\n sha256 = \"650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/new_debug_unreachable/1.0.6/download\"],\n strip_prefix = \"new_debug_unreachable-1.0.6\",\n build_file = Label(\"@crates//crates:BUILD.new_debug_unreachable-1.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.24.3\",\n sha256 = \"fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.24.3/download\"],\n strip_prefix = \"nix-0.24.3\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.24.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.26.4\",\n sha256 = \"598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.26.4/download\"],\n strip_prefix = \"nix-0.26.4\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.26.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.28.0\",\n sha256 = \"ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.28.0/download\"],\n strip_prefix = \"nix-0.28.0\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.28.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.29.0\",\n sha256 = \"71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.29.0/download\"],\n strip_prefix = \"nix-0.29.0\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.29.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.30.1\",\n sha256 = \"74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.30.1/download\"],\n strip_prefix = \"nix-0.30.1\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.30.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.31.3\",\n sha256 = \"cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.31.3/download\"],\n strip_prefix = \"nix-0.31.3\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.31.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nohash-hasher-0.2.0\",\n sha256 = \"2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nohash-hasher/0.2.0/download\"],\n strip_prefix = \"nohash-hasher-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.nohash-hasher-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nom-7.1.3\",\n sha256 = \"d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nom/7.1.3/download\"],\n strip_prefix = \"nom-7.1.3\",\n build_file = Label(\"@crates//crates:BUILD.nom-7.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nom-8.0.0\",\n sha256 = \"df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nom/8.0.0/download\"],\n strip_prefix = \"nom-8.0.0\",\n build_file = Label(\"@crates//crates:BUILD.nom-8.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__normalize-path-0.2.1\",\n sha256 = \"f5438dd2b2ff4c6df6e1ce22d825ed2fa93ee2922235cc45186991717f0a892d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/normalize-path/0.2.1/download\"],\n strip_prefix = \"normalize-path-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.normalize-path-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__notify-8.2.0\",\n sha256 = \"4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/notify/8.2.0/download\"],\n strip_prefix = \"notify-8.2.0\",\n build_file = Label(\"@crates//crates:BUILD.notify-8.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__notify-types-2.1.0\",\n sha256 = \"42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/notify-types/2.1.0/download\"],\n strip_prefix = \"notify-types-2.1.0\",\n build_file = Label(\"@crates//crates:BUILD.notify-types-2.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nu-ansi-term-0.50.3\",\n sha256 = \"7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nu-ansi-term/0.50.3/download\"],\n strip_prefix = \"nu-ansi-term-0.50.3\",\n build_file = Label(\"@crates//crates:BUILD.nu-ansi-term-0.50.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-bigint-0.4.8\",\n sha256 = \"c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-bigint/0.4.8/download\"],\n strip_prefix = \"num-bigint-0.4.8\",\n build_file = Label(\"@crates//crates:BUILD.num-bigint-0.4.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-conv-0.2.2\",\n sha256 = \"521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-conv/0.2.2/download\"],\n strip_prefix = \"num-conv-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.num-conv-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-format-0.4.4\",\n sha256 = \"a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-format/0.4.4/download\"],\n strip_prefix = \"num-format-0.4.4\",\n build_file = Label(\"@crates//crates:BUILD.num-format-0.4.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-integer-0.1.46\",\n sha256 = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-integer/0.1.46/download\"],\n strip_prefix = \"num-integer-0.1.46\",\n build_file = Label(\"@crates//crates:BUILD.num-integer-0.1.46.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-traits-0.2.19\",\n sha256 = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-traits/0.2.19/download\"],\n strip_prefix = \"num-traits-0.2.19\",\n build_file = Label(\"@crates//crates:BUILD.num-traits-0.2.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__number_prefix-0.4.0\",\n sha256 = \"830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/number_prefix/0.4.0/download\"],\n strip_prefix = \"number_prefix-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.number_prefix-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-0.6.4\",\n sha256 = \"3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2/0.6.4/download\"],\n strip_prefix = \"objc2-0.6.4\",\n build_file = Label(\"@crates//crates:BUILD.objc2-0.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-app-kit-0.3.2\",\n sha256 = \"d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-app-kit/0.3.2/download\"],\n strip_prefix = \"objc2-app-kit-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-app-kit-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-av-foundation-0.3.2\",\n sha256 = \"478ae33fcac9df0a18db8302387c666b8ef08a3e2d62b510ca4fc278a384b6c0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-av-foundation/0.3.2/download\"],\n strip_prefix = \"objc2-av-foundation-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-av-foundation-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-avf-audio-0.3.2\",\n sha256 = \"13a380031deed8e99db00065c45937da434ca987c034e13b87e4441f9e4090be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-avf-audio/0.3.2/download\"],\n strip_prefix = \"objc2-avf-audio-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-avf-audio-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-cloud-kit-0.3.2\",\n sha256 = \"73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-cloud-kit/0.3.2/download\"],\n strip_prefix = \"objc2-cloud-kit-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-cloud-kit-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-audio-0.3.2\",\n sha256 = \"e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-audio/0.3.2/download\"],\n strip_prefix = \"objc2-core-audio-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-audio-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-audio-types-0.3.2\",\n sha256 = \"5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-audio-types/0.3.2/download\"],\n strip_prefix = \"objc2-core-audio-types-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-audio-types-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-data-0.3.2\",\n sha256 = \"0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-data/0.3.2/download\"],\n strip_prefix = \"objc2-core-data-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-data-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-foundation-0.3.2\",\n sha256 = \"2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-foundation/0.3.2/download\"],\n strip_prefix = \"objc2-core-foundation-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-foundation-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-graphics-0.3.2\",\n sha256 = \"e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-graphics/0.3.2/download\"],\n strip_prefix = \"objc2-core-graphics-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-graphics-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-image-0.3.2\",\n sha256 = \"e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-image/0.3.2/download\"],\n strip_prefix = \"objc2-core-image-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-image-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-media-0.3.2\",\n sha256 = \"05ec576860167a15dd9fce7fbee7512beb4e31f532159d3482d1f9c6caedf31d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-media/0.3.2/download\"],\n strip_prefix = \"objc2-core-media-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-media-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-text-0.3.2\",\n sha256 = \"0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-text/0.3.2/download\"],\n strip_prefix = \"objc2-core-text-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-text-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-video-0.3.2\",\n sha256 = \"d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-video/0.3.2/download\"],\n strip_prefix = \"objc2-core-video-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-video-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-encode-4.1.0\",\n sha256 = \"ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-encode/4.1.0/download\"],\n strip_prefix = \"objc2-encode-4.1.0\",\n build_file = Label(\"@crates//crates:BUILD.objc2-encode-4.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-foundation-0.3.2\",\n sha256 = \"e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-foundation/0.3.2/download\"],\n strip_prefix = \"objc2-foundation-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-foundation-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-image-io-0.3.2\",\n sha256 = \"32b0446e98cf4a784cc7a0177715ff317eeaa8463841c616cfc78aa4f953c4ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-image-io/0.3.2/download\"],\n strip_prefix = \"objc2-image-io-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-image-io-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-io-surface-0.3.2\",\n sha256 = \"180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-io-surface/0.3.2/download\"],\n strip_prefix = \"objc2-io-surface-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-io-surface-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-media-toolbox-0.3.2\",\n sha256 = \"edd9fdde720df3da7046bb9097811000c1e7ab5cd579fa89d96b27d56781fb30\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-media-toolbox/0.3.2/download\"],\n strip_prefix = \"objc2-media-toolbox-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-media-toolbox-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-metal-0.3.2\",\n sha256 = \"a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-metal/0.3.2/download\"],\n strip_prefix = \"objc2-metal-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-metal-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-quartz-core-0.3.2\",\n sha256 = \"96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-quartz-core/0.3.2/download\"],\n strip_prefix = \"objc2-quartz-core-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-quartz-core-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-system-configuration-0.3.2\",\n sha256 = \"7216bd11cbda54ccabcab84d523dc93b858ec75ecfb3a7d89513fa22464da396\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-system-configuration/0.3.2/download\"],\n strip_prefix = \"objc2-system-configuration-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-system-configuration-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__oid-registry-0.7.1\",\n sha256 = \"a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/oid-registry/0.7.1/download\"],\n strip_prefix = \"oid-registry-0.7.1\",\n build_file = Label(\"@crates//crates:BUILD.oid-registry-0.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell-1.21.4\",\n sha256 = \"9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell/1.21.4/download\"],\n strip_prefix = \"once_cell-1.21.4\",\n build_file = Label(\"@crates//crates:BUILD.once_cell-1.21.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell_polyfill-1.70.2\",\n sha256 = \"384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell_polyfill/1.70.2/download\"],\n strip_prefix = \"once_cell_polyfill-1.70.2\",\n build_file = Label(\"@crates//crates:BUILD.once_cell_polyfill-1.70.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__onig-6.5.3\",\n sha256 = \"0cc3cbf698f9438986c11a880c90a6d04b9de27575afd28bbf45b154b6c709e2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/onig/6.5.3/download\"],\n strip_prefix = \"onig-6.5.3\",\n build_file = Label(\"@crates//crates:BUILD.onig-6.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__onig_sys-69.9.3\",\n sha256 = \"1e68317604e77e53b85896388e1a803c1d21b74c899ec9e5e1112db90735edd7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/onig_sys/69.9.3/download\"],\n strip_prefix = \"onig_sys-69.9.3\",\n build_file = Label(\"@crates//crates:BUILD.onig_sys-69.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__opaque-debug-0.3.1\",\n sha256 = \"c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/opaque-debug/0.3.1/download\"],\n strip_prefix = \"opaque-debug-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.opaque-debug-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__opus-0.3.1\",\n sha256 = \"4d3809943dff6fbad5f0484449ea26bdb9cb7d8efdf26ed50d3c7f227f69eb5c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/opus/0.3.1/download\"],\n strip_prefix = \"opus-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.opus-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ordered-float-5.3.0\",\n sha256 = \"b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ordered-float/5.3.0/download\"],\n strip_prefix = \"ordered-float-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.ordered-float-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ordered-stream-0.2.0\",\n sha256 = \"9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ordered-stream/0.2.0/download\"],\n strip_prefix = \"ordered-stream-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.ordered-stream-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__os_display-0.1.4\",\n sha256 = \"ad5fd71b79026fb918650dde6d125000a233764f1c2f1659a1c71118e33ea08f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/os_display/0.1.4/download\"],\n strip_prefix = \"os_display-0.1.4\",\n build_file = Label(\"@crates//crates:BUILD.os_display-0.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__os_pipe-1.2.3\",\n sha256 = \"7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/os_pipe/1.2.3/download\"],\n strip_prefix = \"os_pipe-1.2.3\",\n build_file = Label(\"@crates//crates:BUILD.os_pipe-1.2.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__outref-0.5.2\",\n sha256 = \"1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/outref/0.5.2/download\"],\n strip_prefix = \"outref-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.outref-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__p256-0.13.2\",\n sha256 = \"c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/p256/0.13.2/download\"],\n strip_prefix = \"p256-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.p256-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__p384-0.13.1\",\n sha256 = \"fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/p384/0.13.1/download\"],\n strip_prefix = \"p384-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.p384-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__palette-0.7.6\",\n sha256 = \"4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/palette/0.7.6/download\"],\n strip_prefix = \"palette-0.7.6\",\n build_file = Label(\"@crates//crates:BUILD.palette-0.7.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__palette_derive-0.7.6\",\n sha256 = \"f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/palette_derive/0.7.6/download\"],\n strip_prefix = \"palette_derive-0.7.6\",\n build_file = Label(\"@crates//crates:BUILD.palette_derive-0.7.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking-2.2.1\",\n sha256 = \"f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking/2.2.1/download\"],\n strip_prefix = \"parking-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.parking-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot-0.12.5\",\n sha256 = \"93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot/0.12.5/download\"],\n strip_prefix = \"parking_lot-0.12.5\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot-0.12.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot_core-0.9.12\",\n sha256 = \"2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot_core/0.9.12/download\"],\n strip_prefix = \"parking_lot_core-0.9.12\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot_core-0.9.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parse_datetime-0.14.0\",\n sha256 = \"413775a7eac2261d2211a79d10ef275e5b6f7b527eec42ad09adce2ffa92b6e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parse_datetime/0.14.0/download\"],\n strip_prefix = \"parse_datetime-0.14.0\",\n build_file = Label(\"@crates//crates:BUILD.parse_datetime-0.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pcre2-0.2.11\",\n sha256 = \"9e970b0fcce0c7ee6ef662744ff711f21ccd6f11b7cf03cd187a80e89797fc67\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pcre2/0.2.11/download\"],\n strip_prefix = \"pcre2-0.2.11\",\n build_file = Label(\"@crates//crates:BUILD.pcre2-0.2.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pcre2-sys-0.2.10\",\n sha256 = \"18b9073c1a2549bd409bf4a32c94d903bb1a09bf845bc306ae148897fa0760a4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pcre2-sys/0.2.10/download\"],\n strip_prefix = \"pcre2-sys-0.2.10\",\n build_file = Label(\"@crates//crates:BUILD.pcre2-sys-0.2.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__peg-0.8.6\",\n sha256 = \"0aad070be5b63aa72103f2fcdd70a83adbd5e90112ce5b574171ff1c65501773\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/peg/0.8.6/download\"],\n strip_prefix = \"peg-0.8.6\",\n build_file = Label(\"@crates//crates:BUILD.peg-0.8.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__peg-macros-0.8.6\",\n sha256 = \"ddd8ef6825cae95355031ae26a99b616a2a21f22ba2de0197c43dfb05acbe7ee\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/peg-macros/0.8.6/download\"],\n strip_prefix = \"peg-macros-0.8.6\",\n build_file = Label(\"@crates//crates:BUILD.peg-macros-0.8.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__peg-runtime-0.8.6\",\n sha256 = \"7011d97b484a5ebdc4b1fdb3b12d5e4bbbea56e9d22b688f2e79e04b65a7d8a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/peg-runtime/0.8.6/download\"],\n strip_prefix = \"peg-runtime-0.8.6\",\n build_file = Label(\"@crates//crates:BUILD.peg-runtime-0.8.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pem-3.0.6\",\n sha256 = \"1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pem/3.0.6/download\"],\n strip_prefix = \"pem-3.0.6\",\n build_file = Label(\"@crates//crates:BUILD.pem-3.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pem-rfc7468-0.7.0\",\n sha256 = \"88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pem-rfc7468/0.7.0/download\"],\n strip_prefix = \"pem-rfc7468-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.pem-rfc7468-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__percent-encoding-2.3.2\",\n sha256 = \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/percent-encoding/2.3.2/download\"],\n strip_prefix = \"percent-encoding-2.3.2\",\n build_file = Label(\"@crates//crates:BUILD.percent-encoding-2.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest-2.8.8\",\n sha256 = \"7df728be843c7070fab6ab7c328c4e9e9d78e23bf749c0669c86ee7ebfa050a2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest/2.8.8/download\"],\n strip_prefix = \"pest-2.8.8\",\n build_file = Label(\"@crates//crates:BUILD.pest-2.8.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest_derive-2.8.8\",\n sha256 = \"9e2dd6fc3b26b3462ee188aac870f5a41d398f1cd5e2408d16531bd71c9591fd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest_derive/2.8.8/download\"],\n strip_prefix = \"pest_derive-2.8.8\",\n build_file = Label(\"@crates//crates:BUILD.pest_derive-2.8.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest_generator-2.8.8\",\n sha256 = \"6a7a9205cfb6f596a9e8b689c0a15f9ceb7a1aafae7aaf788150ac65b29975b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest_generator/2.8.8/download\"],\n strip_prefix = \"pest_generator-2.8.8\",\n build_file = Label(\"@crates//crates:BUILD.pest_generator-2.8.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest_meta-2.8.8\",\n sha256 = \"85abd351c0de1e8384fc791a0737111a350394937e92b956b743dac12429f57c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest_meta/2.8.8/download\"],\n strip_prefix = \"pest_meta-2.8.8\",\n build_file = Label(\"@crates//crates:BUILD.pest_meta-2.8.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__petgraph-0.8.3\",\n sha256 = \"8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/petgraph/0.8.3/download\"],\n strip_prefix = \"petgraph-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.petgraph-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf-0.11.3\",\n sha256 = \"1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf/0.11.3/download\"],\n strip_prefix = \"phf-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.phf-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf-0.12.1\",\n sha256 = \"913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf/0.12.1/download\"],\n strip_prefix = \"phf-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.phf-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf-0.13.1\",\n sha256 = \"c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf/0.13.1/download\"],\n strip_prefix = \"phf-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_codegen-0.11.3\",\n sha256 = \"aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_codegen/0.11.3/download\"],\n strip_prefix = \"phf_codegen-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.phf_codegen-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_codegen-0.13.1\",\n sha256 = \"49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_codegen/0.13.1/download\"],\n strip_prefix = \"phf_codegen-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_codegen-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_generator-0.11.3\",\n sha256 = \"3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_generator/0.11.3/download\"],\n strip_prefix = \"phf_generator-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.phf_generator-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_generator-0.13.1\",\n sha256 = \"135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_generator/0.13.1/download\"],\n strip_prefix = \"phf_generator-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_generator-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_macros-0.13.1\",\n sha256 = \"812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_macros/0.13.1/download\"],\n strip_prefix = \"phf_macros-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_macros-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_shared-0.11.3\",\n sha256 = \"67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_shared/0.11.3/download\"],\n strip_prefix = \"phf_shared-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.phf_shared-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_shared-0.12.1\",\n sha256 = \"06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_shared/0.12.1/download\"],\n strip_prefix = \"phf_shared-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_shared-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_shared-0.13.1\",\n sha256 = \"e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_shared/0.13.1/download\"],\n strip_prefix = \"phf_shared-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_shared-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pin-project-lite-0.2.17\",\n sha256 = \"a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pin-project-lite/0.2.17/download\"],\n strip_prefix = \"pin-project-lite-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.pin-project-lite-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pin-utils-0.1.0\",\n sha256 = \"8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pin-utils/0.1.0/download\"],\n strip_prefix = \"pin-utils-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.pin-utils-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__piper-0.2.5\",\n sha256 = \"c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/piper/0.2.5/download\"],\n strip_prefix = \"piper-0.2.5\",\n build_file = Label(\"@crates//crates:BUILD.piper-0.2.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pipewire-0.9.2\",\n sha256 = \"9688b89abf11d756499f7c6190711d6dbe5a3acdb30c8fbf001d6596d06a8d44\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pipewire/0.9.2/download\"],\n strip_prefix = \"pipewire-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.pipewire-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pipewire-sys-0.9.2\",\n sha256 = \"cb028afee0d6ca17020b090e3b8fa2d7de23305aef975c7e5192a5050246ea36\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pipewire-sys/0.9.2/download\"],\n strip_prefix = \"pipewire-sys-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.pipewire-sys-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pkcs8-0.10.2\",\n sha256 = \"f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pkcs8/0.10.2/download\"],\n strip_prefix = \"pkcs8-0.10.2\",\n build_file = Label(\"@crates//crates:BUILD.pkcs8-0.10.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pkg-config-0.3.33\",\n sha256 = \"19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pkg-config/0.3.33/download\"],\n strip_prefix = \"pkg-config-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.pkg-config-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__platform-info-2.1.0\",\n sha256 = \"9368d62437c8cbb7c31ee37fd8c08a7d390e09a3ff75698a674953f46705ffcb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/platform-info/2.1.0/download\"],\n strip_prefix = \"platform-info-2.1.0\",\n build_file = Label(\"@crates//crates:BUILD.platform-info-2.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__png-0.18.1\",\n sha256 = \"60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/png/0.18.1/download\"],\n strip_prefix = \"png-0.18.1\",\n build_file = Label(\"@crates//crates:BUILD.png-0.18.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__polling-3.11.0\",\n sha256 = \"5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/polling/3.11.0/download\"],\n strip_prefix = \"polling-3.11.0\",\n build_file = Label(\"@crates//crates:BUILD.polling-3.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__poly1305-0.8.0\",\n sha256 = \"8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/poly1305/0.8.0/download\"],\n strip_prefix = \"poly1305-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.poly1305-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__polyval-0.6.2\",\n sha256 = \"9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/polyval/0.6.2/download\"],\n strip_prefix = \"polyval-0.6.2\",\n build_file = Label(\"@crates//crates:BUILD.polyval-0.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__portable-atomic-1.14.0\",\n sha256 = \"3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/portable-atomic/1.14.0/download\"],\n strip_prefix = \"portable-atomic-1.14.0\",\n build_file = Label(\"@crates//crates:BUILD.portable-atomic-1.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__portable-atomic-util-0.2.7\",\n sha256 = \"c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/portable-atomic-util/0.2.7/download\"],\n strip_prefix = \"portable-atomic-util-0.2.7\",\n build_file = Label(\"@crates//crates:BUILD.portable-atomic-util-0.2.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__portable-pty-0.9.0\",\n sha256 = \"b4a596a2b3d2752d94f51fac2d4a96737b8705dddd311a32b9af47211f08671e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/portable-pty/0.9.0/download\"],\n strip_prefix = \"portable-pty-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.portable-pty-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__potential_utf-0.1.5\",\n sha256 = \"0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/potential_utf/0.1.5/download\"],\n strip_prefix = \"potential_utf-0.1.5\",\n build_file = Label(\"@crates//crates:BUILD.potential_utf-0.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__powerfmt-0.2.0\",\n sha256 = \"439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/powerfmt/0.2.0/download\"],\n strip_prefix = \"powerfmt-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.powerfmt-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ppv-lite86-0.2.21\",\n sha256 = \"85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ppv-lite86/0.2.21/download\"],\n strip_prefix = \"ppv-lite86-0.2.21\",\n build_file = Label(\"@crates//crates:BUILD.ppv-lite86-0.2.21.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__precomputed-hash-0.1.1\",\n sha256 = \"925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/precomputed-hash/0.1.1/download\"],\n strip_prefix = \"precomputed-hash-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.precomputed-hash-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pretty_assertions-1.4.1\",\n sha256 = \"3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pretty_assertions/1.4.1/download\"],\n strip_prefix = \"pretty_assertions-1.4.1\",\n build_file = Label(\"@crates//crates:BUILD.pretty_assertions-1.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prettyplease-0.2.37\",\n sha256 = \"479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prettyplease/0.2.37/download\"],\n strip_prefix = \"prettyplease-0.2.37\",\n build_file = Label(\"@crates//crates:BUILD.prettyplease-0.2.37.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__primeorder-0.13.6\",\n sha256 = \"353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/primeorder/0.13.6/download\"],\n strip_prefix = \"primeorder-0.13.6\",\n build_file = Label(\"@crates//crates:BUILD.primeorder-0.13.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro-crate-3.5.0\",\n sha256 = \"e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro-crate/3.5.0/download\"],\n strip_prefix = \"proc-macro-crate-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro-crate-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro2-1.0.107\",\n sha256 = \"985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro2/1.0.107/download\"],\n strip_prefix = \"proc-macro2-1.0.107\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro2-1.0.107.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__procfs-0.18.0\",\n sha256 = \"25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/procfs/0.18.0/download\"],\n strip_prefix = \"procfs-0.18.0\",\n build_file = Label(\"@crates//crates:BUILD.procfs-0.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__procfs-core-0.18.0\",\n sha256 = \"e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/procfs-core/0.18.0/download\"],\n strip_prefix = \"procfs-core-0.18.0\",\n build_file = Label(\"@crates//crates:BUILD.procfs-core-0.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ptr_meta-0.3.1\",\n sha256 = \"0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ptr_meta/0.3.1/download\"],\n strip_prefix = \"ptr_meta-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.ptr_meta-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ptr_meta_derive-0.3.1\",\n sha256 = \"7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ptr_meta_derive/0.3.1/download\"],\n strip_prefix = \"ptr_meta_derive-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.ptr_meta_derive-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pxfm-0.1.30\",\n sha256 = \"d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pxfm/0.1.30/download\"],\n strip_prefix = \"pxfm-0.1.30\",\n build_file = Label(\"@crates//crates:BUILD.pxfm-0.1.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quantette-0.5.1\",\n sha256 = \"c98fecda8b16396ff9adac67644a523dd1778c42b58606a29df5c31ca925d174\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quantette/0.5.1/download\"],\n strip_prefix = \"quantette-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.quantette-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quick-error-2.0.1\",\n sha256 = \"a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quick-error/2.0.1/download\"],\n strip_prefix = \"quick-error-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.quick-error-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quick-xml-0.30.0\",\n sha256 = \"eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quick-xml/0.30.0/download\"],\n strip_prefix = \"quick-xml-0.30.0\",\n build_file = Label(\"@crates//crates:BUILD.quick-xml-0.30.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quick-xml-0.41.0\",\n sha256 = \"e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quick-xml/0.41.0/download\"],\n strip_prefix = \"quick-xml-0.41.0\",\n build_file = Label(\"@crates//crates:BUILD.quick-xml-0.41.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quote-1.0.47\",\n sha256 = \"1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quote/1.0.47/download\"],\n strip_prefix = \"quote-1.0.47\",\n build_file = Label(\"@crates//crates:BUILD.quote-1.0.47.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__r-efi-5.3.0\",\n sha256 = \"69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/r-efi/5.3.0/download\"],\n strip_prefix = \"r-efi-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.r-efi-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__r-efi-6.0.0\",\n sha256 = \"f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/r-efi/6.0.0/download\"],\n strip_prefix = \"r-efi-6.0.0\",\n build_file = Label(\"@crates//crates:BUILD.r-efi-6.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__radium-0.7.0\",\n sha256 = \"dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/radium/0.7.0/download\"],\n strip_prefix = \"radium-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.radium-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rancor-0.1.2\",\n sha256 = \"daff8b7b3ccf5f7ba270b3e7a0a4d4c701c5797e38dec27c7e2c3dbb830fed1c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rancor/0.1.2/download\"],\n strip_prefix = \"rancor-0.1.2\",\n build_file = Label(\"@crates//crates:BUILD.rancor-0.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand-0.10.2\",\n sha256 = \"c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand/0.10.2/download\"],\n strip_prefix = \"rand-0.10.2\",\n build_file = Label(\"@crates//crates:BUILD.rand-0.10.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand-0.8.7\",\n sha256 = \"22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand/0.8.7/download\"],\n strip_prefix = \"rand-0.8.7\",\n build_file = Label(\"@crates//crates:BUILD.rand-0.8.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand-0.9.5\",\n sha256 = \"b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand/0.9.5/download\"],\n strip_prefix = \"rand-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.rand-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_chacha-0.9.0\",\n sha256 = \"d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_chacha/0.9.0/download\"],\n strip_prefix = \"rand_chacha-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.rand_chacha-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.10.1\",\n sha256 = \"63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.10.1/download\"],\n strip_prefix = \"rand_core-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.6.4\",\n sha256 = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.6.4/download\"],\n strip_prefix = \"rand_core-0.6.4\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.9.5\",\n sha256 = \"76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.9.5/download\"],\n strip_prefix = \"rand_core-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_xoshiro-0.7.0\",\n sha256 = \"f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_xoshiro/0.7.0/download\"],\n strip_prefix = \"rand_xoshiro-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.rand_xoshiro-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rayon-1.12.0\",\n sha256 = \"fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rayon/1.12.0/download\"],\n strip_prefix = \"rayon-1.12.0\",\n build_file = Label(\"@crates//crates:BUILD.rayon-1.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rayon-core-1.13.0\",\n sha256 = \"22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rayon-core/1.13.0/download\"],\n strip_prefix = \"rayon-core-1.13.0\",\n build_file = Label(\"@crates//crates:BUILD.rayon-core-1.13.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rcgen-0.13.2\",\n sha256 = \"75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rcgen/0.13.2/download\"],\n strip_prefix = \"rcgen-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.rcgen-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_syscall-0.5.18\",\n sha256 = \"ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_syscall/0.5.18/download\"],\n strip_prefix = \"redox_syscall-0.5.18\",\n build_file = Label(\"@crates//crates:BUILD.redox_syscall-0.5.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ref-cast-1.0.26\",\n sha256 = \"216e8f773d7923bcba9ceb86a86c93cabb3903a11872fc3f138c49630e50b96d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ref-cast/1.0.26/download\"],\n strip_prefix = \"ref-cast-1.0.26\",\n build_file = Label(\"@crates//crates:BUILD.ref-cast-1.0.26.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ref-cast-impl-1.0.26\",\n sha256 = \"2c9283685feec7d69af75fb0e858d5e7378f33fe4fc699383b2916ab9273e03c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ref-cast-impl/1.0.26/download\"],\n strip_prefix = \"ref-cast-impl-1.0.26\",\n build_file = Label(\"@crates//crates:BUILD.ref-cast-impl-1.0.26.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-1.13.1\",\n sha256 = \"f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex/1.13.1/download\"],\n strip_prefix = \"regex-1.13.1\",\n build_file = Label(\"@crates//crates:BUILD.regex-1.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-automata-0.4.16\",\n sha256 = \"8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-automata/0.4.16/download\"],\n strip_prefix = \"regex-automata-0.4.16\",\n build_file = Label(\"@crates//crates:BUILD.regex-automata-0.4.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-lite-0.1.9\",\n sha256 = \"cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-lite/0.1.9/download\"],\n strip_prefix = \"regex-lite-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.regex-lite-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-syntax-0.8.11\",\n sha256 = \"d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-syntax/0.8.11/download\"],\n strip_prefix = \"regex-syntax-0.8.11\",\n build_file = Label(\"@crates//crates:BUILD.regex-syntax-0.8.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__relative-path-1.9.3\",\n sha256 = \"ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/relative-path/1.9.3/download\"],\n strip_prefix = \"relative-path-1.9.3\",\n build_file = Label(\"@crates//crates:BUILD.relative-path-1.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rend-0.5.4\",\n sha256 = \"663ba70707f96e871406fe10d68128412e619b06d1d47cb91c3a4c6501176240\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rend/0.5.4/download\"],\n strip_prefix = \"rend-0.5.4\",\n build_file = Label(\"@crates//crates:BUILD.rend-0.5.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rfc6979-0.4.0\",\n sha256 = \"f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rfc6979/0.4.0/download\"],\n strip_prefix = \"rfc6979-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.rfc6979-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rgb-0.8.53\",\n sha256 = \"47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rgb/0.8.53/download\"],\n strip_prefix = \"rgb-0.8.53\",\n build_file = Label(\"@crates//crates:BUILD.rgb-0.8.53.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ring-0.17.14\",\n sha256 = \"a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ring/0.17.14/download\"],\n strip_prefix = \"ring-0.17.14\",\n build_file = Label(\"@crates//crates:BUILD.ring-0.17.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rkyv-0.8.17\",\n sha256 = \"815cc8a37159a463064825246cadb07961e25cd9885908606f6d08a98d8f8874\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rkyv/0.8.17/download\"],\n strip_prefix = \"rkyv-0.8.17\",\n build_file = Label(\"@crates//crates:BUILD.rkyv-0.8.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rkyv_derive-0.8.17\",\n sha256 = \"c0ed1a78a1b19d184b0daa629dd9a024573173ec7d485b287cb369fb3607cc1c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rkyv_derive/0.8.17/download\"],\n strip_prefix = \"rkyv_derive-0.8.17\",\n build_file = Label(\"@crates//crates:BUILD.rkyv_derive-0.8.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rlimit-0.11.0\",\n sha256 = \"f35ee2729c56bb610f6dba436bf78135f728b7373bdffae2ec815b2d3eb98cc3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rlimit/0.11.0/download\"],\n strip_prefix = \"rlimit-0.11.0\",\n build_file = Label(\"@crates//crates:BUILD.rlimit-0.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rpds-1.2.1\",\n sha256 = \"e025feb26210bc196b908e72deb063b1b4000754304341cbc168a1e72c857ebc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rpds/1.2.1/download\"],\n strip_prefix = \"rpds-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.rpds-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rstest-0.26.1\",\n sha256 = \"f5a3193c063baaa2a95a33f03035c8a72b83d97a54916055ba22d35ed3839d49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rstest/0.26.1/download\"],\n strip_prefix = \"rstest-0.26.1\",\n build_file = Label(\"@crates//crates:BUILD.rstest-0.26.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rstest_macros-0.26.1\",\n sha256 = \"9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rstest_macros/0.26.1/download\"],\n strip_prefix = \"rstest_macros-0.26.1\",\n build_file = Label(\"@crates//crates:BUILD.rstest_macros-0.26.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rtcp-0.17.2\",\n sha256 = \"adad7f6a501162881032fc84b4bc78ae11f1b30748180b9f5cbe8810bf613aab\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rtcp/0.17.2/download\"],\n strip_prefix = \"rtcp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.rtcp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rtp-0.17.2\",\n sha256 = \"149329e78ada26b5e174a4c281a7a7e5c8bda6008adc90daddd6f98fce56db29\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rtp/0.17.2/download\"],\n strip_prefix = \"rtp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.rtp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustc-hash-1.1.0\",\n sha256 = \"08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustc-hash/1.1.0/download\"],\n strip_prefix = \"rustc-hash-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.rustc-hash-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustc-hash-2.1.3\",\n sha256 = \"6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustc-hash/2.1.3/download\"],\n strip_prefix = \"rustc-hash-2.1.3\",\n build_file = Label(\"@crates//crates:BUILD.rustc-hash-2.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustc_version-0.4.1\",\n sha256 = \"cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustc_version/0.4.1/download\"],\n strip_prefix = \"rustc_version-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.rustc_version-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rusticata-macros-4.1.0\",\n sha256 = \"faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rusticata-macros/4.1.0/download\"],\n strip_prefix = \"rusticata-macros-4.1.0\",\n build_file = Label(\"@crates//crates:BUILD.rusticata-macros-4.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustix-0.38.44\",\n sha256 = \"fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustix/0.38.44/download\"],\n strip_prefix = \"rustix-0.38.44\",\n build_file = Label(\"@crates//crates:BUILD.rustix-0.38.44.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustix-1.1.4\",\n sha256 = \"b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustix/1.1.4/download\"],\n strip_prefix = \"rustix-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.rustix-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustls-0.23.42\",\n sha256 = \"3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustls/0.23.42/download\"],\n strip_prefix = \"rustls-0.23.42\",\n build_file = Label(\"@crates//crates:BUILD.rustls-0.23.42.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustls-pki-types-1.15.1\",\n sha256 = \"2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustls-pki-types/1.15.1/download\"],\n strip_prefix = \"rustls-pki-types-1.15.1\",\n build_file = Label(\"@crates//crates:BUILD.rustls-pki-types-1.15.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustls-webpki-0.103.13\",\n sha256 = \"61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustls-webpki/0.103.13/download\"],\n strip_prefix = \"rustls-webpki-0.103.13\",\n build_file = Label(\"@crates//crates:BUILD.rustls-webpki-0.103.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustversion-1.0.23\",\n sha256 = \"cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustversion/1.0.23/download\"],\n strip_prefix = \"rustversion-1.0.23\",\n build_file = Label(\"@crates//crates:BUILD.rustversion-1.0.23.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__safe_arch-0.9.3\",\n sha256 = \"629516c85c29fe757770fa03f2074cf1eac43d44c02a3de9fc2ef7b0e207dfdd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/safe_arch/0.9.3/download\"],\n strip_prefix = \"safe_arch-0.9.3\",\n build_file = Label(\"@crates//crates:BUILD.safe_arch-0.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__same-file-1.0.6\",\n sha256 = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/same-file/1.0.6/download\"],\n strip_prefix = \"same-file-1.0.6\",\n build_file = Label(\"@crates//crates:BUILD.same-file-1.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__scoped-tls-1.0.1\",\n sha256 = \"e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/scoped-tls/1.0.1/download\"],\n strip_prefix = \"scoped-tls-1.0.1\",\n build_file = Label(\"@crates//crates:BUILD.scoped-tls-1.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__scopeguard-1.2.0\",\n sha256 = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/scopeguard/1.2.0/download\"],\n strip_prefix = \"scopeguard-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.scopeguard-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sdp-0.17.2\",\n sha256 = \"66b6eecfa5151edef84d544ff3885dff98e5b5fe97586757a4b5118bde51c958\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sdp/0.17.2/download\"],\n strip_prefix = \"sdp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.sdp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sec1-0.7.3\",\n sha256 = \"d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sec1/0.7.3/download\"],\n strip_prefix = \"sec1-0.7.3\",\n build_file = Label(\"@crates//crates:BUILD.sec1-0.7.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__self_cell-1.3.0\",\n sha256 = \"2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/self_cell/1.3.0/download\"],\n strip_prefix = \"self_cell-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.self_cell-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__semver-1.0.28\",\n sha256 = \"8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/semver/1.0.28/download\"],\n strip_prefix = \"semver-1.0.28\",\n build_file = Label(\"@crates//crates:BUILD.semver-1.0.28.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde-1.0.229\",\n sha256 = \"4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde/1.0.229/download\"],\n strip_prefix = \"serde-1.0.229\",\n build_file = Label(\"@crates//crates:BUILD.serde-1.0.229.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_core-1.0.229\",\n sha256 = \"67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_core/1.0.229/download\"],\n strip_prefix = \"serde_core-1.0.229\",\n build_file = Label(\"@crates//crates:BUILD.serde_core-1.0.229.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_derive-1.0.229\",\n sha256 = \"e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_derive/1.0.229/download\"],\n strip_prefix = \"serde_derive-1.0.229\",\n build_file = Label(\"@crates//crates:BUILD.serde_derive-1.0.229.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_json-1.0.151\",\n sha256 = \"c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_json/1.0.151/download\"],\n strip_prefix = \"serde_json-1.0.151\",\n build_file = Label(\"@crates//crates:BUILD.serde_json-1.0.151.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_repr-0.1.21\",\n sha256 = \"8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_repr/0.1.21/download\"],\n strip_prefix = \"serde_repr-0.1.21\",\n build_file = Label(\"@crates//crates:BUILD.serde_repr-0.1.21.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_spanned-1.1.1\",\n sha256 = \"6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_spanned/1.1.1/download\"],\n strip_prefix = \"serde_spanned-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.serde_spanned-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial2-0.2.37\",\n sha256 = \"9eb6ea5562eeaed6936b8b54e086aa0f88b9e5b1bef45beb038e2519fa1185b1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial2/0.2.37/download\"],\n strip_prefix = \"serial2-0.2.37\",\n build_file = Label(\"@crates//crates:BUILD.serial2-0.2.37.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sha1-0.10.7\",\n sha256 = \"a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sha1/0.10.7/download\"],\n strip_prefix = \"sha1-0.10.7\",\n build_file = Label(\"@crates//crates:BUILD.sha1-0.10.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sha2-0.10.9\",\n sha256 = \"a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sha2/0.10.9/download\"],\n strip_prefix = \"sha2-0.10.9\",\n build_file = Label(\"@crates//crates:BUILD.sha2-0.10.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sha3-0.10.9\",\n sha256 = \"77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sha3/0.10.9/download\"],\n strip_prefix = \"sha3-0.10.9\",\n build_file = Label(\"@crates//crates:BUILD.sha3-0.10.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shared_library-0.1.9\",\n sha256 = \"5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shared_library/0.1.9/download\"],\n strip_prefix = \"shared_library-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.shared_library-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shell-words-1.1.1\",\n sha256 = \"dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shell-words/1.1.1/download\"],\n strip_prefix = \"shell-words-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.shell-words-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shlex-1.3.0\",\n sha256 = \"0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shlex/1.3.0/download\"],\n strip_prefix = \"shlex-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.shlex-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shlex-2.0.1\",\n sha256 = \"f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shlex/2.0.1/download\"],\n strip_prefix = \"shlex-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.shlex-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__signal-hook-registry-1.4.8\",\n sha256 = \"c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/signal-hook-registry/1.4.8/download\"],\n strip_prefix = \"signal-hook-registry-1.4.8\",\n build_file = Label(\"@crates//crates:BUILD.signal-hook-registry-1.4.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__signature-2.2.0\",\n sha256 = \"77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/signature/2.2.0/download\"],\n strip_prefix = \"signature-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.signature-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__simd-adler32-0.3.10\",\n sha256 = \"3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/simd-adler32/0.3.10/download\"],\n strip_prefix = \"simd-adler32-0.3.10\",\n build_file = Label(\"@crates//crates:BUILD.simd-adler32-0.3.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__simdutf8-0.1.5\",\n sha256 = \"e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/simdutf8/0.1.5/download\"],\n strip_prefix = \"simdutf8-0.1.5\",\n build_file = Label(\"@crates//crates:BUILD.simdutf8-0.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__similar-2.7.0\",\n sha256 = \"bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/similar/2.7.0/download\"],\n strip_prefix = \"similar-2.7.0\",\n build_file = Label(\"@crates//crates:BUILD.similar-2.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__similar-3.1.1\",\n sha256 = \"e6505efef05804732ed8a3f2d4f279429eb485bd69d5b0cc6b19cc02005cda16\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/similar/3.1.1/download\"],\n strip_prefix = \"similar-3.1.1\",\n build_file = Label(\"@crates//crates:BUILD.similar-3.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__siphasher-1.0.3\",\n sha256 = \"8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/siphasher/1.0.3/download\"],\n strip_prefix = \"siphasher-1.0.3\",\n build_file = Label(\"@crates//crates:BUILD.siphasher-1.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__slab-0.4.12\",\n sha256 = \"0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/slab/0.4.12/download\"],\n strip_prefix = \"slab-0.4.12\",\n build_file = Label(\"@crates//crates:BUILD.slab-0.4.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sm3-0.5.0\",\n sha256 = \"da6a89ba31723d185fd7413b98c576a575f356d9b84729d8ecb6ead60000a5b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sm3/0.5.0/download\"],\n strip_prefix = \"sm3-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.sm3-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__smallvec-1.15.2\",\n sha256 = \"8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/smallvec/1.15.2/download\"],\n strip_prefix = \"smallvec-1.15.2\",\n build_file = Label(\"@crates//crates:BUILD.smallvec-1.15.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__smol_str-0.2.2\",\n sha256 = \"dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/smol_str/0.2.2/download\"],\n strip_prefix = \"smol_str-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.smol_str-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__socket2-0.5.10\",\n sha256 = \"e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/socket2/0.5.10/download\"],\n strip_prefix = \"socket2-0.5.10\",\n build_file = Label(\"@crates//crates:BUILD.socket2-0.5.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__socket2-0.6.5\",\n sha256 = \"c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/socket2/0.6.5/download\"],\n strip_prefix = \"socket2-0.6.5\",\n build_file = Label(\"@crates//crates:BUILD.socket2-0.6.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__spin-0.10.1\",\n sha256 = \"023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/spin/0.10.1/download\"],\n strip_prefix = \"spin-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.spin-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__spin-0.9.9\",\n sha256 = \"3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/spin/0.9.9/download\"],\n strip_prefix = \"spin-0.9.9\",\n build_file = Label(\"@crates//crates:BUILD.spin-0.9.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__spki-0.7.3\",\n sha256 = \"d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/spki/0.7.3/download\"],\n strip_prefix = \"spki-0.7.3\",\n build_file = Label(\"@crates//crates:BUILD.spki-0.7.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__stable_deref_trait-1.2.1\",\n sha256 = \"6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/stable_deref_trait/1.2.1/download\"],\n strip_prefix = \"stable_deref_trait-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.stable_deref_trait-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__str_stack-0.1.1\",\n sha256 = \"7f446288b699d66d0fd2e30d1cfe7869194312524b3b9252594868ed26ef056a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/str_stack/0.1.1/download\"],\n strip_prefix = \"str_stack-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.str_stack-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__streaming-iterator-0.1.9\",\n sha256 = \"2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/streaming-iterator/0.1.9/download\"],\n strip_prefix = \"streaming-iterator-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.streaming-iterator-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__string_cache-0.9.0\",\n sha256 = \"a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/string_cache/0.9.0/download\"],\n strip_prefix = \"string_cache-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.string_cache-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__string_cache_codegen-0.6.1\",\n sha256 = \"585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/string_cache_codegen/0.6.1/download\"],\n strip_prefix = \"string_cache_codegen-0.6.1\",\n build_file = Label(\"@crates//crates:BUILD.string_cache_codegen-0.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__strsim-0.11.1\",\n sha256 = \"7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/strsim/0.11.1/download\"],\n strip_prefix = \"strsim-0.11.1\",\n build_file = Label(\"@crates//crates:BUILD.strsim-0.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__strum-0.28.0\",\n sha256 = \"9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/strum/0.28.0/download\"],\n strip_prefix = \"strum-0.28.0\",\n build_file = Label(\"@crates//crates:BUILD.strum-0.28.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__strum_macros-0.28.0\",\n sha256 = \"ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/strum_macros/0.28.0/download\"],\n strip_prefix = \"strum_macros-0.28.0\",\n build_file = Label(\"@crates//crates:BUILD.strum_macros-0.28.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__stun-0.17.2\",\n sha256 = \"2e3b8d5ad1dd4c8cd0595440f26521a71dd593cb5873ee8e06b91510b7d97269\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/stun/0.17.2/download\"],\n strip_prefix = \"stun-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.stun-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__substring-1.4.5\",\n sha256 = \"42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/substring/1.4.5/download\"],\n strip_prefix = \"substring-1.4.5\",\n build_file = Label(\"@crates//crates:BUILD.substring-1.4.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__subtle-2.6.1\",\n sha256 = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/subtle/2.6.1/download\"],\n strip_prefix = \"subtle-2.6.1\",\n build_file = Label(\"@crates//crates:BUILD.subtle-2.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-2.0.119\",\n sha256 = \"872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/2.0.119/download\"],\n strip_prefix = \"syn-2.0.119\",\n build_file = Label(\"@crates//crates:BUILD.syn-2.0.119.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-3.0.3\",\n sha256 = \"53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/3.0.3/download\"],\n strip_prefix = \"syn-3.0.3\",\n build_file = Label(\"@crates//crates:BUILD.syn-3.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__synstructure-0.13.2\",\n sha256 = \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/synstructure/0.13.2/download\"],\n strip_prefix = \"synstructure-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.synstructure-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syntect-5.3.0\",\n sha256 = \"656b45c05d95a5704399aeef6bd0ddec7b2b3531b7c9e900abbf7c4d2190c925\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syntect/5.3.0/download\"],\n strip_prefix = \"syntect-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.syntect-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__system-deps-7.0.8\",\n sha256 = \"396a35feb67335377e0251fcbc1092fc85c484bd4e3a7a54319399da127796e7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/system-deps/7.0.8/download\"],\n strip_prefix = \"system-deps-7.0.8\",\n build_file = Label(\"@crates//crates:BUILD.system-deps-7.0.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tap-1.0.1\",\n sha256 = \"55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tap/1.0.1/download\"],\n strip_prefix = \"tap-1.0.1\",\n build_file = Label(\"@crates//crates:BUILD.tap-1.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__target-lexicon-0.13.5\",\n sha256 = \"adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/target-lexicon/0.13.5/download\"],\n strip_prefix = \"target-lexicon-0.13.5\",\n build_file = Label(\"@crates//crates:BUILD.target-lexicon-0.13.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tempfile-3.27.0\",\n sha256 = \"32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tempfile/3.27.0/download\"],\n strip_prefix = \"tempfile-3.27.0\",\n build_file = Label(\"@crates//crates:BUILD.tempfile-3.27.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tendril-0.5.1\",\n sha256 = \"5fed54709c5b3a53d09bb1c113ea4f5ceafd1e772ddcb0030a82e1d56c087b08\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tendril/0.5.1/download\"],\n strip_prefix = \"tendril-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.tendril-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__termcolor-1.4.1\",\n sha256 = \"06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/termcolor/1.4.1/download\"],\n strip_prefix = \"termcolor-1.4.1\",\n build_file = Label(\"@crates//crates:BUILD.termcolor-1.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__terminal_size-0.4.4\",\n sha256 = \"230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/terminal_size/0.4.4/download\"],\n strip_prefix = \"terminal_size-0.4.4\",\n build_file = Label(\"@crates//crates:BUILD.terminal_size-0.4.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__terminfo-0.9.0\",\n sha256 = \"d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/terminfo/0.9.0/download\"],\n strip_prefix = \"terminfo-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.terminfo-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-1.0.69\",\n sha256 = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror/1.0.69/download\"],\n strip_prefix = \"thiserror-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-2.0.19\",\n sha256 = \"09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror/2.0.19/download\"],\n strip_prefix = \"thiserror-2.0.19\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-2.0.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-impl-1.0.69\",\n sha256 = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror-impl/1.0.69/download\"],\n strip_prefix = \"thiserror-impl-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-impl-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-impl-2.0.19\",\n sha256 = \"43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror-impl/2.0.19/download\"],\n strip_prefix = \"thiserror-impl-2.0.19\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-impl-2.0.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tiff-0.11.3\",\n sha256 = \"b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tiff/0.11.3/download\"],\n strip_prefix = \"tiff-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.tiff-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tiktoken-rs-0.11.0\",\n sha256 = \"fac4a168cfc1d8ed65bf17a6ee0843ad9a68f863c63c0fb2fa7eab67838782ee\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tiktoken-rs/0.11.0/download\"],\n strip_prefix = \"tiktoken-rs-0.11.0\",\n build_file = Label(\"@crates//crates:BUILD.tiktoken-rs-0.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__time-0.3.54\",\n sha256 = \"3e1d5e639ff6bab73cb6885cc7e7b1de96c3f32c68ec55f3952614bec1092244\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/time/0.3.54/download\"],\n strip_prefix = \"time-0.3.54\",\n build_file = Label(\"@crates//crates:BUILD.time-0.3.54.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__time-core-0.1.9\",\n sha256 = \"9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/time-core/0.1.9/download\"],\n strip_prefix = \"time-core-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.time-core-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__time-macros-0.2.32\",\n sha256 = \"7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/time-macros/0.2.32/download\"],\n strip_prefix = \"time-macros-0.2.32\",\n build_file = Label(\"@crates//crates:BUILD.time-macros-0.2.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tiny-keccak-2.0.2\",\n sha256 = \"2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tiny-keccak/2.0.2/download\"],\n strip_prefix = \"tiny-keccak-2.0.2\",\n build_file = Label(\"@crates//crates:BUILD.tiny-keccak-2.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinystr-0.8.3\",\n sha256 = \"c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinystr/0.8.3/download\"],\n strip_prefix = \"tinystr-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.tinystr-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinyvec-1.12.0\",\n sha256 = \"bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinyvec/1.12.0/download\"],\n strip_prefix = \"tinyvec-1.12.0\",\n build_file = Label(\"@crates//crates:BUILD.tinyvec-1.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinyvec_macros-0.1.1\",\n sha256 = \"1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinyvec_macros/0.1.1/download\"],\n strip_prefix = \"tinyvec_macros-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.tinyvec_macros-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tokio-1.53.1\",\n sha256 = \"202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tokio/1.53.1/download\"],\n strip_prefix = \"tokio-1.53.1\",\n build_file = Label(\"@crates//crates:BUILD.tokio-1.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tokio-macros-2.7.1\",\n sha256 = \"6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tokio-macros/2.7.1/download\"],\n strip_prefix = \"tokio-macros-2.7.1\",\n build_file = Label(\"@crates//crates:BUILD.tokio-macros-2.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tokio-util-0.7.19\",\n sha256 = \"494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tokio-util/0.7.19/download\"],\n strip_prefix = \"tokio-util-0.7.19\",\n build_file = Label(\"@crates//crates:BUILD.tokio-util-0.7.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml-1.1.3-spec-1.1.0\",\n sha256 = \"53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml/1.1.3+spec-1.1.0/download\"],\n strip_prefix = \"toml-1.1.3+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml-1.1.3+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_datetime-1.1.1-spec-1.1.0\",\n sha256 = \"3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_datetime/1.1.1+spec-1.1.0/download\"],\n strip_prefix = \"toml_datetime-1.1.1+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml_datetime-1.1.1+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_edit-0.25.13-spec-1.1.0\",\n sha256 = \"6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_edit/0.25.13+spec-1.1.0/download\"],\n strip_prefix = \"toml_edit-0.25.13+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml_edit-0.25.13+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_parser-1.1.3-spec-1.1.0\",\n sha256 = \"1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_parser/1.1.3+spec-1.1.0/download\"],\n strip_prefix = \"toml_parser-1.1.3+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml_parser-1.1.3+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_writer-1.1.2-spec-1.1.0\",\n sha256 = \"7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_writer/1.1.2+spec-1.1.0/download\"],\n strip_prefix = \"toml_writer-1.1.2+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml_writer-1.1.2+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tracing-0.1.44\",\n sha256 = \"63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tracing/0.1.44/download\"],\n strip_prefix = \"tracing-0.1.44\",\n build_file = Label(\"@crates//crates:BUILD.tracing-0.1.44.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tracing-attributes-0.1.31\",\n sha256 = \"7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tracing-attributes/0.1.31/download\"],\n strip_prefix = \"tracing-attributes-0.1.31\",\n build_file = Label(\"@crates//crates:BUILD.tracing-attributes-0.1.31.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tracing-core-0.1.36\",\n sha256 = \"db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tracing-core/0.1.36/download\"],\n strip_prefix = \"tracing-core-0.1.36\",\n build_file = Label(\"@crates//crates:BUILD.tracing-core-0.1.36.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-0.25.10\",\n sha256 = \"78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter/0.25.10/download\"],\n strip_prefix = \"tree-sitter-0.25.10\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-0.25.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-astro-next-0.1.1\",\n sha256 = \"794a4a59fc2d88e49b4bc41fef9522d77184a36f4e68bbaf545cd1eb2364c46e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-astro-next/0.1.1/download\"],\n strip_prefix = \"tree-sitter-astro-next-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-astro-next-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-bash-0.25.1\",\n sha256 = \"9e5ec769279cc91b561d3df0d8a5deb26b0ad40d183127f409494d6d8fc53062\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-bash/0.25.1/download\"],\n strip_prefix = \"tree-sitter-bash-0.25.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-bash-0.25.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-c-0.24.2\",\n sha256 = \"a9b2eb57a55fed6b00812912e730b7a275cf4fe98bfd6a5d76263d4438371728\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-c/0.24.2/download\"],\n strip_prefix = \"tree-sitter-c-0.24.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-c-0.24.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-c-sharp-0.23.5\",\n sha256 = \"c1aac67f1ad71de1d6d39708d34811081c26dfa495658de6c14c34200849357c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-c-sharp/0.23.5/download\"],\n strip_prefix = \"tree-sitter-c-sharp-0.23.5\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-c-sharp-0.23.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-clojure-0.1.0\",\n sha256 = \"4004884cc509449a1d78fa3e1f02b4e953d0a8065984445304795e72e885338c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-clojure/0.1.0/download\"],\n strip_prefix = \"tree-sitter-clojure-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-clojure-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-cmake-0.7.4\",\n sha256 = \"164e0c4f4236ec5ceff14824a5528615cf462e100467e49826442ff57d327061\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-cmake/0.7.4/download\"],\n strip_prefix = \"tree-sitter-cmake-0.7.4\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-cmake-0.7.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-cpp-0.23.4\",\n sha256 = \"df2196ea9d47b4ab4a31b9297eaa5a5d19a0b121dceb9f118f6790ad0ab94743\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-cpp/0.23.4/download\"],\n strip_prefix = \"tree-sitter-cpp-0.23.4\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-cpp-0.23.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-css-0.25.0\",\n sha256 = \"a5cbc5e18f29a2c6d6435891f42569525cf95435a3e01c2f1947abcde178686f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-css/0.25.0/download\"],\n strip_prefix = \"tree-sitter-css-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-css-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-dart-0.2.0\",\n sha256 = \"325dd1e24ee9ee21111e9c43680ae7d6010aaa9f282b048a99b9c7163c1cf553\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-dart/0.2.0/download\"],\n strip_prefix = \"tree-sitter-dart-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-dart-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-diff-0.1.0\",\n sha256 = \"dfe1e5ca280a65dfe5ba4205c1bcc84edf486464fed315db53dee6da9a335889\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-diff/0.1.0/download\"],\n strip_prefix = \"tree-sitter-diff-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-diff-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-dockerfile-updated-0.2.0\",\n sha256 = \"5e61eb704364be179ab9be89e2891c8e77c0041eca5891a5c04164a21f6df7a0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-dockerfile-updated/0.2.0/download\"],\n strip_prefix = \"tree-sitter-dockerfile-updated-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-dockerfile-updated-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-elisp-1.6.1\",\n sha256 = \"5e2e9a6ab3cebf24ca41cdc1f985549b9b33f7ef25c19ac7d18e53a4ee24da09\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-elisp/1.6.1/download\"],\n strip_prefix = \"tree-sitter-elisp-1.6.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-elisp-1.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-elixir-0.3.5\",\n sha256 = \"66dd064a762ed95bfc29857fa3cb7403bb1e5cb88112de0f6341b7e47284ba40\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-elixir/0.3.5/download\"],\n strip_prefix = \"tree-sitter-elixir-0.3.5\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-elixir-0.3.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-erlang-0.16.0\",\n sha256 = \"ceb442e728225d601db0661f60d64e166bd9b9a55c587f71d4e4f27378717cce\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-erlang/0.16.0/download\"],\n strip_prefix = \"tree-sitter-erlang-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-erlang-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-fortran-0.6.0\",\n sha256 = \"ea5fea41363a9b59666001dc26c4b356d4e164da27c6ce31145e00aba6bf9b16\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-fortran/0.6.0/download\"],\n strip_prefix = \"tree-sitter-fortran-0.6.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-fortran-0.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-go-0.25.0\",\n sha256 = \"c8560a4d2f835cc0d4d2c2e03cbd0dde2f6114b43bc491164238d333e28b16ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-go/0.25.0/download\"],\n strip_prefix = \"tree-sitter-go-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-go-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-graphql-0.1.0\",\n sha256 = \"efedc4cac157161cc23a0adc4553a2cedc908e1cd754b6cd033a919bb81ce5d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-graphql/0.1.0/download\"],\n strip_prefix = \"tree-sitter-graphql-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-graphql-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-haskell-0.23.1\",\n sha256 = \"977c51e504548cba13fc27cb5a2edab2124cf6716a1934915d07ab99523b05a4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-haskell/0.23.1/download\"],\n strip_prefix = \"tree-sitter-haskell-0.23.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-haskell-0.23.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-hcl-1.1.0\",\n sha256 = \"5a7b2cc3d7121553b84309fab9d11b3ff3d420403eef9ae50f9fd1cd9d9cf012\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-hcl/1.1.0/download\"],\n strip_prefix = \"tree-sitter-hcl-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-hcl-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-html-0.23.2\",\n sha256 = \"261b708e5d92061ede329babaaa427b819329a9d427a1d710abb0f67bbef63ee\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-html/0.23.2/download\"],\n strip_prefix = \"tree-sitter-html-0.23.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-html-0.23.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-ini-1.4.0\",\n sha256 = \"387f79682cd53b7c0a5777c96e601a02b9965a787984ef86dbb8952bdab2d62f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-ini/1.4.0/download\"],\n strip_prefix = \"tree-sitter-ini-1.4.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-ini-1.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-java-0.23.5\",\n sha256 = \"0aa6cbcdc8c679b214e616fd3300da67da0e492e066df01bcf5a5921a71e90d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-java/0.23.5/download\"],\n strip_prefix = \"tree-sitter-java-0.23.5\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-java-0.23.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-javascript-0.25.0\",\n sha256 = \"68204f2abc0627a90bdf06e605f5c470aa26fdcb2081ea553a04bdad756693f5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-javascript/0.25.0/download\"],\n strip_prefix = \"tree-sitter-javascript-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-javascript-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-json-0.24.8\",\n sha256 = \"4d727acca406c0020cffc6cf35516764f36c8e3dc4408e5ebe2cb35a947ec471\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-json/0.24.8/download\"],\n strip_prefix = \"tree-sitter-json-0.24.8\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-json-0.24.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-julia-0.23.1\",\n sha256 = \"4144731a178812ee867619b1e98b3b91e54c1652304b26e5ebe3175b701de323\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-julia/0.23.1/download\"],\n strip_prefix = \"tree-sitter-julia-0.23.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-julia-0.23.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-just-0.2.0\",\n sha256 = \"bd46794f2c270f43d73b2f2c8c256992471f3493c903604da0886df984771920\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-just/0.2.0/download\"],\n strip_prefix = \"tree-sitter-just-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-just-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-kotlin-sg-0.4.1\",\n sha256 = \"c06ec43ae3c12165d4ac08afe4e1f5fc6757ffe274fa7bd5af9007ef11ba4319\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-kotlin-sg/0.4.1/download\"],\n strip_prefix = \"tree-sitter-kotlin-sg-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-kotlin-sg-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-language-0.1.7\",\n sha256 = \"009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-language/0.1.7/download\"],\n strip_prefix = \"tree-sitter-language-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-language-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-lua-0.5.0\",\n sha256 = \"8daaf5f4235188a58603c39760d5fa5d4b920d36a299c934adddae757f32a10c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-lua/0.5.0/download\"],\n strip_prefix = \"tree-sitter-lua-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-lua-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-make-1.1.1\",\n sha256 = \"c5998dc7cbcbdab19fae8aefef982bf2d6544513d8d2e69cc44aec4c63810104\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-make/1.1.1/download\"],\n strip_prefix = \"tree-sitter-make-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-make-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-md-0.5.3\",\n sha256 = \"2efd398be546456c814598ee56c0f51769a77241511b4a58077815d120afa882\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-md/0.5.3/download\"],\n strip_prefix = \"tree-sitter-md-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-md-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-nix-0.3.0\",\n sha256 = \"4952a9733f3a98f6683a0ccd1035d84ab7a52f7e84eeed58548d86765ad92de3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-nix/0.3.0/download\"],\n strip_prefix = \"tree-sitter-nix-0.3.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-nix-0.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-objc-3.0.2\",\n sha256 = \"9ca8bb556423fc176f0535e79d525f783a6684d3c9da81bf9d905303c129e1d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-objc/3.0.2/download\"],\n strip_prefix = \"tree-sitter-objc-3.0.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-objc-3.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-ocaml-0.24.2\",\n sha256 = \"7d19db582b3855f56b5f9ec484170fbfb9ee60b938ec7720d76d2ee788e8b640\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-ocaml/0.24.2/download\"],\n strip_prefix = \"tree-sitter-ocaml-0.24.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-ocaml-0.24.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-odin-1.3.0\",\n sha256 = \"24db210fe9ba2237c71c5030d7b146c7025420ba72dd8013d13cd822c3a8d77a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-odin/1.3.0/download\"],\n strip_prefix = \"tree-sitter-odin-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-odin-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-php-0.24.2\",\n sha256 = \"0d8c17c3ab69052c5eeaa7ff5cd972dd1bc25d1b97ee779fec391ad3b5df5592\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-php/0.24.2/download\"],\n strip_prefix = \"tree-sitter-php-0.24.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-php-0.24.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-powershell-0.26.4\",\n sha256 = \"3faf304d44b9ddd4a7d97804bb8de7daf564336dd5a526dc6de5b39238243022\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-powershell/0.26.4/download\"],\n strip_prefix = \"tree-sitter-powershell-0.26.4\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-powershell-0.26.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-proto-0.4.0\",\n sha256 = \"2e410ccb5fa3cbd6bf7b8e512ecf7ad9d5254395b822bfe9f751b50fa978f31c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-proto/0.4.0/download\"],\n strip_prefix = \"tree-sitter-proto-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-proto-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-python-0.25.0\",\n sha256 = \"6bf85fd39652e740bf60f46f4cda9492c3a9ad75880575bf14960f775cb74a1c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-python/0.25.0/download\"],\n strip_prefix = \"tree-sitter-python-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-python-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-r-1.3.0\",\n sha256 = \"ffc9954ec870dcad6cffdd302b405306c68cf031ed79a78cd9746f6740d9fe20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-r/1.3.0/download\"],\n strip_prefix = \"tree-sitter-r-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-r-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-regex-0.25.0\",\n sha256 = \"bd8a59be9f0ac131fd8f062eaaba14882b2fa5a6a7882a20134cb1d60df2e625\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-regex/0.25.0/download\"],\n strip_prefix = \"tree-sitter-regex-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-regex-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-ruby-0.23.1\",\n sha256 = \"be0484ea4ef6bb9c575b4fdabde7e31340a8d2dbc7d52b321ac83da703249f95\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-ruby/0.23.1/download\"],\n strip_prefix = \"tree-sitter-ruby-0.23.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-ruby-0.23.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-rust-0.24.2\",\n sha256 = \"439e577dbe07423ec2582ac62c7531120dbfccfa6e5f92406f93dd271a120e45\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-rust/0.24.2/download\"],\n strip_prefix = \"tree-sitter-rust-0.24.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-rust-0.24.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-scala-0.26.0\",\n sha256 = \"de5a4a7ff23a55474ce6a741d52aaeca7a82fe9421bb982b86e98c6ac8629397\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-scala/0.26.0/download\"],\n strip_prefix = \"tree-sitter-scala-0.26.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-scala-0.26.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-sequel-0.3.11\",\n sha256 = \"9d198ad3c319c02e43c21efa1ec796b837afcb96ffaef1a40c1978fbdcec7d17\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-sequel/0.3.11/download\"],\n strip_prefix = \"tree-sitter-sequel-0.3.11\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-sequel-0.3.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-solidity-1.2.13\",\n sha256 = \"4eacf8875b70879f0cb670c60b233ad0b68752d9e1474e6c3ef168eea8a90b25\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-solidity/1.2.13/download\"],\n strip_prefix = \"tree-sitter-solidity-1.2.13\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-solidity-1.2.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-starlark-1.3.0\",\n sha256 = \"8934f282d085cc4b9ee28aa688aa3fbe8aa3766201c2a6252f411d45b4c3a721\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-starlark/1.3.0/download\"],\n strip_prefix = \"tree-sitter-starlark-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-starlark-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-svelte-next-0.1.1\",\n sha256 = \"56f88190d0743e897c3e148a7e241aba0a8844b8afe816943851426e3f7b9753\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-svelte-next/0.1.1/download\"],\n strip_prefix = \"tree-sitter-svelte-next-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-svelte-next-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-swift-0.7.3\",\n sha256 = \"fe36052155b9dd69ca82b3b8f1b4ccfb2d867125ac1a4db1dd7331829242668c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-swift/0.7.3/download\"],\n strip_prefix = \"tree-sitter-swift-0.7.3\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-swift-0.7.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-tlaplus-1.5.0\",\n sha256 = \"ddaacc0337bfee38f233a91a704dc36b887a0c385348163f65344d64b73f79e1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-tlaplus/1.5.0/download\"],\n strip_prefix = \"tree-sitter-tlaplus-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-tlaplus-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-toml-ng-0.7.0\",\n sha256 = \"e9adc2c898ae49730e857d75be403da3f92bb81d8e37a2f918a08dd10de5ebb1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-toml-ng/0.7.0/download\"],\n strip_prefix = \"tree-sitter-toml-ng-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-toml-ng-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-typescript-0.23.2\",\n sha256 = \"6c5f76ed8d947a75cc446d5fccd8b602ebf0cde64ccf2ffa434d873d7a575eff\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-typescript/0.23.2/download\"],\n strip_prefix = \"tree-sitter-typescript-0.23.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-typescript-0.23.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-verilog-1.0.3\",\n sha256 = \"d4e7e0360395852f1f6ff5b7b82c72dc6557d181073188df1d60ec469ea69c66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-verilog/1.0.3/download\"],\n strip_prefix = \"tree-sitter-verilog-1.0.3\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-verilog-1.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-vue-next-0.1.0\",\n sha256 = \"e9ac89acaa8165aaabfa8ae9683aa423b0d2bf42c815dae5ca031a36a75525f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-vue-next/0.1.0/download\"],\n strip_prefix = \"tree-sitter-vue-next-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-vue-next-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-xml-0.7.0\",\n sha256 = \"e670041f591d994f54d597ddcd8f4ebc930e282c4c76a42268743b71f0c8b6b3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-xml/0.7.0/download\"],\n strip_prefix = \"tree-sitter-xml-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-xml-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-yaml-0.7.2\",\n sha256 = \"53c223db85f05e34794f065454843b0668ebc15d240ada63e2b5939f43ce7c97\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-yaml/0.7.2/download\"],\n strip_prefix = \"tree-sitter-yaml-0.7.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-yaml-0.7.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-zig-1.1.2\",\n sha256 = \"ab11fc124851b0db4dd5e55983bbd9631192e93238389dcd44521715e5d53e28\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-zig/1.1.2/download\"],\n strip_prefix = \"tree-sitter-zig-1.1.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-zig-1.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree_magic_mini-3.2.2\",\n sha256 = \"b8765b90061cba6c22b5831f675da109ae5561588290f9fa2317adab2714d5a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree_magic_mini/3.2.2/download\"],\n strip_prefix = \"tree_magic_mini-3.2.2\",\n build_file = Label(\"@crates//crates:BUILD.tree_magic_mini-3.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__triomphe-0.1.16\",\n sha256 = \"b40688ea6389c8171614b25491f71d4a27946e0c7ce2da1c6de27e25abf1a0ae\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/triomphe/0.1.16/download\"],\n strip_prefix = \"triomphe-0.1.16\",\n build_file = Label(\"@crates//crates:BUILD.triomphe-0.1.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ttf-parser-0.21.1\",\n sha256 = \"2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ttf-parser/0.21.1/download\"],\n strip_prefix = \"ttf-parser-0.21.1\",\n build_file = Label(\"@crates//crates:BUILD.ttf-parser-0.21.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__turn-0.17.2\",\n sha256 = \"d99249a493335eb44c4d7943a8751b22561a82c9903d8eb2d29780b3927880a7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/turn/0.17.2/download\"],\n strip_prefix = \"turn-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.turn-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__type-map-0.5.1\",\n sha256 = \"cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/type-map/0.5.1/download\"],\n strip_prefix = \"type-map-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.type-map-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__typed-arena-2.0.2\",\n sha256 = \"6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/typed-arena/2.0.2/download\"],\n strip_prefix = \"typed-arena-2.0.2\",\n build_file = Label(\"@crates//crates:BUILD.typed-arena-2.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__typenum-1.20.1\",\n sha256 = \"b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/typenum/1.20.1/download\"],\n strip_prefix = \"typenum-1.20.1\",\n build_file = Label(\"@crates//crates:BUILD.typenum-1.20.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ucd-trie-0.1.7\",\n sha256 = \"2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ucd-trie/0.1.7/download\"],\n strip_prefix = \"ucd-trie-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.ucd-trie-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uds_windows-1.2.1\",\n sha256 = \"f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uds_windows/1.2.1/download\"],\n strip_prefix = \"uds_windows-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.uds_windows-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unic-langid-0.9.6\",\n sha256 = \"a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unic-langid/0.9.6/download\"],\n strip_prefix = \"unic-langid-0.9.6\",\n build_file = Label(\"@crates//crates:BUILD.unic-langid-0.9.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unic-langid-impl-0.9.6\",\n sha256 = \"dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unic-langid-impl/0.9.6/download\"],\n strip_prefix = \"unic-langid-impl-0.9.6\",\n build_file = Label(\"@crates//crates:BUILD.unic-langid-impl-0.9.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicase-2.9.0\",\n sha256 = \"dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicase/2.9.0/download\"],\n strip_prefix = \"unicase-2.9.0\",\n build_file = Label(\"@crates//crates:BUILD.unicase-2.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-ident-1.0.24\",\n sha256 = \"e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-ident/1.0.24/download\"],\n strip_prefix = \"unicode-ident-1.0.24\",\n build_file = Label(\"@crates//crates:BUILD.unicode-ident-1.0.24.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-segmentation-1.13.3\",\n sha256 = \"c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-segmentation/1.13.3/download\"],\n strip_prefix = \"unicode-segmentation-1.13.3\",\n build_file = Label(\"@crates//crates:BUILD.unicode-segmentation-1.13.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-width-0.1.14\",\n sha256 = \"7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-width/0.1.14/download\"],\n strip_prefix = \"unicode-width-0.1.14\",\n build_file = Label(\"@crates//crates:BUILD.unicode-width-0.1.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-width-0.2.2\",\n sha256 = \"b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-width/0.2.2/download\"],\n strip_prefix = \"unicode-width-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.unicode-width-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unit-prefix-0.5.2\",\n sha256 = \"81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unit-prefix/0.5.2/download\"],\n strip_prefix = \"unit-prefix-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.unit-prefix-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__universal-hash-0.5.1\",\n sha256 = \"fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/universal-hash/0.5.1/download\"],\n strip_prefix = \"universal-hash-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.universal-hash-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__untrusted-0.9.0\",\n sha256 = \"8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/untrusted/0.9.0/download\"],\n strip_prefix = \"untrusted-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.untrusted-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__url-2.5.8\",\n sha256 = \"ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/url/2.5.8/download\"],\n strip_prefix = \"url-2.5.8\",\n build_file = Label(\"@crates//crates:BUILD.url-2.5.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__urlencoding-2.1.3\",\n sha256 = \"daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/urlencoding/2.1.3/download\"],\n strip_prefix = \"urlencoding-2.1.3\",\n build_file = Label(\"@crates//crates:BUILD.urlencoding-2.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf16_iter-1.0.5\",\n sha256 = \"c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf16_iter/1.0.5/download\"],\n strip_prefix = \"utf16_iter-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.utf16_iter-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8-chars-3.0.7\",\n sha256 = \"92498c67ea3511b37eccff13b573ed871faf0ce9c4056ab032bd01a681f445a0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8-chars/3.0.7/download\"],\n strip_prefix = \"utf8-chars-3.0.7\",\n build_file = Label(\"@crates//crates:BUILD.utf8-chars-3.0.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8_iter-1.0.4\",\n sha256 = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8_iter/1.0.4/download\"],\n strip_prefix = \"utf8_iter-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.utf8_iter-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8parse-0.2.2\",\n sha256 = \"06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8parse/0.2.2/download\"],\n strip_prefix = \"utf8parse-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.utf8parse-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore-0.0.30\",\n sha256 = \"71f4e82877d06de779c611a3d54720f56f1e68b228fb30a5b6c66ef07e68263d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore/0.0.30/download\"],\n strip_prefix = \"uucore-0.0.30\",\n build_file = Label(\"@crates//crates:BUILD.uucore-0.0.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore-0.8.0\",\n sha256 = \"07d779636d827cde4100f0e65ff3fd23b0b1f1195055475c6e6813d425f30c8e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore/0.8.0/download\"],\n strip_prefix = \"uucore-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.uucore-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore-0.9.0\",\n sha256 = \"069b34217c27f611e1589f540f58118dbf226a9e407d38ab472052ff075a1dc2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore/0.9.0/download\"],\n strip_prefix = \"uucore-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.uucore-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore_procs-0.0.30\",\n sha256 = \"c72435859e812e602e225dea48d014abb6b1072220a8d44f2fe0565553b1f7e4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore_procs/0.0.30/download\"],\n strip_prefix = \"uucore_procs-0.0.30\",\n build_file = Label(\"@crates//crates:BUILD.uucore_procs-0.0.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore_procs-0.8.0\",\n sha256 = \"da865e8a648b260dbd89fca76d0801995877ab27a4e259b6dec30ba9743b86ab\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore_procs/0.8.0/download\"],\n strip_prefix = \"uucore_procs-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.uucore_procs-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore_procs-0.9.0\",\n sha256 = \"34337da211e7abfff7189b794afb3b5018fe356fb36474b73645458fc1201350\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore_procs/0.9.0/download\"],\n strip_prefix = \"uucore_procs-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.uucore_procs-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uuhelp_parser-0.0.30\",\n sha256 = \"0bb6d972f580f8223cb7052d8580aea2b7061e368cf476de32ea9457b19459ed\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uuhelp_parser/0.0.30/download\"],\n strip_prefix = \"uuhelp_parser-0.0.30\",\n build_file = Label(\"@crates//crates:BUILD.uuhelp_parser-0.0.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uuid-1.24.0\",\n sha256 = \"bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uuid/1.24.0/download\"],\n strip_prefix = \"uuid-1.24.0\",\n build_file = Label(\"@crates//crates:BUILD.uuid-1.24.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uutils_term_grid-0.8.0\",\n sha256 = \"382d49b39de4a115f203305057741126b09a615892d773a2d419a2b816e30e39\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uutils_term_grid/0.8.0/download\"],\n strip_prefix = \"uutils_term_grid-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.uutils_term_grid-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uzers-0.12.2\",\n sha256 = \"0b8275fb1afee25b4111d2dc8b5c505dbbc4afd0b990cb96deb2d88bff8be18d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uzers/0.12.2/download\"],\n strip_prefix = \"uzers-0.12.2\",\n build_file = Label(\"@crates//crates:BUILD.uzers-0.12.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__version-compare-0.2.1\",\n sha256 = \"03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/version-compare/0.2.1/download\"],\n strip_prefix = \"version-compare-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.version-compare-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__version_check-0.9.5\",\n sha256 = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/version_check/0.9.5/download\"],\n strip_prefix = \"version_check-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.version_check-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__vsimd-0.8.0\",\n sha256 = \"5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/vsimd/0.8.0/download\"],\n strip_prefix = \"vsimd-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.vsimd-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__waitgroup-0.1.2\",\n sha256 = \"d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/waitgroup/0.1.2/download\"],\n strip_prefix = \"waitgroup-0.1.2\",\n build_file = Label(\"@crates//crates:BUILD.waitgroup-0.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__walkdir-2.5.0\",\n sha256 = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/walkdir/2.5.0/download\"],\n strip_prefix = \"walkdir-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.walkdir-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasi-0.11.1-wasi-snapshot-preview1\",\n sha256 = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasi/0.11.1+wasi-snapshot-preview1/download\"],\n strip_prefix = \"wasi-0.11.1+wasi-snapshot-preview1\",\n build_file = Label(\"@crates//crates:BUILD.wasi-0.11.1+wasi-snapshot-preview1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasi-0.14.7-wasi-0.2.4\",\n sha256 = \"883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasi/0.14.7+wasi-0.2.4/download\"],\n strip_prefix = \"wasi-0.14.7+wasi-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.wasi-0.14.7+wasi-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasip2-1.0.4-wasi-0.2.12\",\n sha256 = \"b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasip2/1.0.4+wasi-0.2.12/download\"],\n strip_prefix = \"wasip2-1.0.4+wasi-0.2.12\",\n build_file = Label(\"@crates//crates:BUILD.wasip2-1.0.4+wasi-0.2.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasite-1.0.2\",\n sha256 = \"66fe902b4a6b8028a753d5424909b764ccf79b7a209eac9bf97e59cda9f71a42\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasite/1.0.2/download\"],\n strip_prefix = \"wasite-1.0.2\",\n build_file = Label(\"@crates//crates:BUILD.wasite-1.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasm-bindgen-0.2.126\",\n sha256 = \"4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasm-bindgen/0.2.126/download\"],\n strip_prefix = \"wasm-bindgen-0.2.126\",\n build_file = Label(\"@crates//crates:BUILD.wasm-bindgen-0.2.126.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasm-bindgen-macro-0.2.126\",\n sha256 = \"167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasm-bindgen-macro/0.2.126/download\"],\n strip_prefix = \"wasm-bindgen-macro-0.2.126\",\n build_file = Label(\"@crates//crates:BUILD.wasm-bindgen-macro-0.2.126.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasm-bindgen-macro-support-0.2.126\",\n sha256 = \"f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasm-bindgen-macro-support/0.2.126/download\"],\n strip_prefix = \"wasm-bindgen-macro-support-0.2.126\",\n build_file = Label(\"@crates//crates:BUILD.wasm-bindgen-macro-support-0.2.126.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasm-bindgen-shared-0.2.126\",\n sha256 = \"dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasm-bindgen-shared/0.2.126/download\"],\n strip_prefix = \"wasm-bindgen-shared-0.2.126\",\n build_file = Label(\"@crates//crates:BUILD.wasm-bindgen-shared-0.2.126.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-backend-0.3.16\",\n sha256 = \"016ccf01d1c58b6f8999612813e17c9b2390f7d70671428869913310f83f54b8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-backend/0.3.16/download\"],\n strip_prefix = \"wayland-backend-0.3.16\",\n build_file = Label(\"@crates//crates:BUILD.wayland-backend-0.3.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-client-0.31.15\",\n sha256 = \"e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-client/0.31.15/download\"],\n strip_prefix = \"wayland-client-0.31.15\",\n build_file = Label(\"@crates//crates:BUILD.wayland-client-0.31.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-protocols-0.32.13\",\n sha256 = \"23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-protocols/0.32.13/download\"],\n strip_prefix = \"wayland-protocols-0.32.13\",\n build_file = Label(\"@crates//crates:BUILD.wayland-protocols-0.32.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-protocols-wlr-0.3.12\",\n sha256 = \"eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-protocols-wlr/0.3.12/download\"],\n strip_prefix = \"wayland-protocols-wlr-0.3.12\",\n build_file = Label(\"@crates//crates:BUILD.wayland-protocols-wlr-0.3.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-scanner-0.31.11\",\n sha256 = \"338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-scanner/0.31.11/download\"],\n strip_prefix = \"wayland-scanner-0.31.11\",\n build_file = Label(\"@crates//crates:BUILD.wayland-scanner-0.31.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-server-0.31.14\",\n sha256 = \"0dde9c29be0f723a573977de51ee455bf3dfa03652730a74f9dd3b337e374d75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-server/0.31.14/download\"],\n strip_prefix = \"wayland-server-0.31.14\",\n build_file = Label(\"@crates//crates:BUILD.wayland-server-0.31.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-sys-0.31.11\",\n sha256 = \"d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-sys/0.31.11/download\"],\n strip_prefix = \"wayland-sys-0.31.11\",\n build_file = Label(\"@crates//crates:BUILD.wayland-sys-0.31.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__web-sys-0.3.103\",\n sha256 = \"8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/web-sys/0.3.103/download\"],\n strip_prefix = \"web-sys-0.3.103\",\n build_file = Label(\"@crates//crates:BUILD.web-sys-0.3.103.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__web-time-1.1.0\",\n sha256 = \"5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/web-time/1.1.0/download\"],\n strip_prefix = \"web-time-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.web-time-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__web_atoms-0.2.5\",\n sha256 = \"075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/web_atoms/0.2.5/download\"],\n strip_prefix = \"web_atoms-0.2.5\",\n build_file = Label(\"@crates//crates:BUILD.web_atoms-0.2.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-0.17.2\",\n sha256 = \"baaacdf9d96224d7b6e2872ba065578f38775f7634367e3ac2cc87c7271da433\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc/0.17.2/download\"],\n strip_prefix = \"webrtc-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-data-0.17.2\",\n sha256 = \"bd470286275809f2fcfcdb1e73ef5f1500be82eff7fe98150ce81b20aad5a2a4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-data/0.17.2/download\"],\n strip_prefix = \"webrtc-data-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-data-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-ice-0.17.2\",\n sha256 = \"5b7fd30f52e6fda8664779b84b7904b2553b76fee24d9ca665e774ae32b13f53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-ice/0.17.2/download\"],\n strip_prefix = \"webrtc-ice-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-ice-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-mdns-0.17.2\",\n sha256 = \"91ffa0ea00c0fae979aafa5db285fec5eeb360e1ea246ebec529ba4e09f8e03e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-mdns/0.17.2/download\"],\n strip_prefix = \"webrtc-mdns-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-mdns-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-media-0.17.2\",\n sha256 = \"26a6c7335bdd03dc023cb9a3bd7966866d969c92c86987b73aa16dfa39c7ca29\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-media/0.17.2/download\"],\n strip_prefix = \"webrtc-media-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-media-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-sctp-0.17.2\",\n sha256 = \"1c4b637f0d8eb96d900ac0f79b3060ddd21ca88dfefa467e96e67ab0016f2574\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-sctp/0.17.2/download\"],\n strip_prefix = \"webrtc-sctp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-sctp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-srtp-0.17.2\",\n sha256 = \"45d2b667a0b5d04eebcb7cb22fd51b2af3721f418097b496e72de16386c8d0c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-srtp/0.17.2/download\"],\n strip_prefix = \"webrtc-srtp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-srtp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-util-0.17.2\",\n sha256 = \"1beae0b4f24969741c26ca282a257dc5823bd9cbe608f7e3ca3775102d323ad9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-util/0.17.2/download\"],\n strip_prefix = \"webrtc-util-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-util-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__weezl-0.1.12\",\n sha256 = \"a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/weezl/0.1.12/download\"],\n strip_prefix = \"weezl-0.1.12\",\n build_file = Label(\"@crates//crates:BUILD.weezl-0.1.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__whoami-2.1.2\",\n sha256 = \"998767ef88740d1f5b0682a9c53c24431453923962269c2db68ee43788c5a40d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/whoami/2.1.2/download\"],\n strip_prefix = \"whoami-2.1.2\",\n build_file = Label(\"@crates//crates:BUILD.whoami-2.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wide-0.8.3\",\n sha256 = \"13ca908d26e4786149c48efcf6c0ea09ab0e06d1fe3c17dc1b4b0f1ca4a7e788\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wide/0.8.3/download\"],\n strip_prefix = \"wide-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.wide-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__widestring-1.2.1\",\n sha256 = \"72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/widestring/1.2.1/download\"],\n strip_prefix = \"widestring-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.widestring-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wild-2.2.1\",\n sha256 = \"a3131afc8c575281e1e80f36ed6a092aa502c08b18ed7524e86fbbb12bb410e1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wild/2.2.1/download\"],\n strip_prefix = \"wild-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.wild-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-0.3.9\",\n sha256 = \"5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi/0.3.9/download\"],\n strip_prefix = \"winapi-0.3.9\",\n build_file = Label(\"@crates//crates:BUILD.winapi-0.3.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-i686-pc-windows-gnu-0.4.0\",\n sha256 = \"ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-i686-pc-windows-gnu/0.4.0/download\"],\n strip_prefix = \"winapi-i686-pc-windows-gnu-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.winapi-i686-pc-windows-gnu-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-util-0.1.11\",\n sha256 = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-util/0.1.11/download\"],\n strip_prefix = \"winapi-util-0.1.11\",\n build_file = Label(\"@crates//crates:BUILD.winapi-util-0.1.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-x86_64-pc-windows-gnu-0.4.0\",\n sha256 = \"712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-x86_64-pc-windows-gnu/0.4.0/download\"],\n strip_prefix = \"winapi-x86_64-pc-windows-gnu-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.winapi-x86_64-pc-windows-gnu-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-0.51.1\",\n sha256 = \"ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows/0.51.1/download\"],\n strip_prefix = \"windows-0.51.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-0.51.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-0.61.3\",\n sha256 = \"9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows/0.61.3/download\"],\n strip_prefix = \"windows-0.61.3\",\n build_file = Label(\"@crates//crates:BUILD.windows-0.61.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-0.62.2\",\n sha256 = \"527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows/0.62.2/download\"],\n strip_prefix = \"windows-0.62.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-0.62.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-collections-0.2.0\",\n sha256 = \"3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-collections/0.2.0/download\"],\n strip_prefix = \"windows-collections-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-collections-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-collections-0.3.2\",\n sha256 = \"23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-collections/0.3.2/download\"],\n strip_prefix = \"windows-collections-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-collections-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-core-0.51.1\",\n sha256 = \"f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-core/0.51.1/download\"],\n strip_prefix = \"windows-core-0.51.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-core-0.51.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-core-0.61.2\",\n sha256 = \"c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-core/0.61.2/download\"],\n strip_prefix = \"windows-core-0.61.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-core-0.61.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-core-0.62.2\",\n sha256 = \"b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-core/0.62.2/download\"],\n strip_prefix = \"windows-core-0.62.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-core-0.62.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-future-0.2.1\",\n sha256 = \"fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-future/0.2.1/download\"],\n strip_prefix = \"windows-future-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-future-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-future-0.3.2\",\n sha256 = \"e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-future/0.3.2/download\"],\n strip_prefix = \"windows-future-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-future-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-implement-0.60.2\",\n sha256 = \"053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-implement/0.60.2/download\"],\n strip_prefix = \"windows-implement-0.60.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-implement-0.60.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-interface-0.59.3\",\n sha256 = \"3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-interface/0.59.3/download\"],\n strip_prefix = \"windows-interface-0.59.3\",\n build_file = Label(\"@crates//crates:BUILD.windows-interface-0.59.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-link-0.1.3\",\n sha256 = \"5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-link/0.1.3/download\"],\n strip_prefix = \"windows-link-0.1.3\",\n build_file = Label(\"@crates//crates:BUILD.windows-link-0.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-link-0.2.1\",\n sha256 = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-link/0.2.1/download\"],\n strip_prefix = \"windows-link-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-link-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-numerics-0.2.0\",\n sha256 = \"9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-numerics/0.2.0/download\"],\n strip_prefix = \"windows-numerics-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-numerics-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-numerics-0.3.1\",\n sha256 = \"6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-numerics/0.3.1/download\"],\n strip_prefix = \"windows-numerics-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-numerics-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-result-0.3.4\",\n sha256 = \"56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-result/0.3.4/download\"],\n strip_prefix = \"windows-result-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.windows-result-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-result-0.4.1\",\n sha256 = \"7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-result/0.4.1/download\"],\n strip_prefix = \"windows-result-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-result-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-strings-0.4.2\",\n sha256 = \"56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-strings/0.4.2/download\"],\n strip_prefix = \"windows-strings-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-strings-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-strings-0.5.1\",\n sha256 = \"7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-strings/0.5.1/download\"],\n strip_prefix = \"windows-strings-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-strings-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.52.0\",\n sha256 = \"282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.52.0/download\"],\n strip_prefix = \"windows-sys-0.52.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.52.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.59.0\",\n sha256 = \"1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.59.0/download\"],\n strip_prefix = \"windows-sys-0.59.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.59.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.60.2\",\n sha256 = \"f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.60.2/download\"],\n strip_prefix = \"windows-sys-0.60.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.60.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.61.2\",\n sha256 = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.61.2/download\"],\n strip_prefix = \"windows-sys-0.61.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.61.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.48.5\",\n sha256 = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.48.5/download\"],\n strip_prefix = \"windows-targets-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.52.6\",\n sha256 = \"9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.52.6/download\"],\n strip_prefix = \"windows-targets-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.53.5\",\n sha256 = \"4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.53.5/download\"],\n strip_prefix = \"windows-targets-0.53.5\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.53.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-threading-0.1.0\",\n sha256 = \"b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-threading/0.1.0/download\"],\n strip_prefix = \"windows-threading-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-threading-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-threading-0.2.1\",\n sha256 = \"3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-threading/0.2.1/download\"],\n strip_prefix = \"windows-threading-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-threading-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.48.5\",\n sha256 = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.52.6\",\n sha256 = \"32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.52.6/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.53.1\",\n sha256 = \"a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.53.1/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.48.5\",\n sha256 = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.52.6\",\n sha256 = \"09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.52.6/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.53.1\",\n sha256 = \"b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.53.1/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.48.5\",\n sha256 = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.48.5/download\"],\n strip_prefix = \"windows_i686_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.52.6\",\n sha256 = \"8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.52.6/download\"],\n strip_prefix = \"windows_i686_gnu-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.53.1\",\n sha256 = \"960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.53.1/download\"],\n strip_prefix = \"windows_i686_gnu-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnullvm-0.52.6\",\n sha256 = \"0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnullvm/0.52.6/download\"],\n strip_prefix = \"windows_i686_gnullvm-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnullvm-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnullvm-0.53.1\",\n sha256 = \"fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnullvm/0.53.1/download\"],\n strip_prefix = \"windows_i686_gnullvm-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnullvm-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.48.5\",\n sha256 = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.48.5/download\"],\n strip_prefix = \"windows_i686_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.52.6\",\n sha256 = \"240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.52.6/download\"],\n strip_prefix = \"windows_i686_msvc-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.53.1\",\n sha256 = \"1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.53.1/download\"],\n strip_prefix = \"windows_i686_msvc-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.48.5\",\n sha256 = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.52.6\",\n sha256 = \"147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.52.6/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.53.1\",\n sha256 = \"9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.53.1/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.48.5\",\n sha256 = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.52.6\",\n sha256 = \"24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.52.6/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.53.1\",\n sha256 = \"0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.53.1/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.48.5\",\n sha256 = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.52.6\",\n sha256 = \"589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.52.6/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.53.1\",\n sha256 = \"d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.53.1/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winnow-0.7.15\",\n sha256 = \"df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winnow/0.7.15/download\"],\n strip_prefix = \"winnow-0.7.15\",\n build_file = Label(\"@crates//crates:BUILD.winnow-0.7.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winnow-1.0.4\",\n sha256 = \"23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winnow/1.0.4/download\"],\n strip_prefix = \"winnow-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.winnow-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winreg-0.10.1\",\n sha256 = \"80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winreg/0.10.1/download\"],\n strip_prefix = \"winreg-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.winreg-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winreg-0.56.0\",\n sha256 = \"7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winreg/0.56.0/download\"],\n strip_prefix = \"winreg-0.56.0\",\n build_file = Label(\"@crates//crates:BUILD.winreg-0.56.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wit-bindgen-0.57.1\",\n sha256 = \"1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wit-bindgen/0.57.1/download\"],\n strip_prefix = \"wit-bindgen-0.57.1\",\n build_file = Label(\"@crates//crates:BUILD.wit-bindgen-0.57.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wl-clipboard-rs-0.9.3\",\n sha256 = \"e9651471a32e87d96ef3a127715382b2d11cc7c8bb9822ded8a7cc94072eb0a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wl-clipboard-rs/0.9.3/download\"],\n strip_prefix = \"wl-clipboard-rs-0.9.3\",\n build_file = Label(\"@crates//crates:BUILD.wl-clipboard-rs-0.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__write16-1.0.0\",\n sha256 = \"d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/write16/1.0.0/download\"],\n strip_prefix = \"write16-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.write16-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__writeable-0.6.3\",\n sha256 = \"1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/writeable/0.6.3/download\"],\n strip_prefix = \"writeable-0.6.3\",\n build_file = Label(\"@crates//crates:BUILD.writeable-0.6.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wyz-0.5.1\",\n sha256 = \"05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wyz/0.5.1/download\"],\n strip_prefix = \"wyz-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.wyz-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__x11rb-0.13.2\",\n sha256 = \"9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/x11rb/0.13.2/download\"],\n strip_prefix = \"x11rb-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.x11rb-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__x11rb-protocol-0.13.2\",\n sha256 = \"ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/x11rb-protocol/0.13.2/download\"],\n strip_prefix = \"x11rb-protocol-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.x11rb-protocol-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__x25519-dalek-2.0.1\",\n sha256 = \"c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/x25519-dalek/2.0.1/download\"],\n strip_prefix = \"x25519-dalek-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.x25519-dalek-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__x509-parser-0.16.0\",\n sha256 = \"fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/x509-parser/0.16.0/download\"],\n strip_prefix = \"x509-parser-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.x509-parser-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xattr-1.6.1\",\n sha256 = \"32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xattr/1.6.1/download\"],\n strip_prefix = \"xattr-1.6.1\",\n build_file = Label(\"@crates//crates:BUILD.xattr-1.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xcap-0.9.6\",\n sha256 = \"b6ad471d5ba232bc276382d26a9d3b837d6853b7df389058b5bb1e94dcdd248c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xcap/0.9.6/download\"],\n strip_prefix = \"xcap-0.9.6\",\n build_file = Label(\"@crates//crates:BUILD.xcap-0.9.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xcb-1.7.0\",\n sha256 = \"ee4c580d8205abb0a5cf4eb7e927bd664e425b6c3263f9c5310583da96970cf6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xcb/1.7.0/download\"],\n strip_prefix = \"xcb-1.7.0\",\n build_file = Label(\"@crates//crates:BUILD.xcb-1.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xkbcommon-0.9.0\",\n sha256 = \"a7a974f48060a14e95705c01f24ad9c3345022f4d97441b8a36beb7ed5c4a02d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xkbcommon/0.9.0/download\"],\n strip_prefix = \"xkbcommon-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.xkbcommon-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xkeysym-0.2.1\",\n sha256 = \"b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xkeysym/0.2.1/download\"],\n strip_prefix = \"xkeysym-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.xkeysym-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xml-rs-0.8.28\",\n sha256 = \"3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xml-rs/0.8.28/download\"],\n strip_prefix = \"xml-rs-0.8.28\",\n build_file = Label(\"@crates//crates:BUILD.xml-rs-0.8.28.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xxhash-rust-0.8.18\",\n sha256 = \"aee1b19627c7c60102ab80d3a9cbe18de90bfe03bfa6c3715447681f0e8c8af6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xxhash-rust/0.8.18/download\"],\n strip_prefix = \"xxhash-rust-0.8.18\",\n build_file = Label(\"@crates//crates:BUILD.xxhash-rust-0.8.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yaml-rust-0.4.5\",\n sha256 = \"56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yaml-rust/0.4.5/download\"],\n strip_prefix = \"yaml-rust-0.4.5\",\n build_file = Label(\"@crates//crates:BUILD.yaml-rust-0.4.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yansi-1.0.1\",\n sha256 = \"cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yansi/1.0.1/download\"],\n strip_prefix = \"yansi-1.0.1\",\n build_file = Label(\"@crates//crates:BUILD.yansi-1.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yasna-0.5.2\",\n sha256 = \"e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yasna/0.5.2/download\"],\n strip_prefix = \"yasna-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.yasna-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-0.8.3\",\n sha256 = \"709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke/0.8.3/download\"],\n strip_prefix = \"yoke-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.yoke-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-derive-0.8.2\",\n sha256 = \"de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke-derive/0.8.2/download\"],\n strip_prefix = \"yoke-derive-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.yoke-derive-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__z85-3.0.7\",\n sha256 = \"c6e61e59a957b7ccee15d2049f86e8bfd6f66968fcd88f018950662d9b86e675\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/z85/3.0.7/download\"],\n strip_prefix = \"z85-3.0.7\",\n build_file = Label(\"@crates//crates:BUILD.z85-3.0.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zbus-5.18.0\",\n sha256 = \"fe18fb60dc696039e738717b76eaea21e7a4489bbb1885020b43c94236d7e98a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zbus/5.18.0/download\"],\n strip_prefix = \"zbus-5.18.0\",\n build_file = Label(\"@crates//crates:BUILD.zbus-5.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zbus_macros-5.18.0\",\n sha256 = \"fe96480bed92df2b442a1a30df364e12d08eed03aeb061f2b8dc6afb2be91119\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zbus_macros/5.18.0/download\"],\n strip_prefix = \"zbus_macros-5.18.0\",\n build_file = Label(\"@crates//crates:BUILD.zbus_macros-5.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zbus_names-4.3.4\",\n sha256 = \"d8bf88b4a3ff53e883001e0e0115b297a9d53c31b9c1edd2bfdd853e3428624e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zbus_names/4.3.4/download\"],\n strip_prefix = \"zbus_names-4.3.4\",\n build_file = Label(\"@crates//crates:BUILD.zbus_names-4.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerocopy-0.8.55\",\n sha256 = \"b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerocopy/0.8.55/download\"],\n strip_prefix = \"zerocopy-0.8.55\",\n build_file = Label(\"@crates//crates:BUILD.zerocopy-0.8.55.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerocopy-derive-0.8.55\",\n sha256 = \"0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerocopy-derive/0.8.55/download\"],\n strip_prefix = \"zerocopy-derive-0.8.55\",\n build_file = Label(\"@crates//crates:BUILD.zerocopy-derive-0.8.55.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-0.1.8\",\n sha256 = \"0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom/0.1.8/download\"],\n strip_prefix = \"zerofrom-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-derive-0.1.7\",\n sha256 = \"11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom-derive/0.1.7/download\"],\n strip_prefix = \"zerofrom-derive-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-derive-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize-1.9.0\",\n sha256 = \"e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize/1.9.0/download\"],\n strip_prefix = \"zeroize-1.9.0\",\n build_file = Label(\"@crates//crates:BUILD.zeroize-1.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize_derive-1.5.0\",\n sha256 = \"3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize_derive/1.5.0/download\"],\n strip_prefix = \"zeroize_derive-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.zeroize_derive-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerotrie-0.2.4\",\n sha256 = \"0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerotrie/0.2.4/download\"],\n strip_prefix = \"zerotrie-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.zerotrie-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-0.11.6\",\n sha256 = \"90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec/0.11.6/download\"],\n strip_prefix = \"zerovec-0.11.6\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-0.11.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-derive-0.11.3\",\n sha256 = \"625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec-derive/0.11.3/download\"],\n strip_prefix = \"zerovec-derive-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-derive-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zmij-1.0.23\",\n sha256 = \"29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zmij/1.0.23/download\"],\n strip_prefix = \"zmij-1.0.23\",\n build_file = Label(\"@crates//crates:BUILD.zmij-1.0.23.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zune-core-0.5.1\",\n sha256 = \"cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zune-core/0.5.1/download\"],\n strip_prefix = \"zune-core-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.zune-core-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zune-jpeg-0.5.15\",\n sha256 = \"27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zune-jpeg/0.5.15/download\"],\n strip_prefix = \"zune-jpeg-0.5.15\",\n build_file = Label(\"@crates//crates:BUILD.zune-jpeg-0.5.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zvariant-5.13.1\",\n sha256 = \"bee2a0bcd2a907786a456fff45aaaaf54c9ba5f50b71ae9ec1a4edd200c94911\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zvariant/5.13.1/download\"],\n strip_prefix = \"zvariant-5.13.1\",\n build_file = Label(\"@crates//crates:BUILD.zvariant-5.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zvariant_derive-5.13.1\",\n sha256 = \"38a708216a18780796770bfe3f4739c7c83a3e8f789b755534bbbc06e4e23e12\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zvariant_derive/5.13.1/download\"],\n strip_prefix = \"zvariant_derive-5.13.1\",\n build_file = Label(\"@crates//crates:BUILD.zvariant_derive-5.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zvariant_utils-3.5.0\",\n sha256 = \"90cb9383f9b45290407a1258b202d3f8f01db719eb60b4e4055c6375af4fc7c7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zvariant_utils/3.5.0/download\"],\n strip_prefix = \"zvariant_utils-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.zvariant_utils-3.5.0.bazel\"),\n )\n\n return [\n struct(repo = \"crates\", is_dev_dep = False),\n struct(repo=\"crates__ansi-width-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__anyhow-1.0.104\", is_dev_dep = False),\n struct(repo=\"crates__arboard-3.6.1\", is_dev_dep = False),\n struct(repo=\"crates__argmax-0.3.1\", is_dev_dep = False),\n struct(repo=\"crates__ast-grep-core-0.39.9\", is_dev_dep = False),\n struct(repo=\"crates__async-recursion-1.1.1\", is_dev_dep = False),\n struct(repo=\"crates__async-trait-0.1.91\", is_dev_dep = False),\n struct(repo=\"crates__audiopus_sys-0.2.2\", is_dev_dep = False),\n struct(repo=\"crates__base64-0.22.1\", is_dev_dep = False),\n struct(repo=\"crates__base64-simd-0.8.0\", is_dev_dep = False),\n struct(repo=\"crates__bigdecimal-0.4.10\", is_dev_dep = False),\n struct(repo=\"crates__binary-heap-plus-0.5.0\", is_dev_dep = False),\n struct(repo=\"crates__bon-3.9.3\", is_dev_dep = False),\n struct(repo=\"crates__brush-parser-0.3.0\", is_dev_dep = False),\n struct(repo=\"crates__brush-parser-0.4.0\", is_dev_dep = False),\n struct(repo=\"crates__bstr-1.13.0\", is_dev_dep = False),\n struct(repo=\"crates__bytecount-0.6.9\", is_dev_dep = False),\n struct(repo=\"crates__bytes-1.12.1\", is_dev_dep = False),\n struct(repo=\"crates__cached-0.59.0\", is_dev_dep = False),\n struct(repo=\"crates__cfg-if-1.0.4\", is_dev_dep = False),\n struct(repo=\"crates__check_elevation-0.2.7\", is_dev_dep = False),\n struct(repo=\"crates__chrono-0.4.45\", is_dev_dep = False),\n struct(repo=\"crates__clap-4.6.4\", is_dev_dep = False),\n struct(repo=\"crates__clipboard-win-5.4.1\", is_dev_dep = False),\n struct(repo=\"crates__codesnake-0.2.1\", is_dev_dep = False),\n struct(repo=\"crates__color-print-0.3.7\", is_dev_dep = False),\n struct(repo=\"crates__command-fds-0.3.3\", is_dev_dep = False),\n struct(repo=\"crates__compare-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__core-graphics-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__dashmap-6.2.1\", is_dev_dep = False),\n struct(repo=\"crates__dns-lookup-3.0.1\", is_dev_dep = False),\n struct(repo=\"crates__enigo-0.6.1\", is_dev_dep = False),\n struct(repo=\"crates__faccess-0.2.4\", is_dev_dep = False),\n struct(repo=\"crates__fancy-regex-0.17.0\", is_dev_dep = False),\n struct(repo=\"crates__fancy-regex-0.18.0\", is_dev_dep = False),\n struct(repo=\"crates__filetime-0.2.29\", is_dev_dep = False),\n struct(repo=\"crates__flume-0.11.1\", is_dev_dep = False),\n struct(repo=\"crates__foldhash-0.2.0\", is_dev_dep = False),\n struct(repo=\"crates__fontdue-0.9.3\", is_dev_dep = False),\n struct(repo=\"crates__fs_extra-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__futures-0.3.33\", is_dev_dep = False),\n struct(repo=\"crates__getrandom-0.4.3\", is_dev_dep = False),\n struct(repo=\"crates__glob-0.3.4\", is_dev_dep = False),\n struct(repo=\"crates__globset-0.4.19\", is_dev_dep = False),\n struct(repo=\"crates__grep-cli-0.1.12\", is_dev_dep = False),\n struct(repo=\"crates__grep-matcher-0.1.9\", is_dev_dep = False),\n struct(repo=\"crates__grep-pcre2-0.1.10\", is_dev_dep = False),\n struct(repo=\"crates__grep-printer-0.3.1\", is_dev_dep = False),\n struct(repo=\"crates__grep-regex-0.1.14\", is_dev_dep = False),\n struct(repo=\"crates__grep-searcher-0.1.17\", is_dev_dep = False),\n struct(repo=\"crates__hex-0.4.3\", is_dev_dep = False),\n struct(repo=\"crates__hifijson-0.2.3\", is_dev_dep = False),\n struct(repo=\"crates__hostname-0.4.2\", is_dev_dep = False),\n struct(repo=\"crates__html-to-markdown-rs-2.30.0\", is_dev_dep = False),\n struct(repo=\"crates__icy_sixel-0.5.0\", is_dev_dep = False),\n struct(repo=\"crates__ignore-0.4.31\", is_dev_dep = False),\n struct(repo=\"crates__image-0.25.10\", is_dev_dep = False),\n struct(repo=\"crates__indicatif-0.18.6\", is_dev_dep = False),\n struct(repo=\"crates__inferno-0.12.8\", is_dev_dep = False),\n struct(repo=\"crates__inherent-1.0.14\", is_dev_dep = False),\n struct(repo=\"crates__itertools-0.14.0\", is_dev_dep = False),\n struct(repo=\"crates__jaq-core-2.2.1\", is_dev_dep = False),\n struct(repo=\"crates__jaq-json-1.1.3\", is_dev_dep = False),\n struct(repo=\"crates__jaq-std-2.1.2\", is_dev_dep = False),\n struct(repo=\"crates__jiff-0.2.35\", is_dev_dep = False),\n struct(repo=\"crates__libc-0.2.189\", is_dev_dep = False),\n struct(repo=\"crates__lscolors-0.21.0\", is_dev_dep = False),\n struct(repo=\"crates__maudio-0.1.6\", is_dev_dep = False),\n struct(repo=\"crates__memchr-2.8.3\", is_dev_dep = False),\n struct(repo=\"crates__memmap2-0.9.11\", is_dev_dep = False),\n struct(repo=\"crates__napi-3.11.0\", is_dev_dep = False),\n struct(repo=\"crates__napi-build-2.3.2\", is_dev_dep = False),\n struct(repo=\"crates__napi-derive-3.6.0\", is_dev_dep = False),\n struct(repo=\"crates__nix-0.29.0\", is_dev_dep = False),\n struct(repo=\"crates__nix-0.31.3\", is_dev_dep = False),\n struct(repo=\"crates__nom-8.0.0\", is_dev_dep = False),\n struct(repo=\"crates__normalize-path-0.2.1\", is_dev_dep = False),\n struct(repo=\"crates__notify-8.2.0\", is_dev_dep = False),\n struct(repo=\"crates__num-bigint-0.4.8\", is_dev_dep = False),\n struct(repo=\"crates__num-traits-0.2.19\", is_dev_dep = False),\n struct(repo=\"crates__onig-6.5.3\", is_dev_dep = False),\n struct(repo=\"crates__opus-0.3.1\", is_dev_dep = False),\n struct(repo=\"crates__os_display-0.1.4\", is_dev_dep = False),\n struct(repo=\"crates__os_pipe-1.2.3\", is_dev_dep = False),\n struct(repo=\"crates__parking_lot-0.12.5\", is_dev_dep = False),\n struct(repo=\"crates__parse_datetime-0.14.0\", is_dev_dep = False),\n struct(repo=\"crates__phf-0.13.1\", is_dev_dep = False),\n struct(repo=\"crates__platform-info-2.1.0\", is_dev_dep = False),\n struct(repo=\"crates__png-0.18.1\", is_dev_dep = False),\n struct(repo=\"crates__portable-pty-0.9.0\", is_dev_dep = False),\n struct(repo=\"crates__procfs-0.18.0\", is_dev_dep = False),\n struct(repo=\"crates__rand-0.10.2\", is_dev_dep = False),\n struct(repo=\"crates__rayon-1.12.0\", is_dev_dep = False),\n struct(repo=\"crates__regex-1.13.1\", is_dev_dep = False),\n struct(repo=\"crates__rlimit-0.11.0\", is_dev_dep = False),\n struct(repo=\"crates__rpds-1.2.1\", is_dev_dep = False),\n struct(repo=\"crates__rustc-hash-2.1.3\", is_dev_dep = False),\n struct(repo=\"crates__rustix-1.1.4\", is_dev_dep = False),\n struct(repo=\"crates__self_cell-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__serde-1.0.229\", is_dev_dep = False),\n struct(repo=\"crates__serde_json-1.0.151\", is_dev_dep = False),\n struct(repo=\"crates__similar-3.1.1\", is_dev_dep = False),\n struct(repo=\"crates__smallvec-1.15.2\", is_dev_dep = False),\n struct(repo=\"crates__strum-0.28.0\", is_dev_dep = False),\n struct(repo=\"crates__strum_macros-0.28.0\", is_dev_dep = False),\n struct(repo=\"crates__syntect-5.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tempfile-3.27.0\", is_dev_dep = False),\n struct(repo=\"crates__terminfo-0.9.0\", is_dev_dep = False),\n struct(repo=\"crates__thiserror-2.0.19\", is_dev_dep = False),\n struct(repo=\"crates__tiktoken-rs-0.11.0\", is_dev_dep = False),\n struct(repo=\"crates__tokio-1.53.1\", is_dev_dep = False),\n struct(repo=\"crates__tokio-util-0.7.19\", is_dev_dep = False),\n struct(repo=\"crates__toml-1.1.3-spec-1.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tracing-0.1.44\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-0.25.10\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-astro-next-0.1.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-bash-0.25.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-c-0.24.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-c-sharp-0.23.5\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-clojure-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-cmake-0.7.4\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-cpp-0.23.4\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-css-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-dart-0.2.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-diff-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-dockerfile-updated-0.2.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-elisp-1.6.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-elixir-0.3.5\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-erlang-0.16.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-fortran-0.6.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-go-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-graphql-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-haskell-0.23.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-hcl-1.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-html-0.23.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-ini-1.4.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-java-0.23.5\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-javascript-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-json-0.24.8\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-julia-0.23.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-just-0.2.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-kotlin-sg-0.4.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-lua-0.5.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-make-1.1.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-md-0.5.3\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-nix-0.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-objc-3.0.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-ocaml-0.24.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-odin-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-php-0.24.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-powershell-0.26.4\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-proto-0.4.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-python-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-r-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-regex-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-ruby-0.23.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-rust-0.24.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-scala-0.26.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-sequel-0.3.11\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-solidity-1.2.13\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-starlark-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-svelte-next-0.1.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-swift-0.7.3\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-tlaplus-1.5.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-toml-ng-0.7.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-typescript-0.23.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-verilog-1.0.3\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-vue-next-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-xml-0.7.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-yaml-0.7.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-zig-1.1.2\", is_dev_dep = False),\n struct(repo=\"crates__unicode-segmentation-1.13.3\", is_dev_dep = False),\n struct(repo=\"crates__unicode-width-0.1.14\", is_dev_dep = False),\n struct(repo=\"crates__unicode-width-0.2.2\", is_dev_dep = False),\n struct(repo=\"crates__uucore-0.0.30\", is_dev_dep = False),\n struct(repo=\"crates__uucore-0.8.0\", is_dev_dep = False),\n struct(repo=\"crates__uucore-0.9.0\", is_dev_dep = False),\n struct(repo=\"crates__uuid-1.24.0\", is_dev_dep = False),\n struct(repo=\"crates__uutils_term_grid-0.8.0\", is_dev_dep = False),\n struct(repo=\"crates__uzers-0.12.2\", is_dev_dep = False),\n struct(repo=\"crates__webrtc-0.17.2\", is_dev_dep = False),\n struct(repo=\"crates__whoami-2.1.2\", is_dev_dep = False),\n struct(repo=\"crates__windows-sys-0.59.0\", is_dev_dep = False),\n struct(repo=\"crates__windows-sys-0.61.2\", is_dev_dep = False),\n struct(repo=\"crates__winreg-0.56.0\", is_dev_dep = False),\n struct(repo=\"crates__x11rb-0.13.2\", is_dev_dep = False),\n struct(repo=\"crates__xcap-0.9.6\", is_dev_dep = False),\n struct(repo=\"crates__xkeysym-0.2.1\", is_dev_dep = False),\n struct(repo=\"crates__xxhash-rust-0.8.18\", is_dev_dep = False),\n struct(repo=\"crates__yansi-1.0.1\", is_dev_dep = False),\n struct(repo = \"crates__pretty_assertions-1.4.1\", is_dev_dep = True),\n struct(repo = \"crates__rstest-0.26.1\", is_dev_dep = True),\n ]\n", + "crates.bzl": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\"\"\"\n# `crates_repository` API\n\n- [aliases](#aliases)\n- [crate_edition](#crate_edition)\n- [crate_deps](#crate_deps)\n- [all_crate_deps](#all_crate_deps)\n- [crate_repositories](#crate_repositories)\n\n\"\"\"\n\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"git_repository\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@rules_rust//crate_universe:defs.bzl\", \"crates_vendor_remote_repository\", \"local_crate_mirror\")\n\n###############################################################################\n# MACROS API\n###############################################################################\n\n# An identifier that represent common dependencies (unconditional).\n_COMMON_CONDITION = \"\"\n\ndef _flatten_dependency_maps(all_dependency_maps):\n \"\"\"Flatten a list of dependency maps into one dictionary.\n\n Dependency maps have the following structure:\n\n ```python\n DEPENDENCIES_MAP = {\n # The first key in the map is a Bazel package\n # name of the workspace this file is defined in.\n \"workspace_member_package\": {\n\n # Not all dependencies are supported for all platforms.\n # the condition key is the condition required to be true\n # on the host platform.\n \"condition\": {\n\n # An alias to a crate target. # The label of the crate target the\n # Aliases are only crate names. # package name refers to.\n \"package_name\": \"@full//:label\",\n }\n }\n }\n ```\n\n Args:\n all_dependency_maps (list): A list of dicts as described above\n\n Returns:\n dict: A dictionary as described above\n \"\"\"\n dependencies = {}\n\n for workspace_deps_map in all_dependency_maps:\n for pkg_name, conditional_deps_map in workspace_deps_map.items():\n if pkg_name not in dependencies:\n non_frozen_map = dict()\n for key, values in conditional_deps_map.items():\n non_frozen_map.update({key: dict(values.items())})\n dependencies.setdefault(pkg_name, non_frozen_map)\n continue\n\n for condition, deps_map in conditional_deps_map.items():\n # If the condition has not been recorded, do so and continue\n if condition not in dependencies[pkg_name]:\n dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))\n continue\n\n # Alert on any miss-matched dependencies\n inconsistent_entries = []\n for crate_name, crate_label in deps_map.items():\n existing = dependencies[pkg_name][condition].get(crate_name)\n if existing and existing != crate_label:\n inconsistent_entries.append((crate_name, existing, crate_label))\n dependencies[pkg_name][condition].update({crate_name: crate_label})\n\n return dependencies\n\ndef crate_deps(deps, package_name = None):\n \"\"\"Finds the fully qualified label of the requested crates for the package where this macro is called.\n\n Args:\n deps (list): The desired list of crate targets.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()`.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if not deps:\n return []\n\n if package_name == None:\n package_name = native.package_name()\n\n # Join both sets of dependencies\n dependencies = _flatten_dependency_maps([\n _NORMAL_DEPENDENCIES,\n _NORMAL_DEV_DEPENDENCIES,\n _PROC_MACRO_DEPENDENCIES,\n _PROC_MACRO_DEV_DEPENDENCIES,\n _BUILD_DEPENDENCIES,\n _BUILD_PROC_MACRO_DEPENDENCIES,\n ]).pop(package_name, {})\n\n # Combine all conditional packages so we can easily index over a flat list\n # TODO: Perhaps this should actually return select statements and maintain\n # the conditionals of the dependencies\n flat_deps = {}\n for deps_set in dependencies.values():\n for crate_name, crate_label in deps_set.items():\n flat_deps.update({crate_name: crate_label})\n\n missing_crates = []\n crate_targets = []\n for crate_target in deps:\n if crate_target not in flat_deps:\n missing_crates.append(crate_target)\n else:\n crate_targets.append(flat_deps[crate_target])\n\n if missing_crates:\n fail(\"Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`\".format(\n missing_crates,\n package_name,\n dependencies,\n ))\n\n return crate_targets\n\ndef crate_edition(package_name = None):\n \"\"\"Finds the Rust edition for the package where this macro is called.\n\n Args:\n package_name (str, optional): The package name whose edition should be\n looked up. Defaults to `native.package_name()` when unset.\n\n Returns:\n str: The Rust edition declared by the package's Cargo.toml file.\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n if package_name not in _CRATE_EDITIONS:\n fail(\"Tried to get crate_edition for package \" + package_name + \" but that package had no Cargo.toml file\")\n\n return _CRATE_EDITIONS[package_name]\n\ndef all_crate_deps(\n normal = False, \n normal_dev = False, \n proc_macro = False, \n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Finds the fully qualified label of all requested direct crate dependencies \\\n for the package where this macro is called.\n\n If no parameters are set, all normal dependencies are returned. Setting any one flag will\n otherwise impact the contents of the returned list.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list.\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_dependency_maps = []\n if normal:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n if normal_dev:\n all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)\n if proc_macro:\n all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)\n if proc_macro_dev:\n all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)\n if build:\n all_dependency_maps.append(_BUILD_DEPENDENCIES)\n if build_proc_macro:\n all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)\n\n # Default to always using normal dependencies\n if not all_dependency_maps:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n\n dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)\n\n if not dependencies:\n if dependencies == None:\n fail(\"Tried to get all_crate_deps for package \" + package_name + \" but that package had no Cargo.toml file\")\n else:\n return []\n\n crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())\n for condition, deps in dependencies.items():\n crate_deps += selects.with_or({\n tuple(_CONDITIONS[condition]): deps.values(),\n \"//conditions:default\": [],\n })\n\n return crate_deps\n\ndef aliases(\n normal = False,\n normal_dev = False,\n proc_macro = False,\n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Produces a map of Crate alias names to their original label\n\n If no dependency kinds are specified, `normal` and `proc_macro` are used by default.\n Setting any one flag will otherwise determine the contents of the returned dict.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list..\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n dict: The aliases of all associated packages\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_aliases_maps = []\n if normal:\n all_aliases_maps.append(_NORMAL_ALIASES)\n if normal_dev:\n all_aliases_maps.append(_NORMAL_DEV_ALIASES)\n if proc_macro:\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n if proc_macro_dev:\n all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)\n if build:\n all_aliases_maps.append(_BUILD_ALIASES)\n if build_proc_macro:\n all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)\n\n # Default to always using normal aliases\n if not all_aliases_maps:\n all_aliases_maps.append(_NORMAL_ALIASES)\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n\n aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)\n\n if not aliases:\n return dict()\n\n common_items = aliases.pop(_COMMON_CONDITION, {}).items()\n\n # If there are only common items in the dictionary, immediately return them\n if not len(aliases.keys()) == 1:\n return dict(common_items)\n\n # Build a single select statement where each conditional has accounted for the\n # common set of aliases.\n crate_aliases = {\"//conditions:default\": dict(common_items)}\n for condition, deps in aliases.items():\n condition_triples = _CONDITIONS[condition]\n for triple in condition_triples:\n if triple in crate_aliases:\n crate_aliases[triple].update(deps)\n else:\n crate_aliases.update({triple: dict(deps.items() + common_items)})\n\n return select(crate_aliases)\n\n###############################################################################\n# WORKSPACE MEMBER DEPS, ALIASES, AND EDITIONS\n###############################################################################\n\n_CRATE_EDITIONS = {\n \"crates/vendor/brush-builtins\": \"2024\",\n \"crates/vendor/brush-core\": \"2024\",\n \"crates/vendor/jaq\": \"2024\",\n \"crates/pi-ast\": \"2024\",\n \"crates/pi-iso\": \"2024\",\n \"crates/pi-natives\": \"2024\",\n \"crates/pi-shell\": \"2024\",\n \"crates/pi-uutils-ctx\": \"2024\",\n \"crates/pi-voice\": \"2024\",\n \"crates/pi-walker\": \"2024\",\n \"crates/pi-uu-diff\": \"2024\",\n \"crates/pi-uu-grep\": \"2024\",\n \"crates/vendor/uu-b2sum\": \"2024\",\n \"crates/vendor/uu-base32\": \"2024\",\n \"crates/vendor/uu-base64\": \"2024\",\n \"crates/vendor/uu-basename\": \"2024\",\n \"crates/vendor/uu-cat\": \"2024\",\n \"crates/vendor/uu-checksum-common\": \"2024\",\n \"crates/vendor/uu-comm\": \"2024\",\n \"crates/vendor/uu-cut\": \"2024\",\n \"crates/vendor/uu-date\": \"2024\",\n \"crates/vendor/uu-dirname\": \"2024\",\n \"crates/vendor/uu-find\": \"2024\",\n \"crates/vendor/uu-head\": \"2024\",\n \"crates/vendor/uu-hostname\": \"2024\",\n \"crates/vendor/uu-ln\": \"2024\",\n \"crates/vendor/uu-ls\": \"2024\",\n \"crates/vendor/uu-md5sum\": \"2024\",\n \"crates/vendor/uu-mkdir\": \"2024\",\n \"crates/vendor/uu-mktemp\": \"2024\",\n \"crates/vendor/uu-mv\": \"2024\",\n \"crates/vendor/uu-nproc\": \"2024\",\n \"crates/vendor/uu-paste\": \"2024\",\n \"crates/vendor/uu-printenv\": \"2024\",\n \"crates/vendor/uu-readlink\": \"2024\",\n \"crates/vendor/uu-realpath\": \"2024\",\n \"crates/vendor/uu-rm\": \"2024\",\n \"crates/vendor/uu-sed\": \"2024\",\n \"crates/vendor/uu-seq\": \"2024\",\n \"crates/vendor/uu-sha1sum\": \"2024\",\n \"crates/vendor/uu-sha224sum\": \"2024\",\n \"crates/vendor/uu-sha256sum\": \"2024\",\n \"crates/vendor/uu-sha384sum\": \"2024\",\n \"crates/vendor/uu-sha512sum\": \"2024\",\n \"crates/vendor/uu-sort\": \"2024\",\n \"crates/vendor/uu-stat\": \"2024\",\n \"crates/vendor/uu-tac\": \"2024\",\n \"crates/vendor/uu-tail\": \"2024\",\n \"crates/vendor/uu-tee\": \"2024\",\n \"crates/vendor/uu-touch\": \"2024\",\n \"crates/vendor/uu-tr\": \"2024\",\n \"crates/vendor/uu-truncate\": \"2024\",\n \"crates/vendor/uu-uname\": \"2024\",\n \"crates/vendor/uu-uniq\": \"2024\",\n \"crates/vendor/uu-wc\": \"2024\",\n \"crates/vendor/uu-whoami\": \"2024\",\n \"crates/vendor/uu-xargs\": \"2024\",\n \"crates/vendor/uu-yes\": \"2024\",\n}\n\n_NORMAL_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n \"brush-parser\": Label(\"//brush-parser-0.4.0\"),\n \"cfg-if\": Label(\"//cfg-if-1.0.4\"),\n \"chrono\": Label(\"//chrono-0.4.45\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"fancy-regex\": Label(\"//fancy-regex-0.17.0\"),\n \"futures\": Label(\"//futures-0.3.33\"),\n \"itertools\": Label(\"//itertools-0.14.0\"),\n \"strum\": Label(\"//strum-0.28.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"tracing\": Label(\"//tracing-0.1.44\"),\n },\n \"cfg(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"))\": {\n \"procfs\": Label(\"//procfs-0.18.0\"),\n },\n \"cfg(any(unix, windows))\": {\n \"tokio\": Label(\"//tokio-1.53.1\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(target_family = \\\"wasm\\\")\": {\n \"tokio\": Label(\"//tokio-1.53.1\"),\n },\n \"cfg(unix)\": {\n \"nix\": Label(\"//nix-0.31.3\"),\n \"rlimit\": Label(\"//rlimit-0.11.0\"),\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n \"bon\": Label(\"//bon-3.9.3\"),\n \"brush-parser\": Label(\"//brush-parser-0.4.0\"),\n \"cached\": Label(\"//cached-0.59.0\"),\n \"cfg-if\": Label(\"//cfg-if-1.0.4\"),\n \"chrono\": Label(\"//chrono-0.4.45\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"color-print\": Label(\"//color-print-0.3.7\"),\n \"fancy-regex\": Label(\"//fancy-regex-0.17.0\"),\n \"futures\": Label(\"//futures-0.3.33\"),\n \"itertools\": Label(\"//itertools-0.14.0\"),\n \"normalize-path\": Label(\"//normalize-path-0.2.1\"),\n \"rand\": Label(\"//rand-0.10.2\"),\n \"rpds\": Label(\"//rpds-1.2.1\"),\n \"strum\": Label(\"//strum-0.28.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"tokio-util\": Label(\"//tokio-util-0.7.19\"),\n \"tracing\": Label(\"//tracing-0.1.44\"),\n },\n \"cfg(any(unix, windows))\": {\n \"hostname\": Label(\"//hostname-0.4.2\"),\n \"tokio\": Label(\"//tokio-1.53.1\"),\n },\n \"cfg(target_family = \\\"wasm\\\")\": {\n \"tokio\": Label(\"//tokio-1.53.1\"),\n },\n \"cfg(unix)\": {\n \"command-fds\": Label(\"//command-fds-0.3.3\"),\n \"libc\": Label(\"//libc-0.2.189\"),\n \"nix\": Label(\"//nix-0.31.3\"),\n \"terminfo\": Label(\"//terminfo-0.9.0\"),\n \"uzers\": Label(\"//uzers-0.12.2\"),\n },\n \"cfg(windows)\": {\n \"check_elevation\": Label(\"//check_elevation-0.2.7\"),\n \"whoami\": Label(\"//whoami-2.1.2\"),\n \"windows-sys\": Label(\"//windows-sys-0.59.0\"),\n },\n \"wasm32-unknown-unknown\": {\n \"getrandom\": Label(\"//getrandom-0.4.3\"),\n \"uuid\": Label(\"//uuid-1.24.0\"),\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n \"codesnake\": Label(\"//codesnake-0.2.1\"),\n \"hifijson\": Label(\"//hifijson-0.2.3\"),\n \"jaq-core\": Label(\"//jaq-core-2.2.1\"),\n \"jaq-json\": Label(\"//jaq-json-1.1.3\"),\n \"jaq-std\": Label(\"//jaq-std-2.1.2\"),\n \"memmap2\": Label(\"//memmap2-0.9.11\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n \"unicode-width\": Label(\"//unicode-width-0.1.14\"),\n \"yansi\": Label(\"//yansi-1.0.1\"),\n },\n },\n \"crates/pi-ast\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"ast-grep-core\": Label(\"//ast-grep-core-0.39.9\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"phf\": Label(\"//phf-0.13.1\"),\n \"serde\": Label(\"//serde-1.0.229\"),\n \"tree-sitter\": Label(\"//tree-sitter-0.25.10\"),\n \"tree_sitter_astro\": Label(\"//tree-sitter-astro-next-0.1.1\"),\n \"tree-sitter-bash\": Label(\"//tree-sitter-bash-0.25.1\"),\n \"tree-sitter-c\": Label(\"//tree-sitter-c-0.24.2\"),\n \"tree-sitter-c-sharp\": Label(\"//tree-sitter-c-sharp-0.23.5\"),\n \"tree-sitter-clojure\": Label(\"//tree-sitter-clojure-0.1.0\"),\n \"tree-sitter-cmake\": Label(\"//tree-sitter-cmake-0.7.4\"),\n \"tree-sitter-cpp\": Label(\"//tree-sitter-cpp-0.23.4\"),\n \"tree-sitter-css\": Label(\"//tree-sitter-css-0.25.0\"),\n \"tree-sitter-dart\": Label(\"//tree-sitter-dart-0.2.0\"),\n \"tree-sitter-diff\": Label(\"//tree-sitter-diff-0.1.0\"),\n \"tree_sitter_dockerfile\": Label(\"//tree-sitter-dockerfile-updated-0.2.0\"),\n \"tree-sitter-elisp\": Label(\"//tree-sitter-elisp-1.6.1\"),\n \"tree-sitter-elixir\": Label(\"//tree-sitter-elixir-0.3.5\"),\n \"tree-sitter-erlang\": Label(\"//tree-sitter-erlang-0.16.0\"),\n \"tree-sitter-fortran\": Label(\"//tree-sitter-fortran-0.6.0\"),\n \"tree-sitter-go\": Label(\"//tree-sitter-go-0.25.0\"),\n \"tree-sitter-graphql\": Label(\"//tree-sitter-graphql-0.1.0\"),\n \"tree-sitter-haskell\": Label(\"//tree-sitter-haskell-0.23.1\"),\n \"tree-sitter-hcl\": Label(\"//tree-sitter-hcl-1.1.0\"),\n \"tree-sitter-html\": Label(\"//tree-sitter-html-0.23.2\"),\n \"tree-sitter-ini\": Label(\"//tree-sitter-ini-1.4.0\"),\n \"tree-sitter-java\": Label(\"//tree-sitter-java-0.23.5\"),\n \"tree-sitter-javascript\": Label(\"//tree-sitter-javascript-0.25.0\"),\n \"tree-sitter-json\": Label(\"//tree-sitter-json-0.24.8\"),\n \"tree-sitter-julia\": Label(\"//tree-sitter-julia-0.23.1\"),\n \"tree-sitter-just\": Label(\"//tree-sitter-just-0.2.0\"),\n \"tree_sitter_kotlin\": Label(\"//tree-sitter-kotlin-sg-0.4.1\"),\n \"tree-sitter-lua\": Label(\"//tree-sitter-lua-0.5.0\"),\n \"tree-sitter-make\": Label(\"//tree-sitter-make-1.1.1\"),\n \"tree-sitter-md\": Label(\"//tree-sitter-md-0.5.3\"),\n \"tree-sitter-nix\": Label(\"//tree-sitter-nix-0.3.0\"),\n \"tree-sitter-objc\": Label(\"//tree-sitter-objc-3.0.2\"),\n \"tree-sitter-ocaml\": Label(\"//tree-sitter-ocaml-0.24.2\"),\n \"tree-sitter-odin\": Label(\"//tree-sitter-odin-1.3.0\"),\n \"tree-sitter-php\": Label(\"//tree-sitter-php-0.24.2\"),\n \"tree-sitter-powershell\": Label(\"//tree-sitter-powershell-0.26.4\"),\n \"tree-sitter-proto\": Label(\"//tree-sitter-proto-0.4.0\"),\n \"tree-sitter-python\": Label(\"//tree-sitter-python-0.25.0\"),\n \"tree-sitter-r\": Label(\"//tree-sitter-r-1.3.0\"),\n \"tree-sitter-regex\": Label(\"//tree-sitter-regex-0.25.0\"),\n \"tree-sitter-ruby\": Label(\"//tree-sitter-ruby-0.23.1\"),\n \"tree-sitter-rust\": Label(\"//tree-sitter-rust-0.24.2\"),\n \"tree-sitter-scala\": Label(\"//tree-sitter-scala-0.26.0\"),\n \"tree_sitter_sql\": Label(\"//tree-sitter-sequel-0.3.11\"),\n \"tree-sitter-solidity\": Label(\"//tree-sitter-solidity-1.2.13\"),\n \"tree-sitter-starlark\": Label(\"//tree-sitter-starlark-1.3.0\"),\n \"tree_sitter_svelte\": Label(\"//tree-sitter-svelte-next-0.1.1\"),\n \"tree-sitter-swift\": Label(\"//tree-sitter-swift-0.7.3\"),\n \"tree-sitter-tlaplus\": Label(\"//tree-sitter-tlaplus-1.5.0\"),\n \"tree-sitter-toml-ng\": Label(\"//tree-sitter-toml-ng-0.7.0\"),\n \"tree-sitter-typescript\": Label(\"//tree-sitter-typescript-0.23.2\"),\n \"tree-sitter-verilog\": Label(\"//tree-sitter-verilog-1.0.3\"),\n \"tree_sitter_vue\": Label(\"//tree-sitter-vue-next-0.1.0\"),\n \"tree-sitter-xml\": Label(\"//tree-sitter-xml-0.7.0\"),\n \"tree-sitter-yaml\": Label(\"//tree-sitter-yaml-0.7.2\"),\n \"tree-sitter-zig\": Label(\"//tree-sitter-zig-1.1.2\"),\n },\n },\n \"crates/pi-iso\": {\n _COMMON_CONDITION: {\n \"similar\": Label(\"//similar-3.1.1\"),\n \"tokio\": Label(\"//tokio-1.53.1\"),\n },\n \"cfg(target_os = \\\"linux\\\")\": {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"arboard\": Label(\"//arboard-3.6.1\"),\n \"ast-grep-core\": Label(\"//ast-grep-core-0.39.9\"),\n \"base64\": Label(\"//base64-0.22.1\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"flume\": Label(\"//flume-0.11.1\"),\n \"fontdue\": Label(\"//fontdue-0.9.3\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"grep-matcher\": Label(\"//grep-matcher-0.1.9\"),\n \"grep-pcre2\": Label(\"//grep-pcre2-0.1.10\"),\n \"grep-regex\": Label(\"//grep-regex-0.1.14\"),\n \"grep-searcher\": Label(\"//grep-searcher-0.1.17\"),\n \"html-to-markdown-rs\": Label(\"//html-to-markdown-rs-2.30.0\"),\n \"icy_sixel\": Label(\"//icy_sixel-0.5.0\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"image\": Label(\"//image-0.25.10\"),\n \"inferno\": Label(\"//inferno-0.12.8\"),\n \"napi\": Label(\"//napi-3.12.0\"),\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"phf\": Label(\"//phf-0.13.1\"),\n \"png\": Label(\"//png-0.18.1\"),\n \"portable-pty\": Label(\"//portable-pty-0.9.0\"),\n \"rayon\": Label(\"//rayon-1.12.0\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"serde\": Label(\"//serde-1.0.229\"),\n \"serde_json\": Label(\"//serde_json-1.0.151\"),\n \"smallvec\": Label(\"//smallvec-1.15.2\"),\n \"syntect\": Label(\"//syntect-5.3.0\"),\n \"tiktoken-rs\": Label(\"//tiktoken-rs-0.11.0\"),\n \"tokio\": Label(\"//tokio-1.53.1\"),\n \"tokio-util\": Label(\"//tokio-util-0.7.19\"),\n \"toml\": Label(\"//toml-1.1.3+spec-1.1.0\"),\n \"unicode-segmentation\": Label(\"//unicode-segmentation-1.13.3\"),\n \"unicode-width\": Label(\"//unicode-width-0.2.2\"),\n \"xxhash-rust\": Label(\"//xxhash-rust-0.8.18\"),\n },\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"windows\\\"))\": {\n \"enigo\": Label(\"//enigo-0.6.1\"),\n \"xcap\": Label(\"//xcap-0.9.6\"),\n },\n \"cfg(target_os = \\\"linux\\\")\": {\n \"x11rb\": Label(\"//x11rb-0.13.2\"),\n \"xkeysym\": Label(\"//xkeysym-0.2.1\"),\n },\n \"cfg(target_os = \\\"macos\\\")\": {\n \"core-graphics\": Label(\"//core-graphics-0.25.0\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"clipboard-win\": Label(\"//clipboard-win-5.4.1\"),\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n \"winreg\": Label(\"//winreg-0.56.0\"),\n },\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"brush-parser\": Label(\"//brush-parser-0.3.0\"),\n \"bytes\": Label(\"//bytes-1.12.1\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"flume\": Label(\"//flume-0.11.1\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"jiff\": Label(\"//jiff-0.2.35\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"os_pipe\": Label(\"//os_pipe-1.2.3\"),\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"serde\": Label(\"//serde-1.0.229\"),\n \"serde_json\": Label(\"//serde_json-1.0.151\"),\n \"tokio\": Label(\"//tokio-1.53.1\"),\n \"tokio-util\": Label(\"//tokio-util-0.7.19\"),\n \"toml\": Label(\"//toml-1.1.3+spec-1.1.0\"),\n \"xxhash-rust\": Label(\"//xxhash-rust-0.8.18\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"smallvec\": Label(\"//smallvec-1.15.2\"),\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n \"winreg\": Label(\"//winreg-0.56.0\"),\n },\n },\n \"crates/pi-uutils-ctx\": {\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n },\n \"crates/pi-voice\": {\n _COMMON_CONDITION: {\n \"audiopus_sys\": Label(\"//audiopus_sys-0.2.2\"),\n \"bytes\": Label(\"//bytes-1.12.1\"),\n \"flume\": Label(\"//flume-0.11.1\"),\n \"maudio\": Label(\"//maudio-0.1.6\"),\n \"opus\": Label(\"//opus-0.3.1\"),\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tokio\": Label(\"//tokio-1.53.1\"),\n \"webrtc\": Label(\"//webrtc-0.17.2\"),\n },\n },\n \"crates/pi-walker\": {\n _COMMON_CONDITION: {\n \"dashmap\": Label(\"//dashmap-6.2.1\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"rayon\": Label(\"//rayon-1.12.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"similar\": Label(\"//similar-3.1.1\"),\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"globset\": Label(\"//globset-0.4.19\"),\n \"grep-cli\": Label(\"//grep-cli-0.1.12\"),\n \"grep-matcher\": Label(\"//grep-matcher-0.1.9\"),\n \"grep-pcre2\": Label(\"//grep-pcre2-0.1.10\"),\n \"grep-printer\": Label(\"//grep-printer-0.3.1\"),\n \"grep-regex\": Label(\"//grep-regex-0.1.14\"),\n \"grep-searcher\": Label(\"//grep-searcher-0.1.17\"),\n \"ignore\": Label(\"//ignore-0.4.31\"),\n \"serde_json\": Label(\"//serde_json-1.0.151\"),\n },\n },\n \"crates/vendor/uu-b2sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-base32\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-basename\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-cat\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-checksum-common\": {\n _COMMON_CONDITION: {\n \"base64-simd\": Label(\"//base64-simd-0.8.0\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"hex\": Label(\"//hex-0.4.3\"),\n \"os_display\": Label(\"//os_display-0.1.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-comm\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-cut\": {\n _COMMON_CONDITION: {\n \"bstr\": Label(\"//bstr-1.13.0\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"jiff\": Label(\"//jiff-0.2.35\"),\n \"parse_datetime\": Label(\"//parse_datetime-0.14.0\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n \"argmax\": Label(\"//argmax-0.3.1\"),\n \"chrono\": Label(\"//chrono-0.4.45\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"faccess\": Label(\"//faccess-0.2.4\"),\n \"nix\": Label(\"//nix-0.29.0\"),\n \"onig\": Label(\"//onig-6.5.3\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"uucore\": Label(\"//uucore-0.0.30\"),\n },\n },\n \"crates/vendor/uu-head\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"hostname\": Label(\"//hostname-0.4.2\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"openbsd\\\"))\": {\n \"dns-lookup\": Label(\"//dns-lookup-3.0.1\"),\n },\n \"cfg(target_os = \\\"windows\\\")\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-ls\": {\n _COMMON_CONDITION: {\n \"ansi-width\": Label(\"//ansi-width-0.1.0\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"glob\": Label(\"//glob-0.3.4\"),\n \"lscolors\": Label(\"//lscolors-0.21.0\"),\n \"rustc-hash\": Label(\"//rustc-hash-2.1.3\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n \"uutils_term_grid\": Label(\"//uutils_term_grid-0.8.0\"),\n },\n \"cfg(not(target_os = \\\"wasi\\\"))\": {\n \"hostname\": Label(\"//hostname-0.4.2\"),\n },\n },\n \"crates/vendor/uu-md5sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-mkdir\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"rand\": Label(\"//rand-0.10.2\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-mv\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"fs_extra\": Label(\"//fs_extra-1.3.0\"),\n \"indicatif\": Label(\"//indicatif-0.18.6\"),\n \"libc\": Label(\"//libc-0.2.189\"),\n \"rustc-hash\": Label(\"//rustc-hash-2.1.3\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"libc\": Label(\"//libc-0.2.189\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-paste\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-rm\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"indicatif\": Label(\"//indicatif-0.18.6\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"fancy-regex\": Label(\"//fancy-regex-0.18.0\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n \"uucore\": Label(\"//uucore-0.9.0\"),\n },\n \"cfg(unix)\": {\n \"memmap2\": Label(\"//memmap2-0.9.11\"),\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n \"bigdecimal\": Label(\"//bigdecimal-0.4.10\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"num-bigint\": Label(\"//num-bigint-0.4.8\"),\n \"num-traits\": Label(\"//num-traits-0.2.19\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha224sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha256sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha384sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sha512sum\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-sort\": {\n _COMMON_CONDITION: {\n \"bigdecimal\": Label(\"//bigdecimal-0.4.10\"),\n \"binary-heap-plus\": Label(\"//binary-heap-plus-0.5.0\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"compare\": Label(\"//compare-0.1.0\"),\n \"flume\": Label(\"//flume-0.11.1\"),\n \"foldhash\": Label(\"//foldhash-0.2.0\"),\n \"itertools\": Label(\"//itertools-0.14.0\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"rand\": Label(\"//rand-0.10.2\"),\n \"rayon\": Label(\"//rayon-1.12.0\"),\n \"self_cell\": Label(\"//self_cell-1.3.0\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"nix\": Label(\"//nix-0.31.3\"),\n },\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"memmap2\": Label(\"//memmap2-0.9.11\"),\n \"regex\": Label(\"//regex-1.13.1\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"memchr\": Label(\"//memchr-2.8.3\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(not(target_os = \\\"wasi\\\"))\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n \"notify\": Label(\"//notify-8.2.0\"),\n },\n \"cfg(unix)\": {\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-tee\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"filetime\": Label(\"//filetime-0.2.29\"),\n \"jiff\": Label(\"//jiff-0.2.35\"),\n \"parse_datetime\": Label(\"//parse_datetime-0.14.0\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n \"cfg(windows)\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-tr\": {\n _COMMON_CONDITION: {\n \"bytecount\": Label(\"//bytecount-0.6.9\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"nom\": Label(\"//nom-8.0.0\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"platform-info\": Label(\"//platform-info-2.1.0\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-uniq\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n \"crates/vendor/uu-wc\": {\n _COMMON_CONDITION: {\n \"bytecount\": Label(\"//bytecount-0.6.9\"),\n \"clap\": Label(\"//clap-4.6.4\"),\n \"thiserror\": Label(\"//thiserror-2.0.19\"),\n \"unicode-width\": Label(\"//unicode-width-0.2.2\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(unix)\": {\n \"libc\": Label(\"//libc-0.2.189\"),\n \"rustix\": Label(\"//rustix-1.1.4\"),\n },\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n \"cfg(target_os = \\\"windows\\\")\": {\n \"windows-sys\": Label(\"//windows-sys-0.61.2\"),\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"libc\": Label(\"//libc-0.2.189\"),\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n \"clap\": Label(\"//clap-4.6.4\"),\n \"itertools\": Label(\"//itertools-0.14.0\"),\n \"uucore\": Label(\"//uucore-0.8.0\"),\n },\n },\n}\n\n\n_NORMAL_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n },\n \"cfg(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"))\": {\n },\n \"cfg(any(unix, windows))\": {\n },\n \"cfg(target_family = \\\"wasm\\\")\": {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n },\n \"cfg(any(unix, windows))\": {\n },\n \"cfg(target_family = \\\"wasm\\\")\": {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n \"wasm32-unknown-unknown\": {\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-ast\": {\n _COMMON_CONDITION: {\n Label(\"//tree-sitter-astro-next-0.1.1\"): \"tree_sitter_astro\",\n Label(\"//tree-sitter-dockerfile-updated-0.2.0\"): \"tree_sitter_dockerfile\",\n Label(\"//tree-sitter-kotlin-sg-0.4.1\"): \"tree_sitter_kotlin\",\n Label(\"//tree-sitter-sequel-0.3.11\"): \"tree_sitter_sql\",\n Label(\"//tree-sitter-svelte-next-0.1.1\"): \"tree_sitter_svelte\",\n Label(\"//tree-sitter-vue-next-0.1.0\"): \"tree_sitter_vue\",\n },\n },\n \"crates/pi-iso\": {\n _COMMON_CONDITION: {\n },\n \"cfg(target_os = \\\"linux\\\")\": {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n },\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"windows\\\"))\": {\n },\n \"cfg(target_os = \\\"linux\\\")\": {\n },\n \"cfg(target_os = \\\"macos\\\")\": {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/pi-uutils-ctx\": {\n \"cfg(unix)\": {\n },\n },\n \"crates/pi-voice\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-walker\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-b2sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-base32\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-basename\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-cat\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-checksum-common\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-comm\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-cut\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-head\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n },\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"openbsd\\\"))\": {\n },\n \"cfg(target_os = \\\"windows\\\")\": {\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ls\": {\n _COMMON_CONDITION: {\n },\n \"cfg(not(target_os = \\\"wasi\\\"))\": {\n },\n },\n \"crates/vendor/uu-md5sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-mkdir\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-mv\": {\n _COMMON_CONDITION: {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-paste\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-rm\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha224sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha256sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha384sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha512sum\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sort\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n },\n \"cfg(not(target_os = \\\"wasi\\\"))\": {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-tee\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n \"cfg(windows)\": {\n },\n },\n \"crates/vendor/uu-tr\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uniq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-wc\": {\n _COMMON_CONDITION: {\n },\n \"cfg(unix)\": {\n },\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n },\n \"cfg(target_os = \\\"windows\\\")\": {\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_NORMAL_DEV_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"pretty_assertions\": Label(\"//pretty_assertions-1.4.1\"),\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n \"anyhow\": Label(\"//anyhow-1.0.104\"),\n \"pretty_assertions\": Label(\"//pretty_assertions-1.4.1\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n \"filetime\": Label(\"//filetime-0.2.29\"),\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"rstest\": Label(\"//rstest-0.26.1\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n \"tempfile\": Label(\"//tempfile-3.27.0\"),\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n \"parking_lot\": Label(\"//parking_lot-0.12.5\"),\n },\n },\n}\n\n\n_NORMAL_DEV_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_PROC_MACRO_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n \"strum_macros\": Label(\"//strum_macros-0.28.0\"),\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n \"async-recursion\": Label(\"//async-recursion-1.1.1\"),\n \"async-trait\": Label(\"//async-trait-0.1.91\"),\n \"inherent\": Label(\"//inherent-1.0.14\"),\n \"strum_macros\": Label(\"//strum_macros-0.28.0\"),\n },\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n _COMMON_CONDITION: {\n \"async-trait\": Label(\"//async-trait-0.1.91\"),\n },\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n \"napi-derive\": Label(\"//napi-derive-3.6.1\"),\n },\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_PROC_MACRO_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_PROC_MACRO_DEV_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_PROC_MACRO_DEV_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/brush-core\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/jaq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-uu-grep\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-dirname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-find\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ln\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-readlink\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-realpath\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-seq\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tac\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tail\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uname\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-xargs\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/vendor/uu-yes\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_BUILD_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n \"napi-build\": Label(\"//napi-build-2.4.0\"),\n \"serde\": Label(\"//serde-1.0.229\"),\n \"serde_json\": Label(\"//serde_json-1.0.151\"),\n },\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_BUILD_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n _COMMON_CONDITION: {\n },\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_DEPENDENCIES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_ALIASES = {\n \"crates/vendor/brush-builtins\": {\n },\n \"crates/vendor/brush-core\": {\n },\n \"crates/vendor/jaq\": {\n },\n \"crates/pi-ast\": {\n },\n \"crates/pi-iso\": {\n },\n \"crates/pi-natives\": {\n },\n \"crates/pi-shell\": {\n },\n \"crates/pi-uutils-ctx\": {\n },\n \"crates/pi-voice\": {\n },\n \"crates/pi-walker\": {\n },\n \"crates/pi-uu-diff\": {\n },\n \"crates/pi-uu-grep\": {\n },\n \"crates/vendor/uu-b2sum\": {\n },\n \"crates/vendor/uu-base32\": {\n },\n \"crates/vendor/uu-base64\": {\n },\n \"crates/vendor/uu-basename\": {\n },\n \"crates/vendor/uu-cat\": {\n },\n \"crates/vendor/uu-checksum-common\": {\n },\n \"crates/vendor/uu-comm\": {\n },\n \"crates/vendor/uu-cut\": {\n },\n \"crates/vendor/uu-date\": {\n },\n \"crates/vendor/uu-dirname\": {\n },\n \"crates/vendor/uu-find\": {\n },\n \"crates/vendor/uu-head\": {\n },\n \"crates/vendor/uu-hostname\": {\n },\n \"crates/vendor/uu-ln\": {\n },\n \"crates/vendor/uu-ls\": {\n },\n \"crates/vendor/uu-md5sum\": {\n },\n \"crates/vendor/uu-mkdir\": {\n },\n \"crates/vendor/uu-mktemp\": {\n },\n \"crates/vendor/uu-mv\": {\n },\n \"crates/vendor/uu-nproc\": {\n },\n \"crates/vendor/uu-paste\": {\n },\n \"crates/vendor/uu-printenv\": {\n },\n \"crates/vendor/uu-readlink\": {\n },\n \"crates/vendor/uu-realpath\": {\n },\n \"crates/vendor/uu-rm\": {\n },\n \"crates/vendor/uu-sed\": {\n },\n \"crates/vendor/uu-seq\": {\n },\n \"crates/vendor/uu-sha1sum\": {\n },\n \"crates/vendor/uu-sha224sum\": {\n },\n \"crates/vendor/uu-sha256sum\": {\n },\n \"crates/vendor/uu-sha384sum\": {\n },\n \"crates/vendor/uu-sha512sum\": {\n },\n \"crates/vendor/uu-sort\": {\n },\n \"crates/vendor/uu-stat\": {\n },\n \"crates/vendor/uu-tac\": {\n },\n \"crates/vendor/uu-tail\": {\n },\n \"crates/vendor/uu-tee\": {\n },\n \"crates/vendor/uu-touch\": {\n },\n \"crates/vendor/uu-tr\": {\n },\n \"crates/vendor/uu-truncate\": {\n },\n \"crates/vendor/uu-uname\": {\n },\n \"crates/vendor/uu-uniq\": {\n },\n \"crates/vendor/uu-wc\": {\n },\n \"crates/vendor/uu-whoami\": {\n },\n \"crates/vendor/uu-xargs\": {\n },\n \"crates/vendor/uu-yes\": {\n },\n}\n\n\n_CONDITIONS = {\n \"aarch64-apple-darwin\": [\"@@//bazel/triples:aarch64-apple-darwin\"],\n \"aarch64-linux-android\": [],\n \"aarch64-pc-windows-gnullvm\": [],\n \"aarch64-unknown-linux-gnu\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\"],\n \"aarch64-unknown-linux-musl\": [\"@@//bazel/triples:aarch64-unknown-linux-musl\"],\n \"cfg(all(all(target_arch = \\\"aarch64\\\", target_endian = \\\"little\\\"), target_os = \\\"windows\\\"))\": [],\n \"cfg(all(all(target_arch = \\\"aarch64\\\", target_endian = \\\"little\\\"), target_vendor = \\\"apple\\\", any(target_os = \\\"ios\\\", target_os = \\\"macos\\\", target_os = \\\"tvos\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\")))\": [\"@@//bazel/triples:aarch64-apple-darwin\"],\n \"cfg(all(any(all(target_arch = \\\"aarch64\\\", target_endian = \\\"little\\\"), all(target_arch = \\\"arm\\\", target_endian = \\\"little\\\")), any(target_os = \\\"android\\\", target_os = \\\"linux\\\")))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\"],\n \"cfg(all(any(target_arch = \\\"x86_64\\\", target_arch = \\\"arm64ec\\\"), target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(all(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [],\n \"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), not(any(all(target_os = \\\"linux\\\", target_env = \\\"\\\"), getrandom_backend = \\\"custom\\\", getrandom_backend = \\\"linux_raw\\\", getrandom_backend = \\\"rdrand\\\", getrandom_backend = \\\"rndr\\\"))))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(not(curve25519_dalek_backend = \\\"fiat\\\"), not(curve25519_dalek_backend = \\\"serial\\\"), target_arch = \\\"x86_64\\\"))\": [\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(not(rustix_use_libc), not(miri), target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\"))))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", any(target_arch = \\\"s390x\\\", target_arch = \\\"powerpc\\\")), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc\\\"), all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \\\"linux\\\", any(target_endian = \\\"little\\\", target_arch = \\\"s390x\\\"), any(target_arch = \\\"arm\\\", all(target_arch = \\\"aarch64\\\", target_pointer_width = \\\"64\\\"), target_arch = \\\"riscv64\\\", all(rustix_use_experimental_asm, target_arch = \\\"powerpc64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"s390x\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips32r6\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64\\\"), all(rustix_use_experimental_asm, target_arch = \\\"mips64r6\\\"), target_arch = \\\"x86\\\", all(target_arch = \\\"x86_64\\\", target_pointer_width = \\\"64\\\")))))))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_os = \\\"android\\\"))\": [],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_os = \\\"linux\\\"))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\"],\n \"cfg(all(target_arch = \\\"aarch64\\\", target_vendor = \\\"apple\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\"],\n \"cfg(all(target_arch = \\\"loongarch64\\\", target_os = \\\"linux\\\"))\": [],\n \"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\": [],\n \"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"wasi\\\", target_env = \\\"p2\\\"))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"gnu\\\", not(target_abi = \\\"llvm\\\"), not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"gnu\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"gnu\\\", not(target_abi = \\\"llvm\\\"), not(windows_raw_dylib)))\": [\"@@//bazel/triples:x86_64-unknown-linux-gnu\"],\n \"cfg(all(target_arch = \\\"x86_64\\\", target_env = \\\"msvc\\\", not(windows_raw_dylib)))\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\": [],\n \"cfg(all(target_os = \\\"linux\\\", not(target_env = \\\"ohos\\\")))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(target_os = \\\"uefi\\\", getrandom_backend = \\\"efi_rng\\\"))\": [],\n \"cfg(all(unix, not(any(target_os = \\\"macos\\\", target_os = \\\"android\\\", target_os = \\\"emscripten\\\"))))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(all(unix, not(target_os = \\\"macos\\\")))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any())\": [],\n \"cfg(any(target_arch = \\\"aarch64\\\", target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_arch = \\\"aarch64\\\", target_arch = \\\"x86_64\\\", target_arch = \\\"x86\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\": [\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_arch = \\\"x86_64\\\", target_arch = \\\"x86\\\"))\": [\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\", target_os = \\\"macos\\\", target_os = \\\"hurd\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"hurd\\\", target_os = \\\"illumos\\\", target_os = \\\"cygwin\\\", all(target_os = \\\"horizon\\\", target_arch = \\\"arm\\\")))\": [],\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"dragonfly\\\"))\": [],\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\": [],\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"openbsd\\\"))\": [],\n \"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"openbsd\\\", target_os = \\\"netbsd\\\", target_os = \\\"dragonflybsd\\\", target_os = \\\"ios\\\"))\": [],\n \"cfg(any(target_os = \\\"haiku\\\", target_os = \\\"redox\\\", target_os = \\\"nto\\\", target_os = \\\"aix\\\"))\": [],\n \"cfg(any(target_os = \\\"ios\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\", target_os = \\\"tvos\\\"))\": [],\n \"cfg(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"openbsd\\\", target_os = \\\"vita\\\", target_os = \\\"emscripten\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(any(target_os = \\\"macos\\\", target_os = \\\"windows\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(any(unix, target_os = \\\"fuchsia\\\", target_os = \\\"vxworks\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(unix, target_os = \\\"hermit\\\", target_os = \\\"wasi\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(unix, target_os = \\\"redox\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(unix, target_os = \\\"wasi\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(unix, windows))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(any(windows, target_os = \\\"linux\\\"))\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(curve25519_dalek_backend = \\\"fiat\\\")\": [],\n \"cfg(not(all(target_arch = \\\"arm\\\", target_os = \\\"none\\\")))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(not(any(target_os = \\\"android\\\", target_os = \\\"linux\\\")))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(not(target_has_atomic = \\\"ptr\\\"))\": [],\n \"cfg(not(target_os = \\\"wasi\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(not(target_os = \\\"windows\\\"))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(not(windows))\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(target_arch = \\\"aarch64\\\")\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\"],\n \"cfg(target_arch = \\\"spirv\\\")\": [],\n \"cfg(target_arch = \\\"x86\\\")\": [],\n \"cfg(target_arch = \\\"x86_64\\\")\": [\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-pc-windows-msvc\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(target_family = \\\"wasm\\\")\": [],\n \"cfg(target_os = \\\"android\\\")\": [],\n \"cfg(target_os = \\\"freebsd\\\")\": [],\n \"cfg(target_os = \\\"haiku\\\")\": [],\n \"cfg(target_os = \\\"hermit\\\")\": [],\n \"cfg(target_os = \\\"linux\\\")\": [\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(target_os = \\\"macos\\\")\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(target_os = \\\"netbsd\\\")\": [],\n \"cfg(target_os = \\\"redox\\\")\": [],\n \"cfg(target_os = \\\"solaris\\\")\": [],\n \"cfg(target_os = \\\"vxworks\\\")\": [],\n \"cfg(target_os = \\\"wasi\\\")\": [],\n \"cfg(target_os = \\\"windows\\\")\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(target_vendor = \\\"apple\\\")\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"cfg(unix)\": [\"@@//bazel/triples:aarch64-apple-darwin\",\"@@//bazel/triples:aarch64-unknown-linux-gnu\",\"@@//bazel/triples:aarch64-unknown-linux-musl\",\"@@//bazel/triples:x86_64-apple-darwin\",\"@@//bazel/triples:x86_64-unknown-linux-gnu\",\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n \"cfg(windows)\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"cfg(windows_raw_dylib)\": [],\n \"i686-pc-windows-gnu\": [],\n \"i686-pc-windows-gnullvm\": [],\n \"wasm32-unknown-unknown\": [],\n \"x86_64-apple-darwin\": [\"@@//bazel/triples:x86_64-apple-darwin\"],\n \"x86_64-pc-windows-gnu\": [],\n \"x86_64-pc-windows-gnullvm\": [],\n \"x86_64-pc-windows-msvc\": [\"@@//bazel/triples:x86_64-pc-windows-msvc\"],\n \"x86_64-unknown-linux-gnu\": [\"@@//bazel/triples:x86_64-unknown-linux-gnu\"],\n \"x86_64-unknown-linux-musl\": [\"@@//bazel/triples:x86_64-unknown-linux-musl\"],\n}\n\n###############################################################################\n\ndef crate_repositories():\n \"\"\"A macro for defining repositories for all generated crates.\n\n Returns:\n A list of repos visible to the module through the module extension.\n \"\"\"\n maybe(\n crates_vendor_remote_repository,\n name = \"crates\",\n # Lean interface: just point at `crates.bzl`; the repo rule\n # derives the sibling `BUILD.bazel` and `defs.bzl`.\n crates_module = Label(\"@crates//crates:crates.bzl\"),\n )\n maybe(\n http_archive,\n name = \"crates__adler2-2.0.1\",\n sha256 = \"320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/adler2/2.0.1/download\"],\n strip_prefix = \"adler2-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.adler2-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__aead-0.5.2\",\n sha256 = \"d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aead/0.5.2/download\"],\n strip_prefix = \"aead-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.aead-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__aes-0.8.4\",\n sha256 = \"b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aes/0.8.4/download\"],\n strip_prefix = \"aes-0.8.4\",\n build_file = Label(\"@crates//crates:BUILD.aes-0.8.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__aes-gcm-0.10.3\",\n sha256 = \"831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aes-gcm/0.10.3/download\"],\n strip_prefix = \"aes-gcm-0.10.3\",\n build_file = Label(\"@crates//crates:BUILD.aes-gcm-0.10.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ahash-0.8.12\",\n sha256 = \"5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ahash/0.8.12/download\"],\n strip_prefix = \"ahash-0.8.12\",\n build_file = Label(\"@crates//crates:BUILD.ahash-0.8.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__aho-corasick-1.1.4\",\n sha256 = \"ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aho-corasick/1.1.4/download\"],\n strip_prefix = \"aho-corasick-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.aho-corasick-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__allocator-api2-0.2.21\",\n sha256 = \"683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/allocator-api2/0.2.21/download\"],\n strip_prefix = \"allocator-api2-0.2.21\",\n build_file = Label(\"@crates//crates:BUILD.allocator-api2-0.2.21.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__android_system_properties-0.1.5\",\n sha256 = \"819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/android_system_properties/0.1.5/download\"],\n strip_prefix = \"android_system_properties-0.1.5\",\n build_file = Label(\"@crates//crates:BUILD.android_system_properties-0.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__annotate-snippets-0.11.5\",\n sha256 = \"710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/annotate-snippets/0.11.5/download\"],\n strip_prefix = \"annotate-snippets-0.11.5\",\n build_file = Label(\"@crates//crates:BUILD.annotate-snippets-0.11.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ansi-width-0.1.0\",\n sha256 = \"219e3ce6f2611d83b51ec2098a12702112c29e57203a6b0a0929b2cddb486608\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ansi-width/0.1.0/download\"],\n strip_prefix = \"ansi-width-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.ansi-width-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstream-1.0.0\",\n sha256 = \"824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstream/1.0.0/download\"],\n strip_prefix = \"anstream-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.anstream-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-1.0.14\",\n sha256 = \"940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle/1.0.14/download\"],\n strip_prefix = \"anstyle-1.0.14\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-1.0.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-parse-1.0.0\",\n sha256 = \"52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle-parse/1.0.0/download\"],\n strip_prefix = \"anstyle-parse-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-parse-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-query-1.1.5\",\n sha256 = \"40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle-query/1.1.5/download\"],\n strip_prefix = \"anstyle-query-1.1.5\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-query-1.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-wincon-3.0.11\",\n sha256 = \"291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle-wincon/3.0.11/download\"],\n strip_prefix = \"anstyle-wincon-3.0.11\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-wincon-3.0.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anyhow-1.0.104\",\n sha256 = \"330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anyhow/1.0.104/download\"],\n strip_prefix = \"anyhow-1.0.104\",\n build_file = Label(\"@crates//crates:BUILD.anyhow-1.0.104.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__arboard-3.6.1\",\n sha256 = \"0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/arboard/3.6.1/download\"],\n strip_prefix = \"arboard-3.6.1\",\n build_file = Label(\"@crates//crates:BUILD.arboard-3.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__arc-swap-1.9.2\",\n sha256 = \"c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/arc-swap/1.9.2/download\"],\n strip_prefix = \"arc-swap-1.9.2\",\n build_file = Label(\"@crates//crates:BUILD.arc-swap-1.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__archery-1.2.2\",\n sha256 = \"70e0a5f99dfebb87bb342d0f53bb92c81842e100bbb915223e38349580e5441d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/archery/1.2.2/download\"],\n strip_prefix = \"archery-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.archery-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__argmax-0.3.1\",\n sha256 = \"5b7e3ef5e3a7f2c5e5a49d90ad087c03d38258e75155daac64deb62c50972c66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/argmax/0.3.1/download\"],\n strip_prefix = \"argmax-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.argmax-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__arrayref-0.3.9\",\n sha256 = \"76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/arrayref/0.3.9/download\"],\n strip_prefix = \"arrayref-0.3.9\",\n build_file = Label(\"@crates//crates:BUILD.arrayref-0.3.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__arrayvec-0.7.8\",\n sha256 = \"d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/arrayvec/0.7.8/download\"],\n strip_prefix = \"arrayvec-0.7.8\",\n build_file = Label(\"@crates//crates:BUILD.arrayvec-0.7.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__asn1-rs-0.6.2\",\n sha256 = \"5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/asn1-rs/0.6.2/download\"],\n strip_prefix = \"asn1-rs-0.6.2\",\n build_file = Label(\"@crates//crates:BUILD.asn1-rs-0.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__asn1-rs-derive-0.5.1\",\n sha256 = \"965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/asn1-rs-derive/0.5.1/download\"],\n strip_prefix = \"asn1-rs-derive-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.asn1-rs-derive-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__asn1-rs-impl-0.2.0\",\n sha256 = \"7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/asn1-rs-impl/0.2.0/download\"],\n strip_prefix = \"asn1-rs-impl-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.asn1-rs-impl-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ast-grep-core-0.39.9\",\n sha256 = \"057ae90e7256ebf85f840b1638268df0142c9d19467d500b790631fd301acc27\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ast-grep-core/0.39.9/download\"],\n strip_prefix = \"ast-grep-core-0.39.9\",\n build_file = Label(\"@crates//crates:BUILD.ast-grep-core-0.39.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__astral-tl-0.7.11\",\n sha256 = \"d90933ffb0f97e2fc2e0de21da9d3f20597b804012d199843a6fe7c2810d28f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/astral-tl/0.7.11/download\"],\n strip_prefix = \"astral-tl-0.7.11\",\n build_file = Label(\"@crates//crates:BUILD.astral-tl-0.7.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-broadcast-0.7.2\",\n sha256 = \"435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-broadcast/0.7.2/download\"],\n strip_prefix = \"async-broadcast-0.7.2\",\n build_file = Label(\"@crates//crates:BUILD.async-broadcast-0.7.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-channel-2.5.0\",\n sha256 = \"924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-channel/2.5.0/download\"],\n strip_prefix = \"async-channel-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.async-channel-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-executor-1.14.0\",\n sha256 = \"c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-executor/1.14.0/download\"],\n strip_prefix = \"async-executor-1.14.0\",\n build_file = Label(\"@crates//crates:BUILD.async-executor-1.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-io-2.6.0\",\n sha256 = \"456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-io/2.6.0/download\"],\n strip_prefix = \"async-io-2.6.0\",\n build_file = Label(\"@crates//crates:BUILD.async-io-2.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-lock-3.4.2\",\n sha256 = \"290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-lock/3.4.2/download\"],\n strip_prefix = \"async-lock-3.4.2\",\n build_file = Label(\"@crates//crates:BUILD.async-lock-3.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-process-2.5.0\",\n sha256 = \"fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-process/2.5.0/download\"],\n strip_prefix = \"async-process-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.async-process-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-recursion-1.1.1\",\n sha256 = \"3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-recursion/1.1.1/download\"],\n strip_prefix = \"async-recursion-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.async-recursion-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-signal-0.2.14\",\n sha256 = \"52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-signal/0.2.14/download\"],\n strip_prefix = \"async-signal-0.2.14\",\n build_file = Label(\"@crates//crates:BUILD.async-signal-0.2.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-task-4.7.1\",\n sha256 = \"8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-task/4.7.1/download\"],\n strip_prefix = \"async-task-4.7.1\",\n build_file = Label(\"@crates//crates:BUILD.async-task-4.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__async-trait-0.1.91\",\n sha256 = \"ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/async-trait/0.1.91/download\"],\n strip_prefix = \"async-trait-0.1.91\",\n build_file = Label(\"@crates//crates:BUILD.async-trait-0.1.91.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__atomic-waker-1.1.2\",\n sha256 = \"1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/atomic-waker/1.1.2/download\"],\n strip_prefix = \"atomic-waker-1.1.2\",\n build_file = Label(\"@crates//crates:BUILD.atomic-waker-1.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__audiopus_sys-0.2.2\",\n sha256 = \"62314a1546a2064e033665d658e88c620a62904be945f8147e6b16c3db9f8651\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/audiopus_sys/0.2.2/download\"],\n strip_prefix = \"audiopus_sys-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.audiopus_sys-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__autocfg-1.5.1\",\n sha256 = \"f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/autocfg/1.5.1/download\"],\n strip_prefix = \"autocfg-1.5.1\",\n build_file = Label(\"@crates//crates:BUILD.autocfg-1.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base16ct-0.2.0\",\n sha256 = \"4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base16ct/0.2.0/download\"],\n strip_prefix = \"base16ct-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.base16ct-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64-0.22.1\",\n sha256 = \"72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64/0.22.1/download\"],\n strip_prefix = \"base64-0.22.1\",\n build_file = Label(\"@crates//crates:BUILD.base64-0.22.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64-simd-0.8.0\",\n sha256 = \"339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64-simd/0.8.0/download\"],\n strip_prefix = \"base64-simd-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.base64-simd-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__base64ct-1.8.3\",\n sha256 = \"2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/base64ct/1.8.3/download\"],\n strip_prefix = \"base64ct-1.8.3\",\n build_file = Label(\"@crates//crates:BUILD.base64ct-1.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bigdecimal-0.4.10\",\n sha256 = \"4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bigdecimal/0.4.10/download\"],\n strip_prefix = \"bigdecimal-0.4.10\",\n build_file = Label(\"@crates//crates:BUILD.bigdecimal-0.4.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__binary-heap-plus-0.5.0\",\n sha256 = \"e4551d8382e911ecc0d0f0ffb602777988669be09447d536ff4388d1def11296\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/binary-heap-plus/0.5.0/download\"],\n strip_prefix = \"binary-heap-plus-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.binary-heap-plus-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bincode-1.3.3\",\n sha256 = \"b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bincode/1.3.3/download\"],\n strip_prefix = \"bincode-1.3.3\",\n build_file = Label(\"@crates//crates:BUILD.bincode-1.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bindgen-0.72.1\",\n sha256 = \"993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bindgen/0.72.1/download\"],\n strip_prefix = \"bindgen-0.72.1\",\n build_file = Label(\"@crates//crates:BUILD.bindgen-0.72.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bit-set-0.8.0\",\n sha256 = \"08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bit-set/0.8.0/download\"],\n strip_prefix = \"bit-set-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.bit-set-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bit-vec-0.8.0\",\n sha256 = \"5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bit-vec/0.8.0/download\"],\n strip_prefix = \"bit-vec-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.bit-vec-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitflags-1.3.2\",\n sha256 = \"bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitflags/1.3.2/download\"],\n strip_prefix = \"bitflags-1.3.2\",\n build_file = Label(\"@crates//crates:BUILD.bitflags-1.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitflags-2.13.1\",\n sha256 = \"b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitflags/2.13.1/download\"],\n strip_prefix = \"bitflags-2.13.1\",\n build_file = Label(\"@crates//crates:BUILD.bitflags-2.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitvec-1.1.1\",\n sha256 = \"ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitvec/1.1.1/download\"],\n strip_prefix = \"bitvec-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.bitvec-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blake2b_simd-1.0.4\",\n sha256 = \"b79834656f71332577234b50bfc009996f7449e0c056884e6a02492ded0ca2f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blake2b_simd/1.0.4/download\"],\n strip_prefix = \"blake2b_simd-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.blake2b_simd-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blake3-1.8.5\",\n sha256 = \"0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blake3/1.8.5/download\"],\n strip_prefix = \"blake3-1.8.5\",\n build_file = Label(\"@crates//crates:BUILD.blake3-1.8.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-buffer-0.10.4\",\n sha256 = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-buffer/0.10.4/download\"],\n strip_prefix = \"block-buffer-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.block-buffer-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-buffer-0.12.1\",\n sha256 = \"d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-buffer/0.12.1/download\"],\n strip_prefix = \"block-buffer-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.block-buffer-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block-padding-0.3.3\",\n sha256 = \"a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block-padding/0.3.3/download\"],\n strip_prefix = \"block-padding-0.3.3\",\n build_file = Label(\"@crates//crates:BUILD.block-padding-0.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__block2-0.6.2\",\n sha256 = \"cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/block2/0.6.2/download\"],\n strip_prefix = \"block2-0.6.2\",\n build_file = Label(\"@crates//crates:BUILD.block2-0.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__blocking-1.6.2\",\n sha256 = \"e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/blocking/1.6.2/download\"],\n strip_prefix = \"blocking-1.6.2\",\n build_file = Label(\"@crates//crates:BUILD.blocking-1.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bon-3.9.3\",\n sha256 = \"a602c73c7b0148ec6d12af6fd5cc7a46e2eacc8878271a999abac56eed12f561\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bon/3.9.3/download\"],\n strip_prefix = \"bon-3.9.3\",\n build_file = Label(\"@crates//crates:BUILD.bon-3.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bon-macros-3.9.3\",\n sha256 = \"6dee98b0db6a962de883bf5d20362dee4d7ca0d12fe39a7c6c73c844e1cd7c1f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bon-macros/3.9.3/download\"],\n strip_prefix = \"bon-macros-3.9.3\",\n build_file = Label(\"@crates//crates:BUILD.bon-macros-3.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__brush-parser-0.3.0\",\n sha256 = \"f7367124d4f38fdcd65f4b815bda7caeb3de377b9cd95ffa1b23627989c93718\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/brush-parser/0.3.0/download\"],\n strip_prefix = \"brush-parser-0.3.0\",\n build_file = Label(\"@crates//crates:BUILD.brush-parser-0.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__brush-parser-0.4.0\",\n sha256 = \"9f64b19efc02f0dd6cac1d462e20a1098f425f09cb13624efbb1b7d63f061735\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/brush-parser/0.4.0/download\"],\n strip_prefix = \"brush-parser-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.brush-parser-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bstr-1.13.0\",\n sha256 = \"1f7dc094d718f2e1c1559ad110e27eeaae14a5465d3d56dd6dbd793079fbd530\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bstr/1.13.0/download\"],\n strip_prefix = \"bstr-1.13.0\",\n build_file = Label(\"@crates//crates:BUILD.bstr-1.13.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bumpalo-3.20.3\",\n sha256 = \"72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bumpalo/3.20.3/download\"],\n strip_prefix = \"bumpalo-3.20.3\",\n build_file = Label(\"@crates//crates:BUILD.bumpalo-3.20.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__by_address-1.2.1\",\n sha256 = \"64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/by_address/1.2.1/download\"],\n strip_prefix = \"by_address-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.by_address-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytecheck-0.8.2\",\n sha256 = \"0caa33a2c0edca0419d15ac723dff03f1956f7978329b1e3b5fdaaaed9d3ca8b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytecheck/0.8.2/download\"],\n strip_prefix = \"bytecheck-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.bytecheck-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytecheck_derive-0.8.2\",\n sha256 = \"89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytecheck_derive/0.8.2/download\"],\n strip_prefix = \"bytecheck_derive-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.bytecheck_derive-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytecount-0.6.9\",\n sha256 = \"175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytecount/0.6.9/download\"],\n strip_prefix = \"bytecount-0.6.9\",\n build_file = Label(\"@crates//crates:BUILD.bytecount-0.6.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytemuck-1.25.2\",\n sha256 = \"95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytemuck/1.25.2/download\"],\n strip_prefix = \"bytemuck-1.25.2\",\n build_file = Label(\"@crates//crates:BUILD.bytemuck-1.25.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytemuck_derive-1.11.0\",\n sha256 = \"f65693059b6b9c588b9f62fed1cedbf0a8b805631457ea162d68f0de186f3de5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytemuck_derive/1.11.0/download\"],\n strip_prefix = \"bytemuck_derive-1.11.0\",\n build_file = Label(\"@crates//crates:BUILD.bytemuck_derive-1.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__byteorder-1.5.0\",\n sha256 = \"1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/byteorder/1.5.0/download\"],\n strip_prefix = \"byteorder-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.byteorder-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__byteorder-lite-0.1.0\",\n sha256 = \"8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/byteorder-lite/0.1.0/download\"],\n strip_prefix = \"byteorder-lite-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.byteorder-lite-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bytes-1.12.1\",\n sha256 = \"fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bytes/1.12.1/download\"],\n strip_prefix = \"bytes-1.12.1\",\n build_file = Label(\"@crates//crates:BUILD.bytes-1.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached-0.56.0\",\n sha256 = \"801927ee168e17809ab8901d9f01f700cd7d8d6a6527997fee44e4b0327a253c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached/0.56.0/download\"],\n strip_prefix = \"cached-0.56.0\",\n build_file = Label(\"@crates//crates:BUILD.cached-0.56.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached-0.59.0\",\n sha256 = \"53b6f5d101f0f6322c8646a45b7c581a673e476329040d97565815c2461dd0c4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached/0.59.0/download\"],\n strip_prefix = \"cached-0.59.0\",\n build_file = Label(\"@crates//crates:BUILD.cached-0.59.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached_proc_macro-0.25.0\",\n sha256 = \"9225bdcf4e4a9a4c08bf16607908eb2fbf746828d5e0b5e019726dbf6571f201\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached_proc_macro/0.25.0/download\"],\n strip_prefix = \"cached_proc_macro-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.cached_proc_macro-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached_proc_macro-0.27.0\",\n sha256 = \"8ebcf9c75f17a17d55d11afc98e46167d4790a263f428891b8705ab2f793eca3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached_proc_macro/0.27.0/download\"],\n strip_prefix = \"cached_proc_macro-0.27.0\",\n build_file = Label(\"@crates//crates:BUILD.cached_proc_macro-0.27.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cached_proc_macro_types-0.1.1\",\n sha256 = \"ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cached_proc_macro_types/0.1.1/download\"],\n strip_prefix = \"cached_proc_macro_types-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.cached_proc_macro_types-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__calendrical_calculations-0.2.4\",\n sha256 = \"5abbd6eeda6885048d357edc66748eea6e0268e3dd11f326fff5bd248d779c26\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/calendrical_calculations/0.2.4/download\"],\n strip_prefix = \"calendrical_calculations-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.calendrical_calculations-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cbc-0.1.2\",\n sha256 = \"26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cbc/0.1.2/download\"],\n strip_prefix = \"cbc-0.1.2\",\n build_file = Label(\"@crates//crates:BUILD.cbc-0.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cc-1.2.67\",\n sha256 = \"e17dd265a7d0f31ef544e1b20e03add05d3b45b491b633b10d67145d2acc1a38\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cc/1.2.67/download\"],\n strip_prefix = \"cc-1.2.67\",\n build_file = Label(\"@crates//crates:BUILD.cc-1.2.67.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ccm-0.5.0\",\n sha256 = \"9ae3c82e4355234767756212c570e29833699ab63e6ffd161887314cc5b43847\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ccm/0.5.0/download\"],\n strip_prefix = \"ccm-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.ccm-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cexpr-0.6.0\",\n sha256 = \"6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cexpr/0.6.0/download\"],\n strip_prefix = \"cexpr-0.6.0\",\n build_file = Label(\"@crates//crates:BUILD.cexpr-0.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg-expr-0.20.8\",\n sha256 = \"fb693542bcafa528e198be0ebd9d3632ca5b7c93dbe7237460e199910835997c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg-expr/0.20.8/download\"],\n strip_prefix = \"cfg-expr-0.20.8\",\n build_file = Label(\"@crates//crates:BUILD.cfg-expr-0.20.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg-if-1.0.4\",\n sha256 = \"9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg-if/1.0.4/download\"],\n strip_prefix = \"cfg-if-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.cfg-if-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg_aliases-0.1.1\",\n sha256 = \"fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg_aliases/0.1.1/download\"],\n strip_prefix = \"cfg_aliases-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.cfg_aliases-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg_aliases-0.2.2\",\n sha256 = \"f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg_aliases/0.2.2/download\"],\n strip_prefix = \"cfg_aliases-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.cfg_aliases-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chacha20-0.10.1\",\n sha256 = \"d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chacha20/0.10.1/download\"],\n strip_prefix = \"chacha20-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.chacha20-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chacha20-0.9.1\",\n sha256 = \"c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chacha20/0.9.1/download\"],\n strip_prefix = \"chacha20-0.9.1\",\n build_file = Label(\"@crates//crates:BUILD.chacha20-0.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chacha20poly1305-0.10.1\",\n sha256 = \"10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chacha20poly1305/0.10.1/download\"],\n strip_prefix = \"chacha20poly1305-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.chacha20poly1305-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__check_elevation-0.2.7\",\n sha256 = \"a7fe1fbbd8bd3174109071530f12932ff471eeff30d83e9c485d6ff424ac534b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/check_elevation/0.2.7/download\"],\n strip_prefix = \"check_elevation-0.2.7\",\n build_file = Label(\"@crates//crates:BUILD.check_elevation-0.2.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chrono-0.4.45\",\n sha256 = \"1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chrono/0.4.45/download\"],\n strip_prefix = \"chrono-0.4.45\",\n build_file = Label(\"@crates//crates:BUILD.chrono-0.4.45.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__chrono-tz-0.10.4\",\n sha256 = \"a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/chrono-tz/0.10.4/download\"],\n strip_prefix = \"chrono-tz-0.10.4\",\n build_file = Label(\"@crates//crates:BUILD.chrono-tz-0.10.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cipher-0.4.4\",\n sha256 = \"773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cipher/0.4.4/download\"],\n strip_prefix = \"cipher-0.4.4\",\n build_file = Label(\"@crates//crates:BUILD.cipher-0.4.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clang-sys-1.8.1\",\n sha256 = \"0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clang-sys/1.8.1/download\"],\n strip_prefix = \"clang-sys-1.8.1\",\n build_file = Label(\"@crates//crates:BUILD.clang-sys-1.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap-4.6.4\",\n sha256 = \"d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap/4.6.4/download\"],\n strip_prefix = \"clap-4.6.4\",\n build_file = Label(\"@crates//crates:BUILD.clap-4.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap_builder-4.6.2\",\n sha256 = \"f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap_builder/4.6.2/download\"],\n strip_prefix = \"clap_builder-4.6.2\",\n build_file = Label(\"@crates//crates:BUILD.clap_builder-4.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap_derive-4.6.4\",\n sha256 = \"d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap_derive/4.6.4/download\"],\n strip_prefix = \"clap_derive-4.6.4\",\n build_file = Label(\"@crates//crates:BUILD.clap_derive-4.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap_lex-1.1.0\",\n sha256 = \"c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap_lex/1.1.0/download\"],\n strip_prefix = \"clap_lex-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.clap_lex-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clipboard-win-5.4.1\",\n sha256 = \"bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clipboard-win/5.4.1/download\"],\n strip_prefix = \"clipboard-win-5.4.1\",\n build_file = Label(\"@crates//crates:BUILD.clipboard-win-5.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cmake-0.1.58\",\n sha256 = \"c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cmake/0.1.58/download\"],\n strip_prefix = \"cmake-0.1.58\",\n build_file = Label(\"@crates//crates:BUILD.cmake-0.1.58.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__codesnake-0.2.1\",\n sha256 = \"2205f7f6d3de68ecf4c291c789b3edf07b6569268abd0188819086f71ae42225\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/codesnake/0.2.1/download\"],\n strip_prefix = \"codesnake-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.codesnake-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__color-print-0.3.7\",\n sha256 = \"3aa954171903797d5623e047d9ab69d91b493657917bdfb8c2c80ecaf9cdb6f4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/color-print/0.3.7/download\"],\n strip_prefix = \"color-print-0.3.7\",\n build_file = Label(\"@crates//crates:BUILD.color-print-0.3.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__color-print-proc-macro-0.3.7\",\n sha256 = \"692186b5ebe54007e45a59aea47ece9eb4108e141326c304cdc91699a7118a22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/color-print-proc-macro/0.3.7/download\"],\n strip_prefix = \"color-print-proc-macro-0.3.7\",\n build_file = Label(\"@crates//crates:BUILD.color-print-proc-macro-0.3.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__color_quant-1.1.0\",\n sha256 = \"3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/color_quant/1.1.0/download\"],\n strip_prefix = \"color_quant-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.color_quant-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__colorchoice-1.0.5\",\n sha256 = \"1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/colorchoice/1.0.5/download\"],\n strip_prefix = \"colorchoice-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.colorchoice-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__command-fds-0.3.3\",\n sha256 = \"1b60b5124979fccd9addd89d8b97a1d6eebb4950694520c75ddd722535ea443f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/command-fds/0.3.3/download\"],\n strip_prefix = \"command-fds-0.3.3\",\n build_file = Label(\"@crates//crates:BUILD.command-fds-0.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__compare-0.1.0\",\n sha256 = \"120133d4db2ec47efe2e26502ee984747630c67f51974fca0b6c1340cf2368d3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/compare/0.1.0/download\"],\n strip_prefix = \"compare-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.compare-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__concurrent-queue-2.5.0\",\n sha256 = \"4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/concurrent-queue/2.5.0/download\"],\n strip_prefix = \"concurrent-queue-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.concurrent-queue-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__console-0.16.4\",\n sha256 = \"4fe5f465a4f6fee88fad41b85d990f84c835335e85b5d9e6e63e0d06d28cba7c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/console/0.16.4/download\"],\n strip_prefix = \"console-0.16.4\",\n build_file = Label(\"@crates//crates:BUILD.console-0.16.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__const-oid-0.10.2\",\n sha256 = \"a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/const-oid/0.10.2/download\"],\n strip_prefix = \"const-oid-0.10.2\",\n build_file = Label(\"@crates//crates:BUILD.const-oid-0.10.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__const-oid-0.9.6\",\n sha256 = \"c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/const-oid/0.9.6/download\"],\n strip_prefix = \"const-oid-0.9.6\",\n build_file = Label(\"@crates//crates:BUILD.const-oid-0.9.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__const-random-0.1.18\",\n sha256 = \"87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/const-random/0.1.18/download\"],\n strip_prefix = \"const-random-0.1.18\",\n build_file = Label(\"@crates//crates:BUILD.const-random-0.1.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__const-random-macro-0.1.16\",\n sha256 = \"f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/const-random-macro/0.1.16/download\"],\n strip_prefix = \"const-random-macro-0.1.16\",\n build_file = Label(\"@crates//crates:BUILD.const-random-macro-0.1.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__constant_time_eq-0.4.2\",\n sha256 = \"3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/constant_time_eq/0.4.2/download\"],\n strip_prefix = \"constant_time_eq-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.constant_time_eq-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__convert_case-0.11.0\",\n sha256 = \"affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/convert_case/0.11.0/download\"],\n strip_prefix = \"convert_case-0.11.0\",\n build_file = Label(\"@crates//crates:BUILD.convert_case-0.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__convert_case-0.8.0\",\n sha256 = \"baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/convert_case/0.8.0/download\"],\n strip_prefix = \"convert_case-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.convert_case-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cookie-factory-0.3.3\",\n sha256 = \"9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cookie-factory/0.3.3/download\"],\n strip_prefix = \"cookie-factory-0.3.3\",\n build_file = Label(\"@crates//crates:BUILD.cookie-factory-0.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core-foundation-0.10.1\",\n sha256 = \"b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core-foundation/0.10.1/download\"],\n strip_prefix = \"core-foundation-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.core-foundation-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core-foundation-sys-0.8.7\",\n sha256 = \"773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core-foundation-sys/0.8.7/download\"],\n strip_prefix = \"core-foundation-sys-0.8.7\",\n build_file = Label(\"@crates//crates:BUILD.core-foundation-sys-0.8.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core-graphics-0.25.0\",\n sha256 = \"064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core-graphics/0.25.0/download\"],\n strip_prefix = \"core-graphics-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.core-graphics-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core-graphics-types-0.2.0\",\n sha256 = \"3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core-graphics-types/0.2.0/download\"],\n strip_prefix = \"core-graphics-types-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.core-graphics-types-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__core_maths-0.1.1\",\n sha256 = \"77745e017f5edba1a9c1d854f6f3a52dac8a12dd5af5d2f54aecf61e43d80d30\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/core_maths/0.1.1/download\"],\n strip_prefix = \"core_maths-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.core_maths-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cpufeatures-0.2.17\",\n sha256 = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cpufeatures/0.2.17/download\"],\n strip_prefix = \"cpufeatures-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.cpufeatures-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cpufeatures-0.3.0\",\n sha256 = \"8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cpufeatures/0.3.0/download\"],\n strip_prefix = \"cpufeatures-0.3.0\",\n build_file = Label(\"@crates//crates:BUILD.cpufeatures-0.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crc-3.4.0\",\n sha256 = \"5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crc/3.4.0/download\"],\n strip_prefix = \"crc-3.4.0\",\n build_file = Label(\"@crates//crates:BUILD.crc-3.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crc-catalog-2.5.0\",\n sha256 = \"217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crc-catalog/2.5.0/download\"],\n strip_prefix = \"crc-catalog-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.crc-catalog-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crc-fast-1.8.2\",\n sha256 = \"85d9be5297a59f1b7651fd2711a1f4461929f53b182b394df0df15b3a387ef51\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crc-fast/1.8.2/download\"],\n strip_prefix = \"crc-fast-1.8.2\",\n build_file = Label(\"@crates//crates:BUILD.crc-fast-1.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crc32fast-1.5.0\",\n sha256 = \"9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crc32fast/1.5.0/download\"],\n strip_prefix = \"crc32fast-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.crc32fast-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crossbeam-deque-0.8.7\",\n sha256 = \"5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crossbeam-deque/0.8.7/download\"],\n strip_prefix = \"crossbeam-deque-0.8.7\",\n build_file = Label(\"@crates//crates:BUILD.crossbeam-deque-0.8.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crossbeam-epoch-0.9.20\",\n sha256 = \"2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crossbeam-epoch/0.9.20/download\"],\n strip_prefix = \"crossbeam-epoch-0.9.20\",\n build_file = Label(\"@crates//crates:BUILD.crossbeam-epoch-0.9.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crossbeam-utils-0.8.22\",\n sha256 = \"61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crossbeam-utils/0.8.22/download\"],\n strip_prefix = \"crossbeam-utils-0.8.22\",\n build_file = Label(\"@crates//crates:BUILD.crossbeam-utils-0.8.22.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crunchy-0.2.4\",\n sha256 = \"460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crunchy/0.2.4/download\"],\n strip_prefix = \"crunchy-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.crunchy-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-bigint-0.5.5\",\n sha256 = \"0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-bigint/0.5.5/download\"],\n strip_prefix = \"crypto-bigint-0.5.5\",\n build_file = Label(\"@crates//crates:BUILD.crypto-bigint-0.5.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-common-0.1.7\",\n sha256 = \"78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-common/0.1.7/download\"],\n strip_prefix = \"crypto-common-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.crypto-common-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__crypto-common-0.2.2\",\n sha256 = \"ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/crypto-common/0.2.2/download\"],\n strip_prefix = \"crypto-common-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.crypto-common-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ctor-1.0.11\",\n sha256 = \"e9bb72bb94fdc1bd619f4c18cc91ecf6302aeb333d31b3c6ec0bb841cd920209\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ctor/1.0.11/download\"],\n strip_prefix = \"ctor-1.0.11\",\n build_file = Label(\"@crates//crates:BUILD.ctor-1.0.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ctr-0.9.2\",\n sha256 = \"0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ctr/0.9.2/download\"],\n strip_prefix = \"ctr-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.ctr-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__curve25519-dalek-4.1.3\",\n sha256 = \"97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/curve25519-dalek/4.1.3/download\"],\n strip_prefix = \"curve25519-dalek-4.1.3\",\n build_file = Label(\"@crates//crates:BUILD.curve25519-dalek-4.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__curve25519-dalek-derive-0.1.1\",\n sha256 = \"f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/curve25519-dalek-derive/0.1.1/download\"],\n strip_prefix = \"curve25519-dalek-derive-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.curve25519-dalek-derive-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling-0.20.11\",\n sha256 = \"fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling/0.20.11/download\"],\n strip_prefix = \"darling-0.20.11\",\n build_file = Label(\"@crates//crates:BUILD.darling-0.20.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling-0.23.0\",\n sha256 = \"25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling/0.23.0/download\"],\n strip_prefix = \"darling-0.23.0\",\n build_file = Label(\"@crates//crates:BUILD.darling-0.23.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling_core-0.20.11\",\n sha256 = \"0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling_core/0.20.11/download\"],\n strip_prefix = \"darling_core-0.20.11\",\n build_file = Label(\"@crates//crates:BUILD.darling_core-0.20.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling_core-0.23.0\",\n sha256 = \"9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling_core/0.23.0/download\"],\n strip_prefix = \"darling_core-0.23.0\",\n build_file = Label(\"@crates//crates:BUILD.darling_core-0.23.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling_macro-0.20.11\",\n sha256 = \"fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling_macro/0.20.11/download\"],\n strip_prefix = \"darling_macro-0.20.11\",\n build_file = Label(\"@crates//crates:BUILD.darling_macro-0.20.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__darling_macro-0.23.0\",\n sha256 = \"ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/darling_macro/0.23.0/download\"],\n strip_prefix = \"darling_macro-0.23.0\",\n build_file = Label(\"@crates//crates:BUILD.darling_macro-0.23.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dashmap-6.2.1\",\n sha256 = \"e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dashmap/6.2.1/download\"],\n strip_prefix = \"dashmap-6.2.1\",\n build_file = Label(\"@crates//crates:BUILD.dashmap-6.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__data-encoding-2.11.0\",\n sha256 = \"a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/data-encoding/2.11.0/download\"],\n strip_prefix = \"data-encoding-2.11.0\",\n build_file = Label(\"@crates//crates:BUILD.data-encoding-2.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__data-encoding-macro-0.1.20\",\n sha256 = \"3259c913752a86488b501ed8680446a5ed2d5aeac6e596cb23ba3800768ea32c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/data-encoding-macro/0.1.20/download\"],\n strip_prefix = \"data-encoding-macro-0.1.20\",\n build_file = Label(\"@crates//crates:BUILD.data-encoding-macro-0.1.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__data-encoding-macro-internal-0.1.18\",\n sha256 = \"ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/data-encoding-macro-internal/0.1.18/download\"],\n strip_prefix = \"data-encoding-macro-internal-0.1.18\",\n build_file = Label(\"@crates//crates:BUILD.data-encoding-macro-internal-0.1.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__defmt-1.1.1\",\n sha256 = \"e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/defmt/1.1.1/download\"],\n strip_prefix = \"defmt-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.defmt-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__defmt-macros-1.1.1\",\n sha256 = \"bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/defmt-macros/1.1.1/download\"],\n strip_prefix = \"defmt-macros-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.defmt-macros-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__defmt-parser-1.0.0\",\n sha256 = \"10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/defmt-parser/1.0.0/download\"],\n strip_prefix = \"defmt-parser-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.defmt-parser-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__der-0.7.10\",\n sha256 = \"e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/der/0.7.10/download\"],\n strip_prefix = \"der-0.7.10\",\n build_file = Label(\"@crates//crates:BUILD.der-0.7.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__der-parser-9.0.0\",\n sha256 = \"5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/der-parser/9.0.0/download\"],\n strip_prefix = \"der-parser-9.0.0\",\n build_file = Label(\"@crates//crates:BUILD.der-parser-9.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__deranged-0.5.8\",\n sha256 = \"7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/deranged/0.5.8/download\"],\n strip_prefix = \"deranged-0.5.8\",\n build_file = Label(\"@crates//crates:BUILD.deranged-0.5.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__diff-0.1.13\",\n sha256 = \"56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/diff/0.1.13/download\"],\n strip_prefix = \"diff-0.1.13\",\n build_file = Label(\"@crates//crates:BUILD.diff-0.1.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__digest-0.10.7\",\n sha256 = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/digest/0.10.7/download\"],\n strip_prefix = \"digest-0.10.7\",\n build_file = Label(\"@crates//crates:BUILD.digest-0.10.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__digest-0.11.3\",\n sha256 = \"f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/digest/0.11.3/download\"],\n strip_prefix = \"digest-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.digest-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dispatch2-0.3.1\",\n sha256 = \"1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dispatch2/0.3.1/download\"],\n strip_prefix = \"dispatch2-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.dispatch2-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__displaydoc-0.2.6\",\n sha256 = \"1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/displaydoc/0.2.6/download\"],\n strip_prefix = \"displaydoc-0.2.6\",\n build_file = Label(\"@crates//crates:BUILD.displaydoc-0.2.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dlib-0.5.3\",\n sha256 = \"ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dlib/0.5.3/download\"],\n strip_prefix = \"dlib-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.dlib-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dns-lookup-3.0.1\",\n sha256 = \"6e39034cee21a2f5bbb66ba0e3689819c4bb5d00382a282006e802a7ffa6c41d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dns-lookup/3.0.1/download\"],\n strip_prefix = \"dns-lookup-3.0.1\",\n build_file = Label(\"@crates//crates:BUILD.dns-lookup-3.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__downcast-rs-1.2.1\",\n sha256 = \"75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/downcast-rs/1.2.1/download\"],\n strip_prefix = \"downcast-rs-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.downcast-rs-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-0.14.1\",\n sha256 = \"80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm/0.14.1/download\"],\n strip_prefix = \"drm-0.14.1\",\n build_file = Label(\"@crates//crates:BUILD.drm-0.14.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-0.15.0\",\n sha256 = \"7a41816e58f47f49acfd956651055ddcf137c4882c2098c30c448817af21183a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm/0.15.0/download\"],\n strip_prefix = \"drm-0.15.0\",\n build_file = Label(\"@crates//crates:BUILD.drm-0.15.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-ffi-0.9.1\",\n sha256 = \"51a91c9b32ac4e8105dec255e849e0d66e27d7c34d184364fb93e469db08f690\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm-ffi/0.9.1/download\"],\n strip_prefix = \"drm-ffi-0.9.1\",\n build_file = Label(\"@crates//crates:BUILD.drm-ffi-0.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-fourcc-2.2.0\",\n sha256 = \"0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm-fourcc/2.2.0/download\"],\n strip_prefix = \"drm-fourcc-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.drm-fourcc-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__drm-sys-0.8.1\",\n sha256 = \"ecc8e1361066d91f5ffccff060a3c3be9c3ecde15be2959c1937595f7a82a9f8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/drm-sys/0.8.1/download\"],\n strip_prefix = \"drm-sys-0.8.1\",\n build_file = Label(\"@crates//crates:BUILD.drm-sys-0.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dtls-0.17.2\",\n sha256 = \"01a431e87fc386bd5e02deb554a013f97bc406e47a7d8e97efb7c6366b980e9c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dtls/0.17.2/download\"],\n strip_prefix = \"dtls-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.dtls-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dunce-1.0.5\",\n sha256 = \"92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dunce/1.0.5/download\"],\n strip_prefix = \"dunce-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.dunce-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__dyn-clone-1.0.20\",\n sha256 = \"d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/dyn-clone/1.0.20/download\"],\n strip_prefix = \"dyn-clone-1.0.20\",\n build_file = Label(\"@crates//crates:BUILD.dyn-clone-1.0.20.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ecdsa-0.16.9\",\n sha256 = \"ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ecdsa/0.16.9/download\"],\n strip_prefix = \"ecdsa-0.16.9\",\n build_file = Label(\"@crates//crates:BUILD.ecdsa-0.16.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__either-1.17.0\",\n sha256 = \"9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/either/1.17.0/download\"],\n strip_prefix = \"either-1.17.0\",\n build_file = Label(\"@crates//crates:BUILD.either-1.17.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__elliptic-curve-0.13.8\",\n sha256 = \"b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/elliptic-curve/0.13.8/download\"],\n strip_prefix = \"elliptic-curve-0.13.8\",\n build_file = Label(\"@crates//crates:BUILD.elliptic-curve-0.13.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__encode_unicode-1.0.0\",\n sha256 = \"34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/encode_unicode/1.0.0/download\"],\n strip_prefix = \"encode_unicode-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.encode_unicode-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__encoding_rs-0.8.35\",\n sha256 = \"75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/encoding_rs/0.8.35/download\"],\n strip_prefix = \"encoding_rs-0.8.35\",\n build_file = Label(\"@crates//crates:BUILD.encoding_rs-0.8.35.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__encoding_rs_io-0.1.7\",\n sha256 = \"1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/encoding_rs_io/0.1.7/download\"],\n strip_prefix = \"encoding_rs_io-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.encoding_rs_io-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__endi-1.1.1\",\n sha256 = \"66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/endi/1.1.1/download\"],\n strip_prefix = \"endi-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.endi-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__enigo-0.6.1\",\n sha256 = \"71c6c56e50f7acae2906a0dcbb34529ca647e40421119ad5d12e7f8ba6e50010\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/enigo/0.6.1/download\"],\n strip_prefix = \"enigo-0.6.1\",\n build_file = Label(\"@crates//crates:BUILD.enigo-0.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__enumflags2-0.7.12\",\n sha256 = \"1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/enumflags2/0.7.12/download\"],\n strip_prefix = \"enumflags2-0.7.12\",\n build_file = Label(\"@crates//crates:BUILD.enumflags2-0.7.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__enumflags2_derive-0.7.12\",\n sha256 = \"67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/enumflags2_derive/0.7.12/download\"],\n strip_prefix = \"enumflags2_derive-0.7.12\",\n build_file = Label(\"@crates//crates:BUILD.enumflags2_derive-0.7.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__equivalent-1.0.2\",\n sha256 = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/equivalent/1.0.2/download\"],\n strip_prefix = \"equivalent-1.0.2\",\n build_file = Label(\"@crates//crates:BUILD.equivalent-1.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__errno-0.3.14\",\n sha256 = \"39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/errno/0.3.14/download\"],\n strip_prefix = \"errno-0.3.14\",\n build_file = Label(\"@crates//crates:BUILD.errno-0.3.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__error-code-3.3.2\",\n sha256 = \"dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/error-code/3.3.2/download\"],\n strip_prefix = \"error-code-3.3.2\",\n build_file = Label(\"@crates//crates:BUILD.error-code-3.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__event-listener-5.4.2\",\n sha256 = \"5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/event-listener/5.4.2/download\"],\n strip_prefix = \"event-listener-5.4.2\",\n build_file = Label(\"@crates//crates:BUILD.event-listener-5.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__event-listener-strategy-0.5.4\",\n sha256 = \"8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/event-listener-strategy/0.5.4/download\"],\n strip_prefix = \"event-listener-strategy-0.5.4\",\n build_file = Label(\"@crates//crates:BUILD.event-listener-strategy-0.5.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__faccess-0.2.4\",\n sha256 = \"59ae66425802d6a903e268ae1a08b8c38ba143520f227a205edf4e9c7e3e26d5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/faccess/0.2.4/download\"],\n strip_prefix = \"faccess-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.faccess-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fancy-regex-0.16.2\",\n sha256 = \"998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fancy-regex/0.16.2/download\"],\n strip_prefix = \"fancy-regex-0.16.2\",\n build_file = Label(\"@crates//crates:BUILD.fancy-regex-0.16.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fancy-regex-0.17.0\",\n sha256 = \"72cf461f865c862bb7dc573f643dd6a2b6842f7c30b07882b56bd148cc2761b8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fancy-regex/0.17.0/download\"],\n strip_prefix = \"fancy-regex-0.17.0\",\n build_file = Label(\"@crates//crates:BUILD.fancy-regex-0.17.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fancy-regex-0.18.0\",\n sha256 = \"e1e1dacd0d2082dfcf1351c4bdd566bbe89a2b263235a2b50058f1e130a47277\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fancy-regex/0.18.0/download\"],\n strip_prefix = \"fancy-regex-0.18.0\",\n build_file = Label(\"@crates//crates:BUILD.fancy-regex-0.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fast-srgb8-1.0.0\",\n sha256 = \"dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fast-srgb8/1.0.0/download\"],\n strip_prefix = \"fast-srgb8-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.fast-srgb8-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fastrand-2.5.0\",\n sha256 = \"da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fastrand/2.5.0/download\"],\n strip_prefix = \"fastrand-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.fastrand-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fax-0.2.7\",\n sha256 = \"caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fax/0.2.7/download\"],\n strip_prefix = \"fax-0.2.7\",\n build_file = Label(\"@crates//crates:BUILD.fax-0.2.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fdeflate-0.3.7\",\n sha256 = \"1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fdeflate/0.3.7/download\"],\n strip_prefix = \"fdeflate-0.3.7\",\n build_file = Label(\"@crates//crates:BUILD.fdeflate-0.3.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ff-0.13.1\",\n sha256 = \"c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ff/0.13.1/download\"],\n strip_prefix = \"ff-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.ff-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fiat-crypto-0.2.9\",\n sha256 = \"28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fiat-crypto/0.2.9/download\"],\n strip_prefix = \"fiat-crypto-0.2.9\",\n build_file = Label(\"@crates//crates:BUILD.fiat-crypto-0.2.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__filedescriptor-0.8.3\",\n sha256 = \"e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/filedescriptor/0.8.3/download\"],\n strip_prefix = \"filedescriptor-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.filedescriptor-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__filetime-0.2.29\",\n sha256 = \"5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/filetime/0.2.29/download\"],\n strip_prefix = \"filetime-0.2.29\",\n build_file = Label(\"@crates//crates:BUILD.filetime-0.2.29.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__find-msvc-tools-0.1.9\",\n sha256 = \"5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/find-msvc-tools/0.1.9/download\"],\n strip_prefix = \"find-msvc-tools-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.find-msvc-tools-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fixed_decimal-0.7.2\",\n sha256 = \"79c3c892f121fff406e5dd6b28c1b30096b95111c30701a899d4f2b18da6d1bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fixed_decimal/0.7.2/download\"],\n strip_prefix = \"fixed_decimal-0.7.2\",\n build_file = Label(\"@crates//crates:BUILD.fixed_decimal-0.7.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fixedbitset-0.5.7\",\n sha256 = \"1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fixedbitset/0.5.7/download\"],\n strip_prefix = \"fixedbitset-0.5.7\",\n build_file = Label(\"@crates//crates:BUILD.fixedbitset-0.5.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__flate2-1.1.9\",\n sha256 = \"843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/flate2/1.1.9/download\"],\n strip_prefix = \"flate2-1.1.9\",\n build_file = Label(\"@crates//crates:BUILD.flate2-1.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fluent-0.17.0\",\n sha256 = \"8137a6d5a2c50d6b0ebfcb9aaa91a28154e0a70605f112d30cb0cd4a78670477\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fluent/0.17.0/download\"],\n strip_prefix = \"fluent-0.17.0\",\n build_file = Label(\"@crates//crates:BUILD.fluent-0.17.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fluent-bundle-0.16.0\",\n sha256 = \"01203cb8918f5711e73891b347816d932046f95f54207710bda99beaeb423bf4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fluent-bundle/0.16.0/download\"],\n strip_prefix = \"fluent-bundle-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.fluent-bundle-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fluent-langneg-0.13.1\",\n sha256 = \"7eebbe59450baee8282d71676f3bfed5689aeab00b27545e83e5f14b1195e8b0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fluent-langneg/0.13.1/download\"],\n strip_prefix = \"fluent-langneg-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.fluent-langneg-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fluent-syntax-0.12.0\",\n sha256 = \"54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fluent-syntax/0.12.0/download\"],\n strip_prefix = \"fluent-syntax-0.12.0\",\n build_file = Label(\"@crates//crates:BUILD.fluent-syntax-0.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__flume-0.11.1\",\n sha256 = \"da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/flume/0.11.1/download\"],\n strip_prefix = \"flume-0.11.1\",\n build_file = Label(\"@crates//crates:BUILD.flume-0.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fnv-1.0.7\",\n sha256 = \"3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fnv/1.0.7/download\"],\n strip_prefix = \"fnv-1.0.7\",\n build_file = Label(\"@crates//crates:BUILD.fnv-1.0.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foldhash-0.1.5\",\n sha256 = \"d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foldhash/0.1.5/download\"],\n strip_prefix = \"foldhash-0.1.5\",\n build_file = Label(\"@crates//crates:BUILD.foldhash-0.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foldhash-0.2.0\",\n sha256 = \"77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foldhash/0.2.0/download\"],\n strip_prefix = \"foldhash-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.foldhash-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fontdue-0.9.3\",\n sha256 = \"2e57e16b3fe8ff4364c0661fdaac543fb38b29ea9bc9c2f45612d90adf931d2b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fontdue/0.9.3/download\"],\n strip_prefix = \"fontdue-0.9.3\",\n build_file = Label(\"@crates//crates:BUILD.fontdue-0.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-0.5.0\",\n sha256 = \"d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types/0.5.0/download\"],\n strip_prefix = \"foreign-types-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-macros-0.2.4\",\n sha256 = \"ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types-macros/0.2.4/download\"],\n strip_prefix = \"foreign-types-macros-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-macros-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__foreign-types-shared-0.3.1\",\n sha256 = \"aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/foreign-types-shared/0.3.1/download\"],\n strip_prefix = \"foreign-types-shared-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.foreign-types-shared-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__form_urlencoded-1.2.2\",\n sha256 = \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/form_urlencoded/1.2.2/download\"],\n strip_prefix = \"form_urlencoded-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.form_urlencoded-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fs_extra-1.3.0\",\n sha256 = \"42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fs_extra/1.3.0/download\"],\n strip_prefix = \"fs_extra-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.fs_extra-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__fsevent-sys-4.1.0\",\n sha256 = \"76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/fsevent-sys/4.1.0/download\"],\n strip_prefix = \"fsevent-sys-4.1.0\",\n build_file = Label(\"@crates//crates:BUILD.fsevent-sys-4.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__funty-2.0.0\",\n sha256 = \"e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/funty/2.0.0/download\"],\n strip_prefix = \"funty-2.0.0\",\n build_file = Label(\"@crates//crates:BUILD.funty-2.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-0.3.33\",\n sha256 = \"a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures/0.3.33/download\"],\n strip_prefix = \"futures-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-channel-0.3.33\",\n sha256 = \"262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-channel/0.3.33/download\"],\n strip_prefix = \"futures-channel-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-channel-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-core-0.3.33\",\n sha256 = \"2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-core/0.3.33/download\"],\n strip_prefix = \"futures-core-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-core-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-executor-0.3.33\",\n sha256 = \"6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-executor/0.3.33/download\"],\n strip_prefix = \"futures-executor-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-executor-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-io-0.3.33\",\n sha256 = \"4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-io/0.3.33/download\"],\n strip_prefix = \"futures-io-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-io-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-lite-2.6.1\",\n sha256 = \"f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-lite/2.6.1/download\"],\n strip_prefix = \"futures-lite-2.6.1\",\n build_file = Label(\"@crates//crates:BUILD.futures-lite-2.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-macro-0.3.33\",\n sha256 = \"2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-macro/0.3.33/download\"],\n strip_prefix = \"futures-macro-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-macro-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-sink-0.3.33\",\n sha256 = \"e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-sink/0.3.33/download\"],\n strip_prefix = \"futures-sink-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-sink-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-task-0.3.33\",\n sha256 = \"b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-task/0.3.33/download\"],\n strip_prefix = \"futures-task-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-task-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-timer-3.0.4\",\n sha256 = \"af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-timer/3.0.4/download\"],\n strip_prefix = \"futures-timer-3.0.4\",\n build_file = Label(\"@crates//crates:BUILD.futures-timer-3.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__futures-util-0.3.33\",\n sha256 = \"a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/futures-util/0.3.33/download\"],\n strip_prefix = \"futures-util-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.futures-util-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gbm-0.18.0\",\n sha256 = \"ce852e998d3ca5e4a97014fb31c940dc5ef344ec7d364984525fd11e8a547e6a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gbm/0.18.0/download\"],\n strip_prefix = \"gbm-0.18.0\",\n build_file = Label(\"@crates//crates:BUILD.gbm-0.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gbm-sys-0.4.0\",\n sha256 = \"c13a5f2acc785d8fb6bf6b7ab6bfb0ef5dad4f4d97e8e70bb8e470722312f76f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gbm-sys/0.4.0/download\"],\n strip_prefix = \"gbm-sys-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.gbm-sys-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__generic-array-0.14.7\",\n sha256 = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/generic-array/0.14.7/download\"],\n strip_prefix = \"generic-array-0.14.7\",\n build_file = Label(\"@crates//crates:BUILD.generic-array-0.14.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gethostname-1.1.0\",\n sha256 = \"1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gethostname/1.1.0/download\"],\n strip_prefix = \"gethostname-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.gethostname-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.2.17\",\n sha256 = \"ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.2.17/download\"],\n strip_prefix = \"getrandom-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.3.4\",\n sha256 = \"899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.3.4/download\"],\n strip_prefix = \"getrandom-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__getrandom-0.4.3\",\n sha256 = \"300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/getrandom/0.4.3/download\"],\n strip_prefix = \"getrandom-0.4.3\",\n build_file = Label(\"@crates//crates:BUILD.getrandom-0.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ghash-0.5.1\",\n sha256 = \"f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ghash/0.5.1/download\"],\n strip_prefix = \"ghash-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.ghash-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gif-0.14.2\",\n sha256 = \"ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gif/0.14.2/download\"],\n strip_prefix = \"gif-0.14.2\",\n build_file = Label(\"@crates//crates:BUILD.gif-0.14.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gl-0.14.0\",\n sha256 = \"a94edab108827d67608095e269cf862e60d920f144a5026d3dbcfd8b877fb404\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gl/0.14.0/download\"],\n strip_prefix = \"gl-0.14.0\",\n build_file = Label(\"@crates//crates:BUILD.gl-0.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__gl_generator-0.14.0\",\n sha256 = \"1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/gl_generator/0.14.0/download\"],\n strip_prefix = \"gl_generator-0.14.0\",\n build_file = Label(\"@crates//crates:BUILD.gl_generator-0.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__glob-0.3.4\",\n sha256 = \"e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/glob/0.3.4/download\"],\n strip_prefix = \"glob-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.glob-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__globset-0.4.19\",\n sha256 = \"e47d37d2ae4464254884b60ab7071be2b876a9c35b696bd018ddcc76847309cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/globset/0.4.19/download\"],\n strip_prefix = \"globset-0.4.19\",\n build_file = Label(\"@crates//crates:BUILD.globset-0.4.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-cli-0.1.12\",\n sha256 = \"cf32d263c5d5cc2a23ce587097f5ddafdb188492ba2e6fb638eaccdc22453631\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-cli/0.1.12/download\"],\n strip_prefix = \"grep-cli-0.1.12\",\n build_file = Label(\"@crates//crates:BUILD.grep-cli-0.1.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-matcher-0.1.9\",\n sha256 = \"f9417543f4870fc8f1c8e1af870afae2431007626d9e703fce6471c468d33847\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-matcher/0.1.9/download\"],\n strip_prefix = \"grep-matcher-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.grep-matcher-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-pcre2-0.1.10\",\n sha256 = \"b752bb6f57dd3716e55b63a33ca05b5825c3d66cd427468874a5564af6ca365c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-pcre2/0.1.10/download\"],\n strip_prefix = \"grep-pcre2-0.1.10\",\n build_file = Label(\"@crates//crates:BUILD.grep-pcre2-0.1.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-printer-0.3.1\",\n sha256 = \"fd76035e87871f51c1ee5b793e32122b3ccf9c692662d9622ef1686ff5321acb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-printer/0.3.1/download\"],\n strip_prefix = \"grep-printer-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.grep-printer-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-regex-0.1.14\",\n sha256 = \"0ce0c256c3ad82bcc07b812c15a45ec1d398122e8e15124f96695234db7112ef\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-regex/0.1.14/download\"],\n strip_prefix = \"grep-regex-0.1.14\",\n build_file = Label(\"@crates//crates:BUILD.grep-regex-0.1.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__grep-searcher-0.1.17\",\n sha256 = \"72348823a0eafc4bc2e9051064f28b5b42cc100b571b3a35d67918d711efcbc6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/grep-searcher/0.1.17/download\"],\n strip_prefix = \"grep-searcher-0.1.17\",\n build_file = Label(\"@crates//crates:BUILD.grep-searcher-0.1.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__group-0.13.0\",\n sha256 = \"f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/group/0.13.0/download\"],\n strip_prefix = \"group-0.13.0\",\n build_file = Label(\"@crates//crates:BUILD.group-0.13.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__half-2.7.1\",\n sha256 = \"6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/half/2.7.1/download\"],\n strip_prefix = \"half-2.7.1\",\n build_file = Label(\"@crates//crates:BUILD.half-2.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.14.5\",\n sha256 = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.14.5/download\"],\n strip_prefix = \"hashbrown-0.14.5\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.14.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.15.5\",\n sha256 = \"9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.15.5/download\"],\n strip_prefix = \"hashbrown-0.15.5\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.15.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.16.1\",\n sha256 = \"841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.16.1/download\"],\n strip_prefix = \"hashbrown-0.16.1\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.16.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.17.1\",\n sha256 = \"ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.17.1/download\"],\n strip_prefix = \"hashbrown-0.17.1\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.17.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__heck-0.5.0\",\n sha256 = \"2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/heck/0.5.0/download\"],\n strip_prefix = \"heck-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.heck-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hermit-abi-0.5.2\",\n sha256 = \"fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hermit-abi/0.5.2/download\"],\n strip_prefix = \"hermit-abi-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.hermit-abi-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hex-0.4.3\",\n sha256 = \"7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hex/0.4.3/download\"],\n strip_prefix = \"hex-0.4.3\",\n build_file = Label(\"@crates//crates:BUILD.hex-0.4.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hifijson-0.2.3\",\n sha256 = \"0a7763b98ba8a24f59e698bf9ab197e7676c640d6455d1580b4ce7dc560f0f0d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hifijson/0.2.3/download\"],\n strip_prefix = \"hifijson-0.2.3\",\n build_file = Label(\"@crates//crates:BUILD.hifijson-0.2.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hkdf-0.12.4\",\n sha256 = \"7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hkdf/0.12.4/download\"],\n strip_prefix = \"hkdf-0.12.4\",\n build_file = Label(\"@crates//crates:BUILD.hkdf-0.12.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hmac-0.12.1\",\n sha256 = \"6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hmac/0.12.1/download\"],\n strip_prefix = \"hmac-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.hmac-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hostname-0.4.2\",\n sha256 = \"617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hostname/0.4.2/download\"],\n strip_prefix = \"hostname-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.hostname-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__html-escape-0.2.14\",\n sha256 = \"46c1ff2d1cbf39efe5af0900ced8a069b5e61557a17544eb0c4a50239937389e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/html-escape/0.2.14/download\"],\n strip_prefix = \"html-escape-0.2.14\",\n build_file = Label(\"@crates//crates:BUILD.html-escape-0.2.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__html-to-markdown-rs-2.30.0\",\n sha256 = \"7ea41945a2fd834381642a000ef75b03f0030f3023f3dd3291fc5c372d3dda33\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/html-to-markdown-rs/2.30.0/download\"],\n strip_prefix = \"html-to-markdown-rs-2.30.0\",\n build_file = Label(\"@crates//crates:BUILD.html-to-markdown-rs-2.30.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__html5ever-0.39.0\",\n sha256 = \"46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/html5ever/0.39.0/download\"],\n strip_prefix = \"html5ever-0.39.0\",\n build_file = Label(\"@crates//crates:BUILD.html5ever-0.39.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hybrid-array-0.4.13\",\n sha256 = \"818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hybrid-array/0.4.13/download\"],\n strip_prefix = \"hybrid-array-0.4.13\",\n build_file = Label(\"@crates//crates:BUILD.hybrid-array-0.4.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__iana-time-zone-0.1.65\",\n sha256 = \"e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/iana-time-zone/0.1.65/download\"],\n strip_prefix = \"iana-time-zone-0.1.65\",\n build_file = Label(\"@crates//crates:BUILD.iana-time-zone-0.1.65.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__iana-time-zone-haiku-0.1.2\",\n sha256 = \"f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/iana-time-zone-haiku/0.1.2/download\"],\n strip_prefix = \"iana-time-zone-haiku-0.1.2\",\n build_file = Label(\"@crates//crates:BUILD.iana-time-zone-haiku-0.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_calendar-2.2.1\",\n sha256 = \"a2b2acc6263f494f1df50685b53ff8e57869e47d5c6fe39c23d518ae9a4f3e45\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_calendar/2.2.1/download\"],\n strip_prefix = \"icu_calendar-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_calendar-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_calendar_data-2.2.0\",\n sha256 = \"118577bcf3a0fa7c6ac0a7d6e951814da84ee56b9b1f68fb4d8d10b08cefaf4d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_calendar_data/2.2.0/download\"],\n strip_prefix = \"icu_calendar_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_calendar_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collator-2.2.1\",\n sha256 = \"8bbdf98e5e0aa827770acee171ebb568aaab975a36b56afdb5fd0e2f525750bb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collator/2.2.1/download\"],\n strip_prefix = \"icu_collator-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_collator-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collator_data-2.2.0\",\n sha256 = \"038ed8e5817f2059c2f3efb0945ba78d060d3d25e8f1a1bea5139f821a21a2f0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collator_data/2.2.0/download\"],\n strip_prefix = \"icu_collator_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_collator_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_collections-2.2.0\",\n sha256 = \"2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_collections/2.2.0/download\"],\n strip_prefix = \"icu_collections-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_collections-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_datetime-2.2.0\",\n sha256 = \"989d56ea5bbc43ae2b4e0388874b002884eaf4ed3a76c84a6c8c5ad575e04d72\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_datetime/2.2.0/download\"],\n strip_prefix = \"icu_datetime-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_datetime-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_datetime_data-2.2.0\",\n sha256 = \"40d3cc1b690d9703202bc319692ac8a1f3a6390686f0930ff40542450fa34f0b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_datetime_data/2.2.0/download\"],\n strip_prefix = \"icu_datetime_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_datetime_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_decimal-2.2.0\",\n sha256 = \"288247df2e32aa776ac54fdd64de552149ac43cb840f2761811f0e8d09719dd4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_decimal/2.2.0/download\"],\n strip_prefix = \"icu_decimal-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_decimal-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_decimal_data-2.2.0\",\n sha256 = \"6f14a5ca9e8af29eef62064f269078424283d90dbaffeac5225addf62aaabc22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_decimal_data/2.2.0/download\"],\n strip_prefix = \"icu_decimal_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_decimal_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locale-2.2.0\",\n sha256 = \"d5a396343c7208121dc86e35623d3dfe19814a7613cfd14964994cdc9c9a2e26\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locale/2.2.0/download\"],\n strip_prefix = \"icu_locale-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locale-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locale_core-2.2.0\",\n sha256 = \"92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locale_core/2.2.0/download\"],\n strip_prefix = \"icu_locale_core-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locale_core-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_locale_data-2.2.0\",\n sha256 = \"d5fdcc9ac77c6d74ff5cf6e65ef3181d6af32003b16fce3a77fb451d2f695993\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_locale_data/2.2.0/download\"],\n strip_prefix = \"icu_locale_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_locale_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer-2.2.0\",\n sha256 = \"c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer/2.2.0/download\"],\n strip_prefix = \"icu_normalizer-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_normalizer_data-2.2.0\",\n sha256 = \"da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_normalizer_data/2.2.0/download\"],\n strip_prefix = \"icu_normalizer_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_normalizer_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_pattern-0.4.2\",\n sha256 = \"1c4c568054ffe735398a9f4c55aec37ad7c768844553cc0978f09cc9b933a1fb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_pattern/0.4.2/download\"],\n strip_prefix = \"icu_pattern-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.icu_pattern-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_plurals-2.2.0\",\n sha256 = \"2a50023f1d49ad5c4333380328a0d4a19e4b9d6d842ec06639affd5ba47c8103\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_plurals/2.2.0/download\"],\n strip_prefix = \"icu_plurals-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_plurals-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_plurals_data-2.2.0\",\n sha256 = \"8485497155dc865f901decb93ecc20d3e467df67bfeceb91e3ba34e2b11e8e1d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_plurals_data/2.2.0/download\"],\n strip_prefix = \"icu_plurals_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_plurals_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties-2.2.0\",\n sha256 = \"bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties/2.2.0/download\"],\n strip_prefix = \"icu_properties-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_properties_data-2.2.0\",\n sha256 = \"8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_properties_data/2.2.0/download\"],\n strip_prefix = \"icu_properties_data-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_properties_data-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_provider-2.2.0\",\n sha256 = \"139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_provider/2.2.0/download\"],\n strip_prefix = \"icu_provider-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_provider-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_time-2.2.0\",\n sha256 = \"ec3af0c141da0a61d4f6970cd1d5f4b388b17ea22f8124f8f6049d3d5147586a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_time/2.2.0/download\"],\n strip_prefix = \"icu_time-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.icu_time-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icu_time_data-2.2.1\",\n sha256 = \"2e0ee79a0bb29772465234bfbad6ea04fbc5220bef9fa4f318cc53eb8897070e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icu_time_data/2.2.1/download\"],\n strip_prefix = \"icu_time_data-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.icu_time_data-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__icy_sixel-0.5.0\",\n sha256 = \"85518b9086bf01117761b90e7691c0ef3236fa8adfb1fb44dd248fe5f87215d5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/icy_sixel/0.5.0/download\"],\n strip_prefix = \"icy_sixel-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.icy_sixel-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ident_case-1.0.1\",\n sha256 = \"b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ident_case/1.0.1/download\"],\n strip_prefix = \"ident_case-1.0.1\",\n build_file = Label(\"@crates//crates:BUILD.ident_case-1.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna-1.1.0\",\n sha256 = \"3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna/1.1.0/download\"],\n strip_prefix = \"idna-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.idna-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__idna_adapter-1.2.2\",\n sha256 = \"cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/idna_adapter/1.2.2/download\"],\n strip_prefix = \"idna_adapter-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.idna_adapter-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ignore-0.4.31\",\n sha256 = \"7f8a7b8211e695a1d0cd91cace480d4d0bd57667ab10277cc412c5f7f4884f83\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ignore/0.4.31/download\"],\n strip_prefix = \"ignore-0.4.31\",\n build_file = Label(\"@crates//crates:BUILD.ignore-0.4.31.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__image-0.25.10\",\n sha256 = \"85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/image/0.25.10/download\"],\n strip_prefix = \"image-0.25.10\",\n build_file = Label(\"@crates//crates:BUILD.image-0.25.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__image-webp-0.2.4\",\n sha256 = \"525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/image-webp/0.2.4/download\"],\n strip_prefix = \"image-webp-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.image-webp-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indenter-0.3.4\",\n sha256 = \"964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indenter/0.3.4/download\"],\n strip_prefix = \"indenter-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.indenter-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indexmap-2.14.0\",\n sha256 = \"d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indexmap/2.14.0/download\"],\n strip_prefix = \"indexmap-2.14.0\",\n build_file = Label(\"@crates//crates:BUILD.indexmap-2.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indicatif-0.18.6\",\n sha256 = \"9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indicatif/0.18.6/download\"],\n strip_prefix = \"indicatif-0.18.6\",\n build_file = Label(\"@crates//crates:BUILD.indicatif-0.18.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inferno-0.12.8\",\n sha256 = \"0c460d4fa06223667240720ab69a8045133755ae6dfbe100cf481b95e3a014f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inferno/0.12.8/download\"],\n strip_prefix = \"inferno-0.12.8\",\n build_file = Label(\"@crates//crates:BUILD.inferno-0.12.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inherent-1.0.14\",\n sha256 = \"bee2c455ca60511a054699102d40ce7153621cb2429558f9eaa600e4499b5984\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inherent/1.0.14/download\"],\n strip_prefix = \"inherent-1.0.14\",\n build_file = Label(\"@crates//crates:BUILD.inherent-1.0.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inotify-0.11.4\",\n sha256 = \"153be1941a183ec9ccd095ddbe17a8b8d435ef6c76e9e02451b933c3999af2c8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inotify/0.11.4/download\"],\n strip_prefix = \"inotify-0.11.4\",\n build_file = Label(\"@crates//crates:BUILD.inotify-0.11.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inotify-sys-0.1.8\",\n sha256 = \"c033f80b2c113cdf91ab7a33faa9cbc014726dcad99880c8609af2a370edf37d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inotify-sys/0.1.8/download\"],\n strip_prefix = \"inotify-sys-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.inotify-sys-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__inout-0.1.4\",\n sha256 = \"879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/inout/0.1.4/download\"],\n strip_prefix = \"inout-0.1.4\",\n build_file = Label(\"@crates//crates:BUILD.inout-0.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__insta-1.48.0\",\n sha256 = \"86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/insta/1.48.0/download\"],\n strip_prefix = \"insta-1.48.0\",\n build_file = Label(\"@crates//crates:BUILD.insta-1.48.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__interceptor-0.17.2\",\n sha256 = \"88c11a956a48159f7fe539b8198f12b4db9b709ae5f94385b840db38f97fed74\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/interceptor/0.17.2/download\"],\n strip_prefix = \"interceptor-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.interceptor-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__intl-memoizer-0.5.3\",\n sha256 = \"310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/intl-memoizer/0.5.3/download\"],\n strip_prefix = \"intl-memoizer-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.intl-memoizer-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__intl_pluralrules-7.0.2\",\n sha256 = \"078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/intl_pluralrules/7.0.2/download\"],\n strip_prefix = \"intl_pluralrules-7.0.2\",\n build_file = Label(\"@crates//crates:BUILD.intl_pluralrules-7.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ipnet-2.12.0\",\n sha256 = \"d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ipnet/2.12.0/download\"],\n strip_prefix = \"ipnet-2.12.0\",\n build_file = Label(\"@crates//crates:BUILD.ipnet-2.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__is_terminal_polyfill-1.70.2\",\n sha256 = \"a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/is_terminal_polyfill/1.70.2/download\"],\n strip_prefix = \"is_terminal_polyfill-1.70.2\",\n build_file = Label(\"@crates//crates:BUILD.is_terminal_polyfill-1.70.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itertools-0.13.0\",\n sha256 = \"413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itertools/0.13.0/download\"],\n strip_prefix = \"itertools-0.13.0\",\n build_file = Label(\"@crates//crates:BUILD.itertools-0.13.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itertools-0.14.0\",\n sha256 = \"2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itertools/0.14.0/download\"],\n strip_prefix = \"itertools-0.14.0\",\n build_file = Label(\"@crates//crates:BUILD.itertools-0.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itoa-1.0.18\",\n sha256 = \"8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itoa/1.0.18/download\"],\n strip_prefix = \"itoa-1.0.18\",\n build_file = Label(\"@crates//crates:BUILD.itoa-1.0.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jaq-core-2.2.1\",\n sha256 = \"77526a72eb79412c29fd141767a6549bbfcb1cb40e00556fe16532d5e878e098\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jaq-core/2.2.1/download\"],\n strip_prefix = \"jaq-core-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.jaq-core-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jaq-json-1.1.3\",\n sha256 = \"01dbdbd07b076e8403abac68ce7744d93e2ecd953bbc44bf77bf00e1e81172bc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jaq-json/1.1.3/download\"],\n strip_prefix = \"jaq-json-1.1.3\",\n build_file = Label(\"@crates//crates:BUILD.jaq-json-1.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jaq-std-2.1.2\",\n sha256 = \"2c264fe397c981705976c71f1bfe020382b9eda52ae950e57fe885e147bdd67d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jaq-std/2.1.2/download\"],\n strip_prefix = \"jaq-std-2.1.2\",\n build_file = Label(\"@crates//crates:BUILD.jaq-std-2.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-0.2.35\",\n sha256 = \"668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff/0.2.35/download\"],\n strip_prefix = \"jiff-0.2.35\",\n build_file = Label(\"@crates//crates:BUILD.jiff-0.2.35.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-core-0.1.0\",\n sha256 = \"7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-core/0.1.0/download\"],\n strip_prefix = \"jiff-core-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.jiff-core-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-icu-0.2.2\",\n sha256 = \"0e67c2beaae8b10a82d849b9aabb698a43a682f32b17bcdc035d5ecadb44d646\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-icu/0.2.2/download\"],\n strip_prefix = \"jiff-icu-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.jiff-icu-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-static-0.2.35\",\n sha256 = \"3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-static/0.2.35/download\"],\n strip_prefix = \"jiff-static-0.2.35\",\n build_file = Label(\"@crates//crates:BUILD.jiff-static-0.2.35.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-tzdb-0.1.8\",\n sha256 = \"142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-tzdb/0.1.8/download\"],\n strip_prefix = \"jiff-tzdb-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.jiff-tzdb-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jiff-tzdb-platform-0.1.3\",\n sha256 = \"875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jiff-tzdb-platform/0.1.3/download\"],\n strip_prefix = \"jiff-tzdb-platform-0.1.3\",\n build_file = Label(\"@crates//crates:BUILD.jiff-tzdb-platform-0.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__jobserver-0.1.35\",\n sha256 = \"1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/jobserver/0.1.35/download\"],\n strip_prefix = \"jobserver-0.1.35\",\n build_file = Label(\"@crates//crates:BUILD.jobserver-0.1.35.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__js-sys-0.3.103\",\n sha256 = \"53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/js-sys/0.3.103/download\"],\n strip_prefix = \"js-sys-0.3.103\",\n build_file = Label(\"@crates//crates:BUILD.js-sys-0.3.103.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__keccak-0.1.6\",\n sha256 = \"cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/keccak/0.1.6/download\"],\n strip_prefix = \"keccak-0.1.6\",\n build_file = Label(\"@crates//crates:BUILD.keccak-0.1.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__khronos-egl-6.0.0\",\n sha256 = \"6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/khronos-egl/6.0.0/download\"],\n strip_prefix = \"khronos-egl-6.0.0\",\n build_file = Label(\"@crates//crates:BUILD.khronos-egl-6.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__khronos_api-3.1.0\",\n sha256 = \"e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/khronos_api/3.1.0/download\"],\n strip_prefix = \"khronos_api-3.1.0\",\n build_file = Label(\"@crates//crates:BUILD.khronos_api-3.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__kqueue-1.2.0\",\n sha256 = \"273c0752728918e0ac4976f2b275b6fefb9ecd400585dec929419f3844cd87b5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/kqueue/1.2.0/download\"],\n strip_prefix = \"kqueue-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.kqueue-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__kqueue-sys-1.1.2\",\n sha256 = \"07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/kqueue-sys/1.1.2/download\"],\n strip_prefix = \"kqueue-sys-1.1.2\",\n build_file = Label(\"@crates//crates:BUILD.kqueue-sys-1.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lazy_static-1.5.0\",\n sha256 = \"bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lazy_static/1.5.0/download\"],\n strip_prefix = \"lazy_static-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.lazy_static-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libc-0.2.189\",\n sha256 = \"3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libc/0.2.189/download\"],\n strip_prefix = \"libc-0.2.189\",\n build_file = Label(\"@crates//crates:BUILD.libc-0.2.189.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libloading-0.8.9\",\n sha256 = \"d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libloading/0.8.9/download\"],\n strip_prefix = \"libloading-0.8.9\",\n build_file = Label(\"@crates//crates:BUILD.libloading-0.8.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libloading-0.9.0\",\n sha256 = \"754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libloading/0.9.0/download\"],\n strip_prefix = \"libloading-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.libloading-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libm-0.2.16\",\n sha256 = \"b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libm/0.2.16/download\"],\n strip_prefix = \"libm-0.2.16\",\n build_file = Label(\"@crates//crates:BUILD.libm-0.2.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libredox-0.1.18\",\n sha256 = \"c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libredox/0.1.18/download\"],\n strip_prefix = \"libredox-0.1.18\",\n build_file = Label(\"@crates//crates:BUILD.libredox-0.1.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libspa-0.9.2\",\n sha256 = \"b6b8cfa2a7656627b4c92c6b9ef929433acd673d5ab3708cda1b18478ac00df4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libspa/0.9.2/download\"],\n strip_prefix = \"libspa-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.libspa-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libspa-sys-0.9.2\",\n sha256 = \"901049455d2eb6decf9058235d745237952f4804bc584c5fcb41412e6adcc6e0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libspa-sys/0.9.2/download\"],\n strip_prefix = \"libspa-sys-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.libspa-sys-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libwayshot-xcap-0.3.3\",\n sha256 = \"ea8a46e4d016ef464e386e4970f5415fe0939c2d63abe0c2f539c05ef88c5fe5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libwayshot-xcap/0.3.3/download\"],\n strip_prefix = \"libwayshot-xcap-0.3.3\",\n build_file = Label(\"@crates//crates:BUILD.libwayshot-xcap-0.3.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linked-hash-map-0.5.6\",\n sha256 = \"0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linked-hash-map/0.5.6/download\"],\n strip_prefix = \"linked-hash-map-0.5.6\",\n build_file = Label(\"@crates//crates:BUILD.linked-hash-map-0.5.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.12.1\",\n sha256 = \"32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.12.1/download\"],\n strip_prefix = \"linux-raw-sys-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.4.15\",\n sha256 = \"d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.4.15/download\"],\n strip_prefix = \"linux-raw-sys-0.4.15\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.4.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__linux-raw-sys-0.9.4\",\n sha256 = \"cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/linux-raw-sys/0.9.4/download\"],\n strip_prefix = \"linux-raw-sys-0.9.4\",\n build_file = Label(\"@crates//crates:BUILD.linux-raw-sys-0.9.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__litemap-0.8.2\",\n sha256 = \"92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/litemap/0.8.2/download\"],\n strip_prefix = \"litemap-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.litemap-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lock_api-0.4.14\",\n sha256 = \"224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lock_api/0.4.14/download\"],\n strip_prefix = \"lock_api-0.4.14\",\n build_file = Label(\"@crates//crates:BUILD.lock_api-0.4.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__log-0.4.33\",\n sha256 = \"0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/log/0.4.33/download\"],\n strip_prefix = \"log-0.4.33\",\n build_file = Label(\"@crates//crates:BUILD.log-0.4.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lru-0.16.4\",\n sha256 = \"7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lru/0.16.4/download\"],\n strip_prefix = \"lru-0.16.4\",\n build_file = Label(\"@crates//crates:BUILD.lru-0.16.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__lscolors-0.21.0\",\n sha256 = \"d60e266dfb1426eb2d24792602e041131fdc0236bb7007abc0e589acafd60929\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/lscolors/0.21.0/download\"],\n strip_prefix = \"lscolors-0.21.0\",\n build_file = Label(\"@crates//crates:BUILD.lscolors-0.21.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__markup5ever-0.39.0\",\n sha256 = \"7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/markup5ever/0.39.0/download\"],\n strip_prefix = \"markup5ever-0.39.0\",\n build_file = Label(\"@crates//crates:BUILD.markup5ever-0.39.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__maudio-0.1.6\",\n sha256 = \"c6ab2d47a7b24f4cf6ab85d335b4a6cc932f650080dfe0819b22bc553aada602\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/maudio/0.1.6/download\"],\n strip_prefix = \"maudio-0.1.6\",\n build_file = Label(\"@crates//crates:BUILD.maudio-0.1.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__maudio-sys-0.1.3\",\n patch_args = [\n \"-p1\",\n ],\n patches = [\n \"@@//bazel/patches:maudio-sys-target-bindings.patch\",\n ],\n sha256 = \"f00ae1969d0a389937161b834623e5cba2d8449752a0970d71382cf9a905bb35\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/maudio-sys/0.1.3/download\"],\n strip_prefix = \"maudio-sys-0.1.3\",\n build_file = Label(\"@crates//crates:BUILD.maudio-sys-0.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__md-5-0.10.6\",\n sha256 = \"d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/md-5/0.10.6/download\"],\n strip_prefix = \"md-5-0.10.6\",\n build_file = Label(\"@crates//crates:BUILD.md-5-0.10.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memchr-2.8.3\",\n sha256 = \"cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memchr/2.8.3/download\"],\n strip_prefix = \"memchr-2.8.3\",\n build_file = Label(\"@crates//crates:BUILD.memchr-2.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memmap2-0.9.11\",\n sha256 = \"d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memmap2/0.9.11/download\"],\n strip_prefix = \"memmap2-0.9.11\",\n build_file = Label(\"@crates//crates:BUILD.memmap2-0.9.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memoffset-0.7.1\",\n sha256 = \"5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memoffset/0.7.1/download\"],\n strip_prefix = \"memoffset-0.7.1\",\n build_file = Label(\"@crates//crates:BUILD.memoffset-0.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memoffset-0.9.1\",\n sha256 = \"488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memoffset/0.9.1/download\"],\n strip_prefix = \"memoffset-0.9.1\",\n build_file = Label(\"@crates//crates:BUILD.memoffset-0.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__minimal-lexical-0.2.1\",\n sha256 = \"68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/minimal-lexical/0.2.1/download\"],\n strip_prefix = \"minimal-lexical-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.minimal-lexical-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__miniz_oxide-0.8.9\",\n sha256 = \"1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/miniz_oxide/0.8.9/download\"],\n strip_prefix = \"miniz_oxide-0.8.9\",\n build_file = Label(\"@crates//crates:BUILD.miniz_oxide-0.8.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__mio-1.2.2\",\n sha256 = \"30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/mio/1.2.2/download\"],\n strip_prefix = \"mio-1.2.2\",\n build_file = Label(\"@crates//crates:BUILD.mio-1.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__moxcms-0.8.1\",\n sha256 = \"bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/moxcms/0.8.1/download\"],\n strip_prefix = \"moxcms-0.8.1\",\n build_file = Label(\"@crates//crates:BUILD.moxcms-0.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__munge-0.4.7\",\n sha256 = \"5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/munge/0.4.7/download\"],\n strip_prefix = \"munge-0.4.7\",\n build_file = Label(\"@crates//crates:BUILD.munge-0.4.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__munge_macro-0.4.7\",\n sha256 = \"4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/munge_macro/0.4.7/download\"],\n strip_prefix = \"munge_macro-0.4.7\",\n build_file = Label(\"@crates//crates:BUILD.munge_macro-0.4.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nanorand-0.7.0\",\n sha256 = \"6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nanorand/0.7.0/download\"],\n strip_prefix = \"nanorand-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.nanorand-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-3.12.0\",\n sha256 = \"6f71d6bc097c4a6eb853c3f24991ab8c9f50f57d1f719e305175541482217e36\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi/3.12.0/download\"],\n strip_prefix = \"napi-3.12.0\",\n build_file = Label(\"@crates//crates:BUILD.napi-3.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-build-2.4.0\",\n sha256 = \"5282704fbe8d49b0cf8b08e3f33233416a528658f205c7e5ace63b582de0b11c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi-build/2.4.0/download\"],\n strip_prefix = \"napi-build-2.4.0\",\n build_file = Label(\"@crates//crates:BUILD.napi-build-2.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-derive-3.6.1\",\n sha256 = \"4d5c9c02556ea6dc99dffd36c1ce60141411657438501a125b675776d011ce92\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi-derive/3.6.1/download\"],\n strip_prefix = \"napi-derive-3.6.1\",\n build_file = Label(\"@crates//crates:BUILD.napi-derive-3.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-derive-backend-6.1.0\",\n sha256 = \"6a9d8365cf97f54d9b6d6dbf83a25ca227ad7d6e920717426c599225aca6740b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi-derive-backend/6.1.0/download\"],\n strip_prefix = \"napi-derive-backend-6.1.0\",\n build_file = Label(\"@crates//crates:BUILD.napi-derive-backend-6.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__napi-sys-3.3.0\",\n sha256 = \"85fbf1fa9f1babfe396d74bbbf52b3643770243e8f5b0b46715d4caf7f0dfc9a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/napi-sys/3.3.0/download\"],\n strip_prefix = \"napi-sys-3.3.0\",\n build_file = Label(\"@crates//crates:BUILD.napi-sys-3.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__new_debug_unreachable-1.0.6\",\n sha256 = \"650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/new_debug_unreachable/1.0.6/download\"],\n strip_prefix = \"new_debug_unreachable-1.0.6\",\n build_file = Label(\"@crates//crates:BUILD.new_debug_unreachable-1.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.24.3\",\n sha256 = \"fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.24.3/download\"],\n strip_prefix = \"nix-0.24.3\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.24.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.26.4\",\n sha256 = \"598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.26.4/download\"],\n strip_prefix = \"nix-0.26.4\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.26.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.28.0\",\n sha256 = \"ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.28.0/download\"],\n strip_prefix = \"nix-0.28.0\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.28.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.29.0\",\n sha256 = \"71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.29.0/download\"],\n strip_prefix = \"nix-0.29.0\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.29.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.30.1\",\n sha256 = \"74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.30.1/download\"],\n strip_prefix = \"nix-0.30.1\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.30.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nix-0.31.3\",\n sha256 = \"cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nix/0.31.3/download\"],\n strip_prefix = \"nix-0.31.3\",\n build_file = Label(\"@crates//crates:BUILD.nix-0.31.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nohash-hasher-0.2.0\",\n sha256 = \"2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nohash-hasher/0.2.0/download\"],\n strip_prefix = \"nohash-hasher-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.nohash-hasher-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nom-7.1.3\",\n sha256 = \"d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nom/7.1.3/download\"],\n strip_prefix = \"nom-7.1.3\",\n build_file = Label(\"@crates//crates:BUILD.nom-7.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nom-8.0.0\",\n sha256 = \"df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nom/8.0.0/download\"],\n strip_prefix = \"nom-8.0.0\",\n build_file = Label(\"@crates//crates:BUILD.nom-8.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__normalize-path-0.2.1\",\n sha256 = \"f5438dd2b2ff4c6df6e1ce22d825ed2fa93ee2922235cc45186991717f0a892d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/normalize-path/0.2.1/download\"],\n strip_prefix = \"normalize-path-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.normalize-path-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__notify-8.2.0\",\n sha256 = \"4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/notify/8.2.0/download\"],\n strip_prefix = \"notify-8.2.0\",\n build_file = Label(\"@crates//crates:BUILD.notify-8.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__notify-types-2.1.0\",\n sha256 = \"42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/notify-types/2.1.0/download\"],\n strip_prefix = \"notify-types-2.1.0\",\n build_file = Label(\"@crates//crates:BUILD.notify-types-2.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__nu-ansi-term-0.50.3\",\n sha256 = \"7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/nu-ansi-term/0.50.3/download\"],\n strip_prefix = \"nu-ansi-term-0.50.3\",\n build_file = Label(\"@crates//crates:BUILD.nu-ansi-term-0.50.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-bigint-0.4.8\",\n sha256 = \"c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-bigint/0.4.8/download\"],\n strip_prefix = \"num-bigint-0.4.8\",\n build_file = Label(\"@crates//crates:BUILD.num-bigint-0.4.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-conv-0.2.2\",\n sha256 = \"521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-conv/0.2.2/download\"],\n strip_prefix = \"num-conv-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.num-conv-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-format-0.4.4\",\n sha256 = \"a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-format/0.4.4/download\"],\n strip_prefix = \"num-format-0.4.4\",\n build_file = Label(\"@crates//crates:BUILD.num-format-0.4.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-integer-0.1.46\",\n sha256 = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-integer/0.1.46/download\"],\n strip_prefix = \"num-integer-0.1.46\",\n build_file = Label(\"@crates//crates:BUILD.num-integer-0.1.46.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__num-traits-0.2.19\",\n sha256 = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/num-traits/0.2.19/download\"],\n strip_prefix = \"num-traits-0.2.19\",\n build_file = Label(\"@crates//crates:BUILD.num-traits-0.2.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__number_prefix-0.4.0\",\n sha256 = \"830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/number_prefix/0.4.0/download\"],\n strip_prefix = \"number_prefix-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.number_prefix-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-0.6.4\",\n sha256 = \"3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2/0.6.4/download\"],\n strip_prefix = \"objc2-0.6.4\",\n build_file = Label(\"@crates//crates:BUILD.objc2-0.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-app-kit-0.3.2\",\n sha256 = \"d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-app-kit/0.3.2/download\"],\n strip_prefix = \"objc2-app-kit-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-app-kit-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-av-foundation-0.3.2\",\n sha256 = \"478ae33fcac9df0a18db8302387c666b8ef08a3e2d62b510ca4fc278a384b6c0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-av-foundation/0.3.2/download\"],\n strip_prefix = \"objc2-av-foundation-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-av-foundation-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-avf-audio-0.3.2\",\n sha256 = \"13a380031deed8e99db00065c45937da434ca987c034e13b87e4441f9e4090be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-avf-audio/0.3.2/download\"],\n strip_prefix = \"objc2-avf-audio-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-avf-audio-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-cloud-kit-0.3.2\",\n sha256 = \"73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-cloud-kit/0.3.2/download\"],\n strip_prefix = \"objc2-cloud-kit-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-cloud-kit-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-audio-0.3.2\",\n sha256 = \"e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-audio/0.3.2/download\"],\n strip_prefix = \"objc2-core-audio-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-audio-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-audio-types-0.3.2\",\n sha256 = \"5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-audio-types/0.3.2/download\"],\n strip_prefix = \"objc2-core-audio-types-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-audio-types-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-data-0.3.2\",\n sha256 = \"0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-data/0.3.2/download\"],\n strip_prefix = \"objc2-core-data-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-data-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-foundation-0.3.2\",\n sha256 = \"2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-foundation/0.3.2/download\"],\n strip_prefix = \"objc2-core-foundation-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-foundation-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-graphics-0.3.2\",\n sha256 = \"e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-graphics/0.3.2/download\"],\n strip_prefix = \"objc2-core-graphics-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-graphics-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-image-0.3.2\",\n sha256 = \"e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-image/0.3.2/download\"],\n strip_prefix = \"objc2-core-image-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-image-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-media-0.3.2\",\n sha256 = \"05ec576860167a15dd9fce7fbee7512beb4e31f532159d3482d1f9c6caedf31d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-media/0.3.2/download\"],\n strip_prefix = \"objc2-core-media-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-media-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-text-0.3.2\",\n sha256 = \"0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-text/0.3.2/download\"],\n strip_prefix = \"objc2-core-text-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-text-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-core-video-0.3.2\",\n sha256 = \"d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-core-video/0.3.2/download\"],\n strip_prefix = \"objc2-core-video-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-core-video-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-encode-4.1.0\",\n sha256 = \"ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-encode/4.1.0/download\"],\n strip_prefix = \"objc2-encode-4.1.0\",\n build_file = Label(\"@crates//crates:BUILD.objc2-encode-4.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-foundation-0.3.2\",\n sha256 = \"e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-foundation/0.3.2/download\"],\n strip_prefix = \"objc2-foundation-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-foundation-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-image-io-0.3.2\",\n sha256 = \"32b0446e98cf4a784cc7a0177715ff317eeaa8463841c616cfc78aa4f953c4ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-image-io/0.3.2/download\"],\n strip_prefix = \"objc2-image-io-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-image-io-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-io-surface-0.3.2\",\n sha256 = \"180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-io-surface/0.3.2/download\"],\n strip_prefix = \"objc2-io-surface-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-io-surface-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-media-toolbox-0.3.2\",\n sha256 = \"edd9fdde720df3da7046bb9097811000c1e7ab5cd579fa89d96b27d56781fb30\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-media-toolbox/0.3.2/download\"],\n strip_prefix = \"objc2-media-toolbox-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-media-toolbox-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-metal-0.3.2\",\n sha256 = \"a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-metal/0.3.2/download\"],\n strip_prefix = \"objc2-metal-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-metal-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-quartz-core-0.3.2\",\n sha256 = \"96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-quartz-core/0.3.2/download\"],\n strip_prefix = \"objc2-quartz-core-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-quartz-core-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__objc2-system-configuration-0.3.2\",\n sha256 = \"7216bd11cbda54ccabcab84d523dc93b858ec75ecfb3a7d89513fa22464da396\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/objc2-system-configuration/0.3.2/download\"],\n strip_prefix = \"objc2-system-configuration-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.objc2-system-configuration-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__oid-registry-0.7.1\",\n sha256 = \"a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/oid-registry/0.7.1/download\"],\n strip_prefix = \"oid-registry-0.7.1\",\n build_file = Label(\"@crates//crates:BUILD.oid-registry-0.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell-1.21.4\",\n sha256 = \"9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell/1.21.4/download\"],\n strip_prefix = \"once_cell-1.21.4\",\n build_file = Label(\"@crates//crates:BUILD.once_cell-1.21.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell_polyfill-1.70.2\",\n sha256 = \"384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell_polyfill/1.70.2/download\"],\n strip_prefix = \"once_cell_polyfill-1.70.2\",\n build_file = Label(\"@crates//crates:BUILD.once_cell_polyfill-1.70.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__onig-6.5.3\",\n sha256 = \"0cc3cbf698f9438986c11a880c90a6d04b9de27575afd28bbf45b154b6c709e2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/onig/6.5.3/download\"],\n strip_prefix = \"onig-6.5.3\",\n build_file = Label(\"@crates//crates:BUILD.onig-6.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__onig_sys-69.9.3\",\n sha256 = \"1e68317604e77e53b85896388e1a803c1d21b74c899ec9e5e1112db90735edd7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/onig_sys/69.9.3/download\"],\n strip_prefix = \"onig_sys-69.9.3\",\n build_file = Label(\"@crates//crates:BUILD.onig_sys-69.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__opaque-debug-0.3.1\",\n sha256 = \"c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/opaque-debug/0.3.1/download\"],\n strip_prefix = \"opaque-debug-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.opaque-debug-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__opus-0.3.1\",\n sha256 = \"4d3809943dff6fbad5f0484449ea26bdb9cb7d8efdf26ed50d3c7f227f69eb5c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/opus/0.3.1/download\"],\n strip_prefix = \"opus-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.opus-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ordered-float-5.3.0\",\n sha256 = \"b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ordered-float/5.3.0/download\"],\n strip_prefix = \"ordered-float-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.ordered-float-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ordered-stream-0.2.0\",\n sha256 = \"9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ordered-stream/0.2.0/download\"],\n strip_prefix = \"ordered-stream-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.ordered-stream-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__os_display-0.1.4\",\n sha256 = \"ad5fd71b79026fb918650dde6d125000a233764f1c2f1659a1c71118e33ea08f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/os_display/0.1.4/download\"],\n strip_prefix = \"os_display-0.1.4\",\n build_file = Label(\"@crates//crates:BUILD.os_display-0.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__os_pipe-1.2.3\",\n sha256 = \"7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/os_pipe/1.2.3/download\"],\n strip_prefix = \"os_pipe-1.2.3\",\n build_file = Label(\"@crates//crates:BUILD.os_pipe-1.2.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__outref-0.5.2\",\n sha256 = \"1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/outref/0.5.2/download\"],\n strip_prefix = \"outref-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.outref-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__p256-0.13.2\",\n sha256 = \"c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/p256/0.13.2/download\"],\n strip_prefix = \"p256-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.p256-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__p384-0.13.1\",\n sha256 = \"fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/p384/0.13.1/download\"],\n strip_prefix = \"p384-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.p384-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__palette-0.7.6\",\n sha256 = \"4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/palette/0.7.6/download\"],\n strip_prefix = \"palette-0.7.6\",\n build_file = Label(\"@crates//crates:BUILD.palette-0.7.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__palette_derive-0.7.6\",\n sha256 = \"f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/palette_derive/0.7.6/download\"],\n strip_prefix = \"palette_derive-0.7.6\",\n build_file = Label(\"@crates//crates:BUILD.palette_derive-0.7.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking-2.2.1\",\n sha256 = \"f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking/2.2.1/download\"],\n strip_prefix = \"parking-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.parking-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot-0.12.5\",\n sha256 = \"93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot/0.12.5/download\"],\n strip_prefix = \"parking_lot-0.12.5\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot-0.12.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parking_lot_core-0.9.12\",\n sha256 = \"2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parking_lot_core/0.9.12/download\"],\n strip_prefix = \"parking_lot_core-0.9.12\",\n build_file = Label(\"@crates//crates:BUILD.parking_lot_core-0.9.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__parse_datetime-0.14.0\",\n sha256 = \"413775a7eac2261d2211a79d10ef275e5b6f7b527eec42ad09adce2ffa92b6e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/parse_datetime/0.14.0/download\"],\n strip_prefix = \"parse_datetime-0.14.0\",\n build_file = Label(\"@crates//crates:BUILD.parse_datetime-0.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pcre2-0.2.11\",\n sha256 = \"9e970b0fcce0c7ee6ef662744ff711f21ccd6f11b7cf03cd187a80e89797fc67\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pcre2/0.2.11/download\"],\n strip_prefix = \"pcre2-0.2.11\",\n build_file = Label(\"@crates//crates:BUILD.pcre2-0.2.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pcre2-sys-0.2.10\",\n sha256 = \"18b9073c1a2549bd409bf4a32c94d903bb1a09bf845bc306ae148897fa0760a4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pcre2-sys/0.2.10/download\"],\n strip_prefix = \"pcre2-sys-0.2.10\",\n build_file = Label(\"@crates//crates:BUILD.pcre2-sys-0.2.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__peg-0.8.6\",\n sha256 = \"0aad070be5b63aa72103f2fcdd70a83adbd5e90112ce5b574171ff1c65501773\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/peg/0.8.6/download\"],\n strip_prefix = \"peg-0.8.6\",\n build_file = Label(\"@crates//crates:BUILD.peg-0.8.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__peg-macros-0.8.6\",\n sha256 = \"ddd8ef6825cae95355031ae26a99b616a2a21f22ba2de0197c43dfb05acbe7ee\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/peg-macros/0.8.6/download\"],\n strip_prefix = \"peg-macros-0.8.6\",\n build_file = Label(\"@crates//crates:BUILD.peg-macros-0.8.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__peg-runtime-0.8.6\",\n sha256 = \"7011d97b484a5ebdc4b1fdb3b12d5e4bbbea56e9d22b688f2e79e04b65a7d8a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/peg-runtime/0.8.6/download\"],\n strip_prefix = \"peg-runtime-0.8.6\",\n build_file = Label(\"@crates//crates:BUILD.peg-runtime-0.8.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pem-3.0.6\",\n sha256 = \"1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pem/3.0.6/download\"],\n strip_prefix = \"pem-3.0.6\",\n build_file = Label(\"@crates//crates:BUILD.pem-3.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pem-rfc7468-0.7.0\",\n sha256 = \"88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pem-rfc7468/0.7.0/download\"],\n strip_prefix = \"pem-rfc7468-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.pem-rfc7468-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__percent-encoding-2.3.2\",\n sha256 = \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/percent-encoding/2.3.2/download\"],\n strip_prefix = \"percent-encoding-2.3.2\",\n build_file = Label(\"@crates//crates:BUILD.percent-encoding-2.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest-2.8.8\",\n sha256 = \"7df728be843c7070fab6ab7c328c4e9e9d78e23bf749c0669c86ee7ebfa050a2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest/2.8.8/download\"],\n strip_prefix = \"pest-2.8.8\",\n build_file = Label(\"@crates//crates:BUILD.pest-2.8.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest_derive-2.8.8\",\n sha256 = \"9e2dd6fc3b26b3462ee188aac870f5a41d398f1cd5e2408d16531bd71c9591fd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest_derive/2.8.8/download\"],\n strip_prefix = \"pest_derive-2.8.8\",\n build_file = Label(\"@crates//crates:BUILD.pest_derive-2.8.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest_generator-2.8.8\",\n sha256 = \"6a7a9205cfb6f596a9e8b689c0a15f9ceb7a1aafae7aaf788150ac65b29975b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest_generator/2.8.8/download\"],\n strip_prefix = \"pest_generator-2.8.8\",\n build_file = Label(\"@crates//crates:BUILD.pest_generator-2.8.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest_meta-2.8.8\",\n sha256 = \"85abd351c0de1e8384fc791a0737111a350394937e92b956b743dac12429f57c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest_meta/2.8.8/download\"],\n strip_prefix = \"pest_meta-2.8.8\",\n build_file = Label(\"@crates//crates:BUILD.pest_meta-2.8.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__petgraph-0.8.3\",\n sha256 = \"8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/petgraph/0.8.3/download\"],\n strip_prefix = \"petgraph-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.petgraph-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf-0.11.3\",\n sha256 = \"1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf/0.11.3/download\"],\n strip_prefix = \"phf-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.phf-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf-0.12.1\",\n sha256 = \"913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf/0.12.1/download\"],\n strip_prefix = \"phf-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.phf-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf-0.13.1\",\n sha256 = \"c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf/0.13.1/download\"],\n strip_prefix = \"phf-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_codegen-0.11.3\",\n sha256 = \"aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_codegen/0.11.3/download\"],\n strip_prefix = \"phf_codegen-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.phf_codegen-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_codegen-0.13.1\",\n sha256 = \"49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_codegen/0.13.1/download\"],\n strip_prefix = \"phf_codegen-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_codegen-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_generator-0.11.3\",\n sha256 = \"3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_generator/0.11.3/download\"],\n strip_prefix = \"phf_generator-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.phf_generator-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_generator-0.13.1\",\n sha256 = \"135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_generator/0.13.1/download\"],\n strip_prefix = \"phf_generator-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_generator-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_macros-0.13.1\",\n sha256 = \"812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_macros/0.13.1/download\"],\n strip_prefix = \"phf_macros-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_macros-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_shared-0.11.3\",\n sha256 = \"67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_shared/0.11.3/download\"],\n strip_prefix = \"phf_shared-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.phf_shared-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_shared-0.12.1\",\n sha256 = \"06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_shared/0.12.1/download\"],\n strip_prefix = \"phf_shared-0.12.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_shared-0.12.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__phf_shared-0.13.1\",\n sha256 = \"e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/phf_shared/0.13.1/download\"],\n strip_prefix = \"phf_shared-0.13.1\",\n build_file = Label(\"@crates//crates:BUILD.phf_shared-0.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pin-project-lite-0.2.17\",\n sha256 = \"a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pin-project-lite/0.2.17/download\"],\n strip_prefix = \"pin-project-lite-0.2.17\",\n build_file = Label(\"@crates//crates:BUILD.pin-project-lite-0.2.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pin-utils-0.1.0\",\n sha256 = \"8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pin-utils/0.1.0/download\"],\n strip_prefix = \"pin-utils-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.pin-utils-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__piper-0.2.5\",\n sha256 = \"c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/piper/0.2.5/download\"],\n strip_prefix = \"piper-0.2.5\",\n build_file = Label(\"@crates//crates:BUILD.piper-0.2.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pipewire-0.9.2\",\n sha256 = \"9688b89abf11d756499f7c6190711d6dbe5a3acdb30c8fbf001d6596d06a8d44\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pipewire/0.9.2/download\"],\n strip_prefix = \"pipewire-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.pipewire-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pipewire-sys-0.9.2\",\n sha256 = \"cb028afee0d6ca17020b090e3b8fa2d7de23305aef975c7e5192a5050246ea36\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pipewire-sys/0.9.2/download\"],\n strip_prefix = \"pipewire-sys-0.9.2\",\n build_file = Label(\"@crates//crates:BUILD.pipewire-sys-0.9.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pkcs8-0.10.2\",\n sha256 = \"f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pkcs8/0.10.2/download\"],\n strip_prefix = \"pkcs8-0.10.2\",\n build_file = Label(\"@crates//crates:BUILD.pkcs8-0.10.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pkg-config-0.3.33\",\n sha256 = \"19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pkg-config/0.3.33/download\"],\n strip_prefix = \"pkg-config-0.3.33\",\n build_file = Label(\"@crates//crates:BUILD.pkg-config-0.3.33.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__platform-info-2.1.0\",\n sha256 = \"9368d62437c8cbb7c31ee37fd8c08a7d390e09a3ff75698a674953f46705ffcb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/platform-info/2.1.0/download\"],\n strip_prefix = \"platform-info-2.1.0\",\n build_file = Label(\"@crates//crates:BUILD.platform-info-2.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__png-0.18.1\",\n sha256 = \"60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/png/0.18.1/download\"],\n strip_prefix = \"png-0.18.1\",\n build_file = Label(\"@crates//crates:BUILD.png-0.18.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__polling-3.11.0\",\n sha256 = \"5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/polling/3.11.0/download\"],\n strip_prefix = \"polling-3.11.0\",\n build_file = Label(\"@crates//crates:BUILD.polling-3.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__poly1305-0.8.0\",\n sha256 = \"8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/poly1305/0.8.0/download\"],\n strip_prefix = \"poly1305-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.poly1305-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__polyval-0.6.2\",\n sha256 = \"9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/polyval/0.6.2/download\"],\n strip_prefix = \"polyval-0.6.2\",\n build_file = Label(\"@crates//crates:BUILD.polyval-0.6.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__portable-atomic-1.14.0\",\n sha256 = \"3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/portable-atomic/1.14.0/download\"],\n strip_prefix = \"portable-atomic-1.14.0\",\n build_file = Label(\"@crates//crates:BUILD.portable-atomic-1.14.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__portable-atomic-util-0.2.7\",\n sha256 = \"c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/portable-atomic-util/0.2.7/download\"],\n strip_prefix = \"portable-atomic-util-0.2.7\",\n build_file = Label(\"@crates//crates:BUILD.portable-atomic-util-0.2.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__portable-pty-0.9.0\",\n sha256 = \"b4a596a2b3d2752d94f51fac2d4a96737b8705dddd311a32b9af47211f08671e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/portable-pty/0.9.0/download\"],\n strip_prefix = \"portable-pty-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.portable-pty-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__potential_utf-0.1.5\",\n sha256 = \"0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/potential_utf/0.1.5/download\"],\n strip_prefix = \"potential_utf-0.1.5\",\n build_file = Label(\"@crates//crates:BUILD.potential_utf-0.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__powerfmt-0.2.0\",\n sha256 = \"439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/powerfmt/0.2.0/download\"],\n strip_prefix = \"powerfmt-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.powerfmt-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ppv-lite86-0.2.21\",\n sha256 = \"85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ppv-lite86/0.2.21/download\"],\n strip_prefix = \"ppv-lite86-0.2.21\",\n build_file = Label(\"@crates//crates:BUILD.ppv-lite86-0.2.21.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__precomputed-hash-0.1.1\",\n sha256 = \"925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/precomputed-hash/0.1.1/download\"],\n strip_prefix = \"precomputed-hash-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.precomputed-hash-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pretty_assertions-1.4.1\",\n sha256 = \"3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pretty_assertions/1.4.1/download\"],\n strip_prefix = \"pretty_assertions-1.4.1\",\n build_file = Label(\"@crates//crates:BUILD.pretty_assertions-1.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__prettyplease-0.2.37\",\n sha256 = \"479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/prettyplease/0.2.37/download\"],\n strip_prefix = \"prettyplease-0.2.37\",\n build_file = Label(\"@crates//crates:BUILD.prettyplease-0.2.37.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__primeorder-0.13.6\",\n sha256 = \"353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/primeorder/0.13.6/download\"],\n strip_prefix = \"primeorder-0.13.6\",\n build_file = Label(\"@crates//crates:BUILD.primeorder-0.13.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro-crate-3.5.0\",\n sha256 = \"e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro-crate/3.5.0/download\"],\n strip_prefix = \"proc-macro-crate-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro-crate-3.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro2-1.0.107\",\n sha256 = \"985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro2/1.0.107/download\"],\n strip_prefix = \"proc-macro2-1.0.107\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro2-1.0.107.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__procfs-0.18.0\",\n sha256 = \"25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/procfs/0.18.0/download\"],\n strip_prefix = \"procfs-0.18.0\",\n build_file = Label(\"@crates//crates:BUILD.procfs-0.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__procfs-core-0.18.0\",\n sha256 = \"e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/procfs-core/0.18.0/download\"],\n strip_prefix = \"procfs-core-0.18.0\",\n build_file = Label(\"@crates//crates:BUILD.procfs-core-0.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ptr_meta-0.3.1\",\n sha256 = \"0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ptr_meta/0.3.1/download\"],\n strip_prefix = \"ptr_meta-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.ptr_meta-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ptr_meta_derive-0.3.1\",\n sha256 = \"7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ptr_meta_derive/0.3.1/download\"],\n strip_prefix = \"ptr_meta_derive-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.ptr_meta_derive-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pxfm-0.1.30\",\n sha256 = \"d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pxfm/0.1.30/download\"],\n strip_prefix = \"pxfm-0.1.30\",\n build_file = Label(\"@crates//crates:BUILD.pxfm-0.1.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quantette-0.5.1\",\n sha256 = \"c98fecda8b16396ff9adac67644a523dd1778c42b58606a29df5c31ca925d174\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quantette/0.5.1/download\"],\n strip_prefix = \"quantette-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.quantette-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quick-error-2.0.1\",\n sha256 = \"a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quick-error/2.0.1/download\"],\n strip_prefix = \"quick-error-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.quick-error-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quick-xml-0.30.0\",\n sha256 = \"eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quick-xml/0.30.0/download\"],\n strip_prefix = \"quick-xml-0.30.0\",\n build_file = Label(\"@crates//crates:BUILD.quick-xml-0.30.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quick-xml-0.41.0\",\n sha256 = \"e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quick-xml/0.41.0/download\"],\n strip_prefix = \"quick-xml-0.41.0\",\n build_file = Label(\"@crates//crates:BUILD.quick-xml-0.41.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quote-1.0.47\",\n sha256 = \"1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quote/1.0.47/download\"],\n strip_prefix = \"quote-1.0.47\",\n build_file = Label(\"@crates//crates:BUILD.quote-1.0.47.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__r-efi-5.3.0\",\n sha256 = \"69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/r-efi/5.3.0/download\"],\n strip_prefix = \"r-efi-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.r-efi-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__r-efi-6.0.0\",\n sha256 = \"f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/r-efi/6.0.0/download\"],\n strip_prefix = \"r-efi-6.0.0\",\n build_file = Label(\"@crates//crates:BUILD.r-efi-6.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__radium-0.7.0\",\n sha256 = \"dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/radium/0.7.0/download\"],\n strip_prefix = \"radium-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.radium-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rancor-0.1.2\",\n sha256 = \"daff8b7b3ccf5f7ba270b3e7a0a4d4c701c5797e38dec27c7e2c3dbb830fed1c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rancor/0.1.2/download\"],\n strip_prefix = \"rancor-0.1.2\",\n build_file = Label(\"@crates//crates:BUILD.rancor-0.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand-0.10.2\",\n sha256 = \"c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand/0.10.2/download\"],\n strip_prefix = \"rand-0.10.2\",\n build_file = Label(\"@crates//crates:BUILD.rand-0.10.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand-0.8.7\",\n sha256 = \"22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand/0.8.7/download\"],\n strip_prefix = \"rand-0.8.7\",\n build_file = Label(\"@crates//crates:BUILD.rand-0.8.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand-0.9.5\",\n sha256 = \"b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand/0.9.5/download\"],\n strip_prefix = \"rand-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.rand-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_chacha-0.9.0\",\n sha256 = \"d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_chacha/0.9.0/download\"],\n strip_prefix = \"rand_chacha-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.rand_chacha-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.10.1\",\n sha256 = \"63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.10.1/download\"],\n strip_prefix = \"rand_core-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.6.4\",\n sha256 = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.6.4/download\"],\n strip_prefix = \"rand_core-0.6.4\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_core-0.9.5\",\n sha256 = \"76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_core/0.9.5/download\"],\n strip_prefix = \"rand_core-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.rand_core-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rand_xoshiro-0.7.0\",\n sha256 = \"f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rand_xoshiro/0.7.0/download\"],\n strip_prefix = \"rand_xoshiro-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.rand_xoshiro-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rayon-1.12.0\",\n sha256 = \"fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rayon/1.12.0/download\"],\n strip_prefix = \"rayon-1.12.0\",\n build_file = Label(\"@crates//crates:BUILD.rayon-1.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rayon-core-1.13.0\",\n sha256 = \"22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rayon-core/1.13.0/download\"],\n strip_prefix = \"rayon-core-1.13.0\",\n build_file = Label(\"@crates//crates:BUILD.rayon-core-1.13.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rcgen-0.13.2\",\n sha256 = \"75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rcgen/0.13.2/download\"],\n strip_prefix = \"rcgen-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.rcgen-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__redox_syscall-0.5.18\",\n sha256 = \"ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/redox_syscall/0.5.18/download\"],\n strip_prefix = \"redox_syscall-0.5.18\",\n build_file = Label(\"@crates//crates:BUILD.redox_syscall-0.5.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ref-cast-1.0.26\",\n sha256 = \"216e8f773d7923bcba9ceb86a86c93cabb3903a11872fc3f138c49630e50b96d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ref-cast/1.0.26/download\"],\n strip_prefix = \"ref-cast-1.0.26\",\n build_file = Label(\"@crates//crates:BUILD.ref-cast-1.0.26.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ref-cast-impl-1.0.26\",\n sha256 = \"2c9283685feec7d69af75fb0e858d5e7378f33fe4fc699383b2916ab9273e03c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ref-cast-impl/1.0.26/download\"],\n strip_prefix = \"ref-cast-impl-1.0.26\",\n build_file = Label(\"@crates//crates:BUILD.ref-cast-impl-1.0.26.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-1.13.1\",\n sha256 = \"f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex/1.13.1/download\"],\n strip_prefix = \"regex-1.13.1\",\n build_file = Label(\"@crates//crates:BUILD.regex-1.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-automata-0.4.16\",\n sha256 = \"8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-automata/0.4.16/download\"],\n strip_prefix = \"regex-automata-0.4.16\",\n build_file = Label(\"@crates//crates:BUILD.regex-automata-0.4.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-lite-0.1.9\",\n sha256 = \"cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-lite/0.1.9/download\"],\n strip_prefix = \"regex-lite-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.regex-lite-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-syntax-0.8.11\",\n sha256 = \"d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-syntax/0.8.11/download\"],\n strip_prefix = \"regex-syntax-0.8.11\",\n build_file = Label(\"@crates//crates:BUILD.regex-syntax-0.8.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__relative-path-1.9.3\",\n sha256 = \"ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/relative-path/1.9.3/download\"],\n strip_prefix = \"relative-path-1.9.3\",\n build_file = Label(\"@crates//crates:BUILD.relative-path-1.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rend-0.5.4\",\n sha256 = \"663ba70707f96e871406fe10d68128412e619b06d1d47cb91c3a4c6501176240\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rend/0.5.4/download\"],\n strip_prefix = \"rend-0.5.4\",\n build_file = Label(\"@crates//crates:BUILD.rend-0.5.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rfc6979-0.4.0\",\n sha256 = \"f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rfc6979/0.4.0/download\"],\n strip_prefix = \"rfc6979-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.rfc6979-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rgb-0.8.53\",\n sha256 = \"47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rgb/0.8.53/download\"],\n strip_prefix = \"rgb-0.8.53\",\n build_file = Label(\"@crates//crates:BUILD.rgb-0.8.53.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ring-0.17.14\",\n sha256 = \"a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ring/0.17.14/download\"],\n strip_prefix = \"ring-0.17.14\",\n build_file = Label(\"@crates//crates:BUILD.ring-0.17.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rkyv-0.8.17\",\n sha256 = \"815cc8a37159a463064825246cadb07961e25cd9885908606f6d08a98d8f8874\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rkyv/0.8.17/download\"],\n strip_prefix = \"rkyv-0.8.17\",\n build_file = Label(\"@crates//crates:BUILD.rkyv-0.8.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rkyv_derive-0.8.17\",\n sha256 = \"c0ed1a78a1b19d184b0daa629dd9a024573173ec7d485b287cb369fb3607cc1c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rkyv_derive/0.8.17/download\"],\n strip_prefix = \"rkyv_derive-0.8.17\",\n build_file = Label(\"@crates//crates:BUILD.rkyv_derive-0.8.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rlimit-0.11.0\",\n sha256 = \"f35ee2729c56bb610f6dba436bf78135f728b7373bdffae2ec815b2d3eb98cc3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rlimit/0.11.0/download\"],\n strip_prefix = \"rlimit-0.11.0\",\n build_file = Label(\"@crates//crates:BUILD.rlimit-0.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rpds-1.2.1\",\n sha256 = \"e025feb26210bc196b908e72deb063b1b4000754304341cbc168a1e72c857ebc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rpds/1.2.1/download\"],\n strip_prefix = \"rpds-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.rpds-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rstest-0.26.1\",\n sha256 = \"f5a3193c063baaa2a95a33f03035c8a72b83d97a54916055ba22d35ed3839d49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rstest/0.26.1/download\"],\n strip_prefix = \"rstest-0.26.1\",\n build_file = Label(\"@crates//crates:BUILD.rstest-0.26.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rstest_macros-0.26.1\",\n sha256 = \"9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rstest_macros/0.26.1/download\"],\n strip_prefix = \"rstest_macros-0.26.1\",\n build_file = Label(\"@crates//crates:BUILD.rstest_macros-0.26.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rtcp-0.17.2\",\n sha256 = \"adad7f6a501162881032fc84b4bc78ae11f1b30748180b9f5cbe8810bf613aab\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rtcp/0.17.2/download\"],\n strip_prefix = \"rtcp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.rtcp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rtp-0.17.2\",\n sha256 = \"149329e78ada26b5e174a4c281a7a7e5c8bda6008adc90daddd6f98fce56db29\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rtp/0.17.2/download\"],\n strip_prefix = \"rtp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.rtp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustc-hash-1.1.0\",\n sha256 = \"08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustc-hash/1.1.0/download\"],\n strip_prefix = \"rustc-hash-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.rustc-hash-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustc-hash-2.1.3\",\n sha256 = \"6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustc-hash/2.1.3/download\"],\n strip_prefix = \"rustc-hash-2.1.3\",\n build_file = Label(\"@crates//crates:BUILD.rustc-hash-2.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustc_version-0.4.1\",\n sha256 = \"cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustc_version/0.4.1/download\"],\n strip_prefix = \"rustc_version-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.rustc_version-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rusticata-macros-4.1.0\",\n sha256 = \"faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rusticata-macros/4.1.0/download\"],\n strip_prefix = \"rusticata-macros-4.1.0\",\n build_file = Label(\"@crates//crates:BUILD.rusticata-macros-4.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustix-0.38.44\",\n sha256 = \"fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustix/0.38.44/download\"],\n strip_prefix = \"rustix-0.38.44\",\n build_file = Label(\"@crates//crates:BUILD.rustix-0.38.44.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustix-1.1.4\",\n sha256 = \"b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustix/1.1.4/download\"],\n strip_prefix = \"rustix-1.1.4\",\n build_file = Label(\"@crates//crates:BUILD.rustix-1.1.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustls-0.23.42\",\n sha256 = \"3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustls/0.23.42/download\"],\n strip_prefix = \"rustls-0.23.42\",\n build_file = Label(\"@crates//crates:BUILD.rustls-0.23.42.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustls-pki-types-1.15.1\",\n sha256 = \"2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustls-pki-types/1.15.1/download\"],\n strip_prefix = \"rustls-pki-types-1.15.1\",\n build_file = Label(\"@crates//crates:BUILD.rustls-pki-types-1.15.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustls-webpki-0.103.13\",\n sha256 = \"61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustls-webpki/0.103.13/download\"],\n strip_prefix = \"rustls-webpki-0.103.13\",\n build_file = Label(\"@crates//crates:BUILD.rustls-webpki-0.103.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustversion-1.0.23\",\n sha256 = \"cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustversion/1.0.23/download\"],\n strip_prefix = \"rustversion-1.0.23\",\n build_file = Label(\"@crates//crates:BUILD.rustversion-1.0.23.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__safe_arch-0.9.3\",\n sha256 = \"629516c85c29fe757770fa03f2074cf1eac43d44c02a3de9fc2ef7b0e207dfdd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/safe_arch/0.9.3/download\"],\n strip_prefix = \"safe_arch-0.9.3\",\n build_file = Label(\"@crates//crates:BUILD.safe_arch-0.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__same-file-1.0.6\",\n sha256 = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/same-file/1.0.6/download\"],\n strip_prefix = \"same-file-1.0.6\",\n build_file = Label(\"@crates//crates:BUILD.same-file-1.0.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__scoped-tls-1.0.1\",\n sha256 = \"e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/scoped-tls/1.0.1/download\"],\n strip_prefix = \"scoped-tls-1.0.1\",\n build_file = Label(\"@crates//crates:BUILD.scoped-tls-1.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__scopeguard-1.2.0\",\n sha256 = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/scopeguard/1.2.0/download\"],\n strip_prefix = \"scopeguard-1.2.0\",\n build_file = Label(\"@crates//crates:BUILD.scopeguard-1.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sdp-0.17.2\",\n sha256 = \"66b6eecfa5151edef84d544ff3885dff98e5b5fe97586757a4b5118bde51c958\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sdp/0.17.2/download\"],\n strip_prefix = \"sdp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.sdp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sec1-0.7.3\",\n sha256 = \"d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sec1/0.7.3/download\"],\n strip_prefix = \"sec1-0.7.3\",\n build_file = Label(\"@crates//crates:BUILD.sec1-0.7.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__self_cell-1.3.0\",\n sha256 = \"2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/self_cell/1.3.0/download\"],\n strip_prefix = \"self_cell-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.self_cell-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__semver-1.0.28\",\n sha256 = \"8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/semver/1.0.28/download\"],\n strip_prefix = \"semver-1.0.28\",\n build_file = Label(\"@crates//crates:BUILD.semver-1.0.28.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde-1.0.229\",\n sha256 = \"4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde/1.0.229/download\"],\n strip_prefix = \"serde-1.0.229\",\n build_file = Label(\"@crates//crates:BUILD.serde-1.0.229.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_core-1.0.229\",\n sha256 = \"67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_core/1.0.229/download\"],\n strip_prefix = \"serde_core-1.0.229\",\n build_file = Label(\"@crates//crates:BUILD.serde_core-1.0.229.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_derive-1.0.229\",\n sha256 = \"e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_derive/1.0.229/download\"],\n strip_prefix = \"serde_derive-1.0.229\",\n build_file = Label(\"@crates//crates:BUILD.serde_derive-1.0.229.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_json-1.0.151\",\n sha256 = \"c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_json/1.0.151/download\"],\n strip_prefix = \"serde_json-1.0.151\",\n build_file = Label(\"@crates//crates:BUILD.serde_json-1.0.151.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_repr-0.1.21\",\n sha256 = \"8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_repr/0.1.21/download\"],\n strip_prefix = \"serde_repr-0.1.21\",\n build_file = Label(\"@crates//crates:BUILD.serde_repr-0.1.21.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_spanned-1.1.1\",\n sha256 = \"6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_spanned/1.1.1/download\"],\n strip_prefix = \"serde_spanned-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.serde_spanned-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serial2-0.2.37\",\n sha256 = \"9eb6ea5562eeaed6936b8b54e086aa0f88b9e5b1bef45beb038e2519fa1185b1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serial2/0.2.37/download\"],\n strip_prefix = \"serial2-0.2.37\",\n build_file = Label(\"@crates//crates:BUILD.serial2-0.2.37.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sha1-0.10.7\",\n sha256 = \"a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sha1/0.10.7/download\"],\n strip_prefix = \"sha1-0.10.7\",\n build_file = Label(\"@crates//crates:BUILD.sha1-0.10.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sha2-0.10.9\",\n sha256 = \"a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sha2/0.10.9/download\"],\n strip_prefix = \"sha2-0.10.9\",\n build_file = Label(\"@crates//crates:BUILD.sha2-0.10.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sha3-0.10.9\",\n sha256 = \"77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sha3/0.10.9/download\"],\n strip_prefix = \"sha3-0.10.9\",\n build_file = Label(\"@crates//crates:BUILD.sha3-0.10.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shared_library-0.1.9\",\n sha256 = \"5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shared_library/0.1.9/download\"],\n strip_prefix = \"shared_library-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.shared_library-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shell-words-1.1.1\",\n sha256 = \"dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shell-words/1.1.1/download\"],\n strip_prefix = \"shell-words-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.shell-words-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shlex-1.3.0\",\n sha256 = \"0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shlex/1.3.0/download\"],\n strip_prefix = \"shlex-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.shlex-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__shlex-2.0.1\",\n sha256 = \"f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/shlex/2.0.1/download\"],\n strip_prefix = \"shlex-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.shlex-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__signal-hook-registry-1.4.8\",\n sha256 = \"c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/signal-hook-registry/1.4.8/download\"],\n strip_prefix = \"signal-hook-registry-1.4.8\",\n build_file = Label(\"@crates//crates:BUILD.signal-hook-registry-1.4.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__signature-2.2.0\",\n sha256 = \"77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/signature/2.2.0/download\"],\n strip_prefix = \"signature-2.2.0\",\n build_file = Label(\"@crates//crates:BUILD.signature-2.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__simd-adler32-0.3.10\",\n sha256 = \"3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/simd-adler32/0.3.10/download\"],\n strip_prefix = \"simd-adler32-0.3.10\",\n build_file = Label(\"@crates//crates:BUILD.simd-adler32-0.3.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__simdutf8-0.1.5\",\n sha256 = \"e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/simdutf8/0.1.5/download\"],\n strip_prefix = \"simdutf8-0.1.5\",\n build_file = Label(\"@crates//crates:BUILD.simdutf8-0.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__similar-2.7.0\",\n sha256 = \"bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/similar/2.7.0/download\"],\n strip_prefix = \"similar-2.7.0\",\n build_file = Label(\"@crates//crates:BUILD.similar-2.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__similar-3.1.1\",\n sha256 = \"e6505efef05804732ed8a3f2d4f279429eb485bd69d5b0cc6b19cc02005cda16\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/similar/3.1.1/download\"],\n strip_prefix = \"similar-3.1.1\",\n build_file = Label(\"@crates//crates:BUILD.similar-3.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__siphasher-1.0.3\",\n sha256 = \"8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/siphasher/1.0.3/download\"],\n strip_prefix = \"siphasher-1.0.3\",\n build_file = Label(\"@crates//crates:BUILD.siphasher-1.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__slab-0.4.12\",\n sha256 = \"0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/slab/0.4.12/download\"],\n strip_prefix = \"slab-0.4.12\",\n build_file = Label(\"@crates//crates:BUILD.slab-0.4.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__sm3-0.5.0\",\n sha256 = \"da6a89ba31723d185fd7413b98c576a575f356d9b84729d8ecb6ead60000a5b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/sm3/0.5.0/download\"],\n strip_prefix = \"sm3-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.sm3-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__smallvec-1.15.2\",\n sha256 = \"8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/smallvec/1.15.2/download\"],\n strip_prefix = \"smallvec-1.15.2\",\n build_file = Label(\"@crates//crates:BUILD.smallvec-1.15.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__smol_str-0.2.2\",\n sha256 = \"dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/smol_str/0.2.2/download\"],\n strip_prefix = \"smol_str-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.smol_str-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__socket2-0.5.10\",\n sha256 = \"e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/socket2/0.5.10/download\"],\n strip_prefix = \"socket2-0.5.10\",\n build_file = Label(\"@crates//crates:BUILD.socket2-0.5.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__socket2-0.6.5\",\n sha256 = \"c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/socket2/0.6.5/download\"],\n strip_prefix = \"socket2-0.6.5\",\n build_file = Label(\"@crates//crates:BUILD.socket2-0.6.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__spin-0.10.1\",\n sha256 = \"023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/spin/0.10.1/download\"],\n strip_prefix = \"spin-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.spin-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__spin-0.9.9\",\n sha256 = \"3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/spin/0.9.9/download\"],\n strip_prefix = \"spin-0.9.9\",\n build_file = Label(\"@crates//crates:BUILD.spin-0.9.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__spki-0.7.3\",\n sha256 = \"d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/spki/0.7.3/download\"],\n strip_prefix = \"spki-0.7.3\",\n build_file = Label(\"@crates//crates:BUILD.spki-0.7.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__stable_deref_trait-1.2.1\",\n sha256 = \"6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/stable_deref_trait/1.2.1/download\"],\n strip_prefix = \"stable_deref_trait-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.stable_deref_trait-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__str_stack-0.1.1\",\n sha256 = \"7f446288b699d66d0fd2e30d1cfe7869194312524b3b9252594868ed26ef056a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/str_stack/0.1.1/download\"],\n strip_prefix = \"str_stack-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.str_stack-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__streaming-iterator-0.1.9\",\n sha256 = \"2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/streaming-iterator/0.1.9/download\"],\n strip_prefix = \"streaming-iterator-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.streaming-iterator-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__string_cache-0.9.0\",\n sha256 = \"a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/string_cache/0.9.0/download\"],\n strip_prefix = \"string_cache-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.string_cache-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__string_cache_codegen-0.6.1\",\n sha256 = \"585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/string_cache_codegen/0.6.1/download\"],\n strip_prefix = \"string_cache_codegen-0.6.1\",\n build_file = Label(\"@crates//crates:BUILD.string_cache_codegen-0.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__strsim-0.11.1\",\n sha256 = \"7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/strsim/0.11.1/download\"],\n strip_prefix = \"strsim-0.11.1\",\n build_file = Label(\"@crates//crates:BUILD.strsim-0.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__strum-0.28.0\",\n sha256 = \"9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/strum/0.28.0/download\"],\n strip_prefix = \"strum-0.28.0\",\n build_file = Label(\"@crates//crates:BUILD.strum-0.28.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__strum_macros-0.28.0\",\n sha256 = \"ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/strum_macros/0.28.0/download\"],\n strip_prefix = \"strum_macros-0.28.0\",\n build_file = Label(\"@crates//crates:BUILD.strum_macros-0.28.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__stun-0.17.2\",\n sha256 = \"2e3b8d5ad1dd4c8cd0595440f26521a71dd593cb5873ee8e06b91510b7d97269\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/stun/0.17.2/download\"],\n strip_prefix = \"stun-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.stun-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__substring-1.4.5\",\n sha256 = \"42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/substring/1.4.5/download\"],\n strip_prefix = \"substring-1.4.5\",\n build_file = Label(\"@crates//crates:BUILD.substring-1.4.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__subtle-2.6.1\",\n sha256 = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/subtle/2.6.1/download\"],\n strip_prefix = \"subtle-2.6.1\",\n build_file = Label(\"@crates//crates:BUILD.subtle-2.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-2.0.119\",\n sha256 = \"872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/2.0.119/download\"],\n strip_prefix = \"syn-2.0.119\",\n build_file = Label(\"@crates//crates:BUILD.syn-2.0.119.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-3.0.3\",\n sha256 = \"53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/3.0.3/download\"],\n strip_prefix = \"syn-3.0.3\",\n build_file = Label(\"@crates//crates:BUILD.syn-3.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__synstructure-0.13.2\",\n sha256 = \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/synstructure/0.13.2/download\"],\n strip_prefix = \"synstructure-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.synstructure-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syntect-5.3.0\",\n sha256 = \"656b45c05d95a5704399aeef6bd0ddec7b2b3531b7c9e900abbf7c4d2190c925\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syntect/5.3.0/download\"],\n strip_prefix = \"syntect-5.3.0\",\n build_file = Label(\"@crates//crates:BUILD.syntect-5.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__system-deps-7.0.8\",\n sha256 = \"396a35feb67335377e0251fcbc1092fc85c484bd4e3a7a54319399da127796e7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/system-deps/7.0.8/download\"],\n strip_prefix = \"system-deps-7.0.8\",\n build_file = Label(\"@crates//crates:BUILD.system-deps-7.0.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tap-1.0.1\",\n sha256 = \"55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tap/1.0.1/download\"],\n strip_prefix = \"tap-1.0.1\",\n build_file = Label(\"@crates//crates:BUILD.tap-1.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__target-lexicon-0.13.5\",\n sha256 = \"adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/target-lexicon/0.13.5/download\"],\n strip_prefix = \"target-lexicon-0.13.5\",\n build_file = Label(\"@crates//crates:BUILD.target-lexicon-0.13.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tempfile-3.27.0\",\n sha256 = \"32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tempfile/3.27.0/download\"],\n strip_prefix = \"tempfile-3.27.0\",\n build_file = Label(\"@crates//crates:BUILD.tempfile-3.27.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tendril-0.5.1\",\n sha256 = \"5fed54709c5b3a53d09bb1c113ea4f5ceafd1e772ddcb0030a82e1d56c087b08\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tendril/0.5.1/download\"],\n strip_prefix = \"tendril-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.tendril-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__termcolor-1.4.1\",\n sha256 = \"06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/termcolor/1.4.1/download\"],\n strip_prefix = \"termcolor-1.4.1\",\n build_file = Label(\"@crates//crates:BUILD.termcolor-1.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__terminal_size-0.4.4\",\n sha256 = \"230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/terminal_size/0.4.4/download\"],\n strip_prefix = \"terminal_size-0.4.4\",\n build_file = Label(\"@crates//crates:BUILD.terminal_size-0.4.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__terminfo-0.9.0\",\n sha256 = \"d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/terminfo/0.9.0/download\"],\n strip_prefix = \"terminfo-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.terminfo-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-1.0.69\",\n sha256 = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror/1.0.69/download\"],\n strip_prefix = \"thiserror-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-2.0.19\",\n sha256 = \"09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror/2.0.19/download\"],\n strip_prefix = \"thiserror-2.0.19\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-2.0.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-impl-1.0.69\",\n sha256 = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror-impl/1.0.69/download\"],\n strip_prefix = \"thiserror-impl-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-impl-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-impl-2.0.19\",\n sha256 = \"43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror-impl/2.0.19/download\"],\n strip_prefix = \"thiserror-impl-2.0.19\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-impl-2.0.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tiff-0.11.3\",\n sha256 = \"b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tiff/0.11.3/download\"],\n strip_prefix = \"tiff-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.tiff-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tiktoken-rs-0.11.0\",\n sha256 = \"fac4a168cfc1d8ed65bf17a6ee0843ad9a68f863c63c0fb2fa7eab67838782ee\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tiktoken-rs/0.11.0/download\"],\n strip_prefix = \"tiktoken-rs-0.11.0\",\n build_file = Label(\"@crates//crates:BUILD.tiktoken-rs-0.11.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__time-0.3.54\",\n sha256 = \"3e1d5e639ff6bab73cb6885cc7e7b1de96c3f32c68ec55f3952614bec1092244\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/time/0.3.54/download\"],\n strip_prefix = \"time-0.3.54\",\n build_file = Label(\"@crates//crates:BUILD.time-0.3.54.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__time-core-0.1.9\",\n sha256 = \"9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/time-core/0.1.9/download\"],\n strip_prefix = \"time-core-0.1.9\",\n build_file = Label(\"@crates//crates:BUILD.time-core-0.1.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__time-macros-0.2.32\",\n sha256 = \"7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/time-macros/0.2.32/download\"],\n strip_prefix = \"time-macros-0.2.32\",\n build_file = Label(\"@crates//crates:BUILD.time-macros-0.2.32.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tiny-keccak-2.0.2\",\n sha256 = \"2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tiny-keccak/2.0.2/download\"],\n strip_prefix = \"tiny-keccak-2.0.2\",\n build_file = Label(\"@crates//crates:BUILD.tiny-keccak-2.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinystr-0.8.3\",\n sha256 = \"c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinystr/0.8.3/download\"],\n strip_prefix = \"tinystr-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.tinystr-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinyvec-1.12.0\",\n sha256 = \"bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinyvec/1.12.0/download\"],\n strip_prefix = \"tinyvec-1.12.0\",\n build_file = Label(\"@crates//crates:BUILD.tinyvec-1.12.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tinyvec_macros-0.1.1\",\n sha256 = \"1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tinyvec_macros/0.1.1/download\"],\n strip_prefix = \"tinyvec_macros-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.tinyvec_macros-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tokio-1.53.1\",\n sha256 = \"202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tokio/1.53.1/download\"],\n strip_prefix = \"tokio-1.53.1\",\n build_file = Label(\"@crates//crates:BUILD.tokio-1.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tokio-macros-2.7.1\",\n sha256 = \"6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tokio-macros/2.7.1/download\"],\n strip_prefix = \"tokio-macros-2.7.1\",\n build_file = Label(\"@crates//crates:BUILD.tokio-macros-2.7.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tokio-util-0.7.19\",\n sha256 = \"494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tokio-util/0.7.19/download\"],\n strip_prefix = \"tokio-util-0.7.19\",\n build_file = Label(\"@crates//crates:BUILD.tokio-util-0.7.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml-1.1.3-spec-1.1.0\",\n sha256 = \"53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml/1.1.3+spec-1.1.0/download\"],\n strip_prefix = \"toml-1.1.3+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml-1.1.3+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_datetime-1.1.1-spec-1.1.0\",\n sha256 = \"3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_datetime/1.1.1+spec-1.1.0/download\"],\n strip_prefix = \"toml_datetime-1.1.1+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml_datetime-1.1.1+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_edit-0.25.13-spec-1.1.0\",\n sha256 = \"6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_edit/0.25.13+spec-1.1.0/download\"],\n strip_prefix = \"toml_edit-0.25.13+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml_edit-0.25.13+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_parser-1.1.3-spec-1.1.0\",\n sha256 = \"1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_parser/1.1.3+spec-1.1.0/download\"],\n strip_prefix = \"toml_parser-1.1.3+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml_parser-1.1.3+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__toml_writer-1.1.2-spec-1.1.0\",\n sha256 = \"7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/toml_writer/1.1.2+spec-1.1.0/download\"],\n strip_prefix = \"toml_writer-1.1.2+spec-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.toml_writer-1.1.2+spec-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tracing-0.1.44\",\n sha256 = \"63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tracing/0.1.44/download\"],\n strip_prefix = \"tracing-0.1.44\",\n build_file = Label(\"@crates//crates:BUILD.tracing-0.1.44.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tracing-attributes-0.1.31\",\n sha256 = \"7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tracing-attributes/0.1.31/download\"],\n strip_prefix = \"tracing-attributes-0.1.31\",\n build_file = Label(\"@crates//crates:BUILD.tracing-attributes-0.1.31.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tracing-core-0.1.36\",\n sha256 = \"db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tracing-core/0.1.36/download\"],\n strip_prefix = \"tracing-core-0.1.36\",\n build_file = Label(\"@crates//crates:BUILD.tracing-core-0.1.36.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-0.25.10\",\n sha256 = \"78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter/0.25.10/download\"],\n strip_prefix = \"tree-sitter-0.25.10\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-0.25.10.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-astro-next-0.1.1\",\n sha256 = \"794a4a59fc2d88e49b4bc41fef9522d77184a36f4e68bbaf545cd1eb2364c46e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-astro-next/0.1.1/download\"],\n strip_prefix = \"tree-sitter-astro-next-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-astro-next-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-bash-0.25.1\",\n sha256 = \"9e5ec769279cc91b561d3df0d8a5deb26b0ad40d183127f409494d6d8fc53062\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-bash/0.25.1/download\"],\n strip_prefix = \"tree-sitter-bash-0.25.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-bash-0.25.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-c-0.24.2\",\n sha256 = \"a9b2eb57a55fed6b00812912e730b7a275cf4fe98bfd6a5d76263d4438371728\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-c/0.24.2/download\"],\n strip_prefix = \"tree-sitter-c-0.24.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-c-0.24.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-c-sharp-0.23.5\",\n sha256 = \"c1aac67f1ad71de1d6d39708d34811081c26dfa495658de6c14c34200849357c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-c-sharp/0.23.5/download\"],\n strip_prefix = \"tree-sitter-c-sharp-0.23.5\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-c-sharp-0.23.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-clojure-0.1.0\",\n sha256 = \"4004884cc509449a1d78fa3e1f02b4e953d0a8065984445304795e72e885338c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-clojure/0.1.0/download\"],\n strip_prefix = \"tree-sitter-clojure-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-clojure-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-cmake-0.7.4\",\n sha256 = \"164e0c4f4236ec5ceff14824a5528615cf462e100467e49826442ff57d327061\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-cmake/0.7.4/download\"],\n strip_prefix = \"tree-sitter-cmake-0.7.4\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-cmake-0.7.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-cpp-0.23.4\",\n sha256 = \"df2196ea9d47b4ab4a31b9297eaa5a5d19a0b121dceb9f118f6790ad0ab94743\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-cpp/0.23.4/download\"],\n strip_prefix = \"tree-sitter-cpp-0.23.4\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-cpp-0.23.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-css-0.25.0\",\n sha256 = \"a5cbc5e18f29a2c6d6435891f42569525cf95435a3e01c2f1947abcde178686f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-css/0.25.0/download\"],\n strip_prefix = \"tree-sitter-css-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-css-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-dart-0.2.0\",\n sha256 = \"325dd1e24ee9ee21111e9c43680ae7d6010aaa9f282b048a99b9c7163c1cf553\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-dart/0.2.0/download\"],\n strip_prefix = \"tree-sitter-dart-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-dart-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-diff-0.1.0\",\n sha256 = \"dfe1e5ca280a65dfe5ba4205c1bcc84edf486464fed315db53dee6da9a335889\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-diff/0.1.0/download\"],\n strip_prefix = \"tree-sitter-diff-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-diff-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-dockerfile-updated-0.2.0\",\n sha256 = \"5e61eb704364be179ab9be89e2891c8e77c0041eca5891a5c04164a21f6df7a0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-dockerfile-updated/0.2.0/download\"],\n strip_prefix = \"tree-sitter-dockerfile-updated-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-dockerfile-updated-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-elisp-1.6.1\",\n sha256 = \"5e2e9a6ab3cebf24ca41cdc1f985549b9b33f7ef25c19ac7d18e53a4ee24da09\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-elisp/1.6.1/download\"],\n strip_prefix = \"tree-sitter-elisp-1.6.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-elisp-1.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-elixir-0.3.5\",\n sha256 = \"66dd064a762ed95bfc29857fa3cb7403bb1e5cb88112de0f6341b7e47284ba40\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-elixir/0.3.5/download\"],\n strip_prefix = \"tree-sitter-elixir-0.3.5\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-elixir-0.3.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-erlang-0.16.0\",\n sha256 = \"ceb442e728225d601db0661f60d64e166bd9b9a55c587f71d4e4f27378717cce\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-erlang/0.16.0/download\"],\n strip_prefix = \"tree-sitter-erlang-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-erlang-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-fortran-0.6.0\",\n sha256 = \"ea5fea41363a9b59666001dc26c4b356d4e164da27c6ce31145e00aba6bf9b16\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-fortran/0.6.0/download\"],\n strip_prefix = \"tree-sitter-fortran-0.6.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-fortran-0.6.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-go-0.25.0\",\n sha256 = \"c8560a4d2f835cc0d4d2c2e03cbd0dde2f6114b43bc491164238d333e28b16ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-go/0.25.0/download\"],\n strip_prefix = \"tree-sitter-go-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-go-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-graphql-0.1.0\",\n sha256 = \"efedc4cac157161cc23a0adc4553a2cedc908e1cd754b6cd033a919bb81ce5d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-graphql/0.1.0/download\"],\n strip_prefix = \"tree-sitter-graphql-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-graphql-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-haskell-0.23.1\",\n sha256 = \"977c51e504548cba13fc27cb5a2edab2124cf6716a1934915d07ab99523b05a4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-haskell/0.23.1/download\"],\n strip_prefix = \"tree-sitter-haskell-0.23.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-haskell-0.23.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-hcl-1.1.0\",\n sha256 = \"5a7b2cc3d7121553b84309fab9d11b3ff3d420403eef9ae50f9fd1cd9d9cf012\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-hcl/1.1.0/download\"],\n strip_prefix = \"tree-sitter-hcl-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-hcl-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-html-0.23.2\",\n sha256 = \"261b708e5d92061ede329babaaa427b819329a9d427a1d710abb0f67bbef63ee\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-html/0.23.2/download\"],\n strip_prefix = \"tree-sitter-html-0.23.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-html-0.23.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-ini-1.4.0\",\n sha256 = \"387f79682cd53b7c0a5777c96e601a02b9965a787984ef86dbb8952bdab2d62f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-ini/1.4.0/download\"],\n strip_prefix = \"tree-sitter-ini-1.4.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-ini-1.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-java-0.23.5\",\n sha256 = \"0aa6cbcdc8c679b214e616fd3300da67da0e492e066df01bcf5a5921a71e90d6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-java/0.23.5/download\"],\n strip_prefix = \"tree-sitter-java-0.23.5\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-java-0.23.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-javascript-0.25.0\",\n sha256 = \"68204f2abc0627a90bdf06e605f5c470aa26fdcb2081ea553a04bdad756693f5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-javascript/0.25.0/download\"],\n strip_prefix = \"tree-sitter-javascript-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-javascript-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-json-0.24.8\",\n sha256 = \"4d727acca406c0020cffc6cf35516764f36c8e3dc4408e5ebe2cb35a947ec471\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-json/0.24.8/download\"],\n strip_prefix = \"tree-sitter-json-0.24.8\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-json-0.24.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-julia-0.23.1\",\n sha256 = \"4144731a178812ee867619b1e98b3b91e54c1652304b26e5ebe3175b701de323\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-julia/0.23.1/download\"],\n strip_prefix = \"tree-sitter-julia-0.23.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-julia-0.23.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-just-0.2.0\",\n sha256 = \"bd46794f2c270f43d73b2f2c8c256992471f3493c903604da0886df984771920\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-just/0.2.0/download\"],\n strip_prefix = \"tree-sitter-just-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-just-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-kotlin-sg-0.4.1\",\n sha256 = \"c06ec43ae3c12165d4ac08afe4e1f5fc6757ffe274fa7bd5af9007ef11ba4319\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-kotlin-sg/0.4.1/download\"],\n strip_prefix = \"tree-sitter-kotlin-sg-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-kotlin-sg-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-language-0.1.7\",\n sha256 = \"009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-language/0.1.7/download\"],\n strip_prefix = \"tree-sitter-language-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-language-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-lua-0.5.0\",\n sha256 = \"8daaf5f4235188a58603c39760d5fa5d4b920d36a299c934adddae757f32a10c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-lua/0.5.0/download\"],\n strip_prefix = \"tree-sitter-lua-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-lua-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-make-1.1.1\",\n sha256 = \"c5998dc7cbcbdab19fae8aefef982bf2d6544513d8d2e69cc44aec4c63810104\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-make/1.1.1/download\"],\n strip_prefix = \"tree-sitter-make-1.1.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-make-1.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-md-0.5.3\",\n sha256 = \"2efd398be546456c814598ee56c0f51769a77241511b4a58077815d120afa882\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-md/0.5.3/download\"],\n strip_prefix = \"tree-sitter-md-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-md-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-nix-0.3.0\",\n sha256 = \"4952a9733f3a98f6683a0ccd1035d84ab7a52f7e84eeed58548d86765ad92de3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-nix/0.3.0/download\"],\n strip_prefix = \"tree-sitter-nix-0.3.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-nix-0.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-objc-3.0.2\",\n sha256 = \"9ca8bb556423fc176f0535e79d525f783a6684d3c9da81bf9d905303c129e1d2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-objc/3.0.2/download\"],\n strip_prefix = \"tree-sitter-objc-3.0.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-objc-3.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-ocaml-0.24.2\",\n sha256 = \"7d19db582b3855f56b5f9ec484170fbfb9ee60b938ec7720d76d2ee788e8b640\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-ocaml/0.24.2/download\"],\n strip_prefix = \"tree-sitter-ocaml-0.24.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-ocaml-0.24.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-odin-1.3.0\",\n sha256 = \"24db210fe9ba2237c71c5030d7b146c7025420ba72dd8013d13cd822c3a8d77a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-odin/1.3.0/download\"],\n strip_prefix = \"tree-sitter-odin-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-odin-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-php-0.24.2\",\n sha256 = \"0d8c17c3ab69052c5eeaa7ff5cd972dd1bc25d1b97ee779fec391ad3b5df5592\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-php/0.24.2/download\"],\n strip_prefix = \"tree-sitter-php-0.24.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-php-0.24.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-powershell-0.26.4\",\n sha256 = \"3faf304d44b9ddd4a7d97804bb8de7daf564336dd5a526dc6de5b39238243022\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-powershell/0.26.4/download\"],\n strip_prefix = \"tree-sitter-powershell-0.26.4\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-powershell-0.26.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-proto-0.4.0\",\n sha256 = \"2e410ccb5fa3cbd6bf7b8e512ecf7ad9d5254395b822bfe9f751b50fa978f31c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-proto/0.4.0/download\"],\n strip_prefix = \"tree-sitter-proto-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-proto-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-python-0.25.0\",\n sha256 = \"6bf85fd39652e740bf60f46f4cda9492c3a9ad75880575bf14960f775cb74a1c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-python/0.25.0/download\"],\n strip_prefix = \"tree-sitter-python-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-python-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-r-1.3.0\",\n sha256 = \"ffc9954ec870dcad6cffdd302b405306c68cf031ed79a78cd9746f6740d9fe20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-r/1.3.0/download\"],\n strip_prefix = \"tree-sitter-r-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-r-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-regex-0.25.0\",\n sha256 = \"bd8a59be9f0ac131fd8f062eaaba14882b2fa5a6a7882a20134cb1d60df2e625\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-regex/0.25.0/download\"],\n strip_prefix = \"tree-sitter-regex-0.25.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-regex-0.25.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-ruby-0.23.1\",\n sha256 = \"be0484ea4ef6bb9c575b4fdabde7e31340a8d2dbc7d52b321ac83da703249f95\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-ruby/0.23.1/download\"],\n strip_prefix = \"tree-sitter-ruby-0.23.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-ruby-0.23.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-rust-0.24.2\",\n sha256 = \"439e577dbe07423ec2582ac62c7531120dbfccfa6e5f92406f93dd271a120e45\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-rust/0.24.2/download\"],\n strip_prefix = \"tree-sitter-rust-0.24.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-rust-0.24.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-scala-0.26.0\",\n sha256 = \"de5a4a7ff23a55474ce6a741d52aaeca7a82fe9421bb982b86e98c6ac8629397\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-scala/0.26.0/download\"],\n strip_prefix = \"tree-sitter-scala-0.26.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-scala-0.26.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-sequel-0.3.11\",\n sha256 = \"9d198ad3c319c02e43c21efa1ec796b837afcb96ffaef1a40c1978fbdcec7d17\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-sequel/0.3.11/download\"],\n strip_prefix = \"tree-sitter-sequel-0.3.11\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-sequel-0.3.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-solidity-1.2.13\",\n sha256 = \"4eacf8875b70879f0cb670c60b233ad0b68752d9e1474e6c3ef168eea8a90b25\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-solidity/1.2.13/download\"],\n strip_prefix = \"tree-sitter-solidity-1.2.13\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-solidity-1.2.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-starlark-1.3.0\",\n sha256 = \"8934f282d085cc4b9ee28aa688aa3fbe8aa3766201c2a6252f411d45b4c3a721\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-starlark/1.3.0/download\"],\n strip_prefix = \"tree-sitter-starlark-1.3.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-starlark-1.3.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-svelte-next-0.1.1\",\n sha256 = \"56f88190d0743e897c3e148a7e241aba0a8844b8afe816943851426e3f7b9753\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-svelte-next/0.1.1/download\"],\n strip_prefix = \"tree-sitter-svelte-next-0.1.1\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-svelte-next-0.1.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-swift-0.7.3\",\n sha256 = \"fe36052155b9dd69ca82b3b8f1b4ccfb2d867125ac1a4db1dd7331829242668c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-swift/0.7.3/download\"],\n strip_prefix = \"tree-sitter-swift-0.7.3\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-swift-0.7.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-tlaplus-1.5.0\",\n sha256 = \"ddaacc0337bfee38f233a91a704dc36b887a0c385348163f65344d64b73f79e1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-tlaplus/1.5.0/download\"],\n strip_prefix = \"tree-sitter-tlaplus-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-tlaplus-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-toml-ng-0.7.0\",\n sha256 = \"e9adc2c898ae49730e857d75be403da3f92bb81d8e37a2f918a08dd10de5ebb1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-toml-ng/0.7.0/download\"],\n strip_prefix = \"tree-sitter-toml-ng-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-toml-ng-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-typescript-0.23.2\",\n sha256 = \"6c5f76ed8d947a75cc446d5fccd8b602ebf0cde64ccf2ffa434d873d7a575eff\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-typescript/0.23.2/download\"],\n strip_prefix = \"tree-sitter-typescript-0.23.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-typescript-0.23.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-verilog-1.0.3\",\n sha256 = \"d4e7e0360395852f1f6ff5b7b82c72dc6557d181073188df1d60ec469ea69c66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-verilog/1.0.3/download\"],\n strip_prefix = \"tree-sitter-verilog-1.0.3\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-verilog-1.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-vue-next-0.1.0\",\n sha256 = \"e9ac89acaa8165aaabfa8ae9683aa423b0d2bf42c815dae5ca031a36a75525f1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-vue-next/0.1.0/download\"],\n strip_prefix = \"tree-sitter-vue-next-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-vue-next-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-xml-0.7.0\",\n sha256 = \"e670041f591d994f54d597ddcd8f4ebc930e282c4c76a42268743b71f0c8b6b3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-xml/0.7.0/download\"],\n strip_prefix = \"tree-sitter-xml-0.7.0\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-xml-0.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-yaml-0.7.2\",\n sha256 = \"53c223db85f05e34794f065454843b0668ebc15d240ada63e2b5939f43ce7c97\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-yaml/0.7.2/download\"],\n strip_prefix = \"tree-sitter-yaml-0.7.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-yaml-0.7.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree-sitter-zig-1.1.2\",\n sha256 = \"ab11fc124851b0db4dd5e55983bbd9631192e93238389dcd44521715e5d53e28\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree-sitter-zig/1.1.2/download\"],\n strip_prefix = \"tree-sitter-zig-1.1.2\",\n build_file = Label(\"@crates//crates:BUILD.tree-sitter-zig-1.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__tree_magic_mini-3.2.2\",\n sha256 = \"b8765b90061cba6c22b5831f675da109ae5561588290f9fa2317adab2714d5a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/tree_magic_mini/3.2.2/download\"],\n strip_prefix = \"tree_magic_mini-3.2.2\",\n build_file = Label(\"@crates//crates:BUILD.tree_magic_mini-3.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__triomphe-0.1.16\",\n sha256 = \"b40688ea6389c8171614b25491f71d4a27946e0c7ce2da1c6de27e25abf1a0ae\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/triomphe/0.1.16/download\"],\n strip_prefix = \"triomphe-0.1.16\",\n build_file = Label(\"@crates//crates:BUILD.triomphe-0.1.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ttf-parser-0.21.1\",\n sha256 = \"2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ttf-parser/0.21.1/download\"],\n strip_prefix = \"ttf-parser-0.21.1\",\n build_file = Label(\"@crates//crates:BUILD.ttf-parser-0.21.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__turn-0.17.2\",\n sha256 = \"d99249a493335eb44c4d7943a8751b22561a82c9903d8eb2d29780b3927880a7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/turn/0.17.2/download\"],\n strip_prefix = \"turn-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.turn-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__type-map-0.5.1\",\n sha256 = \"cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/type-map/0.5.1/download\"],\n strip_prefix = \"type-map-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.type-map-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__typed-arena-2.0.2\",\n sha256 = \"6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/typed-arena/2.0.2/download\"],\n strip_prefix = \"typed-arena-2.0.2\",\n build_file = Label(\"@crates//crates:BUILD.typed-arena-2.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__typenum-1.20.1\",\n sha256 = \"b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/typenum/1.20.1/download\"],\n strip_prefix = \"typenum-1.20.1\",\n build_file = Label(\"@crates//crates:BUILD.typenum-1.20.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ucd-trie-0.1.7\",\n sha256 = \"2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ucd-trie/0.1.7/download\"],\n strip_prefix = \"ucd-trie-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.ucd-trie-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uds_windows-1.2.1\",\n sha256 = \"f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uds_windows/1.2.1/download\"],\n strip_prefix = \"uds_windows-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.uds_windows-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unic-langid-0.9.6\",\n sha256 = \"a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unic-langid/0.9.6/download\"],\n strip_prefix = \"unic-langid-0.9.6\",\n build_file = Label(\"@crates//crates:BUILD.unic-langid-0.9.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unic-langid-impl-0.9.6\",\n sha256 = \"dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unic-langid-impl/0.9.6/download\"],\n strip_prefix = \"unic-langid-impl-0.9.6\",\n build_file = Label(\"@crates//crates:BUILD.unic-langid-impl-0.9.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicase-2.9.0\",\n sha256 = \"dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicase/2.9.0/download\"],\n strip_prefix = \"unicase-2.9.0\",\n build_file = Label(\"@crates//crates:BUILD.unicase-2.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-ident-1.0.24\",\n sha256 = \"e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-ident/1.0.24/download\"],\n strip_prefix = \"unicode-ident-1.0.24\",\n build_file = Label(\"@crates//crates:BUILD.unicode-ident-1.0.24.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-segmentation-1.13.3\",\n sha256 = \"c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-segmentation/1.13.3/download\"],\n strip_prefix = \"unicode-segmentation-1.13.3\",\n build_file = Label(\"@crates//crates:BUILD.unicode-segmentation-1.13.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-width-0.1.14\",\n sha256 = \"7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-width/0.1.14/download\"],\n strip_prefix = \"unicode-width-0.1.14\",\n build_file = Label(\"@crates//crates:BUILD.unicode-width-0.1.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-width-0.2.2\",\n sha256 = \"b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-width/0.2.2/download\"],\n strip_prefix = \"unicode-width-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.unicode-width-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unit-prefix-0.5.2\",\n sha256 = \"81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unit-prefix/0.5.2/download\"],\n strip_prefix = \"unit-prefix-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.unit-prefix-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__universal-hash-0.5.1\",\n sha256 = \"fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/universal-hash/0.5.1/download\"],\n strip_prefix = \"universal-hash-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.universal-hash-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__untrusted-0.9.0\",\n sha256 = \"8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/untrusted/0.9.0/download\"],\n strip_prefix = \"untrusted-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.untrusted-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__url-2.5.8\",\n sha256 = \"ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/url/2.5.8/download\"],\n strip_prefix = \"url-2.5.8\",\n build_file = Label(\"@crates//crates:BUILD.url-2.5.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__urlencoding-2.1.3\",\n sha256 = \"daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/urlencoding/2.1.3/download\"],\n strip_prefix = \"urlencoding-2.1.3\",\n build_file = Label(\"@crates//crates:BUILD.urlencoding-2.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf16_iter-1.0.5\",\n sha256 = \"c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf16_iter/1.0.5/download\"],\n strip_prefix = \"utf16_iter-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.utf16_iter-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8-chars-3.0.7\",\n sha256 = \"92498c67ea3511b37eccff13b573ed871faf0ce9c4056ab032bd01a681f445a0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8-chars/3.0.7/download\"],\n strip_prefix = \"utf8-chars-3.0.7\",\n build_file = Label(\"@crates//crates:BUILD.utf8-chars-3.0.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8_iter-1.0.4\",\n sha256 = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8_iter/1.0.4/download\"],\n strip_prefix = \"utf8_iter-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.utf8_iter-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8parse-0.2.2\",\n sha256 = \"06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8parse/0.2.2/download\"],\n strip_prefix = \"utf8parse-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.utf8parse-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore-0.0.30\",\n sha256 = \"71f4e82877d06de779c611a3d54720f56f1e68b228fb30a5b6c66ef07e68263d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore/0.0.30/download\"],\n strip_prefix = \"uucore-0.0.30\",\n build_file = Label(\"@crates//crates:BUILD.uucore-0.0.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore-0.8.0\",\n sha256 = \"07d779636d827cde4100f0e65ff3fd23b0b1f1195055475c6e6813d425f30c8e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore/0.8.0/download\"],\n strip_prefix = \"uucore-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.uucore-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore-0.9.0\",\n sha256 = \"069b34217c27f611e1589f540f58118dbf226a9e407d38ab472052ff075a1dc2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore/0.9.0/download\"],\n strip_prefix = \"uucore-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.uucore-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore_procs-0.0.30\",\n sha256 = \"c72435859e812e602e225dea48d014abb6b1072220a8d44f2fe0565553b1f7e4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore_procs/0.0.30/download\"],\n strip_prefix = \"uucore_procs-0.0.30\",\n build_file = Label(\"@crates//crates:BUILD.uucore_procs-0.0.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore_procs-0.8.0\",\n sha256 = \"da865e8a648b260dbd89fca76d0801995877ab27a4e259b6dec30ba9743b86ab\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore_procs/0.8.0/download\"],\n strip_prefix = \"uucore_procs-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.uucore_procs-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uucore_procs-0.9.0\",\n sha256 = \"34337da211e7abfff7189b794afb3b5018fe356fb36474b73645458fc1201350\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uucore_procs/0.9.0/download\"],\n strip_prefix = \"uucore_procs-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.uucore_procs-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uuhelp_parser-0.0.30\",\n sha256 = \"0bb6d972f580f8223cb7052d8580aea2b7061e368cf476de32ea9457b19459ed\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uuhelp_parser/0.0.30/download\"],\n strip_prefix = \"uuhelp_parser-0.0.30\",\n build_file = Label(\"@crates//crates:BUILD.uuhelp_parser-0.0.30.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uuid-1.24.0\",\n sha256 = \"bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uuid/1.24.0/download\"],\n strip_prefix = \"uuid-1.24.0\",\n build_file = Label(\"@crates//crates:BUILD.uuid-1.24.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uutils_term_grid-0.8.0\",\n sha256 = \"382d49b39de4a115f203305057741126b09a615892d773a2d419a2b816e30e39\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uutils_term_grid/0.8.0/download\"],\n strip_prefix = \"uutils_term_grid-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.uutils_term_grid-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__uzers-0.12.2\",\n sha256 = \"0b8275fb1afee25b4111d2dc8b5c505dbbc4afd0b990cb96deb2d88bff8be18d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/uzers/0.12.2/download\"],\n strip_prefix = \"uzers-0.12.2\",\n build_file = Label(\"@crates//crates:BUILD.uzers-0.12.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__version-compare-0.2.1\",\n sha256 = \"03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/version-compare/0.2.1/download\"],\n strip_prefix = \"version-compare-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.version-compare-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__version_check-0.9.5\",\n sha256 = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/version_check/0.9.5/download\"],\n strip_prefix = \"version_check-0.9.5\",\n build_file = Label(\"@crates//crates:BUILD.version_check-0.9.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__vsimd-0.8.0\",\n sha256 = \"5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/vsimd/0.8.0/download\"],\n strip_prefix = \"vsimd-0.8.0\",\n build_file = Label(\"@crates//crates:BUILD.vsimd-0.8.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__waitgroup-0.1.2\",\n sha256 = \"d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/waitgroup/0.1.2/download\"],\n strip_prefix = \"waitgroup-0.1.2\",\n build_file = Label(\"@crates//crates:BUILD.waitgroup-0.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__walkdir-2.5.0\",\n sha256 = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/walkdir/2.5.0/download\"],\n strip_prefix = \"walkdir-2.5.0\",\n build_file = Label(\"@crates//crates:BUILD.walkdir-2.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasi-0.11.1-wasi-snapshot-preview1\",\n sha256 = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasi/0.11.1+wasi-snapshot-preview1/download\"],\n strip_prefix = \"wasi-0.11.1+wasi-snapshot-preview1\",\n build_file = Label(\"@crates//crates:BUILD.wasi-0.11.1+wasi-snapshot-preview1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasi-0.14.7-wasi-0.2.4\",\n sha256 = \"883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasi/0.14.7+wasi-0.2.4/download\"],\n strip_prefix = \"wasi-0.14.7+wasi-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.wasi-0.14.7+wasi-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasip2-1.0.4-wasi-0.2.12\",\n sha256 = \"b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasip2/1.0.4+wasi-0.2.12/download\"],\n strip_prefix = \"wasip2-1.0.4+wasi-0.2.12\",\n build_file = Label(\"@crates//crates:BUILD.wasip2-1.0.4+wasi-0.2.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasite-1.0.2\",\n sha256 = \"66fe902b4a6b8028a753d5424909b764ccf79b7a209eac9bf97e59cda9f71a42\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasite/1.0.2/download\"],\n strip_prefix = \"wasite-1.0.2\",\n build_file = Label(\"@crates//crates:BUILD.wasite-1.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasm-bindgen-0.2.126\",\n sha256 = \"4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasm-bindgen/0.2.126/download\"],\n strip_prefix = \"wasm-bindgen-0.2.126\",\n build_file = Label(\"@crates//crates:BUILD.wasm-bindgen-0.2.126.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasm-bindgen-macro-0.2.126\",\n sha256 = \"167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasm-bindgen-macro/0.2.126/download\"],\n strip_prefix = \"wasm-bindgen-macro-0.2.126\",\n build_file = Label(\"@crates//crates:BUILD.wasm-bindgen-macro-0.2.126.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasm-bindgen-macro-support-0.2.126\",\n sha256 = \"f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasm-bindgen-macro-support/0.2.126/download\"],\n strip_prefix = \"wasm-bindgen-macro-support-0.2.126\",\n build_file = Label(\"@crates//crates:BUILD.wasm-bindgen-macro-support-0.2.126.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wasm-bindgen-shared-0.2.126\",\n sha256 = \"dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wasm-bindgen-shared/0.2.126/download\"],\n strip_prefix = \"wasm-bindgen-shared-0.2.126\",\n build_file = Label(\"@crates//crates:BUILD.wasm-bindgen-shared-0.2.126.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-backend-0.3.16\",\n sha256 = \"016ccf01d1c58b6f8999612813e17c9b2390f7d70671428869913310f83f54b8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-backend/0.3.16/download\"],\n strip_prefix = \"wayland-backend-0.3.16\",\n build_file = Label(\"@crates//crates:BUILD.wayland-backend-0.3.16.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-client-0.31.15\",\n sha256 = \"e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-client/0.31.15/download\"],\n strip_prefix = \"wayland-client-0.31.15\",\n build_file = Label(\"@crates//crates:BUILD.wayland-client-0.31.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-protocols-0.32.13\",\n sha256 = \"23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-protocols/0.32.13/download\"],\n strip_prefix = \"wayland-protocols-0.32.13\",\n build_file = Label(\"@crates//crates:BUILD.wayland-protocols-0.32.13.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-protocols-wlr-0.3.12\",\n sha256 = \"eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-protocols-wlr/0.3.12/download\"],\n strip_prefix = \"wayland-protocols-wlr-0.3.12\",\n build_file = Label(\"@crates//crates:BUILD.wayland-protocols-wlr-0.3.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-scanner-0.31.11\",\n sha256 = \"338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-scanner/0.31.11/download\"],\n strip_prefix = \"wayland-scanner-0.31.11\",\n build_file = Label(\"@crates//crates:BUILD.wayland-scanner-0.31.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-server-0.31.14\",\n sha256 = \"0dde9c29be0f723a573977de51ee455bf3dfa03652730a74f9dd3b337e374d75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-server/0.31.14/download\"],\n strip_prefix = \"wayland-server-0.31.14\",\n build_file = Label(\"@crates//crates:BUILD.wayland-server-0.31.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wayland-sys-0.31.11\",\n sha256 = \"d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wayland-sys/0.31.11/download\"],\n strip_prefix = \"wayland-sys-0.31.11\",\n build_file = Label(\"@crates//crates:BUILD.wayland-sys-0.31.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__web-sys-0.3.103\",\n sha256 = \"8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/web-sys/0.3.103/download\"],\n strip_prefix = \"web-sys-0.3.103\",\n build_file = Label(\"@crates//crates:BUILD.web-sys-0.3.103.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__web-time-1.1.0\",\n sha256 = \"5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/web-time/1.1.0/download\"],\n strip_prefix = \"web-time-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.web-time-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__web_atoms-0.2.5\",\n sha256 = \"075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/web_atoms/0.2.5/download\"],\n strip_prefix = \"web_atoms-0.2.5\",\n build_file = Label(\"@crates//crates:BUILD.web_atoms-0.2.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-0.17.2\",\n sha256 = \"baaacdf9d96224d7b6e2872ba065578f38775f7634367e3ac2cc87c7271da433\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc/0.17.2/download\"],\n strip_prefix = \"webrtc-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-data-0.17.2\",\n sha256 = \"bd470286275809f2fcfcdb1e73ef5f1500be82eff7fe98150ce81b20aad5a2a4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-data/0.17.2/download\"],\n strip_prefix = \"webrtc-data-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-data-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-ice-0.17.2\",\n sha256 = \"5b7fd30f52e6fda8664779b84b7904b2553b76fee24d9ca665e774ae32b13f53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-ice/0.17.2/download\"],\n strip_prefix = \"webrtc-ice-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-ice-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-mdns-0.17.2\",\n sha256 = \"91ffa0ea00c0fae979aafa5db285fec5eeb360e1ea246ebec529ba4e09f8e03e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-mdns/0.17.2/download\"],\n strip_prefix = \"webrtc-mdns-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-mdns-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-media-0.17.2\",\n sha256 = \"26a6c7335bdd03dc023cb9a3bd7966866d969c92c86987b73aa16dfa39c7ca29\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-media/0.17.2/download\"],\n strip_prefix = \"webrtc-media-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-media-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-sctp-0.17.2\",\n sha256 = \"1c4b637f0d8eb96d900ac0f79b3060ddd21ca88dfefa467e96e67ab0016f2574\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-sctp/0.17.2/download\"],\n strip_prefix = \"webrtc-sctp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-sctp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-srtp-0.17.2\",\n sha256 = \"45d2b667a0b5d04eebcb7cb22fd51b2af3721f418097b496e72de16386c8d0c3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-srtp/0.17.2/download\"],\n strip_prefix = \"webrtc-srtp-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-srtp-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__webrtc-util-0.17.2\",\n sha256 = \"1beae0b4f24969741c26ca282a257dc5823bd9cbe608f7e3ca3775102d323ad9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/webrtc-util/0.17.2/download\"],\n strip_prefix = \"webrtc-util-0.17.2\",\n build_file = Label(\"@crates//crates:BUILD.webrtc-util-0.17.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__weezl-0.1.12\",\n sha256 = \"a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/weezl/0.1.12/download\"],\n strip_prefix = \"weezl-0.1.12\",\n build_file = Label(\"@crates//crates:BUILD.weezl-0.1.12.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__whoami-2.1.2\",\n sha256 = \"998767ef88740d1f5b0682a9c53c24431453923962269c2db68ee43788c5a40d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/whoami/2.1.2/download\"],\n strip_prefix = \"whoami-2.1.2\",\n build_file = Label(\"@crates//crates:BUILD.whoami-2.1.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wide-0.8.3\",\n sha256 = \"13ca908d26e4786149c48efcf6c0ea09ab0e06d1fe3c17dc1b4b0f1ca4a7e788\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wide/0.8.3/download\"],\n strip_prefix = \"wide-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.wide-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__widestring-1.2.1\",\n sha256 = \"72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/widestring/1.2.1/download\"],\n strip_prefix = \"widestring-1.2.1\",\n build_file = Label(\"@crates//crates:BUILD.widestring-1.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wild-2.2.1\",\n sha256 = \"a3131afc8c575281e1e80f36ed6a092aa502c08b18ed7524e86fbbb12bb410e1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wild/2.2.1/download\"],\n strip_prefix = \"wild-2.2.1\",\n build_file = Label(\"@crates//crates:BUILD.wild-2.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-0.3.9\",\n sha256 = \"5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi/0.3.9/download\"],\n strip_prefix = \"winapi-0.3.9\",\n build_file = Label(\"@crates//crates:BUILD.winapi-0.3.9.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-i686-pc-windows-gnu-0.4.0\",\n sha256 = \"ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-i686-pc-windows-gnu/0.4.0/download\"],\n strip_prefix = \"winapi-i686-pc-windows-gnu-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.winapi-i686-pc-windows-gnu-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-util-0.1.11\",\n sha256 = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-util/0.1.11/download\"],\n strip_prefix = \"winapi-util-0.1.11\",\n build_file = Label(\"@crates//crates:BUILD.winapi-util-0.1.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-x86_64-pc-windows-gnu-0.4.0\",\n sha256 = \"712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-x86_64-pc-windows-gnu/0.4.0/download\"],\n strip_prefix = \"winapi-x86_64-pc-windows-gnu-0.4.0\",\n build_file = Label(\"@crates//crates:BUILD.winapi-x86_64-pc-windows-gnu-0.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-0.51.1\",\n sha256 = \"ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows/0.51.1/download\"],\n strip_prefix = \"windows-0.51.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-0.51.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-0.61.3\",\n sha256 = \"9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows/0.61.3/download\"],\n strip_prefix = \"windows-0.61.3\",\n build_file = Label(\"@crates//crates:BUILD.windows-0.61.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-0.62.2\",\n sha256 = \"527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows/0.62.2/download\"],\n strip_prefix = \"windows-0.62.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-0.62.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-collections-0.2.0\",\n sha256 = \"3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-collections/0.2.0/download\"],\n strip_prefix = \"windows-collections-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-collections-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-collections-0.3.2\",\n sha256 = \"23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-collections/0.3.2/download\"],\n strip_prefix = \"windows-collections-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-collections-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-core-0.51.1\",\n sha256 = \"f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-core/0.51.1/download\"],\n strip_prefix = \"windows-core-0.51.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-core-0.51.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-core-0.61.2\",\n sha256 = \"c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-core/0.61.2/download\"],\n strip_prefix = \"windows-core-0.61.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-core-0.61.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-core-0.62.2\",\n sha256 = \"b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-core/0.62.2/download\"],\n strip_prefix = \"windows-core-0.62.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-core-0.62.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-future-0.2.1\",\n sha256 = \"fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-future/0.2.1/download\"],\n strip_prefix = \"windows-future-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-future-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-future-0.3.2\",\n sha256 = \"e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-future/0.3.2/download\"],\n strip_prefix = \"windows-future-0.3.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-future-0.3.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-implement-0.60.2\",\n sha256 = \"053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-implement/0.60.2/download\"],\n strip_prefix = \"windows-implement-0.60.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-implement-0.60.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-interface-0.59.3\",\n sha256 = \"3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-interface/0.59.3/download\"],\n strip_prefix = \"windows-interface-0.59.3\",\n build_file = Label(\"@crates//crates:BUILD.windows-interface-0.59.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-link-0.1.3\",\n sha256 = \"5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-link/0.1.3/download\"],\n strip_prefix = \"windows-link-0.1.3\",\n build_file = Label(\"@crates//crates:BUILD.windows-link-0.1.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-link-0.2.1\",\n sha256 = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-link/0.2.1/download\"],\n strip_prefix = \"windows-link-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-link-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-numerics-0.2.0\",\n sha256 = \"9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-numerics/0.2.0/download\"],\n strip_prefix = \"windows-numerics-0.2.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-numerics-0.2.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-numerics-0.3.1\",\n sha256 = \"6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-numerics/0.3.1/download\"],\n strip_prefix = \"windows-numerics-0.3.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-numerics-0.3.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-result-0.3.4\",\n sha256 = \"56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-result/0.3.4/download\"],\n strip_prefix = \"windows-result-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.windows-result-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-result-0.4.1\",\n sha256 = \"7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-result/0.4.1/download\"],\n strip_prefix = \"windows-result-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-result-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-strings-0.4.2\",\n sha256 = \"56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-strings/0.4.2/download\"],\n strip_prefix = \"windows-strings-0.4.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-strings-0.4.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-strings-0.5.1\",\n sha256 = \"7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-strings/0.5.1/download\"],\n strip_prefix = \"windows-strings-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-strings-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.52.0\",\n sha256 = \"282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.52.0/download\"],\n strip_prefix = \"windows-sys-0.52.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.52.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.59.0\",\n sha256 = \"1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.59.0/download\"],\n strip_prefix = \"windows-sys-0.59.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.59.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.60.2\",\n sha256 = \"f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.60.2/download\"],\n strip_prefix = \"windows-sys-0.60.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.60.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.61.2\",\n sha256 = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.61.2/download\"],\n strip_prefix = \"windows-sys-0.61.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.61.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.48.5\",\n sha256 = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.48.5/download\"],\n strip_prefix = \"windows-targets-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.52.6\",\n sha256 = \"9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.52.6/download\"],\n strip_prefix = \"windows-targets-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-targets-0.53.5\",\n sha256 = \"4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-targets/0.53.5/download\"],\n strip_prefix = \"windows-targets-0.53.5\",\n build_file = Label(\"@crates//crates:BUILD.windows-targets-0.53.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-threading-0.1.0\",\n sha256 = \"b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-threading/0.1.0/download\"],\n strip_prefix = \"windows-threading-0.1.0\",\n build_file = Label(\"@crates//crates:BUILD.windows-threading-0.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-threading-0.2.1\",\n sha256 = \"3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-threading/0.2.1/download\"],\n strip_prefix = \"windows-threading-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-threading-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.48.5\",\n sha256 = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.52.6\",\n sha256 = \"32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.52.6/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_gnullvm-0.53.1\",\n sha256 = \"a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_gnullvm/0.53.1/download\"],\n strip_prefix = \"windows_aarch64_gnullvm-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_gnullvm-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.48.5\",\n sha256 = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.52.6\",\n sha256 = \"09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.52.6/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_aarch64_msvc-0.53.1\",\n sha256 = \"b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_aarch64_msvc/0.53.1/download\"],\n strip_prefix = \"windows_aarch64_msvc-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_aarch64_msvc-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.48.5\",\n sha256 = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.48.5/download\"],\n strip_prefix = \"windows_i686_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.52.6\",\n sha256 = \"8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.52.6/download\"],\n strip_prefix = \"windows_i686_gnu-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnu-0.53.1\",\n sha256 = \"960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnu/0.53.1/download\"],\n strip_prefix = \"windows_i686_gnu-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnu-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnullvm-0.52.6\",\n sha256 = \"0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnullvm/0.52.6/download\"],\n strip_prefix = \"windows_i686_gnullvm-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnullvm-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_gnullvm-0.53.1\",\n sha256 = \"fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_gnullvm/0.53.1/download\"],\n strip_prefix = \"windows_i686_gnullvm-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_gnullvm-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.48.5\",\n sha256 = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.48.5/download\"],\n strip_prefix = \"windows_i686_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.52.6\",\n sha256 = \"240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.52.6/download\"],\n strip_prefix = \"windows_i686_msvc-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_i686_msvc-0.53.1\",\n sha256 = \"1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_i686_msvc/0.53.1/download\"],\n strip_prefix = \"windows_i686_msvc-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_i686_msvc-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.48.5\",\n sha256 = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.52.6\",\n sha256 = \"147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.52.6/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnu-0.53.1\",\n sha256 = \"9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnu/0.53.1/download\"],\n strip_prefix = \"windows_x86_64_gnu-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnu-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.48.5\",\n sha256 = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.52.6\",\n sha256 = \"24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.52.6/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_gnullvm-0.53.1\",\n sha256 = \"0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_gnullvm/0.53.1/download\"],\n strip_prefix = \"windows_x86_64_gnullvm-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_gnullvm-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.48.5\",\n sha256 = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.48.5/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.48.5\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.48.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.52.6\",\n sha256 = \"589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.52.6/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.52.6\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.52.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows_x86_64_msvc-0.53.1\",\n sha256 = \"d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows_x86_64_msvc/0.53.1/download\"],\n strip_prefix = \"windows_x86_64_msvc-0.53.1\",\n build_file = Label(\"@crates//crates:BUILD.windows_x86_64_msvc-0.53.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winnow-0.7.15\",\n sha256 = \"df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winnow/0.7.15/download\"],\n strip_prefix = \"winnow-0.7.15\",\n build_file = Label(\"@crates//crates:BUILD.winnow-0.7.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winnow-1.0.4\",\n sha256 = \"23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winnow/1.0.4/download\"],\n strip_prefix = \"winnow-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.winnow-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winreg-0.10.1\",\n sha256 = \"80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winreg/0.10.1/download\"],\n strip_prefix = \"winreg-0.10.1\",\n build_file = Label(\"@crates//crates:BUILD.winreg-0.10.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winreg-0.56.0\",\n sha256 = \"7d6f32a0ff4a9f6f01231eb2059cc85479330739333e0e58cadf03b6af2cca10\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winreg/0.56.0/download\"],\n strip_prefix = \"winreg-0.56.0\",\n build_file = Label(\"@crates//crates:BUILD.winreg-0.56.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wit-bindgen-0.57.1\",\n sha256 = \"1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wit-bindgen/0.57.1/download\"],\n strip_prefix = \"wit-bindgen-0.57.1\",\n build_file = Label(\"@crates//crates:BUILD.wit-bindgen-0.57.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wl-clipboard-rs-0.9.3\",\n sha256 = \"e9651471a32e87d96ef3a127715382b2d11cc7c8bb9822ded8a7cc94072eb0a3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wl-clipboard-rs/0.9.3/download\"],\n strip_prefix = \"wl-clipboard-rs-0.9.3\",\n build_file = Label(\"@crates//crates:BUILD.wl-clipboard-rs-0.9.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__write16-1.0.0\",\n sha256 = \"d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/write16/1.0.0/download\"],\n strip_prefix = \"write16-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.write16-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__writeable-0.6.3\",\n sha256 = \"1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/writeable/0.6.3/download\"],\n strip_prefix = \"writeable-0.6.3\",\n build_file = Label(\"@crates//crates:BUILD.writeable-0.6.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__wyz-0.5.1\",\n sha256 = \"05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/wyz/0.5.1/download\"],\n strip_prefix = \"wyz-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.wyz-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__x11rb-0.13.2\",\n sha256 = \"9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/x11rb/0.13.2/download\"],\n strip_prefix = \"x11rb-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.x11rb-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__x11rb-protocol-0.13.2\",\n sha256 = \"ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/x11rb-protocol/0.13.2/download\"],\n strip_prefix = \"x11rb-protocol-0.13.2\",\n build_file = Label(\"@crates//crates:BUILD.x11rb-protocol-0.13.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__x25519-dalek-2.0.1\",\n sha256 = \"c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/x25519-dalek/2.0.1/download\"],\n strip_prefix = \"x25519-dalek-2.0.1\",\n build_file = Label(\"@crates//crates:BUILD.x25519-dalek-2.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__x509-parser-0.16.0\",\n sha256 = \"fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/x509-parser/0.16.0/download\"],\n strip_prefix = \"x509-parser-0.16.0\",\n build_file = Label(\"@crates//crates:BUILD.x509-parser-0.16.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xattr-1.6.1\",\n sha256 = \"32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xattr/1.6.1/download\"],\n strip_prefix = \"xattr-1.6.1\",\n build_file = Label(\"@crates//crates:BUILD.xattr-1.6.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xcap-0.9.6\",\n sha256 = \"b6ad471d5ba232bc276382d26a9d3b837d6853b7df389058b5bb1e94dcdd248c\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xcap/0.9.6/download\"],\n strip_prefix = \"xcap-0.9.6\",\n build_file = Label(\"@crates//crates:BUILD.xcap-0.9.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xcb-1.7.0\",\n sha256 = \"ee4c580d8205abb0a5cf4eb7e927bd664e425b6c3263f9c5310583da96970cf6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xcb/1.7.0/download\"],\n strip_prefix = \"xcb-1.7.0\",\n build_file = Label(\"@crates//crates:BUILD.xcb-1.7.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xkbcommon-0.9.0\",\n sha256 = \"a7a974f48060a14e95705c01f24ad9c3345022f4d97441b8a36beb7ed5c4a02d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xkbcommon/0.9.0/download\"],\n strip_prefix = \"xkbcommon-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.xkbcommon-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xkeysym-0.2.1\",\n sha256 = \"b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xkeysym/0.2.1/download\"],\n strip_prefix = \"xkeysym-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.xkeysym-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xml-rs-0.8.28\",\n sha256 = \"3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xml-rs/0.8.28/download\"],\n strip_prefix = \"xml-rs-0.8.28\",\n build_file = Label(\"@crates//crates:BUILD.xml-rs-0.8.28.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__xxhash-rust-0.8.18\",\n sha256 = \"aee1b19627c7c60102ab80d3a9cbe18de90bfe03bfa6c3715447681f0e8c8af6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/xxhash-rust/0.8.18/download\"],\n strip_prefix = \"xxhash-rust-0.8.18\",\n build_file = Label(\"@crates//crates:BUILD.xxhash-rust-0.8.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yaml-rust-0.4.5\",\n sha256 = \"56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yaml-rust/0.4.5/download\"],\n strip_prefix = \"yaml-rust-0.4.5\",\n build_file = Label(\"@crates//crates:BUILD.yaml-rust-0.4.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yansi-1.0.1\",\n sha256 = \"cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yansi/1.0.1/download\"],\n strip_prefix = \"yansi-1.0.1\",\n build_file = Label(\"@crates//crates:BUILD.yansi-1.0.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yasna-0.5.2\",\n sha256 = \"e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yasna/0.5.2/download\"],\n strip_prefix = \"yasna-0.5.2\",\n build_file = Label(\"@crates//crates:BUILD.yasna-0.5.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-0.8.3\",\n sha256 = \"709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke/0.8.3/download\"],\n strip_prefix = \"yoke-0.8.3\",\n build_file = Label(\"@crates//crates:BUILD.yoke-0.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__yoke-derive-0.8.2\",\n sha256 = \"de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/yoke-derive/0.8.2/download\"],\n strip_prefix = \"yoke-derive-0.8.2\",\n build_file = Label(\"@crates//crates:BUILD.yoke-derive-0.8.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__z85-3.0.7\",\n sha256 = \"c6e61e59a957b7ccee15d2049f86e8bfd6f66968fcd88f018950662d9b86e675\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/z85/3.0.7/download\"],\n strip_prefix = \"z85-3.0.7\",\n build_file = Label(\"@crates//crates:BUILD.z85-3.0.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zbus-5.18.0\",\n sha256 = \"fe18fb60dc696039e738717b76eaea21e7a4489bbb1885020b43c94236d7e98a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zbus/5.18.0/download\"],\n strip_prefix = \"zbus-5.18.0\",\n build_file = Label(\"@crates//crates:BUILD.zbus-5.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zbus_macros-5.18.0\",\n sha256 = \"fe96480bed92df2b442a1a30df364e12d08eed03aeb061f2b8dc6afb2be91119\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zbus_macros/5.18.0/download\"],\n strip_prefix = \"zbus_macros-5.18.0\",\n build_file = Label(\"@crates//crates:BUILD.zbus_macros-5.18.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zbus_names-4.3.4\",\n sha256 = \"d8bf88b4a3ff53e883001e0e0115b297a9d53c31b9c1edd2bfdd853e3428624e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zbus_names/4.3.4/download\"],\n strip_prefix = \"zbus_names-4.3.4\",\n build_file = Label(\"@crates//crates:BUILD.zbus_names-4.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerocopy-0.8.55\",\n sha256 = \"b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerocopy/0.8.55/download\"],\n strip_prefix = \"zerocopy-0.8.55\",\n build_file = Label(\"@crates//crates:BUILD.zerocopy-0.8.55.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerocopy-derive-0.8.55\",\n sha256 = \"0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerocopy-derive/0.8.55/download\"],\n strip_prefix = \"zerocopy-derive-0.8.55\",\n build_file = Label(\"@crates//crates:BUILD.zerocopy-derive-0.8.55.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-0.1.8\",\n sha256 = \"0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom/0.1.8/download\"],\n strip_prefix = \"zerofrom-0.1.8\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-0.1.8.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerofrom-derive-0.1.7\",\n sha256 = \"11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerofrom-derive/0.1.7/download\"],\n strip_prefix = \"zerofrom-derive-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.zerofrom-derive-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize-1.9.0\",\n sha256 = \"e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize/1.9.0/download\"],\n strip_prefix = \"zeroize-1.9.0\",\n build_file = Label(\"@crates//crates:BUILD.zeroize-1.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zeroize_derive-1.5.0\",\n sha256 = \"3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zeroize_derive/1.5.0/download\"],\n strip_prefix = \"zeroize_derive-1.5.0\",\n build_file = Label(\"@crates//crates:BUILD.zeroize_derive-1.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerotrie-0.2.4\",\n sha256 = \"0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerotrie/0.2.4/download\"],\n strip_prefix = \"zerotrie-0.2.4\",\n build_file = Label(\"@crates//crates:BUILD.zerotrie-0.2.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-0.11.6\",\n sha256 = \"90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec/0.11.6/download\"],\n strip_prefix = \"zerovec-0.11.6\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-0.11.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zerovec-derive-0.11.3\",\n sha256 = \"625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zerovec-derive/0.11.3/download\"],\n strip_prefix = \"zerovec-derive-0.11.3\",\n build_file = Label(\"@crates//crates:BUILD.zerovec-derive-0.11.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zmij-1.0.23\",\n sha256 = \"29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zmij/1.0.23/download\"],\n strip_prefix = \"zmij-1.0.23\",\n build_file = Label(\"@crates//crates:BUILD.zmij-1.0.23.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zune-core-0.5.1\",\n sha256 = \"cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zune-core/0.5.1/download\"],\n strip_prefix = \"zune-core-0.5.1\",\n build_file = Label(\"@crates//crates:BUILD.zune-core-0.5.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zune-jpeg-0.5.15\",\n sha256 = \"27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zune-jpeg/0.5.15/download\"],\n strip_prefix = \"zune-jpeg-0.5.15\",\n build_file = Label(\"@crates//crates:BUILD.zune-jpeg-0.5.15.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zvariant-5.13.1\",\n sha256 = \"bee2a0bcd2a907786a456fff45aaaaf54c9ba5f50b71ae9ec1a4edd200c94911\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zvariant/5.13.1/download\"],\n strip_prefix = \"zvariant-5.13.1\",\n build_file = Label(\"@crates//crates:BUILD.zvariant-5.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zvariant_derive-5.13.1\",\n sha256 = \"38a708216a18780796770bfe3f4739c7c83a3e8f789b755534bbbc06e4e23e12\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zvariant_derive/5.13.1/download\"],\n strip_prefix = \"zvariant_derive-5.13.1\",\n build_file = Label(\"@crates//crates:BUILD.zvariant_derive-5.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zvariant_utils-3.5.0\",\n sha256 = \"90cb9383f9b45290407a1258b202d3f8f01db719eb60b4e4055c6375af4fc7c7\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zvariant_utils/3.5.0/download\"],\n strip_prefix = \"zvariant_utils-3.5.0\",\n build_file = Label(\"@crates//crates:BUILD.zvariant_utils-3.5.0.bazel\"),\n )\n\n return [\n struct(repo = \"crates\", is_dev_dep = False),\n struct(repo=\"crates__ansi-width-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__anyhow-1.0.104\", is_dev_dep = False),\n struct(repo=\"crates__arboard-3.6.1\", is_dev_dep = False),\n struct(repo=\"crates__argmax-0.3.1\", is_dev_dep = False),\n struct(repo=\"crates__ast-grep-core-0.39.9\", is_dev_dep = False),\n struct(repo=\"crates__async-recursion-1.1.1\", is_dev_dep = False),\n struct(repo=\"crates__async-trait-0.1.91\", is_dev_dep = False),\n struct(repo=\"crates__audiopus_sys-0.2.2\", is_dev_dep = False),\n struct(repo=\"crates__base64-0.22.1\", is_dev_dep = False),\n struct(repo=\"crates__base64-simd-0.8.0\", is_dev_dep = False),\n struct(repo=\"crates__bigdecimal-0.4.10\", is_dev_dep = False),\n struct(repo=\"crates__binary-heap-plus-0.5.0\", is_dev_dep = False),\n struct(repo=\"crates__bon-3.9.3\", is_dev_dep = False),\n struct(repo=\"crates__brush-parser-0.3.0\", is_dev_dep = False),\n struct(repo=\"crates__brush-parser-0.4.0\", is_dev_dep = False),\n struct(repo=\"crates__bstr-1.13.0\", is_dev_dep = False),\n struct(repo=\"crates__bytecount-0.6.9\", is_dev_dep = False),\n struct(repo=\"crates__bytes-1.12.1\", is_dev_dep = False),\n struct(repo=\"crates__cached-0.59.0\", is_dev_dep = False),\n struct(repo=\"crates__cfg-if-1.0.4\", is_dev_dep = False),\n struct(repo=\"crates__check_elevation-0.2.7\", is_dev_dep = False),\n struct(repo=\"crates__chrono-0.4.45\", is_dev_dep = False),\n struct(repo=\"crates__clap-4.6.4\", is_dev_dep = False),\n struct(repo=\"crates__clipboard-win-5.4.1\", is_dev_dep = False),\n struct(repo=\"crates__codesnake-0.2.1\", is_dev_dep = False),\n struct(repo=\"crates__color-print-0.3.7\", is_dev_dep = False),\n struct(repo=\"crates__command-fds-0.3.3\", is_dev_dep = False),\n struct(repo=\"crates__compare-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__core-graphics-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__dashmap-6.2.1\", is_dev_dep = False),\n struct(repo=\"crates__dns-lookup-3.0.1\", is_dev_dep = False),\n struct(repo=\"crates__enigo-0.6.1\", is_dev_dep = False),\n struct(repo=\"crates__faccess-0.2.4\", is_dev_dep = False),\n struct(repo=\"crates__fancy-regex-0.17.0\", is_dev_dep = False),\n struct(repo=\"crates__fancy-regex-0.18.0\", is_dev_dep = False),\n struct(repo=\"crates__filetime-0.2.29\", is_dev_dep = False),\n struct(repo=\"crates__flume-0.11.1\", is_dev_dep = False),\n struct(repo=\"crates__foldhash-0.2.0\", is_dev_dep = False),\n struct(repo=\"crates__fontdue-0.9.3\", is_dev_dep = False),\n struct(repo=\"crates__fs_extra-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__futures-0.3.33\", is_dev_dep = False),\n struct(repo=\"crates__getrandom-0.4.3\", is_dev_dep = False),\n struct(repo=\"crates__glob-0.3.4\", is_dev_dep = False),\n struct(repo=\"crates__globset-0.4.19\", is_dev_dep = False),\n struct(repo=\"crates__grep-cli-0.1.12\", is_dev_dep = False),\n struct(repo=\"crates__grep-matcher-0.1.9\", is_dev_dep = False),\n struct(repo=\"crates__grep-pcre2-0.1.10\", is_dev_dep = False),\n struct(repo=\"crates__grep-printer-0.3.1\", is_dev_dep = False),\n struct(repo=\"crates__grep-regex-0.1.14\", is_dev_dep = False),\n struct(repo=\"crates__grep-searcher-0.1.17\", is_dev_dep = False),\n struct(repo=\"crates__hex-0.4.3\", is_dev_dep = False),\n struct(repo=\"crates__hifijson-0.2.3\", is_dev_dep = False),\n struct(repo=\"crates__hostname-0.4.2\", is_dev_dep = False),\n struct(repo=\"crates__html-to-markdown-rs-2.30.0\", is_dev_dep = False),\n struct(repo=\"crates__icy_sixel-0.5.0\", is_dev_dep = False),\n struct(repo=\"crates__ignore-0.4.31\", is_dev_dep = False),\n struct(repo=\"crates__image-0.25.10\", is_dev_dep = False),\n struct(repo=\"crates__indicatif-0.18.6\", is_dev_dep = False),\n struct(repo=\"crates__inferno-0.12.8\", is_dev_dep = False),\n struct(repo=\"crates__inherent-1.0.14\", is_dev_dep = False),\n struct(repo=\"crates__itertools-0.14.0\", is_dev_dep = False),\n struct(repo=\"crates__jaq-core-2.2.1\", is_dev_dep = False),\n struct(repo=\"crates__jaq-json-1.1.3\", is_dev_dep = False),\n struct(repo=\"crates__jaq-std-2.1.2\", is_dev_dep = False),\n struct(repo=\"crates__jiff-0.2.35\", is_dev_dep = False),\n struct(repo=\"crates__libc-0.2.189\", is_dev_dep = False),\n struct(repo=\"crates__lscolors-0.21.0\", is_dev_dep = False),\n struct(repo=\"crates__maudio-0.1.6\", is_dev_dep = False),\n struct(repo=\"crates__memchr-2.8.3\", is_dev_dep = False),\n struct(repo=\"crates__memmap2-0.9.11\", is_dev_dep = False),\n struct(repo=\"crates__napi-3.12.0\", is_dev_dep = False),\n struct(repo=\"crates__napi-build-2.4.0\", is_dev_dep = False),\n struct(repo=\"crates__napi-derive-3.6.1\", is_dev_dep = False),\n struct(repo=\"crates__nix-0.29.0\", is_dev_dep = False),\n struct(repo=\"crates__nix-0.31.3\", is_dev_dep = False),\n struct(repo=\"crates__nom-8.0.0\", is_dev_dep = False),\n struct(repo=\"crates__normalize-path-0.2.1\", is_dev_dep = False),\n struct(repo=\"crates__notify-8.2.0\", is_dev_dep = False),\n struct(repo=\"crates__num-bigint-0.4.8\", is_dev_dep = False),\n struct(repo=\"crates__num-traits-0.2.19\", is_dev_dep = False),\n struct(repo=\"crates__onig-6.5.3\", is_dev_dep = False),\n struct(repo=\"crates__opus-0.3.1\", is_dev_dep = False),\n struct(repo=\"crates__os_display-0.1.4\", is_dev_dep = False),\n struct(repo=\"crates__os_pipe-1.2.3\", is_dev_dep = False),\n struct(repo=\"crates__parking_lot-0.12.5\", is_dev_dep = False),\n struct(repo=\"crates__parse_datetime-0.14.0\", is_dev_dep = False),\n struct(repo=\"crates__phf-0.13.1\", is_dev_dep = False),\n struct(repo=\"crates__platform-info-2.1.0\", is_dev_dep = False),\n struct(repo=\"crates__png-0.18.1\", is_dev_dep = False),\n struct(repo=\"crates__portable-pty-0.9.0\", is_dev_dep = False),\n struct(repo=\"crates__procfs-0.18.0\", is_dev_dep = False),\n struct(repo=\"crates__rand-0.10.2\", is_dev_dep = False),\n struct(repo=\"crates__rayon-1.12.0\", is_dev_dep = False),\n struct(repo=\"crates__regex-1.13.1\", is_dev_dep = False),\n struct(repo=\"crates__rlimit-0.11.0\", is_dev_dep = False),\n struct(repo=\"crates__rpds-1.2.1\", is_dev_dep = False),\n struct(repo=\"crates__rustc-hash-2.1.3\", is_dev_dep = False),\n struct(repo=\"crates__rustix-1.1.4\", is_dev_dep = False),\n struct(repo=\"crates__self_cell-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__serde-1.0.229\", is_dev_dep = False),\n struct(repo=\"crates__serde_json-1.0.151\", is_dev_dep = False),\n struct(repo=\"crates__similar-3.1.1\", is_dev_dep = False),\n struct(repo=\"crates__smallvec-1.15.2\", is_dev_dep = False),\n struct(repo=\"crates__strum-0.28.0\", is_dev_dep = False),\n struct(repo=\"crates__strum_macros-0.28.0\", is_dev_dep = False),\n struct(repo=\"crates__syntect-5.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tempfile-3.27.0\", is_dev_dep = False),\n struct(repo=\"crates__terminfo-0.9.0\", is_dev_dep = False),\n struct(repo=\"crates__thiserror-2.0.19\", is_dev_dep = False),\n struct(repo=\"crates__tiktoken-rs-0.11.0\", is_dev_dep = False),\n struct(repo=\"crates__tokio-1.53.1\", is_dev_dep = False),\n struct(repo=\"crates__tokio-util-0.7.19\", is_dev_dep = False),\n struct(repo=\"crates__toml-1.1.3-spec-1.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tracing-0.1.44\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-0.25.10\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-astro-next-0.1.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-bash-0.25.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-c-0.24.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-c-sharp-0.23.5\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-clojure-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-cmake-0.7.4\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-cpp-0.23.4\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-css-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-dart-0.2.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-diff-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-dockerfile-updated-0.2.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-elisp-1.6.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-elixir-0.3.5\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-erlang-0.16.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-fortran-0.6.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-go-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-graphql-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-haskell-0.23.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-hcl-1.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-html-0.23.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-ini-1.4.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-java-0.23.5\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-javascript-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-json-0.24.8\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-julia-0.23.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-just-0.2.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-kotlin-sg-0.4.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-lua-0.5.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-make-1.1.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-md-0.5.3\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-nix-0.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-objc-3.0.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-ocaml-0.24.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-odin-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-php-0.24.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-powershell-0.26.4\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-proto-0.4.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-python-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-r-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-regex-0.25.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-ruby-0.23.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-rust-0.24.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-scala-0.26.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-sequel-0.3.11\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-solidity-1.2.13\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-starlark-1.3.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-svelte-next-0.1.1\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-swift-0.7.3\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-tlaplus-1.5.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-toml-ng-0.7.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-typescript-0.23.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-verilog-1.0.3\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-vue-next-0.1.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-xml-0.7.0\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-yaml-0.7.2\", is_dev_dep = False),\n struct(repo=\"crates__tree-sitter-zig-1.1.2\", is_dev_dep = False),\n struct(repo=\"crates__unicode-segmentation-1.13.3\", is_dev_dep = False),\n struct(repo=\"crates__unicode-width-0.1.14\", is_dev_dep = False),\n struct(repo=\"crates__unicode-width-0.2.2\", is_dev_dep = False),\n struct(repo=\"crates__uucore-0.0.30\", is_dev_dep = False),\n struct(repo=\"crates__uucore-0.8.0\", is_dev_dep = False),\n struct(repo=\"crates__uucore-0.9.0\", is_dev_dep = False),\n struct(repo=\"crates__uuid-1.24.0\", is_dev_dep = False),\n struct(repo=\"crates__uutils_term_grid-0.8.0\", is_dev_dep = False),\n struct(repo=\"crates__uzers-0.12.2\", is_dev_dep = False),\n struct(repo=\"crates__webrtc-0.17.2\", is_dev_dep = False),\n struct(repo=\"crates__whoami-2.1.2\", is_dev_dep = False),\n struct(repo=\"crates__windows-sys-0.59.0\", is_dev_dep = False),\n struct(repo=\"crates__windows-sys-0.61.2\", is_dev_dep = False),\n struct(repo=\"crates__winreg-0.56.0\", is_dev_dep = False),\n struct(repo=\"crates__x11rb-0.13.2\", is_dev_dep = False),\n struct(repo=\"crates__xcap-0.9.6\", is_dev_dep = False),\n struct(repo=\"crates__xkeysym-0.2.1\", is_dev_dep = False),\n struct(repo=\"crates__xxhash-rust-0.8.18\", is_dev_dep = False),\n struct(repo=\"crates__yansi-1.0.1\", is_dev_dep = False),\n struct(repo = \"crates__pretty_assertions-1.4.1\", is_dev_dep = True),\n struct(repo = \"crates__rstest-0.26.1\", is_dev_dep = True),\n ]\n", "defs.bzl": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\"\"\"Deprecated: re-exports the crate_universe macros from `:crates.bzl`.\"\"\"\n\nload(\n \":crates.bzl\",\n _aliases = \"aliases\",\n _all_crate_deps = \"all_crate_deps\",\n _crate_deps = \"crate_deps\",\n _crate_edition = \"crate_edition\",\n _crate_repositories = \"crate_repositories\",\n)\n\naliases = _aliases\nall_crate_deps = _all_crate_deps\ncrate_deps = _crate_deps\ncrate_edition = _crate_edition\ncrate_repositories = _crate_repositories\n", "ansi-width-0.1.0/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"ansi-width-0.1.0\",\n actual = \"@crates__ansi-width-0.1.0//:ansi_width\",\n tags = [\"manual\"],\n)\n", "ansi-width/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"ansi-width\",\n actual = \"@crates__ansi-width-0.1.0//:ansi_width\",\n tags = [\"manual\"],\n)\n", @@ -684,12 +685,12 @@ "memchr/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"memchr\",\n actual = \"@crates__memchr-2.8.3//:memchr\",\n tags = [\"manual\"],\n)\n", "memmap2-0.9.11/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"memmap2-0.9.11\",\n actual = \"@crates__memmap2-0.9.11//:memmap2\",\n tags = [\"manual\"],\n)\n", "memmap2/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"memmap2\",\n actual = \"@crates__memmap2-0.9.11//:memmap2\",\n tags = [\"manual\"],\n)\n", - "napi-3.11.0/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-3.11.0\",\n actual = \"@crates__napi-3.11.0//:napi\",\n tags = [\"manual\"],\n)\n", - "napi/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi\",\n actual = \"@crates__napi-3.11.0//:napi\",\n tags = [\"manual\"],\n)\n", - "napi-build-2.3.2/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-build-2.3.2\",\n actual = \"@crates__napi-build-2.3.2//:napi_build\",\n tags = [\"manual\"],\n)\n", - "napi-build/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-build\",\n actual = \"@crates__napi-build-2.3.2//:napi_build\",\n tags = [\"manual\"],\n)\n", - "napi-derive-3.6.0/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-derive-3.6.0\",\n actual = \"@crates__napi-derive-3.6.0//:napi_derive\",\n tags = [\"manual\"],\n)\n", - "napi-derive/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-derive\",\n actual = \"@crates__napi-derive-3.6.0//:napi_derive\",\n tags = [\"manual\"],\n)\n", + "napi-3.12.0/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-3.12.0\",\n actual = \"@crates__napi-3.12.0//:napi\",\n tags = [\"manual\"],\n)\n", + "napi/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi\",\n actual = \"@crates__napi-3.12.0//:napi\",\n tags = [\"manual\"],\n)\n", + "napi-build-2.4.0/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-build-2.4.0\",\n actual = \"@crates__napi-build-2.4.0//:napi_build\",\n tags = [\"manual\"],\n)\n", + "napi-build/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-build\",\n actual = \"@crates__napi-build-2.4.0//:napi_build\",\n tags = [\"manual\"],\n)\n", + "napi-derive-3.6.1/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-derive-3.6.1\",\n actual = \"@crates__napi-derive-3.6.1//:napi_derive\",\n tags = [\"manual\"],\n)\n", + "napi-derive/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"napi-derive\",\n actual = \"@crates__napi-derive-3.6.1//:napi_derive\",\n tags = [\"manual\"],\n)\n", "nix-0.29.0/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"nix-0.29.0\",\n actual = \"@crates__nix-0.29.0//:nix\",\n tags = [\"manual\"],\n)\n", "nix-0.31.3/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"nix-0.31.3\",\n actual = \"@crates__nix-0.31.3//:nix\",\n tags = [\"manual\"],\n)\n", "nom-8.0.0/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"nom-8.0.0\",\n actual = \"@crates__nom-8.0.0//:nom\",\n tags = [\"manual\"],\n)\n", @@ -716,8 +717,8 @@ "parse_datetime/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"parse_datetime\",\n actual = \"@crates__parse_datetime-0.14.0//:parse_datetime\",\n tags = [\"manual\"],\n)\n", "phf-0.13.1/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"phf-0.13.1\",\n actual = \"@crates__phf-0.13.1//:phf\",\n tags = [\"manual\"],\n)\n", "phf/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"phf\",\n actual = \"@crates__phf-0.13.1//:phf\",\n tags = [\"manual\"],\n)\n", - "pi-shell-17.1.7/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"pi-shell-17.1.7\",\n actual = \"@crates__pi-shell-17.1.7//:pi_shell\",\n tags = [\"manual\"],\n)\n", - "pi-shell/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"pi-shell\",\n actual = \"@crates__pi-shell-17.1.7//:pi_shell\",\n tags = [\"manual\"],\n)\n", + "pi-shell-17.1.8/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"pi-shell-17.1.8\",\n actual = \"@crates__pi-shell-17.1.8//:pi_shell\",\n tags = [\"manual\"],\n)\n", + "pi-shell/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"pi-shell\",\n actual = \"@crates__pi-shell-17.1.8//:pi_shell\",\n tags = [\"manual\"],\n)\n", "platform-info-2.1.0/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"platform-info-2.1.0\",\n actual = \"@crates__platform-info-2.1.0//:platform_info\",\n tags = [\"manual\"],\n)\n", "platform-info/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"platform-info\",\n actual = \"@crates__platform-info-2.1.0//:platform_info\",\n tags = [\"manual\"],\n)\n", "png-0.18.1/BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nalias(\n name = \"png-0.18.1\",\n actual = \"@crates__png-0.18.1//:png\",\n tags = [\"manual\"],\n)\n", @@ -5681,56 +5682,56 @@ "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"nanorand\",\n deps = [\n \"@crates__getrandom-0.2.17//:getrandom\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"alloc\",\n \"chacha\",\n \"default\",\n \"getrandom\",\n \"pcg64\",\n \"std\",\n \"tls\",\n \"wyrand\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=nanorand\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@@//bazel/triples:aarch64-apple-darwin\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-musl\": [],\n \"@@//bazel/triples:x86_64-apple-darwin\": [],\n \"@@//bazel/triples:x86_64-pc-windows-msvc\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-musl\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.7.0\",\n)\n" } }, - "crates__napi-3.11.0": { + "crates__napi-3.12.0": { "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributes": { "remote_patch_strip": 1, - "sha256": "de33522036981030a75c231829566bc63414e08101a6f5ff4ac6cef19c8e0941", + "sha256": "6f71d6bc097c4a6eb853c3f24991ab8c9f50f57d1f719e305175541482217e36", "type": "tar.gz", "urls": [ - "https://static.crates.io/crates/napi/3.11.0/download" + "https://static.crates.io/crates/napi/3.12.0/download" ], - "strip_prefix": "napi-3.11.0", - "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"napi\",\n deps = [\n \"@crates__bitflags-2.13.1//:bitflags\",\n \"@crates__ctor-1.0.11//:ctor\",\n \"@crates__futures-0.3.33//:futures\",\n \"@crates__napi-3.11.0//:build_script_build\",\n \"@crates__napi-sys-3.3.0//:napi_sys\",\n \"@crates__nohash-hasher-0.2.0//:nohash_hasher\",\n \"@crates__rustc-hash-2.1.3//:rustc_hash\",\n \"@crates__tokio-1.53.1//:tokio\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"dyn-symbols\",\n \"napi1\",\n \"napi10\",\n \"napi2\",\n \"napi3\",\n \"napi4\",\n \"napi5\",\n \"napi6\",\n \"napi7\",\n \"napi8\",\n \"napi9\",\n \"tokio\",\n \"tokio_rt\",\n \"tokio_time\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@@//bazel/triples:aarch64-apple-darwin\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-musl\": [],\n \"@@//bazel/triples:x86_64-apple-darwin\": [],\n \"@@//bazel/triples:x86_64-pc-windows-msvc\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-musl\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"3.11.0\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"dyn-symbols\",\n \"napi1\",\n \"napi10\",\n \"napi2\",\n \"napi3\",\n \"napi4\",\n \"napi5\",\n \"napi6\",\n \"napi7\",\n \"napi8\",\n \"napi9\",\n \"tokio\",\n \"tokio_rt\",\n \"tokio_time\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n deps = [\n \"@crates__napi-build-2.3.2//:napi_build\",\n ],\n emit_warnings = False,\n edition = \"2021\",\n pkg_name = \"napi\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"3.11.0\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + "strip_prefix": "napi-3.12.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"napi\",\n deps = [\n \"@crates__bitflags-2.13.1//:bitflags\",\n \"@crates__ctor-1.0.11//:ctor\",\n \"@crates__futures-0.3.33//:futures\",\n \"@crates__napi-3.12.0//:build_script_build\",\n \"@crates__napi-sys-3.3.0//:napi_sys\",\n \"@crates__nohash-hasher-0.2.0//:nohash_hasher\",\n \"@crates__rustc-hash-2.1.3//:rustc_hash\",\n \"@crates__tokio-1.53.1//:tokio\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"dyn-symbols\",\n \"napi1\",\n \"napi10\",\n \"napi2\",\n \"napi3\",\n \"napi4\",\n \"napi5\",\n \"napi6\",\n \"napi7\",\n \"napi8\",\n \"napi9\",\n \"tokio\",\n \"tokio_rt\",\n \"tokio_time\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@@//bazel/triples:aarch64-apple-darwin\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-musl\": [],\n \"@@//bazel/triples:x86_64-apple-darwin\": [],\n \"@@//bazel/triples:x86_64-pc-windows-msvc\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-musl\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"3.12.0\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"dyn-symbols\",\n \"napi1\",\n \"napi10\",\n \"napi2\",\n \"napi3\",\n \"napi4\",\n \"napi5\",\n \"napi6\",\n \"napi7\",\n \"napi8\",\n \"napi9\",\n \"tokio\",\n \"tokio_rt\",\n \"tokio_time\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n deps = [\n \"@crates__napi-build-2.4.0//:napi_build\",\n ],\n emit_warnings = False,\n edition = \"2021\",\n pkg_name = \"napi\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"3.12.0\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" } }, - "crates__napi-build-2.3.2": { + "crates__napi-build-2.4.0": { "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributes": { "remote_patch_strip": 1, - "sha256": "c9c366d2c8c60b86fa632df75f745509b52f9128f91a6bad4c796e44abb505e1", + "sha256": "5282704fbe8d49b0cf8b08e3f33233416a528658f205c7e5ace63b582de0b11c", "type": "tar.gz", "urls": [ - "https://static.crates.io/crates/napi-build/2.3.2/download" + "https://static.crates.io/crates/napi-build/2.4.0/download" ], - "strip_prefix": "napi-build-2.3.2", - "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"napi_build\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi-build\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@@//bazel/triples:aarch64-apple-darwin\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-musl\": [],\n \"@@//bazel/triples:x86_64-apple-darwin\": [],\n \"@@//bazel/triples:x86_64-pc-windows-msvc\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-musl\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.3.2\",\n)\n" + "strip_prefix": "napi-build-2.4.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"napi_build\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi-build\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@@//bazel/triples:aarch64-apple-darwin\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-musl\": [],\n \"@@//bazel/triples:x86_64-apple-darwin\": [],\n \"@@//bazel/triples:x86_64-pc-windows-msvc\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-musl\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.4.0\",\n)\n" } }, - "crates__napi-derive-3.6.0": { + "crates__napi-derive-3.6.1": { "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributes": { "remote_patch_strip": 1, - "sha256": "a49c513341a61a16a10af6efcce46b30d0822ba2d4fb197d24d33dfc199c78d5", + "sha256": "4d5c9c02556ea6dc99dffd36c1ce60141411657438501a125b675776d011ce92", "type": "tar.gz", "urls": [ - "https://static.crates.io/crates/napi-derive/3.6.0/download" + "https://static.crates.io/crates/napi-derive/3.6.1/download" ], - "strip_prefix": "napi-derive-3.6.0", - "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_proc_macro(\n name = \"napi_derive\",\n deps = [\n \"@crates__convert_case-0.11.0//:convert_case\",\n \"@crates__ctor-1.0.11//:ctor\",\n \"@crates__napi-derive-backend-6.0.0//:napi_derive_backend\",\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__syn-2.0.119//:syn\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"ctor\",\n \"default\",\n \"strict\",\n \"type-def\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi-derive\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@@//bazel/triples:aarch64-apple-darwin\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-musl\": [],\n \"@@//bazel/triples:x86_64-apple-darwin\": [],\n \"@@//bazel/triples:x86_64-pc-windows-msvc\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-musl\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"3.6.0\",\n)\n" + "strip_prefix": "napi-derive-3.6.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_proc_macro(\n name = \"napi_derive\",\n deps = [\n \"@crates__convert_case-0.11.0//:convert_case\",\n \"@crates__ctor-1.0.11//:ctor\",\n \"@crates__napi-derive-backend-6.1.0//:napi_derive_backend\",\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__syn-2.0.119//:syn\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"ctor\",\n \"default\",\n \"strict\",\n \"type-def\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi-derive\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@@//bazel/triples:aarch64-apple-darwin\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-musl\": [],\n \"@@//bazel/triples:x86_64-apple-darwin\": [],\n \"@@//bazel/triples:x86_64-pc-windows-msvc\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-musl\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"3.6.1\",\n)\n" } }, - "crates__napi-derive-backend-6.0.0": { + "crates__napi-derive-backend-6.1.0": { "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributes": { "remote_patch_strip": 1, - "sha256": "4747005fa3e2c9989ac45a723a514c5db2411238b72981a3cda4c701a9dfea17", + "sha256": "6a9d8365cf97f54d9b6d6dbf83a25ca227ad7d6e920717426c599225aca6740b", "type": "tar.gz", "urls": [ - "https://static.crates.io/crates/napi-derive-backend/6.0.0/download" + "https://static.crates.io/crates/napi-derive-backend/6.1.0/download" ], - "strip_prefix": "napi-derive-backend-6.0.0", - "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"napi_derive_backend\",\n deps = [\n \"@crates__convert_case-0.11.0//:convert_case\",\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__semver-1.0.28//:semver\",\n \"@crates__syn-2.0.119//:syn\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"semver\",\n \"strict\",\n \"type-def\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi-derive-backend\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@@//bazel/triples:aarch64-apple-darwin\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-musl\": [],\n \"@@//bazel/triples:x86_64-apple-darwin\": [],\n \"@@//bazel/triples:x86_64-pc-windows-msvc\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-musl\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"6.0.0\",\n)\n" + "strip_prefix": "napi-derive-backend-6.1.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'oh-my-pi'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"napi_derive_backend\",\n deps = [\n \"@crates__convert_case-0.11.0//:convert_case\",\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__semver-1.0.28//:semver\",\n \"@crates__syn-2.0.119//:syn\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"semver\",\n \"strict\",\n \"type-def\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=napi-derive-backend\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@@//bazel/triples:aarch64-apple-darwin\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:aarch64-unknown-linux-musl\": [],\n \"@@//bazel/triples:x86_64-apple-darwin\": [],\n \"@@//bazel/triples:x86_64-pc-windows-msvc\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-gnu\": [],\n \"@@//bazel/triples:x86_64-unknown-linux-musl\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"6.1.0\",\n)\n" } }, "crates__napi-sys-3.3.0": { diff --git a/bazel/patches/hermetic_cc_toolchain-isolated-compile-cache.patch b/bazel/patches/hermetic_cc_toolchain-isolated-compile-cache.patch index 52ac68089..5b14de212 100644 --- a/bazel/patches/hermetic_cc_toolchain-isolated-compile-cache.patch +++ b/bazel/patches/hermetic_cc_toolchain-isolated-compile-cache.patch @@ -12,9 +12,18 @@ dir. Link steps keep the shared cache: they are the ones that benefit battle-tested path for concurrent artifact builds, and after first warm they are pure readers. +Also opt @zig_config into Bazel's repo contents cache (repo_metadata, +bazel >= 8.3): the fetch is deterministic given the pinned zig archive and +wrapper source, and re-running it cost ~20 s of wrapper compilation on every +fresh output base — every job on ephemeral CI pods. + +Note: bazel's own patch parser (unlike GNU patch) requires the `diff --git` +separator line before each file section of a multi-file patch. + +diff --git a/toolchain/zig-wrapper.zig b/toolchain/zig-wrapper.zig --- a/toolchain/zig-wrapper.zig +++ b/toolchain/zig-wrapper.zig -@@ -252,6 +252,32 @@ fn parseArgs( +@@ -267,6 +267,32 @@ if (run_mode == RunMode.cc) try resolveColonLibraries(arena, cwd, &args); @@ -47,3 +56,19 @@ are pure readers. // Add -target as the last parameter. The wrapper should overwrite // the target specified by other tools calling the wrapper. // Some tools might pass LLVM target triple, which are rejected by zig. +diff --git a/toolchain/defs.bzl b/toolchain/defs.bzl +--- a/toolchain/defs.bzl ++++ b/toolchain/defs.bzl +@@ -278,6 +278,12 @@ + ) + repository_ctx.symlink("tools/zig-wrapper{}".format(exe), tool_path) + ++ # omp: opt into the repo contents cache — the fetch is deterministic ++ # given the pinned zig archive and the wrapper source above. ++ if hasattr(repository_ctx, "repo_metadata"): ++ return repository_ctx.repo_metadata(reproducible = True) ++ return None ++ + zig_repository = repository_rule( + attrs = { + "version": attr.string(), diff --git a/bazel/toolchains/msvc/llvm.bzl b/bazel/toolchains/msvc/llvm.bzl index 35172658c..1a2f9a43e 100644 --- a/bazel/toolchains/msvc/llvm.bzl +++ b/bazel/toolchains/msvc/llvm.bzl @@ -120,6 +120,12 @@ def _llvm_msvc_tools_impl(rctx): rctx.file("BUILD.bazel", _BUILD.format(version = _LLVM_VERSION, host = key), executable = False) + # Opt into the repo contents cache: the fetch is a pure function of the + # pinned URL+sha256 and the deterministic prune above, and the ~172 s + # extraction of the 2 GiB archive was the single largest cost of every + # fresh output base on ephemeral CI pods (profiled: run 30510579596). + return rctx.repo_metadata(reproducible = True) + llvm_msvc_tools_repository = repository_rule( implementation = _llvm_msvc_tools_impl, doc = "Pruned LLVM release binaries (clang-cl/lld-link/llvm-lib/llvm-rc) for the exec host.", diff --git a/bazel/toolchains/msvc/sysroot.bzl b/bazel/toolchains/msvc/sysroot.bzl index 0a6fa8503..486ef1c39 100644 --- a/bazel/toolchains/msvc/sysroot.bzl +++ b/bazel/toolchains/msvc/sysroot.bzl @@ -161,6 +161,14 @@ def _xwin_sysroot_impl(rctx): executable = False, ) + # Opt into the repo contents cache. The splat is channel-stable, not + # bit-reproducible forever (see the module docstring) — caching freezes a + # known-good splat, which also keeps remote action keys stable across + # pods until this file changes or the cache entry ages out (14 d GC). + # OMP_XWIN_CACHE_DIR is a predeclared input (environ attr), so kata and + # dev fetches key separate entries. + return rctx.repo_metadata(reproducible = True) + xwin_sysroot_repository = repository_rule( implementation = _xwin_sysroot_impl, doc = "MSVC CRT + Windows SDK sysroot splatted by a pinned xwin release.", diff --git a/bun.lock b/bun.lock index 961f374ab..c8c73b575 100644 --- a/bun.lock +++ b/bun.lock @@ -21,7 +21,7 @@ }, "packages/agent": { "name": "@oh-my-pi/pi-agent-core", - "version": "17.1.8", + "version": "17.2.0", "dependencies": { "@oh-my-pi/pi-ai": "catalog:", "@oh-my-pi/pi-catalog": "catalog:", @@ -39,7 +39,7 @@ }, "packages/ai": { "name": "@oh-my-pi/pi-ai", - "version": "17.1.8", + "version": "17.2.0", "dependencies": { "@bufbuild/protobuf": "catalog:", "@oh-my-pi/pi-catalog": "catalog:", @@ -55,7 +55,7 @@ }, "packages/catalog": { "name": "@oh-my-pi/pi-catalog", - "version": "17.1.8", + "version": "17.2.0", "dependencies": { "@bufbuild/protobuf": "catalog:", "@oh-my-pi/pi-utils": "catalog:", @@ -69,7 +69,7 @@ }, "packages/coding-agent": { "name": "@oh-my-pi/pi-coding-agent", - "version": "17.1.8", + "version": "17.2.0", "bin": { "omp": "src/cli.ts", }, @@ -143,7 +143,7 @@ }, "packages/hashline": { "name": "@oh-my-pi/hashline", - "version": "17.1.8", + "version": "17.2.0", "dependencies": { "@oh-my-pi/pi-natives": "catalog:", "lru-cache": "catalog:", @@ -187,7 +187,7 @@ }, "packages/mnemopi": { "name": "@oh-my-pi/pi-mnemopi", - "version": "17.1.8", + "version": "17.2.0", "bin": { "mnemopi": "src/cli.ts", }, @@ -214,7 +214,7 @@ }, "packages/natives": { "name": "@oh-my-pi/pi-natives", - "version": "17.1.8", + "version": "17.2.0", "devDependencies": { "@napi-rs/cli": "catalog:", "@types/bun": "catalog:", @@ -222,7 +222,7 @@ }, "packages/snapcompact": { "name": "@oh-my-pi/snapcompact", - "version": "17.1.8", + "version": "17.2.0", "dependencies": { "@oh-my-pi/pi-ai": "catalog:", "@oh-my-pi/pi-natives": "catalog:", @@ -235,7 +235,7 @@ }, "packages/stats": { "name": "@oh-my-pi/omp-stats", - "version": "17.1.8", + "version": "17.2.0", "bin": { "omp-stats": "./src/index.ts", }, @@ -262,7 +262,7 @@ }, "packages/swarm-extension": { "name": "@oh-my-pi/swarm-extension", - "version": "17.1.8", + "version": "17.2.0", "bin": { "omp-swarm": "src/cli.ts", }, @@ -278,7 +278,7 @@ }, "packages/tui": { "name": "@oh-my-pi/pi-tui", - "version": "17.1.8", + "version": "17.2.0", "dependencies": { "@oh-my-pi/pi-natives": "catalog:", "@oh-my-pi/pi-utils": "catalog:", @@ -317,7 +317,7 @@ }, "packages/utils": { "name": "@oh-my-pi/pi-utils", - "version": "17.1.8", + "version": "17.2.0", "dependencies": { "@oh-my-pi/pi-natives": "catalog:", "handlebars": "catalog:", @@ -330,7 +330,7 @@ }, "packages/wire": { "name": "@oh-my-pi/pi-wire", - "version": "17.1.8", + "version": "17.2.0", "devDependencies": { "@types/bun": "catalog:", }, @@ -371,18 +371,18 @@ "@huggingface/transformers": "^4.2.0", "@mozilla/readability": "^0.6.0", "@napi-rs/cli": "3.7.2", - "@oh-my-pi/hashline": "17.1.8", - "@oh-my-pi/omp-stats": "17.1.8", - "@oh-my-pi/pi-agent-core": "17.1.8", - "@oh-my-pi/pi-ai": "17.1.8", - "@oh-my-pi/pi-catalog": "17.1.8", - "@oh-my-pi/pi-coding-agent": "17.1.8", - "@oh-my-pi/pi-mnemopi": "17.1.8", - "@oh-my-pi/pi-natives": "17.1.8", - "@oh-my-pi/pi-tui": "17.1.8", - "@oh-my-pi/pi-utils": "17.1.8", - "@oh-my-pi/pi-wire": "17.1.8", - "@oh-my-pi/snapcompact": "17.1.8", + "@oh-my-pi/hashline": "17.2.0", + "@oh-my-pi/omp-stats": "17.2.0", + "@oh-my-pi/pi-agent-core": "17.2.0", + "@oh-my-pi/pi-ai": "17.2.0", + "@oh-my-pi/pi-catalog": "17.2.0", + "@oh-my-pi/pi-coding-agent": "17.2.0", + "@oh-my-pi/pi-mnemopi": "17.2.0", + "@oh-my-pi/pi-natives": "17.2.0", + "@oh-my-pi/pi-tui": "17.2.0", + "@oh-my-pi/pi-utils": "17.2.0", + "@oh-my-pi/pi-wire": "17.2.0", + "@oh-my-pi/snapcompact": "17.2.0", "@opentelemetry/api": "^1.9.1", "@opentelemetry/api-logs": "^0.220.0", "@opentelemetry/context-async-hooks": "^2.9.0", @@ -524,7 +524,7 @@ "@emnapi/core": ["@emnapi/core@1.9.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA=="], - "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + "@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], @@ -1044,7 +1044,7 @@ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.11.1", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-HYXq73DDpCtNzOmrFsm9eSwCvWCql0RzqjpDzXN9EadiLJ4DNat0nsZ/Bzmy+Ud12mb4/zKDY0cQ805ZzN+i0A=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.11.4", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-s4+sLr9mZ/CyqeRritFeYV/Zx73OAtmaHn6kkBS1XRoJn1hrg3xIDUcpicAEX68tkcIN0iBCgti31C8zxtkhsQ=="], "before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], @@ -1322,7 +1322,7 @@ "lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="], - "lucide-react": ["lucide-react@1.26.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-raglYVR2+VkMfJL158krjVmE+rV5ST2lzA/KQm1FRSjMHT4MnWaegHxoVEpmc2So3nOEhp9oGejJwAPX8MoAjg=="], + "lucide-react": ["lucide-react@1.27.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-rJicGl/3Fly/E0rOH1YmPZ6e49JCnKknh1ox1vpHnkfjujAkKA6sqUZvH3MTAaXXjgexyUwgNwTJzTtYuAFYJw=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], @@ -1488,7 +1488,7 @@ "string-argv": ["string-argv@0.3.2", "", {}, "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="], - "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + "string-width": ["string-width@8.2.2", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg=="], "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], @@ -1574,7 +1574,7 @@ "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], - "yargs": ["yargs@18.0.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^7.2.0", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg=="], + "yargs": ["yargs@18.1.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^8.2.1", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg=="], "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], @@ -1636,11 +1636,13 @@ "@rolldown/binding-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], + "@rolldown/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g=="], "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" }, "bundled": true }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], @@ -1654,6 +1656,8 @@ "cli-progress/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + "cliui/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + "dom-serializer/domelementtype": ["domelementtype@3.0.0", "", {}, "sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg=="], "dom-serializer/entities": ["entities@8.0.0", "", {}, "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA=="], @@ -1686,7 +1690,7 @@ "string_decoder/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], - "vite/lightningcss": ["lightningcss@1.33.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.33.0", "lightningcss-darwin-arm64": "1.33.0", "lightningcss-darwin-x64": "1.33.0", "lightningcss-freebsd-x64": "1.33.0", "lightningcss-linux-arm-gnueabihf": "1.33.0", "lightningcss-linux-arm64-gnu": "1.33.0", "lightningcss-linux-arm64-musl": "1.33.0", "lightningcss-linux-x64-gnu": "1.33.0", "lightningcss-linux-x64-musl": "1.33.0", "lightningcss-win32-arm64-msvc": "1.33.0", "lightningcss-win32-x64-msvc": "1.33.0" } }, "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA=="], + "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], @@ -1714,28 +1718,6 @@ "jszip/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], - "vite/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.33.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg=="], - - "vite/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.33.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg=="], - - "vite/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.33.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ=="], - - "vite/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.33.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg=="], - - "vite/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.33.0", "", { "os": "linux", "cpu": "arm" }, "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ=="], - - "vite/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg=="], - - "vite/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.33.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ=="], - - "vite/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg=="], - - "vite/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.33.0", "", { "os": "linux", "cpu": "x64" }, "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw=="], - - "vite/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.33.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA=="], - - "vite/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.33.0", "", { "os": "win32", "cpu": "x64" }, "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA=="], - "@huggingface/transformers/onnxruntime-node/global-agent/matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "^4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], "@huggingface/transformers/onnxruntime-node/global-agent/serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], diff --git a/crates/pi-natives/BUILD.bazel b/crates/pi-natives/BUILD.bazel index 56eb22670..6e2dc8a41 100644 --- a/crates/pi-natives/BUILD.bazel +++ b/crates/pi-natives/BUILD.bazel @@ -48,6 +48,7 @@ rust_shared_library( "//crates/pi-iso", "//crates/pi-shell", "//crates/pi-uutils-ctx", + "//crates/pi-voice", "//crates/pi-walker", ], ) diff --git a/crates/pi-natives/Cargo.toml b/crates/pi-natives/Cargo.toml index 78ce21756..009ac31bf 100644 --- a/crates/pi-natives/Cargo.toml +++ b/crates/pi-natives/Cargo.toml @@ -15,11 +15,9 @@ workspace = true [dependencies] anyhow.workspace = true -audiopus_sys.workspace = true arboard.workspace = true ast-grep-core.workspace = true base64.workspace = true -bytes.workspace = true clap.workspace = true globset.workspace = true fontdue.workspace = true @@ -32,16 +30,15 @@ icy_sixel.workspace = true ignore.workspace = true image = { workspace = true, features = ["bmp"] } inferno.workspace = true -maudio.workspace = true napi.workspace = true napi-derive.workspace = true -opus.workspace = true parking_lot.workspace = true phf.workspace = true flume.workspace = true pi-ast.workspace = true pi-iso.workspace = true pi-shell.workspace = true +pi-voice.workspace = true pi-walker.workspace = true pi-uutils-ctx = { path = "../pi-uutils-ctx" } portable-pty.workspace = true @@ -58,7 +55,6 @@ tokio-util.workspace = true toml.workspace = true unicode-segmentation.workspace = true unicode-width.workspace = true -webrtc.workspace = true xxhash-rust.workspace = true [target.'cfg(target_os = "linux")'.dependencies] @@ -72,16 +68,6 @@ xcap = { version = "=0.9.6", default-features = false } [target.'cfg(target_os = "macos")'.dependencies] tempfile = "=3.27.0" core-graphics = "0.25" -# Regenerate miniaudio FFI bindings from the compiled headers on macOS only. -# The maudio-sys pregenerated `unix.rs` bindings are Linux-shaped: their -# `ma_device`/`ma_context` backend-state unions omit the `#ifdef -# MA_SUPPORT_COREAUDIO` members that the macOS build of miniaudio.c actually -# contains, so shipping them on darwin is an ABI mismatch that silently breaks -# CoreAudio capture (device init/start succeed but no render callbacks fire). -# darwin builds with host Xcode (libclang available), so bindgen is fine here; -# the hermetic zig/musl/windows toolchains keep the bindgen-free pregen path, -# whose bindings are correct for those platforms. -maudio = { workspace = true, features = ["generate-bindings"] } [target.'cfg(unix)'.dependencies] libc.workspace = true diff --git a/crates/pi-natives/src/audio.rs b/crates/pi-natives/src/audio.rs index 1c68f682c..6ca937fba 100644 --- a/crates/pi-natives/src/audio.rs +++ b/crates/pi-natives/src/audio.rs @@ -1,310 +1,26 @@ -//! Cross-platform microphone capture and streaming speaker playback. +//! N-API bindings for microphone capture and speaker playback. //! -//! miniaudio owns platform device discovery, format conversion, channel mixing, -//! and resampling. The N-API classes expose one stable mono `f32` contract to -//! TypeScript while the internal playback stream is shared with native WebRTC. +//! The engine — device discovery, format conversion, mixing, drain semantics — +//! lives in `pi_voice::audio`; these classes adapt its mono `f32` contract to +//! TypeScript callbacks and `Float32Array` buffers. -use std::sync::{ - Arc, - atomic::{AtomicBool, AtomicU32, Ordering}, -}; +use std::sync::Arc; -use flume::TryRecvError; -use maudio::{ - audio::{performance::PerformanceProfile, sample_rate::SampleRate}, - backend::Backend, - device::{ - Device, - device_builder::{DeviceBuilder, DeviceBuilderOps}, - }, -}; use napi::{ bindgen_prelude::{Float32Array, Result}, threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode, UnknownReturnValue}, }; use napi_derive::napi; use parking_lot::Mutex; -use tokio::sync::Notify; - -const AUDIO_CHANNELS: u32 = 1; -// PulseAudio TCP playback stutters with a 20 ms target buffer; 50 ms absorbs -// transport jitter while preserving interactive latency. -#[cfg(target_os = "linux")] -const PLAYBACK_PERIOD_MS: u32 = 50; -#[cfg(not(target_os = "linux"))] -const PLAYBACK_PERIOD_MS: u32 = 20; -// miniaudio's PulseAudio backend reserves three periods. Android's OpenSL ES -// source emits 125 ms fragments, so Linux capture needs at least 150 ms queued. -#[cfg(target_os = "linux")] -const CAPTURE_PERIOD_MS: u32 = 50; -#[cfg(not(target_os = "linux"))] -const CAPTURE_PERIOD_MS: u32 = 20; -// PulseAudio can retain its default three periods after the producer closes. -// Wait for all of them before stopping the device so the tail reaches the sink. -#[cfg(target_os = "linux")] -const PLAYBACK_DRAIN_CALLBACKS: usize = 3; -#[cfg(not(target_os = "linux"))] -const PLAYBACK_DRAIN_CALLBACKS: usize = 2; - -#[cfg(target_os = "macos")] -const AUDIO_BACKENDS: &[Backend] = &[Backend::CoreAudio]; -#[cfg(target_os = "windows")] -const AUDIO_BACKENDS: &[Backend] = &[Backend::Wasapi]; -#[cfg(target_os = "linux")] -const AUDIO_BACKENDS: &[Backend] = &[Backend::PulseAudio, Backend::Alsa, Backend::Jack]; -#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))] -const AUDIO_BACKENDS: &[Backend] = &[Backend::Sndio, Backend::Audio4, Backend::Oss]; +use pi_voice::audio::{CaptureStream, PlaybackState, PlaybackStream}; type CaptureCallback = ThreadsafeFunction; -type NativeResult = std::result::Result; - -struct PlaybackState { - gain_bits: AtomicU32, - drained: AtomicBool, - stopped: AtomicBool, - notify: Notify, -} - -impl PlaybackState { - fn new() -> Self { - Self { - gain_bits: AtomicU32::new(1.0f32.to_bits()), - drained: AtomicBool::new(false), - stopped: AtomicBool::new(false), - notify: Notify::new(), - } - } - - fn gain(&self) -> f32 { - f32::from_bits(self.gain_bits.load(Ordering::Acquire)) - } - - fn set_gain(&self, gain: f32) { - self.gain_bits.store(gain.to_bits(), Ordering::Release); - } - - fn mark_drained(&self) { - if !self.drained.swap(true, Ordering::AcqRel) { - self.notify.notify_waiters(); - } - } - - fn mark_stopped(&self) { - self.stopped.store(true, Ordering::Release); - self.notify.notify_waiters(); - } - - async fn wait_for_drain(&self) { - loop { - let notified = self.notify.notified(); - if self.drained.load(Ordering::Acquire) || self.stopped.load(Ordering::Acquire) { - return; - } - notified.await; - } - } -} - -/// Producer endpoint for one native playback device. -#[derive(Clone)] -pub(crate) struct PlaybackWriter { - tx: flume::Sender>, - state: Arc, -} - -impl PlaybackWriter { - /// Queue mono floating-point samples without blocking the caller. - pub(crate) fn write(&self, samples: &[f32]) -> NativeResult<()> { - if samples.is_empty() { - return Ok(()); - } - if self.state.stopped.load(Ordering::Acquire) || self.state.drained.load(Ordering::Acquire) { - return Err("Native audio playback is closed".to_owned()); - } - self - .tx - .send(samples.to_vec()) - .map_err(|_| "Native audio playback is closed".to_owned()) - } -} - -/// Running mono playback stream shared by N-API playback and native WebRTC. -pub(crate) struct PlaybackStream { - device: Option>, - writer: Option, - state: Arc, -} - -impl PlaybackStream { - /// Open and start the default speaker at the requested logical sample rate. - pub(crate) fn start(sample_rate: u32) -> NativeResult { - let sample_rate = audio_sample_rate(sample_rate)?; - let state = Arc::new(PlaybackState::new()); - let (tx, rx) = flume::unbounded::>(); - let callback_state = Arc::clone(&state); - let mut current = Vec::new(); - let mut cursor = 0; - let mut empty_callbacks = 0; - let mut builder = DeviceBuilder::playback().f32(); - builder - .sample_rate(sample_rate) - .playback_channels(AUDIO_CHANNELS) - .period_size_millis(PLAYBACK_PERIOD_MS) - .performance_profile(PerformanceProfile::LowLatency) - .backends(AUDIO_BACKENDS); - let mut device = builder - .with_callback(move |_device, output| { - fill_playback( - &rx, - &mut current, - &mut cursor, - output, - &callback_state, - &mut empty_callbacks, - ); - }) - .map_err(|error| format!("Failed to open the default speaker: {error}"))?; - device - .device_start() - .map_err(|error| format!("Failed to start speaker playback: {error}"))?; - - Ok(Self { - device: Some(device), - writer: Some(PlaybackWriter { tx, state: Arc::clone(&state) }), - state, - }) - } - - /// Clone the producer endpoint used by the remote-audio decoder. - pub(crate) fn writer(&self) -> NativeResult { - self - .writer - .clone() - .ok_or_else(|| "Native audio playback is closed".to_owned()) - } - - fn state(&self) -> Arc { - Arc::clone(&self.state) - } - - fn finish_input(&mut self) { - self.writer.take(); - } - - fn set_gain(&self, gain: f32) -> NativeResult<()> { - if !gain.is_finite() { - return Err("Audio playback gain must be finite".to_owned()); - } - self.state.set_gain(gain.max(0.0)); - Ok(()) - } - - /// Stop playback immediately and release the default speaker. - pub(crate) fn stop(&mut self) -> NativeResult<()> { - self.writer.take(); - self.state.mark_stopped(); - let Some(mut device) = self.device.take() else { - return Ok(()); - }; - device - .device_stop() - .map_err(|error| format!("Failed to stop speaker playback: {error}")) - } -} - -impl Drop for PlaybackStream { - fn drop(&mut self) { - let _ = self.stop(); - } -} - -fn audio_sample_rate(sample_rate: u32) -> NativeResult { - SampleRate::try_from(sample_rate) - .map_err(|error| format!("Unsupported audio sample rate {sample_rate}: {error}")) -} - -fn fill_playback( - rx: &flume::Receiver>, - current: &mut Vec, - cursor: &mut usize, - output: &mut [f32], - state: &PlaybackState, - empty_callbacks: &mut usize, -) { - output.fill(0.0); - if state.stopped.load(Ordering::Acquire) { - return; - } - - let gain = state.gain(); - let mut output_offset = 0; - while output_offset < output.len() { - if *cursor == current.len() { - match rx.try_recv() { - Ok(next) => { - *current = next; - *cursor = 0; - *empty_callbacks = 0; - }, - Err(TryRecvError::Empty) => { - *empty_callbacks = 0; - break; - }, - Err(TryRecvError::Disconnected) => { - *empty_callbacks += 1; - if *empty_callbacks >= PLAYBACK_DRAIN_CALLBACKS { - state.mark_drained(); - } - break; - }, - } - } - - let count = (current.len() - *cursor).min(output.len() - output_offset); - let source = ¤t[*cursor..*cursor + count]; - let destination = &mut output[output_offset..output_offset + count]; - if gain == 1.0 { - destination.copy_from_slice(source); - } else { - for (destination, source) in destination.iter_mut().zip(source) { - *destination = *source * gain; - } - } - *cursor += count; - output_offset += count; - } -} - -fn start_capture_device(sample_rate: u32, mut on_audio: C) -> NativeResult> -where - C: FnMut(&[f32]) + Send + 'static, -{ - let sample_rate = audio_sample_rate(sample_rate)?; - let mut builder = DeviceBuilder::capture().f32(); - builder - .sample_rate(sample_rate) - .capture_channels(AUDIO_CHANNELS) - .period_size_millis(CAPTURE_PERIOD_MS) - .performance_profile(PerformanceProfile::LowLatency) - .backends(AUDIO_BACKENDS); - let mut device = builder - .with_callback(move |_device, samples| { - if !samples.is_empty() { - on_audio(samples); - } - }) - .map_err(|error| format!("Failed to open the default microphone: {error}"))?; - device - .device_start() - .map_err(|error| format!("Failed to start microphone capture: {error}"))?; - Ok(device) -} /// Default-microphone capture converted to mono `f32` at the requested sample /// rate. #[napi] pub struct AudioCapture { - device: Mutex>>, + stream: Mutex>, } #[napi] @@ -316,32 +32,22 @@ impl AudioCapture { #[napi(ts_arg_type = "(error: Error | null, samples: Float32Array) => void")] on_audio: CaptureCallback, ) -> Result { - let device = start_capture_device(sample_rate, move |samples| { + let stream = CaptureStream::start(sample_rate, move |samples| { on_audio .call(Ok(Float32Array::new(samples.to_vec())), ThreadsafeFunctionCallMode::NonBlocking); }) .map_err(napi::Error::from_reason)?; - Ok(Self { device: Mutex::new(Some(device)) }) + Ok(Self { stream: Mutex::new(Some(stream)) }) } /// Stop capture immediately and release the microphone. #[napi] pub fn stop(&self) -> Result<()> { - let device = self.device.lock().take(); - let Some(mut device) = device else { + let stream = self.stream.lock().take(); + let Some(mut stream) = stream else { return Ok(()); }; - device.device_stop().map_err(|error| { - napi::Error::from_reason(format!("Failed to stop microphone capture: {error}")) - }) - } -} - -impl Drop for AudioCapture { - fn drop(&mut self) { - if let Some(mut device) = self.device.get_mut().take() { - let _ = device.device_stop(); - } + stream.stop().map_err(napi::Error::from_reason) } } @@ -416,77 +122,3 @@ impl AudioPlayback { Ok(()) } } - -impl Drop for AudioPlayback { - fn drop(&mut self) { - if let Some(mut stream) = self.stream.get_mut().take() { - let _ = stream.stop(); - } - } -} - -#[cfg(test)] -mod tests { - use std::{ - env, - mem::forget, - sync::atomic::AtomicUsize, - thread::sleep, - time::{Duration, Instant}, - }; - - use super::*; - - #[test] - fn playback_preserves_chunk_order_and_applies_render_gain() { - let state = PlaybackState::new(); - state.set_gain(0.5); - let (tx, rx) = flume::unbounded(); - tx.send(vec![1.0, -1.0]).expect("receiver is live"); - tx.send(vec![0.5, -0.5]).expect("receiver is live"); - drop(tx); - let mut current = Vec::new(); - let mut cursor = 0; - let mut empty_callbacks = 0; - let mut output = [9.0; 5]; - - fill_playback(&rx, &mut current, &mut cursor, &mut output, &state, &mut empty_callbacks); - - assert_eq!(output, [0.5, -0.5, 0.25, -0.25, 0.0]); - assert!(!state.drained.load(Ordering::Acquire)); - let mut silence = [1.0; 2]; - while empty_callbacks < PLAYBACK_DRAIN_CALLBACKS { - silence.fill(1.0); - fill_playback(&rx, &mut current, &mut cursor, &mut silence, &state, &mut empty_callbacks); - assert_eq!(silence, [0.0, 0.0]); - assert_eq!( - state.drained.load(Ordering::Acquire), - empty_callbacks >= PLAYBACK_DRAIN_CALLBACKS - ); - } - } - - #[test] - fn opt_in_default_capture_receives_frames() { - if env::var_os("OMP_NATIVE_AUDIO_CAPTURE_TEST").is_none() { - return; - } - - let callbacks = Arc::new(AtomicUsize::new(0)); - let callback_count = Arc::clone(&callbacks); - let mut device = start_capture_device(16_000, move |_samples| { - callback_count.fetch_add(1, Ordering::Relaxed); - }) - .expect("default capture device starts"); - - let deadline = Instant::now() + Duration::from_secs(5); - while callbacks.load(Ordering::Relaxed) == 0 && Instant::now() < deadline { - sleep(Duration::from_millis(20)); - } - if callbacks.load(Ordering::Relaxed) == 0 { - forget(device); - panic!("capture device started but delivered no frames within five seconds"); - } - device.device_stop().expect("capture device stops"); - } -} diff --git a/crates/pi-natives/src/lib.rs b/crates/pi-natives/src/lib.rs index 0c7db473f..fd1d0242b 100644 --- a/crates/pi-natives/src/lib.rs +++ b/crates/pi-natives/src/lib.rs @@ -260,7 +260,7 @@ fn create_windows_napi_tokio_runtime() -> Option { /// MUST stay in sync with `VERSION_SENTINEL_EXPORT` in /// `packages/natives/native/index.js` (which derives the name from /// `package.json#version`). -#[napi(js_name = "__piNativesV17_1_8")] +#[napi(js_name = "__piNativesV17_2_0")] pub const fn pi_natives_version_sentinel() {} /// Native module entry point: install crash diagnostics before any tool can diff --git a/crates/pi-natives/src/live.rs b/crates/pi-natives/src/live.rs index 75bd9b54d..9cbcd99d6 100644 --- a/crates/pi-natives/src/live.rs +++ b/crates/pi-natives/src/live.rs @@ -1,365 +1,21 @@ -//! Native WebRTC media transport for Codex live conversations. +//! N-API bindings for the Codex live WebRTC peer. //! //! The TypeScript host owns authenticated signaling and the sideband protocol; -//! this module owns the realtime WebRTC peer, Opus media, and speaker playback. +//! the realtime peer, Opus media, and speaker playback live in +//! `pi_voice::live`. This class adapts its callbacks to non-blocking +//! threadsafe functions and its PCM input to `Float32Array`. -use std::{ - sync::{ - Arc, Weak, - atomic::{AtomicBool, AtomicUsize, Ordering}, - }, - time::Duration, -}; +use std::sync::Arc; -use bytes::Bytes; use napi::{ bindgen_prelude::{Float32Array, Result}, threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode, UnknownReturnValue}, }; use napi_derive::napi; -use opus::{Application, Channels, Decoder, Encoder}; -use parking_lot::Mutex; -use tokio::{sync::watch, task::JoinHandle}; -use webrtc::{ - api::{ - APIBuilder, - interceptor_registry::register_default_interceptors, - media_engine::{MIME_TYPE_OPUS, MediaEngine}, - }, - data_channel::{RTCDataChannel, data_channel_message::DataChannelMessage}, - interceptor::registry::Registry, - media::Sample, - peer_connection::{ - RTCPeerConnection, configuration::RTCConfiguration, - peer_connection_state::RTCPeerConnectionState, - sdp::session_description::RTCSessionDescription, - }, - rtp_transceiver::{ - rtp_codec::{RTCRtpCodecCapability, RTCRtpCodecParameters, RTPCodecType}, - rtp_sender::RTCRtpSender, - }, - track::{ - track_local::{TrackLocal, track_local_static_sample::TrackLocalStaticSample}, - track_remote::TrackRemote, - }, -}; - -use crate::audio::{PlaybackStream, PlaybackWriter}; - -const DATA_CHANNEL_LABEL: &str = "oai-events"; -const INPUT_SAMPLE_RATE: u32 = 16_000; -const INPUT_FRAME_SAMPLES: usize = 320; -const INPUT_FRAME_DURATION: Duration = Duration::from_millis(20); -const MAX_ENCODED_OPUS_BYTES: usize = 1_275; -const MAX_QUEUED_INPUT_SAMPLES: usize = 32_000; -const OUTPUT_SAMPLE_RATE: u32 = 48_000; -const MAX_DECODED_OPUS_SAMPLES: usize = 5_760; -const OUTPUT_LEVEL_SAMPLES: usize = 2_400; -const OUTPUT_FRAME_SAMPLES: usize = 960; -const DEFAULT_OPEN_TIMEOUT_MS: u32 = 20_000; -const DISCONNECT_GRACE: Duration = Duration::from_secs(2); -const CLOSE_TASK_TIMEOUT: Duration = Duration::from_secs(1); - -const OPUS_CAPABILITY: RTCRtpCodecCapability = RTCRtpCodecCapability { - mime_type: String::new(), - clock_rate: OUTPUT_SAMPLE_RATE, - channels: 2, - sdp_fmtp_line: String::new(), - rtcp_feedback: Vec::new(), -}; +use pi_voice::live::{DEFAULT_OPEN_TIMEOUT_MS, LiveCallbacks, LivePeerCore}; type StringCallback = ThreadsafeFunction; type LevelCallback = ThreadsafeFunction; -type NativeResult = std::result::Result; - -#[derive(Clone, Debug)] -enum PeerSignal { - Connecting, - Open, - Failed(String), - Closed, -} - -enum InputCommand { - Audio(Vec), - Muted(bool), - Close, -} - -struct LiveCallbacks { - event: StringCallback, - level: LevelCallback, - failure: StringCallback, -} - -struct LiveResources { - peer: Arc, - data_channel: Arc, - input_tx: flume::Sender, - input_task: JoinHandle<()>, - rtcp_task: JoinHandle<()>, - playback: PlaybackStream, -} - -struct LivePeerCore { - callbacks: LiveCallbacks, - resources: Mutex>, - signal_tx: watch::Sender, - started: AtomicBool, - closing: AtomicBool, - muted: AtomicBool, - failure_reported: AtomicBool, - queued_samples: AtomicUsize, -} - -impl LivePeerCore { - fn new(callbacks: LiveCallbacks) -> Self { - let (signal_tx, _) = watch::channel(PeerSignal::Connecting); - Self { - callbacks, - resources: Mutex::new(None), - signal_tx, - started: AtomicBool::new(false), - closing: AtomicBool::new(false), - muted: AtomicBool::new(false), - failure_reported: AtomicBool::new(false), - queued_samples: AtomicUsize::new(0), - } - } - - async fn create_offer(self: &Arc) -> NativeResult { - if self.started.swap(true, Ordering::AcqRel) { - return Err("Native live WebRTC peer has already started".to_owned()); - } - if self.closing.load(Ordering::Acquire) { - return Err("Native live WebRTC peer is closed".to_owned()); - } - - let playback = PlaybackStream::start(OUTPUT_SAMPLE_RATE)?; - let playback_tx = playback.writer()?; - let mut media_engine = MediaEngine::default(); - let capability = opus_capability(); - media_engine - .register_codec( - RTCRtpCodecParameters { - capability: capability.clone(), - payload_type: 111, - ..Default::default() - }, - RTPCodecType::Audio, - ) - .map_err(|error| format!("Failed to register the live Opus codec: {error}"))?; - let registry = register_default_interceptors(Registry::new(), &mut media_engine) - .map_err(|error| format!("Failed to configure live WebRTC interceptors: {error}"))?; - let api = APIBuilder::new() - .with_media_engine(media_engine) - .with_interceptor_registry(registry) - .build(); - let peer = Arc::new( - api.new_peer_connection(RTCConfiguration::default()) - .await - .map_err(|error| format!("Failed to create the live WebRTC peer: {error}"))?, - ); - - let track = Arc::new(TrackLocalStaticSample::new( - capability, - "audio".to_owned(), - "omp-live".to_owned(), - )); - let sender = match peer - .add_track(Arc::clone(&track) as Arc) - .await - { - Ok(sender) => sender, - Err(error) => { - let _ = peer.close().await; - return Err(format!("Failed to add the live audio track: {error}")); - }, - }; - - install_peer_callbacks(&peer, Arc::downgrade(self), playback_tx); - let data_channel = match peer.create_data_channel(DATA_CHANNEL_LABEL, None).await { - Ok(channel) => channel, - Err(error) => { - let _ = peer.close().await; - return Err(format!("Failed to create the live data channel: {error}")); - }, - }; - install_data_channel_callbacks(&data_channel, Arc::downgrade(self)); - - let offer = match peer.create_offer(None).await { - Ok(offer) => offer, - Err(error) => { - let _ = peer.close().await; - return Err(format!("Failed to create the live SDP offer: {error}")); - }, - }; - if let Err(error) = peer.set_local_description(offer.clone()).await { - let _ = peer.close().await; - return Err(format!("Failed to install the live SDP offer: {error}")); - } - let mut resources_slot = self.resources.lock(); - if self.closing.load(Ordering::Acquire) { - drop(resources_slot); - let _ = peer.close().await; - return Err("Native live WebRTC peer was closed while starting".to_owned()); - } - - let (input_tx, input_rx) = flume::unbounded(); - let input_task = tokio::spawn(run_input_audio(track, input_rx, Arc::downgrade(self))); - let rtcp_task = tokio::spawn(drain_rtcp(sender)); - let resources = - LiveResources { peer, data_channel, input_tx, input_task, rtcp_task, playback }; - *resources_slot = Some(resources); - Ok(offer.sdp) - } - - async fn accept_answer(&self, sdp: String) -> NativeResult<()> { - let peer = self - .resources - .lock() - .as_ref() - .map(|resources| Arc::clone(&resources.peer)) - .ok_or_else(|| "Native live WebRTC peer has not started".to_owned())?; - let answer = RTCSessionDescription::answer(sdp) - .map_err(|error| format!("Codex returned an invalid live SDP answer: {error}"))?; - peer - .set_remote_description(answer) - .await - .map_err(|error| format!("Failed to install the live SDP answer: {error}")) - } - - async fn wait_for_open(&self, timeout_ms: u32) -> NativeResult<()> { - let mut signal_rx = self.signal_tx.subscribe(); - let wait = async { - loop { - let signal = signal_rx.borrow().clone(); - match signal { - PeerSignal::Open => return Ok(()), - PeerSignal::Failed(message) => return Err(message), - PeerSignal::Closed => { - return Err("Native live WebRTC peer closed before opening".to_owned()); - }, - PeerSignal::Connecting => {}, - } - signal_rx - .changed() - .await - .map_err(|_| "Native live WebRTC peer stopped before opening".to_owned())?; - } - }; - tokio::time::timeout(Duration::from_millis(u64::from(timeout_ms)), wait) - .await - .map_err(|_| "Timed out waiting for the live data channel to open".to_owned())? - } - - fn push_audio(&self, samples: &[f32]) -> NativeResult<()> { - if samples.is_empty() || self.muted.load(Ordering::Acquire) { - return Ok(()); - } - let input_tx = self - .resources - .lock() - .as_ref() - .map(|resources| resources.input_tx.clone()) - .ok_or_else(|| "Native live WebRTC peer has not started".to_owned())?; - let sample_count = samples.len().min(MAX_QUEUED_INPUT_SAMPLES); - let retained = &samples[samples.len() - sample_count..]; - let queued = self - .queued_samples - .fetch_add(sample_count, Ordering::AcqRel); - if queued.saturating_add(sample_count) > MAX_QUEUED_INPUT_SAMPLES { - self - .queued_samples - .fetch_sub(sample_count, Ordering::AcqRel); - return Ok(()); - } - if input_tx - .send(InputCommand::Audio(retained.to_vec())) - .is_err() - { - self - .queued_samples - .fetch_sub(sample_count, Ordering::AcqRel); - return Err("Native live audio input is closed".to_owned()); - } - Ok(()) - } - - fn set_muted(&self, muted: bool) -> NativeResult<()> { - self.muted.store(muted, Ordering::Release); - let input_tx = self - .resources - .lock() - .as_ref() - .map(|resources| resources.input_tx.clone()); - if let Some(input_tx) = input_tx { - input_tx - .send(InputCommand::Muted(muted)) - .map_err(|_| "Native live audio input is closed".to_owned())?; - } - Ok(()) - } - - fn report_event(&self, payload: String) { - self - .callbacks - .event - .call(Ok(payload), ThreadsafeFunctionCallMode::NonBlocking); - } - - fn report_level(&self, level: f64) { - self - .callbacks - .level - .call(Ok(level.clamp(0.0, 1.0)), ThreadsafeFunctionCallMode::NonBlocking); - } - - fn mark_open(&self) { - if !self.closing.load(Ordering::Acquire) { - self.signal_tx.send_replace(PeerSignal::Open); - } - } - - fn report_failure(&self, message: String) { - if self.closing.load(Ordering::Acquire) || self.failure_reported.swap(true, Ordering::AcqRel) - { - return; - } - self - .signal_tx - .send_replace(PeerSignal::Failed(message.clone())); - self - .callbacks - .failure - .call(Ok(message), ThreadsafeFunctionCallMode::NonBlocking); - } - - async fn close(&self) { - if self.closing.swap(true, Ordering::AcqRel) { - let mut signal_rx = self.signal_tx.subscribe(); - while !matches!(*signal_rx.borrow(), PeerSignal::Closed) { - if signal_rx.changed().await.is_err() { - break; - } - } - return; - } - - let resources = self.resources.lock().take(); - if let Some(mut resources) = resources { - let _ = resources.input_tx.send(InputCommand::Close); - let _ = resources.peer.close().await; - let _ = resources.playback.stop(); - let _ = tokio::time::timeout(CLOSE_TASK_TIMEOUT, resources.input_task).await; - resources.rtcp_task.abort(); - let _ = resources.rtcp_task.await; - drop(resources.data_channel); - } - self.queued_samples.store(0, Ordering::Release); - self.signal_tx.send_replace(PeerSignal::Closed); - } -} /// WebRTC peer that accepts 16 kHz mono PCM and renders remote Opus audio. #[napi] @@ -381,9 +37,15 @@ impl LiveWebRtcPeer { ) -> Self { Self { inner: Arc::new(LivePeerCore::new(LiveCallbacks { - event: on_event, - level: on_level, - failure: on_failure, + event: Box::new(move |payload| { + on_event.call(Ok(payload), ThreadsafeFunctionCallMode::NonBlocking); + }), + level: Box::new(move |level| { + on_level.call(Ok(level), ThreadsafeFunctionCallMode::NonBlocking); + }), + failure: Box::new(move |message| { + on_failure.call(Ok(message), ThreadsafeFunctionCallMode::NonBlocking); + }), })), } } @@ -446,7 +108,7 @@ impl LiveWebRtcPeer { impl Drop for LiveWebRtcPeer { fn drop(&mut self) { - if self.inner.closing.load(Ordering::Acquire) { + if self.inner.is_closing() { return; } let inner = Arc::clone(&self.inner); @@ -457,345 +119,3 @@ impl Drop for LiveWebRtcPeer { } } } - -fn opus_capability() -> RTCRtpCodecCapability { - RTCRtpCodecCapability { - mime_type: MIME_TYPE_OPUS.to_owned(), - clock_rate: OPUS_CAPABILITY.clock_rate, - channels: OPUS_CAPABILITY.channels, - sdp_fmtp_line: "minptime=10;useinbandfec=1".to_owned(), - rtcp_feedback: Vec::new(), - } -} - -fn install_peer_callbacks( - peer: &Arc, - core: Weak, - playback_tx: PlaybackWriter, -) { - let output_sender = Arc::new(Mutex::new(Some(playback_tx))); - let output_sender_for_track = Arc::clone(&output_sender); - let core_for_track = core.clone(); - peer.on_track(Box::new(move |track, _receiver, _transceiver| { - let output_sender = output_sender_for_track.lock().take(); - let core = core_for_track.clone(); - Box::pin(async move { - if track.kind() != RTPCodecType::Audio { - return; - } - let Some(output_sender) = output_sender else { - if let Some(core) = core.upgrade() { - core.report_failure( - "Codex live returned more than one remote audio track".to_owned(), - ); - } - return; - }; - tokio::spawn(receive_output_audio(track, output_sender, core)); - }) - })); - - let peer_for_state = Arc::downgrade(peer); - peer.on_peer_connection_state_change(Box::new(move |state| { - let core = core.clone(); - let peer = peer_for_state.clone(); - Box::pin(async move { - let Some(core) = core.upgrade() else { - return; - }; - match state { - RTCPeerConnectionState::Failed => { - core.report_failure("Live WebRTC peer connection failed".to_owned()); - }, - RTCPeerConnectionState::Closed if !core.closing.load(Ordering::Acquire) => { - core.report_failure("Live WebRTC peer connection closed unexpectedly".to_owned()); - }, - RTCPeerConnectionState::Disconnected => { - tokio::time::sleep(DISCONNECT_GRACE).await; - if peer.upgrade().is_some_and(|peer| { - peer.connection_state() == RTCPeerConnectionState::Disconnected - }) { - core.report_failure("Live WebRTC peer connection disconnected".to_owned()); - } - }, - _ => {}, - } - }) - })); -} - -fn install_data_channel_callbacks(data_channel: &Arc, core: Weak) { - let core_for_open = core.clone(); - data_channel.on_open(Box::new(move || { - Box::pin(async move { - if let Some(core) = core_for_open.upgrade() { - core.mark_open(); - } - }) - })); - - let core_for_message = core.clone(); - data_channel.on_message(Box::new(move |message: DataChannelMessage| { - let core = core_for_message.clone(); - Box::pin(async move { - if !message.is_string { - return; - } - if let (Some(core), Ok(payload)) = - (core.upgrade(), String::from_utf8(message.data.to_vec())) - { - core.report_event(payload); - } - }) - })); - - let core_for_close = core.clone(); - data_channel.on_close(Box::new(move || { - let core = core_for_close.clone(); - Box::pin(async move { - if let Some(core) = core.upgrade() { - core.report_failure("Live data channel closed unexpectedly".to_owned()); - } - }) - })); - - data_channel.on_error(Box::new(move |error| { - let core = core.clone(); - Box::pin(async move { - if let Some(core) = core.upgrade() { - core.report_failure(format!("Live data channel failed: {error}")); - } - }) - })); -} - -async fn run_input_audio( - track: Arc, - input_rx: flume::Receiver, - core: Weak, -) { - let mut encoder = match Encoder::new(INPUT_SAMPLE_RATE, Channels::Mono, Application::Voip) { - Ok(encoder) => encoder, - Err(error) => { - if let Some(core) = core.upgrade() { - core.report_failure(format!("Failed to initialize the live Opus encoder: {error}")); - } - return; - }, - }; - if let Err(error) = encoder.set_inband_fec(true) { - if let Some(core) = core.upgrade() { - core.report_failure(format!("Failed to configure the live Opus encoder: {error}")); - } - return; - } - - let mut muted = false; - let mut pending = Vec::with_capacity(INPUT_FRAME_SAMPLES * 2); - let mut encoded = [0u8; MAX_ENCODED_OPUS_BYTES]; - let mut ticker = tokio::time::interval(INPUT_FRAME_DURATION); - ticker.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Burst); - ticker.tick().await; - loop { - tokio::select! { - biased; - command = input_rx.recv_async() => { - let Ok(command) = command else { - break; - }; - match command { - InputCommand::Audio(samples) => { - if let Some(core) = core.upgrade() { - core.queued_samples.fetch_sub(samples.len(), Ordering::AcqRel); - } - if muted { - continue; - } - if samples.len() >= MAX_QUEUED_INPUT_SAMPLES { - pending.clear(); - pending.extend_from_slice(&samples[samples.len() - MAX_QUEUED_INPUT_SAMPLES..]); - continue; - } - let overflow = pending - .len() - .saturating_add(samples.len()) - .saturating_sub(MAX_QUEUED_INPUT_SAMPLES); - if overflow > 0 { - pending.drain(..overflow); - } - pending.extend_from_slice(&samples); - }, - InputCommand::Muted(next_muted) => { - muted = next_muted; - pending.clear(); - }, - InputCommand::Close => break, - } - }, - _ = ticker.tick() => { - let mut frame = [0.0f32; INPUT_FRAME_SAMPLES]; - if !muted { - let consumed = pending.len().min(INPUT_FRAME_SAMPLES); - frame[..consumed].copy_from_slice(&pending[..consumed]); - if consumed > 0 { - pending.copy_within(consumed.., 0); - pending.truncate(pending.len() - consumed); - } - } - let encoded_len = match encoder.encode_float(&frame, &mut encoded) { - Ok(encoded_len) => encoded_len, - Err(error) => { - if let Some(core) = core.upgrade() { - core.report_failure(format!("Failed to encode live microphone audio: {error}")); - } - return; - }, - }; - let sample = Sample { - data: Bytes::copy_from_slice(&encoded[..encoded_len]), - duration: INPUT_FRAME_DURATION, - ..Default::default() - }; - if let Err(error) = track.write_sample(&sample).await { - if let Some(core) = core.upgrade() { - core.report_failure(format!("Failed to send live microphone audio: {error}")); - } - return; - } - }, - } - } -} - -async fn drain_rtcp(sender: Arc) { - while sender.read_rtcp().await.is_ok() {} -} - -async fn receive_output_audio( - track: Arc, - playback_tx: PlaybackWriter, - core: Weak, -) { - if !track - .codec() - .capability - .mime_type - .eq_ignore_ascii_case(MIME_TYPE_OPUS) - { - if let Some(core) = core.upgrade() { - core.report_failure(format!( - "Codex live negotiated unsupported audio codec {}", - track.codec().capability.mime_type - )); - } - return; - } - let mut decoder = match Decoder::new(OUTPUT_SAMPLE_RATE, Channels::Mono) { - Ok(decoder) => decoder, - Err(error) => { - if let Some(core) = core.upgrade() { - core.report_failure(format!("Failed to initialize the live Opus decoder: {error}")); - } - return; - }, - }; - let mut decoded = vec![0.0f32; MAX_DECODED_OPUS_SAMPLES].into_boxed_slice(); - let mut expected_sequence: Option = None; - let mut level = OutputLevel::default(); - - loop { - let packet = match track.read_rtp().await { - Ok((packet, _attributes)) => packet, - Err(error) => { - if let Some(core) = core.upgrade() - && !core.closing.load(Ordering::Acquire) - { - core.report_failure(format!("Live remote audio track failed: {error}")); - } - return; - }, - }; - let sequence = packet.header.sequence_number; - if let Some(expected) = expected_sequence { - let gap = sequence.wrapping_sub(expected); - if gap >= u16::MAX / 2 { - continue; - } - if gap > 0 { - for _ in 1..gap.min(5) { - if let Ok(samples) = - decoder.decode_float(&[], &mut decoded[..OUTPUT_FRAME_SAMPLES], false) - { - if !write_output(&playback_tx, &decoded[..samples], &core) { - return; - } - level.observe(&decoded[..samples], &core); - } - } - if let Ok(samples) = decoder.decode_float(&packet.payload, &mut decoded, true) { - if !write_output(&playback_tx, &decoded[..samples], &core) { - return; - } - level.observe(&decoded[..samples], &core); - } - } - } - expected_sequence = Some(sequence.wrapping_add(1)); - match decoder.decode_float(&packet.payload, &mut decoded, false) { - Ok(samples) => { - if !write_output(&playback_tx, &decoded[..samples], &core) { - return; - } - level.observe(&decoded[..samples], &core); - }, - Err(error) => { - if let Some(core) = core.upgrade() { - core.report_failure(format!("Failed to decode live speaker audio: {error}")); - } - return; - }, - } - } -} - -fn write_output(playback_tx: &PlaybackWriter, samples: &[f32], core: &Weak) -> bool { - match playback_tx.write(samples) { - Ok(()) => true, - Err(error) => { - if let Some(core) = core.upgrade() - && !core.closing.load(Ordering::Acquire) - { - core.report_failure(format!("Live speaker playback failed: {error}")); - } - false - }, - } -} - -#[derive(Default)] -struct OutputLevel { - sum_squares: f64, - samples: usize, -} - -impl OutputLevel { - fn observe(&mut self, decoded: &[f32], core: &Weak) { - let mut offset = 0; - while offset < decoded.len() { - let take = (OUTPUT_LEVEL_SAMPLES - self.samples).min(decoded.len() - offset); - for &sample in &decoded[offset..offset + take] { - let sample = f64::from(sample); - self.sum_squares = sample.mul_add(sample, self.sum_squares); - } - self.samples += take; - offset += take; - if self.samples == OUTPUT_LEVEL_SAMPLES { - if let Some(core) = core.upgrade() { - core.report_level((self.sum_squares / self.samples as f64).sqrt()); - } - self.sum_squares = 0.0; - self.samples = 0; - } - } - } -} diff --git a/crates/pi-voice/BUILD.bazel b/crates/pi-voice/BUILD.bazel new file mode 100644 index 000000000..0e45353d2 --- /dev/null +++ b/crates/pi-voice/BUILD.bazel @@ -0,0 +1,29 @@ +load("@crates//:defs.bzl", "aliases", "all_crate_deps") +load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") + +package(default_visibility = ["//visibility:public"]) + +exports_files(["Cargo.toml"]) + +# napi-free voice engine (miniaudio capture/playback + WebRTC/Opus live peer). +# Keeping the webrtc/opus/maudio graph behind this rlib means the pi_natives +# leaf — which recompiles on every release (version-sentinel edit in lib.rs) — +# no longer pays for the voice stack's monomorphization. +rust_library( + name = "pi-voice", + srcs = glob(["src/**/*.rs"]), + aliases = aliases(), + crate_name = "pi_voice", + edition = "2024", + proc_macro_deps = all_crate_deps(proc_macro = True), + version = "17.1.5", + deps = all_crate_deps(normal = True), +) + +rust_test( + name = "pi-voice_test", + crate = ":pi-voice", + edition = "2024", + proc_macro_deps = all_crate_deps(proc_macro_dev = True), + deps = all_crate_deps(normal_dev = True), +) diff --git a/crates/pi-voice/Cargo.toml b/crates/pi-voice/Cargo.toml new file mode 100644 index 000000000..9decd2a62 --- /dev/null +++ b/crates/pi-voice/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "pi-voice" +version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +# Forces the static libopus build for the `opus` codec crate. +audiopus_sys.workspace = true +bytes.workspace = true +flume.workspace = true +maudio.workspace = true +opus.workspace = true +parking_lot.workspace = true +tokio.workspace = true +webrtc.workspace = true + +[target.'cfg(target_os = "macos")'.dependencies] +# Regenerate miniaudio FFI bindings from the compiled headers on macOS only. +# The maudio-sys pregenerated `unix.rs` bindings are Linux-shaped: their +# `ma_device`/`ma_context` backend-state unions omit the `#ifdef +# MA_SUPPORT_COREAUDIO` members that the macOS build of miniaudio.c actually +# contains, so shipping them on darwin is an ABI mismatch that silently breaks +# CoreAudio capture (device init/start succeed but no render callbacks fire). +# darwin builds with host Xcode (libclang available), so bindgen is fine here; +# the hermetic zig/musl/windows toolchains keep the bindgen-free pregen path, +# whose bindings are correct for those platforms. +maudio = { workspace = true, features = ["generate-bindings"] } diff --git a/crates/pi-voice/src/audio.rs b/crates/pi-voice/src/audio.rs new file mode 100644 index 000000000..abd025b6f --- /dev/null +++ b/crates/pi-voice/src/audio.rs @@ -0,0 +1,400 @@ +//! Cross-platform microphone capture and streaming speaker playback. +//! +//! miniaudio owns platform device discovery, format conversion, channel mixing, +//! and resampling. The engine exposes one stable mono `f32` contract: the +//! N-API classes in pi-natives adapt it to TypeScript, and [`crate::live`] +//! shares [`PlaybackStream`] for remote-audio rendering. + +use std::sync::{ + Arc, + atomic::{AtomicBool, AtomicU32, Ordering}, +}; + +use flume::TryRecvError; +use maudio::{ + audio::{performance::PerformanceProfile, sample_rate::SampleRate}, + backend::Backend, + device::{ + Device, + device_builder::{DeviceBuilder, DeviceBuilderOps}, + }, +}; +use tokio::sync::Notify; + +use crate::VoiceResult; + +const AUDIO_CHANNELS: u32 = 1; +// PulseAudio TCP playback stutters with a 20 ms target buffer; 50 ms absorbs +// transport jitter while preserving interactive latency. +#[cfg(target_os = "linux")] +const PLAYBACK_PERIOD_MS: u32 = 50; +#[cfg(not(target_os = "linux"))] +const PLAYBACK_PERIOD_MS: u32 = 20; +// miniaudio's PulseAudio backend reserves three periods. Android's OpenSL ES +// source emits 125 ms fragments, so Linux capture needs at least 150 ms queued. +#[cfg(target_os = "linux")] +const CAPTURE_PERIOD_MS: u32 = 50; +#[cfg(not(target_os = "linux"))] +const CAPTURE_PERIOD_MS: u32 = 20; +// PulseAudio can retain its default three periods after the producer closes. +// Wait for all of them before stopping the device so the tail reaches the sink. +#[cfg(target_os = "linux")] +const PLAYBACK_DRAIN_CALLBACKS: usize = 3; +#[cfg(not(target_os = "linux"))] +const PLAYBACK_DRAIN_CALLBACKS: usize = 2; + +#[cfg(target_os = "macos")] +const AUDIO_BACKENDS: &[Backend] = &[Backend::CoreAudio]; +#[cfg(target_os = "windows")] +const AUDIO_BACKENDS: &[Backend] = &[Backend::Wasapi]; +#[cfg(target_os = "linux")] +const AUDIO_BACKENDS: &[Backend] = &[Backend::PulseAudio, Backend::Alsa, Backend::Jack]; +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))] +const AUDIO_BACKENDS: &[Backend] = &[Backend::Sndio, Backend::Audio4, Backend::Oss]; + +/// Shared render-time state for one playback device: gain, drain, stop. +/// +/// Held as an `Arc` by both the stream and its N-API wrapper so +/// [`PlaybackState::wait_for_drain`] can outlive the stream lock. +pub struct PlaybackState { + gain_bits: AtomicU32, + drained: AtomicBool, + stopped: AtomicBool, + notify: Notify, +} + +impl PlaybackState { + fn new() -> Self { + Self { + gain_bits: AtomicU32::new(1.0f32.to_bits()), + drained: AtomicBool::new(false), + stopped: AtomicBool::new(false), + notify: Notify::new(), + } + } + + fn gain(&self) -> f32 { + f32::from_bits(self.gain_bits.load(Ordering::Acquire)) + } + + fn set_gain(&self, gain: f32) { + self.gain_bits.store(gain.to_bits(), Ordering::Release); + } + + fn mark_drained(&self) { + if !self.drained.swap(true, Ordering::AcqRel) { + self.notify.notify_waiters(); + } + } + + fn mark_stopped(&self) { + self.stopped.store(true, Ordering::Release); + self.notify.notify_waiters(); + } + + /// Resolve once every queued sample reached the speaker (or the stream + /// stopped). Used by the N-API `AudioPlayback.end()` graceful-close path. + pub async fn wait_for_drain(&self) { + loop { + let notified = self.notify.notified(); + if self.drained.load(Ordering::Acquire) || self.stopped.load(Ordering::Acquire) { + return; + } + notified.await; + } + } +} + +/// Producer endpoint for one native playback device. Cloned into the WebRTC +/// remote-audio decoder so it can feed the same speaker stream. +#[derive(Clone)] +pub struct PlaybackWriter { + tx: flume::Sender>, + state: Arc, +} + +impl PlaybackWriter { + /// Queue mono floating-point samples without blocking the caller. + pub fn write(&self, samples: &[f32]) -> VoiceResult<()> { + if samples.is_empty() { + return Ok(()); + } + if self.state.stopped.load(Ordering::Acquire) || self.state.drained.load(Ordering::Acquire) { + return Err("Native audio playback is closed".to_owned()); + } + self + .tx + .send(samples.to_vec()) + .map_err(|_| "Native audio playback is closed".to_owned()) + } +} + +/// Running mono playback stream shared by N-API playback and native WebRTC. +pub struct PlaybackStream { + device: Option>, + writer: Option, + state: Arc, +} + +impl PlaybackStream { + /// Open and start the default speaker at the requested logical sample rate. + pub fn start(sample_rate: u32) -> VoiceResult { + let sample_rate = audio_sample_rate(sample_rate)?; + let state = Arc::new(PlaybackState::new()); + let (tx, rx) = flume::unbounded::>(); + let callback_state = Arc::clone(&state); + let mut current = Vec::new(); + let mut cursor = 0; + let mut empty_callbacks = 0; + let mut builder = DeviceBuilder::playback().f32(); + builder + .sample_rate(sample_rate) + .playback_channels(AUDIO_CHANNELS) + .period_size_millis(PLAYBACK_PERIOD_MS) + .performance_profile(PerformanceProfile::LowLatency) + .backends(AUDIO_BACKENDS); + let mut device = builder + .with_callback(move |_device, output| { + fill_playback( + &rx, + &mut current, + &mut cursor, + output, + &callback_state, + &mut empty_callbacks, + ); + }) + .map_err(|error| format!("Failed to open the default speaker: {error}"))?; + device + .device_start() + .map_err(|error| format!("Failed to start speaker playback: {error}"))?; + + Ok(Self { + device: Some(device), + writer: Some(PlaybackWriter { tx, state: Arc::clone(&state) }), + state, + }) + } + + /// Clone the producer endpoint used by the remote-audio decoder. + pub fn writer(&self) -> VoiceResult { + self + .writer + .clone() + .ok_or_else(|| "Native audio playback is closed".to_owned()) + } + + /// Shared render-time state, cloned out so callers can await drain after + /// releasing the stream lock. + pub fn state(&self) -> Arc { + Arc::clone(&self.state) + } + + /// Close the producer side so the render callback can detect drain. + pub fn finish_input(&mut self) { + self.writer.take(); + } + + /// Scale audio at render time so gain changes affect already queued + /// samples. Rejects non-finite gains; negative gains clamp to silence. + pub fn set_gain(&self, gain: f32) -> VoiceResult<()> { + if !gain.is_finite() { + return Err("Audio playback gain must be finite".to_owned()); + } + self.state.set_gain(gain.max(0.0)); + Ok(()) + } + + /// Stop playback immediately and release the default speaker. + pub fn stop(&mut self) -> VoiceResult<()> { + self.writer.take(); + self.state.mark_stopped(); + let Some(mut device) = self.device.take() else { + return Ok(()); + }; + device + .device_stop() + .map_err(|error| format!("Failed to stop speaker playback: {error}")) + } +} + +impl Drop for PlaybackStream { + fn drop(&mut self) { + let _ = self.stop(); + } +} + +fn audio_sample_rate(sample_rate: u32) -> VoiceResult { + SampleRate::try_from(sample_rate) + .map_err(|error| format!("Unsupported audio sample rate {sample_rate}: {error}")) +} + +fn fill_playback( + rx: &flume::Receiver>, + current: &mut Vec, + cursor: &mut usize, + output: &mut [f32], + state: &PlaybackState, + empty_callbacks: &mut usize, +) { + output.fill(0.0); + if state.stopped.load(Ordering::Acquire) { + return; + } + + let gain = state.gain(); + let mut output_offset = 0; + while output_offset < output.len() { + if *cursor == current.len() { + match rx.try_recv() { + Ok(next) => { + *current = next; + *cursor = 0; + *empty_callbacks = 0; + }, + Err(TryRecvError::Empty) => { + *empty_callbacks = 0; + break; + }, + Err(TryRecvError::Disconnected) => { + *empty_callbacks += 1; + if *empty_callbacks >= PLAYBACK_DRAIN_CALLBACKS { + state.mark_drained(); + } + break; + }, + } + } + + let count = (current.len() - *cursor).min(output.len() - output_offset); + let source = ¤t[*cursor..*cursor + count]; + let destination = &mut output[output_offset..output_offset + count]; + if gain == 1.0 { + destination.copy_from_slice(source); + } else { + for (destination, source) in destination.iter_mut().zip(source) { + *destination = *source * gain; + } + } + *cursor += count; + output_offset += count; + } +} + +/// Running default-microphone capture delivering low-latency mono `f32` +/// chunks to its callback. Wraps the miniaudio device so N-API callers never +/// see maudio types. +pub struct CaptureStream { + device: Option>, +} + +impl CaptureStream { + /// Open the default microphone at the requested sample rate. `on_audio` + /// runs on the realtime audio thread — it must not block. + pub fn start(sample_rate: u32, mut on_audio: C) -> VoiceResult + where + C: FnMut(&[f32]) + Send + 'static, + { + let sample_rate = audio_sample_rate(sample_rate)?; + let mut builder = DeviceBuilder::capture().f32(); + builder + .sample_rate(sample_rate) + .capture_channels(AUDIO_CHANNELS) + .period_size_millis(CAPTURE_PERIOD_MS) + .performance_profile(PerformanceProfile::LowLatency) + .backends(AUDIO_BACKENDS); + let mut device = builder + .with_callback(move |_device, samples| { + if !samples.is_empty() { + on_audio(samples); + } + }) + .map_err(|error| format!("Failed to open the default microphone: {error}"))?; + device + .device_start() + .map_err(|error| format!("Failed to start microphone capture: {error}"))?; + Ok(Self { device: Some(device) }) + } + + /// Stop capture immediately and release the microphone. + pub fn stop(&mut self) -> VoiceResult<()> { + let Some(mut device) = self.device.take() else { + return Ok(()); + }; + device + .device_stop() + .map_err(|error| format!("Failed to stop microphone capture: {error}")) + } +} + +impl Drop for CaptureStream { + fn drop(&mut self) { + let _ = self.stop(); + } +} + +#[cfg(test)] +mod tests { + use std::{ + env, + mem::forget, + sync::atomic::AtomicUsize, + thread::sleep, + time::{Duration, Instant}, + }; + + use super::*; + + #[test] + fn playback_preserves_chunk_order_and_applies_render_gain() { + let state = PlaybackState::new(); + state.set_gain(0.5); + let (tx, rx) = flume::unbounded(); + tx.send(vec![1.0, -1.0]).expect("receiver is live"); + tx.send(vec![0.5, -0.5]).expect("receiver is live"); + drop(tx); + let mut current = Vec::new(); + let mut cursor = 0; + let mut empty_callbacks = 0; + let mut output = [9.0; 5]; + + fill_playback(&rx, &mut current, &mut cursor, &mut output, &state, &mut empty_callbacks); + + assert_eq!(output, [0.5, -0.5, 0.25, -0.25, 0.0]); + assert!(!state.drained.load(Ordering::Acquire)); + let mut silence = [1.0; 2]; + while empty_callbacks < PLAYBACK_DRAIN_CALLBACKS { + silence.fill(1.0); + fill_playback(&rx, &mut current, &mut cursor, &mut silence, &state, &mut empty_callbacks); + assert_eq!(silence, [0.0, 0.0]); + assert_eq!( + state.drained.load(Ordering::Acquire), + empty_callbacks >= PLAYBACK_DRAIN_CALLBACKS + ); + } + } + + #[test] + fn opt_in_default_capture_receives_frames() { + if env::var_os("OMP_NATIVE_AUDIO_CAPTURE_TEST").is_none() { + return; + } + + let callbacks = Arc::new(AtomicUsize::new(0)); + let callback_count = Arc::clone(&callbacks); + let mut stream = CaptureStream::start(16_000, move |_samples| { + callback_count.fetch_add(1, Ordering::Relaxed); + }) + .expect("default capture device starts"); + + let deadline = Instant::now() + Duration::from_secs(5); + while callbacks.load(Ordering::Relaxed) == 0 && Instant::now() < deadline { + sleep(Duration::from_millis(20)); + } + if callbacks.load(Ordering::Relaxed) == 0 { + forget(stream); + panic!("capture device started but delivered no frames within five seconds"); + } + stream.stop().expect("capture device stops"); + } +} diff --git a/crates/pi-voice/src/lib.rs b/crates/pi-voice/src/lib.rs new file mode 100644 index 000000000..1366b786e --- /dev/null +++ b/crates/pi-voice/src/lib.rs @@ -0,0 +1,26 @@ +//! Native voice engine: microphone capture, speaker playback, and the WebRTC +//! live-conversation peer. +//! +//! napi-free by design. `pi-natives` wraps these types in thin `#[napi]` +//! adapters, so the webrtc/opus/miniaudio dependency graph compiles once into +//! this rlib and rebuilds only when voice code changes — never when the +//! N-API surface elsewhere in the addon does. +//! +//! # Architecture +//! ```text +//! JS (packages/natives) -> #[napi] adapters (pi-natives audio.rs / live.rs) +//! -> pi_voice::audio (miniaudio capture/playback engine) +//! -> pi_voice::live (WebRTC peer + Opus media, feeds audio playback) +//! ``` +//! +//! Async entry points ([`live::LivePeerCore::create_offer`] and friends) run +//! on the caller's ambient tokio runtime — napi-rs's `tokio_rt` inside the +//! addon. Callback fields ([`live::LiveCallbacks`]) are invoked from tokio +//! worker threads and must not block. + +pub mod audio; +pub mod live; + +/// Engine-level result: a human-readable failure message the N-API layer maps +/// to a JS error verbatim. +pub type VoiceResult = std::result::Result; diff --git a/crates/pi-voice/src/live.rs b/crates/pi-voice/src/live.rs new file mode 100644 index 000000000..3e2da3a96 --- /dev/null +++ b/crates/pi-voice/src/live.rs @@ -0,0 +1,722 @@ +//! Native WebRTC media transport for Codex live conversations. +//! +//! The TypeScript host owns authenticated signaling and the sideband protocol; +//! this module owns the realtime WebRTC peer, Opus media, and speaker +//! playback. The N-API class in pi-natives is a thin adapter over +//! [`LivePeerCore`]. + +use std::{ + sync::{ + Arc, Weak, + atomic::{AtomicBool, AtomicUsize, Ordering}, + }, + time::Duration, +}; + +use bytes::Bytes; +use opus::{Application, Channels, Decoder, Encoder}; +use parking_lot::Mutex; +use tokio::{sync::watch, task::JoinHandle}; +use webrtc::{ + api::{ + APIBuilder, + interceptor_registry::register_default_interceptors, + media_engine::{MIME_TYPE_OPUS, MediaEngine}, + }, + data_channel::{RTCDataChannel, data_channel_message::DataChannelMessage}, + interceptor::registry::Registry, + media::Sample, + peer_connection::{ + RTCPeerConnection, configuration::RTCConfiguration, + peer_connection_state::RTCPeerConnectionState, + sdp::session_description::RTCSessionDescription, + }, + rtp_transceiver::{ + rtp_codec::{RTCRtpCodecCapability, RTCRtpCodecParameters, RTPCodecType}, + rtp_sender::RTCRtpSender, + }, + track::{ + track_local::{TrackLocal, track_local_static_sample::TrackLocalStaticSample}, + track_remote::TrackRemote, + }, +}; + +use crate::{ + VoiceResult, + audio::{PlaybackStream, PlaybackWriter}, +}; + +const DATA_CHANNEL_LABEL: &str = "oai-events"; +const INPUT_SAMPLE_RATE: u32 = 16_000; +const INPUT_FRAME_SAMPLES: usize = 320; +const INPUT_FRAME_DURATION: Duration = Duration::from_millis(20); +const MAX_ENCODED_OPUS_BYTES: usize = 1_275; +const MAX_QUEUED_INPUT_SAMPLES: usize = 32_000; +const OUTPUT_SAMPLE_RATE: u32 = 48_000; +const MAX_DECODED_OPUS_SAMPLES: usize = 5_760; +const OUTPUT_LEVEL_SAMPLES: usize = 2_400; +const OUTPUT_FRAME_SAMPLES: usize = 960; +/// Default `wait_for_open` timeout, exposed so the N-API adapter can apply it +/// when TypeScript passes no override. +pub const DEFAULT_OPEN_TIMEOUT_MS: u32 = 20_000; +const DISCONNECT_GRACE: Duration = Duration::from_secs(2); +const CLOSE_TASK_TIMEOUT: Duration = Duration::from_secs(1); + +const OPUS_CAPABILITY: RTCRtpCodecCapability = RTCRtpCodecCapability { + mime_type: String::new(), + clock_rate: OUTPUT_SAMPLE_RATE, + channels: 2, + sdp_fmtp_line: String::new(), + rtcp_feedback: Vec::new(), +}; + +#[derive(Clone, Debug)] +enum PeerSignal { + Connecting, + Open, + Failed(String), + Closed, +} + +enum InputCommand { + Audio(Vec), + Muted(bool), + Close, +} + +/// Host callbacks for peer lifecycle and media events. Every callback is +/// invoked from tokio worker threads and must not block (the N-API adapter +/// forwards through non-blocking threadsafe functions). +pub struct LiveCallbacks { + /// One `oai-events` data-channel text payload. + pub event: Box, + /// RMS output level in `[0, 1]`, one report per level window. + pub level: Box, + /// Terminal transport failure; reported at most once per peer. + pub failure: Box, +} + +struct LiveResources { + peer: Arc, + data_channel: Arc, + input_tx: flume::Sender, + input_task: JoinHandle<()>, + rtcp_task: JoinHandle<()>, + playback: PlaybackStream, +} + +/// WebRTC live-conversation peer: accepts 16 kHz mono PCM input and renders +/// remote Opus audio to the default speaker. Owned as an `Arc` by the N-API +/// `LiveWebRtcPeer` wrapper. +pub struct LivePeerCore { + callbacks: LiveCallbacks, + resources: Mutex>, + signal_tx: watch::Sender, + started: AtomicBool, + closing: AtomicBool, + muted: AtomicBool, + failure_reported: AtomicBool, + queued_samples: AtomicUsize, +} + +impl LivePeerCore { + /// Create an idle peer with its host callbacks registered. + pub fn new(callbacks: LiveCallbacks) -> Self { + let (signal_tx, _) = watch::channel(PeerSignal::Connecting); + Self { + callbacks, + resources: Mutex::new(None), + signal_tx, + started: AtomicBool::new(false), + closing: AtomicBool::new(false), + muted: AtomicBool::new(false), + failure_reported: AtomicBool::new(false), + queued_samples: AtomicUsize::new(0), + } + } + + /// Start the native media peer and return its SDP offer. + /// + /// Fails when called twice, after close, or when the speaker, codec, + /// peer, track, or data channel cannot be set up. + pub async fn create_offer(self: &Arc) -> VoiceResult { + if self.started.swap(true, Ordering::AcqRel) { + return Err("Native live WebRTC peer has already started".to_owned()); + } + if self.closing.load(Ordering::Acquire) { + return Err("Native live WebRTC peer is closed".to_owned()); + } + + let playback = PlaybackStream::start(OUTPUT_SAMPLE_RATE)?; + let playback_tx = playback.writer()?; + let mut media_engine = MediaEngine::default(); + let capability = opus_capability(); + media_engine + .register_codec( + RTCRtpCodecParameters { + capability: capability.clone(), + payload_type: 111, + ..Default::default() + }, + RTPCodecType::Audio, + ) + .map_err(|error| format!("Failed to register the live Opus codec: {error}"))?; + let registry = register_default_interceptors(Registry::new(), &mut media_engine) + .map_err(|error| format!("Failed to configure live WebRTC interceptors: {error}"))?; + let api = APIBuilder::new() + .with_media_engine(media_engine) + .with_interceptor_registry(registry) + .build(); + let peer = Arc::new( + api.new_peer_connection(RTCConfiguration::default()) + .await + .map_err(|error| format!("Failed to create the live WebRTC peer: {error}"))?, + ); + + let track = Arc::new(TrackLocalStaticSample::new( + capability, + "audio".to_owned(), + "omp-live".to_owned(), + )); + let sender = match peer + .add_track(Arc::clone(&track) as Arc) + .await + { + Ok(sender) => sender, + Err(error) => { + let _ = peer.close().await; + return Err(format!("Failed to add the live audio track: {error}")); + }, + }; + + install_peer_callbacks(&peer, Arc::downgrade(self), playback_tx); + let data_channel = match peer.create_data_channel(DATA_CHANNEL_LABEL, None).await { + Ok(channel) => channel, + Err(error) => { + let _ = peer.close().await; + return Err(format!("Failed to create the live data channel: {error}")); + }, + }; + install_data_channel_callbacks(&data_channel, Arc::downgrade(self)); + + let offer = match peer.create_offer(None).await { + Ok(offer) => offer, + Err(error) => { + let _ = peer.close().await; + return Err(format!("Failed to create the live SDP offer: {error}")); + }, + }; + if let Err(error) = peer.set_local_description(offer.clone()).await { + let _ = peer.close().await; + return Err(format!("Failed to install the live SDP offer: {error}")); + } + let mut resources_slot = self.resources.lock(); + if self.closing.load(Ordering::Acquire) { + drop(resources_slot); + let _ = peer.close().await; + return Err("Native live WebRTC peer was closed while starting".to_owned()); + } + + let (input_tx, input_rx) = flume::unbounded(); + let input_task = tokio::spawn(run_input_audio(track, input_rx, Arc::downgrade(self))); + let rtcp_task = tokio::spawn(drain_rtcp(sender)); + let resources = + LiveResources { peer, data_channel, input_tx, input_task, rtcp_task, playback }; + *resources_slot = Some(resources); + Ok(offer.sdp) + } + + /// Apply the remote SDP answer returned by Codex signaling. + pub async fn accept_answer(&self, sdp: String) -> VoiceResult<()> { + let peer = self + .resources + .lock() + .as_ref() + .map(|resources| Arc::clone(&resources.peer)) + .ok_or_else(|| "Native live WebRTC peer has not started".to_owned())?; + let answer = RTCSessionDescription::answer(sdp) + .map_err(|error| format!("Codex returned an invalid live SDP answer: {error}"))?; + peer + .set_remote_description(answer) + .await + .map_err(|error| format!("Failed to install the live SDP answer: {error}")) + } + + /// Wait until the `oai-events` data channel is open, failing on peer + /// failure, close, or timeout. + pub async fn wait_for_open(&self, timeout_ms: u32) -> VoiceResult<()> { + let mut signal_rx = self.signal_tx.subscribe(); + let wait = async { + loop { + let signal = signal_rx.borrow().clone(); + match signal { + PeerSignal::Open => return Ok(()), + PeerSignal::Failed(message) => return Err(message), + PeerSignal::Closed => { + return Err("Native live WebRTC peer closed before opening".to_owned()); + }, + PeerSignal::Connecting => {}, + } + signal_rx + .changed() + .await + .map_err(|_| "Native live WebRTC peer stopped before opening".to_owned())?; + } + }; + tokio::time::timeout(Duration::from_millis(u64::from(timeout_ms)), wait) + .await + .map_err(|_| "Timed out waiting for the live data channel to open".to_owned())? + } + + /// Queue 16 kHz mono PCM for Opus transmission. Silently drops audio while + /// muted or when the bounded input queue is full. + pub fn push_audio(&self, samples: &[f32]) -> VoiceResult<()> { + if samples.is_empty() || self.muted.load(Ordering::Acquire) { + return Ok(()); + } + let input_tx = self + .resources + .lock() + .as_ref() + .map(|resources| resources.input_tx.clone()) + .ok_or_else(|| "Native live WebRTC peer has not started".to_owned())?; + let sample_count = samples.len().min(MAX_QUEUED_INPUT_SAMPLES); + let retained = &samples[samples.len() - sample_count..]; + let queued = self + .queued_samples + .fetch_add(sample_count, Ordering::AcqRel); + if queued.saturating_add(sample_count) > MAX_QUEUED_INPUT_SAMPLES { + self + .queued_samples + .fetch_sub(sample_count, Ordering::AcqRel); + return Ok(()); + } + if input_tx + .send(InputCommand::Audio(retained.to_vec())) + .is_err() + { + self + .queued_samples + .fetch_sub(sample_count, Ordering::AcqRel); + return Err("Native live audio input is closed".to_owned()); + } + Ok(()) + } + + /// Enable or disable microphone transmission, discarding partial muted + /// frames. + pub fn set_muted(&self, muted: bool) -> VoiceResult<()> { + self.muted.store(muted, Ordering::Release); + let input_tx = self + .resources + .lock() + .as_ref() + .map(|resources| resources.input_tx.clone()); + if let Some(input_tx) = input_tx { + input_tx + .send(InputCommand::Muted(muted)) + .map_err(|_| "Native live audio input is closed".to_owned())?; + } + Ok(()) + } + + /// Whether close has begun; lets the adapter's `Drop` skip spawning a + /// redundant close task. + pub fn is_closing(&self) -> bool { + self.closing.load(Ordering::Acquire) + } + + fn report_event(&self, payload: String) { + (self.callbacks.event)(payload); + } + + fn report_level(&self, level: f64) { + (self.callbacks.level)(level.clamp(0.0, 1.0)); + } + + fn mark_open(&self) { + if !self.closing.load(Ordering::Acquire) { + self.signal_tx.send_replace(PeerSignal::Open); + } + } + + fn report_failure(&self, message: String) { + if self.closing.load(Ordering::Acquire) || self.failure_reported.swap(true, Ordering::AcqRel) + { + return; + } + self + .signal_tx + .send_replace(PeerSignal::Failed(message.clone())); + (self.callbacks.failure)(message); + } + + /// Close media, the data channel, the peer connection, and speaker + /// playback. Concurrent calls wait for the first closer to finish. + pub async fn close(&self) { + if self.closing.swap(true, Ordering::AcqRel) { + let mut signal_rx = self.signal_tx.subscribe(); + while !matches!(*signal_rx.borrow(), PeerSignal::Closed) { + if signal_rx.changed().await.is_err() { + break; + } + } + return; + } + + let resources = self.resources.lock().take(); + if let Some(mut resources) = resources { + let _ = resources.input_tx.send(InputCommand::Close); + let _ = resources.peer.close().await; + let _ = resources.playback.stop(); + let _ = tokio::time::timeout(CLOSE_TASK_TIMEOUT, resources.input_task).await; + resources.rtcp_task.abort(); + let _ = resources.rtcp_task.await; + drop(resources.data_channel); + } + self.queued_samples.store(0, Ordering::Release); + self.signal_tx.send_replace(PeerSignal::Closed); + } +} + +fn opus_capability() -> RTCRtpCodecCapability { + RTCRtpCodecCapability { + mime_type: MIME_TYPE_OPUS.to_owned(), + clock_rate: OPUS_CAPABILITY.clock_rate, + channels: OPUS_CAPABILITY.channels, + sdp_fmtp_line: "minptime=10;useinbandfec=1".to_owned(), + rtcp_feedback: Vec::new(), + } +} + +fn install_peer_callbacks( + peer: &Arc, + core: Weak, + playback_tx: PlaybackWriter, +) { + let output_sender = Arc::new(Mutex::new(Some(playback_tx))); + let output_sender_for_track = Arc::clone(&output_sender); + let core_for_track = core.clone(); + peer.on_track(Box::new(move |track, _receiver, _transceiver| { + let output_sender = output_sender_for_track.lock().take(); + let core = core_for_track.clone(); + Box::pin(async move { + if track.kind() != RTPCodecType::Audio { + return; + } + let Some(output_sender) = output_sender else { + if let Some(core) = core.upgrade() { + core.report_failure( + "Codex live returned more than one remote audio track".to_owned(), + ); + } + return; + }; + tokio::spawn(receive_output_audio(track, output_sender, core)); + }) + })); + + let peer_for_state = Arc::downgrade(peer); + peer.on_peer_connection_state_change(Box::new(move |state| { + let core = core.clone(); + let peer = peer_for_state.clone(); + Box::pin(async move { + let Some(core) = core.upgrade() else { + return; + }; + match state { + RTCPeerConnectionState::Failed => { + core.report_failure("Live WebRTC peer connection failed".to_owned()); + }, + RTCPeerConnectionState::Closed if !core.closing.load(Ordering::Acquire) => { + core.report_failure("Live WebRTC peer connection closed unexpectedly".to_owned()); + }, + RTCPeerConnectionState::Disconnected => { + tokio::time::sleep(DISCONNECT_GRACE).await; + if peer.upgrade().is_some_and(|peer| { + peer.connection_state() == RTCPeerConnectionState::Disconnected + }) { + core.report_failure("Live WebRTC peer connection disconnected".to_owned()); + } + }, + _ => {}, + } + }) + })); +} + +fn install_data_channel_callbacks(data_channel: &Arc, core: Weak) { + let core_for_open = core.clone(); + data_channel.on_open(Box::new(move || { + Box::pin(async move { + if let Some(core) = core_for_open.upgrade() { + core.mark_open(); + } + }) + })); + + let core_for_message = core.clone(); + data_channel.on_message(Box::new(move |message: DataChannelMessage| { + let core = core_for_message.clone(); + Box::pin(async move { + if !message.is_string { + return; + } + if let (Some(core), Ok(payload)) = + (core.upgrade(), String::from_utf8(message.data.to_vec())) + { + core.report_event(payload); + } + }) + })); + + let core_for_close = core.clone(); + data_channel.on_close(Box::new(move || { + let core = core_for_close.clone(); + Box::pin(async move { + if let Some(core) = core.upgrade() { + core.report_failure("Live data channel closed unexpectedly".to_owned()); + } + }) + })); + + data_channel.on_error(Box::new(move |error| { + let core = core.clone(); + Box::pin(async move { + if let Some(core) = core.upgrade() { + core.report_failure(format!("Live data channel failed: {error}")); + } + }) + })); +} + +async fn run_input_audio( + track: Arc, + input_rx: flume::Receiver, + core: Weak, +) { + let mut encoder = match Encoder::new(INPUT_SAMPLE_RATE, Channels::Mono, Application::Voip) { + Ok(encoder) => encoder, + Err(error) => { + if let Some(core) = core.upgrade() { + core.report_failure(format!("Failed to initialize the live Opus encoder: {error}")); + } + return; + }, + }; + if let Err(error) = encoder.set_inband_fec(true) { + if let Some(core) = core.upgrade() { + core.report_failure(format!("Failed to configure the live Opus encoder: {error}")); + } + return; + } + + let mut muted = false; + let mut pending = Vec::with_capacity(INPUT_FRAME_SAMPLES * 2); + let mut encoded = [0u8; MAX_ENCODED_OPUS_BYTES]; + let mut ticker = tokio::time::interval(INPUT_FRAME_DURATION); + ticker.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Burst); + ticker.tick().await; + loop { + tokio::select! { + biased; + command = input_rx.recv_async() => { + let Ok(command) = command else { + break; + }; + match command { + InputCommand::Audio(samples) => { + if let Some(core) = core.upgrade() { + core.queued_samples.fetch_sub(samples.len(), Ordering::AcqRel); + } + if muted { + continue; + } + if samples.len() >= MAX_QUEUED_INPUT_SAMPLES { + pending.clear(); + pending.extend_from_slice(&samples[samples.len() - MAX_QUEUED_INPUT_SAMPLES..]); + continue; + } + let overflow = pending + .len() + .saturating_add(samples.len()) + .saturating_sub(MAX_QUEUED_INPUT_SAMPLES); + if overflow > 0 { + pending.drain(..overflow); + } + pending.extend_from_slice(&samples); + }, + InputCommand::Muted(next_muted) => { + muted = next_muted; + pending.clear(); + }, + InputCommand::Close => break, + } + }, + _ = ticker.tick() => { + let mut frame = [0.0f32; INPUT_FRAME_SAMPLES]; + if !muted { + let consumed = pending.len().min(INPUT_FRAME_SAMPLES); + frame[..consumed].copy_from_slice(&pending[..consumed]); + if consumed > 0 { + pending.copy_within(consumed.., 0); + pending.truncate(pending.len() - consumed); + } + } + let encoded_len = match encoder.encode_float(&frame, &mut encoded) { + Ok(encoded_len) => encoded_len, + Err(error) => { + if let Some(core) = core.upgrade() { + core.report_failure(format!("Failed to encode live microphone audio: {error}")); + } + return; + }, + }; + let sample = Sample { + data: Bytes::copy_from_slice(&encoded[..encoded_len]), + duration: INPUT_FRAME_DURATION, + ..Default::default() + }; + if let Err(error) = track.write_sample(&sample).await { + if let Some(core) = core.upgrade() { + core.report_failure(format!("Failed to send live microphone audio: {error}")); + } + return; + } + }, + } + } +} + +async fn drain_rtcp(sender: Arc) { + while sender.read_rtcp().await.is_ok() {} +} + +async fn receive_output_audio( + track: Arc, + playback_tx: PlaybackWriter, + core: Weak, +) { + if !track + .codec() + .capability + .mime_type + .eq_ignore_ascii_case(MIME_TYPE_OPUS) + { + if let Some(core) = core.upgrade() { + core.report_failure(format!( + "Codex live negotiated unsupported audio codec {}", + track.codec().capability.mime_type + )); + } + return; + } + let mut decoder = match Decoder::new(OUTPUT_SAMPLE_RATE, Channels::Mono) { + Ok(decoder) => decoder, + Err(error) => { + if let Some(core) = core.upgrade() { + core.report_failure(format!("Failed to initialize the live Opus decoder: {error}")); + } + return; + }, + }; + let mut decoded = vec![0.0f32; MAX_DECODED_OPUS_SAMPLES].into_boxed_slice(); + let mut expected_sequence: Option = None; + let mut level = OutputLevel::default(); + + loop { + let packet = match track.read_rtp().await { + Ok((packet, _attributes)) => packet, + Err(error) => { + if let Some(core) = core.upgrade() + && !core.closing.load(Ordering::Acquire) + { + core.report_failure(format!("Live remote audio track failed: {error}")); + } + return; + }, + }; + let sequence = packet.header.sequence_number; + if let Some(expected) = expected_sequence { + let gap = sequence.wrapping_sub(expected); + if gap >= u16::MAX / 2 { + continue; + } + if gap > 0 { + for _ in 1..gap.min(5) { + if let Ok(samples) = + decoder.decode_float(&[], &mut decoded[..OUTPUT_FRAME_SAMPLES], false) + { + if !write_output(&playback_tx, &decoded[..samples], &core) { + return; + } + level.observe(&decoded[..samples], &core); + } + } + if let Ok(samples) = decoder.decode_float(&packet.payload, &mut decoded, true) { + if !write_output(&playback_tx, &decoded[..samples], &core) { + return; + } + level.observe(&decoded[..samples], &core); + } + } + } + expected_sequence = Some(sequence.wrapping_add(1)); + match decoder.decode_float(&packet.payload, &mut decoded, false) { + Ok(samples) => { + if !write_output(&playback_tx, &decoded[..samples], &core) { + return; + } + level.observe(&decoded[..samples], &core); + }, + Err(error) => { + if let Some(core) = core.upgrade() { + core.report_failure(format!("Failed to decode live speaker audio: {error}")); + } + return; + }, + } + } +} + +fn write_output(playback_tx: &PlaybackWriter, samples: &[f32], core: &Weak) -> bool { + match playback_tx.write(samples) { + Ok(()) => true, + Err(error) => { + if let Some(core) = core.upgrade() + && !core.closing.load(Ordering::Acquire) + { + core.report_failure(format!("Live speaker playback failed: {error}")); + } + false + }, + } +} + +#[derive(Default)] +struct OutputLevel { + sum_squares: f64, + samples: usize, +} + +impl OutputLevel { + fn observe(&mut self, decoded: &[f32], core: &Weak) { + let mut offset = 0; + while offset < decoded.len() { + let take = (OUTPUT_LEVEL_SAMPLES - self.samples).min(decoded.len() - offset); + for &sample in &decoded[offset..offset + take] { + let sample = f64::from(sample); + self.sum_squares = sample.mul_add(sample, self.sum_squares); + } + self.samples += take; + offset += take; + if self.samples == OUTPUT_LEVEL_SAMPLES { + if let Some(core) = core.upgrade() { + core.report_level((self.sum_squares / self.samples as f64).sqrt()); + } + self.sum_squares = 0.0; + self.samples = 0; + } + } + } +} diff --git a/docs/natives-build-release-debugging.md b/docs/natives-build-release-debugging.md index b2886e8fa..432cf9656 100644 --- a/docs/natives-build-release-debugging.md +++ b/docs/natives-build-release-debugging.md @@ -136,15 +136,17 @@ build --tls_certificate=infra/bazel-remote/ca.crt ### Split Rust validation and addon production -`.github/workflows/ci.yml` separates `rust_validate` from `native_addons`. Both run on `omp-kata` pods for pushes and `ubuntu-22.04` for pull requests, but TypeScript jobs depend only on `native_addons`. +`.github/workflows/ci.yml` separates `rust_validate` from `native_addons`; TypeScript jobs depend only on `native_addons`. -`rust_validate` uses `.github/actions/native-inputs` to inspect the complete pull-request file list. TypeScript-only pull requests skip every Rust step; native-affecting changes and all non-PR events run: +**Pull requests never build or validate Rust.** Native-affecting PRs are rare enough that they don't warrant a PR-side bazel build: `rust_validate` is skipped entirely (`if: github.event_name != 'pull_request'`), and `native_addons` fetches the latest release's Linux x64 addon pair from the `@oh-my-pi/pi-natives-linux-x64` npm leaf, smoke-loads both, and uploads them as the `native-addons` workflow artifact. The loader skips its version sentinel for workspace loads, so release-versioned addons load fine under a newer checkout. A PR whose TypeScript tests depend on changed native behavior fails visibly (and CI emits a notice on any native-touching PR); the Rust side is validated post-merge on main and again at release. + +On non-PR events both jobs run on `omp-kata` pods against the cluster remote cache. `rust_validate` runs: ```bash bazelisk --bazelrc="$rc" test //crates/... # full Rust suite # clippy scope mirrors `cargo clippy --workspace` (libraries only), split by # lint policy via a query kind filter: -bazelisk query "kind('rust_library|rust_shared_library', //crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-walker/...)" \ +bazelisk query "kind('rust_library|rust_shared_library', //crates/pi-ast/... + //crates/pi-iso/... + //crates/pi-natives/... + //crates/pi-shell/... + //crates/pi-voice/... + //crates/pi-walker/...)" \ | xargs bazelisk --bazelrc="$rc" build --config=clippy-strict -- bazelisk query "kind('rust_library|rust_shared_library', //crates/... - (…strict set…) - //crates/vendor/brush-core/... - //crates/vendor/brush-builtins/...)" \ | xargs bazelisk --bazelrc="$rc" build --config=clippy -- @@ -153,19 +155,14 @@ bazelisk --bazelrc="$rc" build --config=rustfmt //crates/... - `--config=clippy` = rules_rust clippy aspect + `-Dwarnings`; `--config=clippy-strict` layers the generated `bazel/clippy.bazelrc` for crates with `[lints] workspace = true`. - `--config=rustfmt` = rustfmt aspect against the workspace `rustfmt.toml`. -- `rust_validate` never saves a hosted disk-cache archive: `native_addons` may concurrently own the same immutable key, while the main-branch warmer publishes a combined validation/addon archive. -`native_addons` is the artifact producer for every downstream TypeScript and release job: - -- Pull requests first restore the exact `native-addons-v1-linux-x64-baseline+modern-opt-` cache entry published by trusted main builds. Both addons are loaded before use; a miss or failed smoke check falls back to building the Linux x64 pair. -- Main and other non-PR runs build `//:natives-linux-all`, smoke the x64 pair before publishing its exact addon cache, and upload every `.node` output as the `native-addons` workflow artifact. -- Downstream jobs use `.github/actions/native-artifacts` to download that workflow artifact and install the requested target set without invoking Bazel. +`native_addons` on main builds `//:natives-linux-all` and uploads every `.node` output as the `native-addons` workflow artifact. Downstream jobs use `.github/actions/native-artifacts` to download that artifact and install the requested target set without invoking Bazel. No toolchain setup steps are required for native jobs: bazelisk is on the GitHub images and baked into the kata runner image; Bazel fetches Rust/zig/LLVM/xwin hermetically. ### Hosted cache warmer -`.github/workflows/bazel-cache-warm.yml` runs the full hosted validation and Linux x64 addon invocation set on `ubuntu-22.04`. Main-branch input changes restore the previous config-compatible generation, rebuild incrementally, and publish one combined exact-key disk-cache archive visible to pull requests. +`.github/workflows/bazel-cache-warm.yml` seeds the GitHub-hosted caches that have no other reliable producer: the `release-darwin-*` bazel disk caches (built on the same macOS images as the `release_binary` darwin matrix, so a release's bazel build is the version-bump delta instead of a ~40-min cold graph) and the shared bun store entry PR jobs restore but never save. It triggers only on pushes that can change those archives (crate/bazel/lock inputs, `bun.lock`, `.github/**`). ### `bazel-cache` action (`.github/actions/bazel-cache`) @@ -176,15 +173,15 @@ Single source of truth for cache wiring, emitted as a bazelrc fragment (its `rc` | omp-kata pod | `--config=ci --config=cache-rw --remote_cache=grpcs://bazel-remote.bazel-cache.svc.cluster.local:9092 --tls_certificate=infra/bazel-remote/ca.crt --remote_header='authorization=Basic '` | | GitHub-hosted | `--config=ci --disk_cache=~/.cache/omp-bazel-disk --repository_cache=~/.cache/omp-bazel-repo` | -Hosted disk caches use `bazel-disk-v3-----`. The config hash covers Cargo/Bazel/toolchain settings; the source hash covers `crates/**` and root `BUILD.bazel`. An exact miss restores the newest config-compatible generation and permits one refreshed exact-key save. The remote endpoint resolves only inside the cluster. +Hosted disk caches use `bazel-disk-v3-----`. The config hash covers Cargo/Bazel/toolchain settings; the source hash covers `crates/**` and root `BUILD.bazel`. Restores fall back from the exact key to the config-scoped prefix, then to a bare `--` prefix — the bare fallback is what keeps release version bumps (which rewrite `Cargo.toml`/`Cargo.lock` and thus the config hash) from rebuilding cold; bazel's content-addressed action keys make a stale archive a partial hit, never a wrong output. An inexact restore permits one refreshed exact-key save, and restored entries untouched for 14 days are pruned so archives don't grow without bound. The remote endpoint resolves only inside the cluster. ### Native artifact actions `.github/actions/bazel-natives` is the direct builder: `bazel-cache` → `OMP_BAZEL_RC= bun scripts/bazel-natives.ts --dest `, followed by a disk-cache save after a hosted miss. `.github/actions/native-artifacts` is the no-build consumer: download `native-addons` → run the same driver with `--source`. -### `release_binary` +### Release binary builds and publishing -Linux and Windows release matrices install addons from the `native_addons` workflow artifact. Darwin artifacts cannot be cross-built on Linux, so each macOS matrix builds only its own architecture through `bazel-natives` with scope `release-`, then `bun run ci:release:build-binaries` embeds and compiles the executable. +Binary builds are build-only and run in parallel with the test fan-out. `release_binary` (Linux + Windows matrices) needs only `native_addons`, whose workflow artifact supplies their addons. `release_binary_darwin` needs only `release_metadata` and starts the moment a release run is detected: darwin artifacts cannot be cross-built on Linux, so each macOS leg builds its own architecture through `bazel-natives` with scope `release-` (seeded near HEAD by the warm workflow — normally just the version-bump delta), then `bun run ci:release:build-binaries` embeds and compiles the executable. Publishing is held behind `release_gate` (the aggregate of every validation job): `release_native_leaves` downloads all built addons and publishes the five `@oh-my-pi/pi-natives-` leaves from one linux runner, and the GitHub release / verify / core npm chain runs beside it. ## Debugging playbook @@ -228,7 +225,7 @@ bazelisk build --nobuild //:natives-win32-x64-baseline ### Cache behavior - **omp-kata:** read-write gRPC to the in-cluster bazel-remote (`grpcs://bazel-remote.bazel-cache.svc.cluster.local:9092`, TLS via the committed `infra/bazel-remote/ca.crt`, htpasswd user `ci`). `--remote_local_fallback` plus retries make an outage degrade to local execution rather than fail the build. -- **GitHub-hosted:** no cluster access. The v3 `actions/cache` disk key separates config and source generations; `.github/workflows/bazel-cache-warm.yml` publishes the combined default-branch archive from the same `ubuntu-22.04` image as pull-request consumers. The smaller final-addon cache is independent and is trusted only after both addons load successfully. +- **GitHub-hosted:** no cluster access; only the darwin release/warm jobs build with bazel here. The v3 `actions/cache` disk key separates config and source generations with prefix + bare fallbacks (see the `bazel-cache` action section above); `.github/workflows/bazel-cache-warm.yml` publishes the `release-darwin-*` archives from the same macOS images as the release consumers. - **msvc repos:** the ~2 GiB LLVM download is sha256-pinned and repository-cache backed; the ~1 GiB xwin CRT/SDK splat is fetched from the Microsoft CDN inside the repo rule and is **not** repo-cache backed — a cold output base re-downloads it. Microsoft advances the VS channel payload over time, so remote-cache hit rates for win32 actions degrade gracefully after an MS bump (same property the previous cross toolchain had). Win32 link actions also don't share cache entries across host OSes (linux vs mac clang binaries). - Server-side operations (deploy, TLS/auth, egress, poisoning boundary): `infra/docs/04-arc-and-caching.md` §5. diff --git a/docs/tools/edit.md b/docs/tools/edit.md index 7e02ca064..3339cca28 100644 --- a/docs/tools/edit.md +++ b/docs/tools/edit.md @@ -8,7 +8,7 @@ - Key collaborators: - `packages/coding-agent/src/utils/edit-mode.ts` — selects active edit mode - `packages/hashline/src/grammar.lark` — canonical constrained-decoding grammar - - `packages/hashline/src/format.ts` — sigils and header constants (`[`, `]`, `#`, `+`, `SWAP`, `DEL`, `INS`) + - `packages/hashline/src/format.ts` — sigils and header constants (`[`, `]`, `#`, `+`, `SWAP`, `CUT`, `INS`, `PASTE`) - `packages/hashline/src/input.ts` — parses `[PATH#TAG]` sections - `packages/hashline/src/tokenizer.ts` / `packages/hashline/src/parser.ts` — tokenizes and parses ops - `packages/hashline/src/apply.ts` — applies parsed edits to file text @@ -30,18 +30,21 @@ Patch language inside `input`: - **Operations**: - `SWAP N.=M:` — replace original lines N.=M with the body rows below. - `SWAP.BLK N:` — replace the whole tree-sitter block beginning on line N (its header line through its closing line) with the body rows. The line span is resolved at apply time from the file's parse tree; point N at the line that opens the construct. The resolved span is exactly the node that begins on line N — a leading decorator, attribute, or doc-comment is a separate node and is not included; point N at the first decorator line (Python wraps `@dec` + `def` as one block) or fall back to `SWAP N.=M:` to take a leading line-comment that parses as its own node (e.g. Rust `///`). On success the result echoes the matched span (`SWAP.BLK N → resolved lines A-B`). Errors (and steers to `SWAP N.=M:`) when the language is unsupported, line N is blank or a closing delimiter, no node begins there, or the resolved block has a syntax error. - - `DEL N.=M` — delete original lines N.=M. No body. - - `DEL.BLK N` — delete the whole tree-sitter block beginning on line N (resolved like `SWAP.BLK N`, with the same decorator/comment caveat). No body. On success the result echoes the matched span (`DEL.BLK N → resolved lines A-B`). Same resolution failure modes and `DEL N.=M` fallback. + - `CUT N.=M` — delete original lines N.=M and capture them in the clipboard. No body. A standalone cut is valid; the latest cut replaces the clipboard contents. + - `CUT.BLK N` — delete and capture the whole tree-sitter block beginning on line N (resolved like `SWAP.BLK N`, with the same decorator/comment caveat). No body. On success the result echoes the matched span (`CUT.BLK N → resolved lines A-B`). Same resolution failure modes and `CUT N.=M` fallback. - `INS.PRE N:` — insert body rows immediately before line N. - `INS.POST N:` — insert body rows immediately after line N. - `INS.BLK.POST N:` — insert body rows after the last line of the tree-sitter block beginning on line N. Point N at the line that opens the construct, never its closing delimiter / last visible line; if you can see the last line already, use plain `INS.POST M:`. An anchor that can't resolve to a block is lowered to plain `INS.POST N:` with a warning instead of failing the patch. - - **Markdown sections**: tree-sitter-md nests a heading and its body (including deeper subsections) in one `section` node, so all three block ops anchored on a `#`/`##`/`###` heading line resolve the whole section — heading through every nested deeper heading, up to the next same-or-higher heading. `DEL.BLK` drops the section, `SWAP.BLK` rewrites it, `INS.BLK.POST` lands after it. A heading with no body resolves to a single line and falls back to the plain op like any other single-line block. + - **Markdown sections**: tree-sitter-md nests a heading and its body (including deeper subsections) in one `section` node, so all four block ops anchored on a `#`/`##`/`###` heading line resolve the whole section — heading through every nested deeper heading, up to the next same-or-higher heading. `CUT.BLK` drops and captures the section, `SWAP.BLK` rewrites it, and `INS.BLK.POST` / `PASTE.BLK.POST` land after it. A heading with no body resolves to a single line and is rejected with guidance to use the corresponding plain line op. - `INS.HEAD:` — insert body rows at the start of the file. - `INS.TAIL:` — insert body rows at the end of the file. + - `PASTE.PRE N` / `PASTE.POST N` / `PASTE.HEAD` / `PASTE.TAIL` — insert the clipboard at that position. No body. An empty clipboard is an error. + - `PASTE.BLK.POST N` — insert the clipboard after the resolved block's last line. An unresolvable anchor lowers to `PASTE.POST N` with a warning, matching `INS.BLK.POST`. + - **Clipboard**: operations execute top-to-bottom across all patch sections. The latest `CUT` wins; `PASTE` does not consume the clipboard and may be repeated. The coding agent persists the register across edit calls in the same session, enabling cross-file moves. Keep each path under one header when clipboard operations would otherwise be interleaved around another file's section. - **Body rows**: - Only body-bearing headers end in `:`. - Every body row is `+TEXT`; `+` alone adds a blank line. - - `DEL` never has body rows. + - `CUT` and `PASTE` never have body rows. - There is no repeat row kind. To keep a line, leave it out of every range; split edits into multiple hunks when needed. - `-` rows are invalid. Literal Markdown bullets or text beginning with `-` / `+` must be written as `+- item` / `++ item`. @@ -52,7 +55,7 @@ Anchors come from `read`/`grep` output. `read` emits a `[PATH#TAG]` header from The canonical grammar is strict, but the hand parser accepts a few non-dangerous variants: - `SWAP N:` — accepted as `SWAP N.=N:`. -- `DEL N` — accepted as single-line delete. +- `CUT N` — accepted as a single-line cut/delete. - Missing trailing colon on `SWAP` or `INS` — accepted. - `SWAP N-M:`, `SWAP N…M:`, `SWAP N M:`, and legacy `SWAP N..M:` — accepted as `SWAP N.=M:`. - Bare body rows with no `+` prefix are auto-prepended with `+` and a `BARE_BODY_AUTO_PIPED_WARNING` is appended. @@ -61,16 +64,17 @@ The canonical grammar is strict, but the hand parser accepts a few non-dangerous - Some malformed bracketed headers are recovered after stripping apply-patch path noise such as `Update File:` / `Add File:` and extra `***`, but the recovered header still needs a valid four-hex tag for the patcher to apply it. - `*** Update File:` / `*** Add File:` / `*** Delete File:` / `*** Move to:` apply_patch sentinels inside the diff body throw an `apply_patch sentinel … is not valid in hashline` error. - `@@`-bracketed hunk headers are rejected with guidance to write a verb header. -- Bare `N` and bare `N M` / `N.=M` headers are rejected with guidance to write `SWAP` or `DEL`. -- `DEL N.=M:` and any body rows under `DEL` / `DEL.BLK` are rejected. -- Empty `INS` / `SWAP.BLK` hunks are rejected; an empty `SWAP N.=M:` (no body rows) is treated as `DEL N.=M`. +- Bare `N` and bare `N M` / `N.=M` headers are rejected with guidance to write `SWAP` or `CUT`. +- A trailing colon on `CUT N.=M:` / `CUT.BLK N:` is tolerated and ignored, but body rows under `CUT`, `CUT.BLK`, or any `PASTE` form are rejected. +- Bare `PASTE` is rejected because the insertion position is required. +- Empty `INS` / `SWAP.BLK` hunks are rejected; an empty `SWAP N.=M:` deletes the range, though `CUT N.=M` is the canonical deletion form. - `-` body rows are rejected with `MINUS_ROW_REJECTED` unless the hunk is unambiguously a Markdown bullet list (see Tolerated input shapes). -- `SWAP.BLK N:` / `DEL.BLK N` / `INS.BLK.POST N:` require a wired tree-sitter resolver; `SWAP.BLK` and `INS.BLK.POST` additionally need at least one `+TEXT` body row, while `DEL.BLK` takes none. An unresolvable block (unsupported language, blank/closing-delimiter line, no node beginning on N, or a syntax error in the resolved block) rejects a `SWAP.BLK` / `DEL.BLK` on the apply/final-preview path (the streaming preview silently drops it instead). `INS.BLK.POST N:` is never rejected this way — it is lowered to plain `INS.POST N:` with a warning: a closing-delimiter-anchor warning when line N is a pure closer (inserting after that end is exactly what the plain form does), a generic unresolved-anchor warning otherwise. +- `SWAP.BLK N:` / `CUT.BLK N` / `INS.BLK.POST N:` / `PASTE.BLK.POST N` consult the wired tree-sitter resolver. `SWAP.BLK` and `INS.BLK.POST` need at least one `+TEXT` body row; `CUT.BLK` and `PASTE.BLK.POST` take none. A null resolution rejects `SWAP.BLK` / `CUT.BLK` on the apply or final-preview path (the streaming preview silently drops it), while `INS.BLK.POST` / `PASTE.BLK.POST` lower to the corresponding plain `POST` form with a warning. A single-line resolution rejects every block form with guidance to use its plain line equivalent. ## Outputs - Single-shot tool result; hashline mode does not use the staged preview/apply devices (`/xdev/resolve`, `/xdev/reject`). - `content` contains one text block per call. For a successful single-file edit it is the post-edit `[path#TAG]` section header (a fresh snapshot tag for the written content), followed by a compact diff preview from `packages/hashline/src/diff-preview.ts` when one is emitted. -- When the patch used `SWAP.BLK`/`DEL.BLK`/`INS.BLK.POST` ops (and the apply matched the tagged content), one `SWAP.BLK N → resolved lines A-B (K lines)` line per block op (single-line spans render `resolved line A (1 line)`; INS.BLK.POST appends `; body lands after line B`) is inserted between the `[PATH#TAG]` header and the diff preview, so the caller can confirm tree-sitter resolved the construct it intended. +- When the patch used `SWAP.BLK` / `CUT.BLK` / `INS.BLK.POST` / `PASTE.BLK.POST` ops (and the apply matched the tagged content), one ` N → resolved lines A-B (K lines)` line per block op is inserted between the `[PATH#TAG]` header and the diff preview. Single-line spans render `resolved line A (1 line)`; `INS.BLK.POST` appends `body lands after line B`, and `PASTE.BLK.POST` appends `clipboard lands after line B`. - Parse, apply, or recovery warnings are appended as: ```text @@ -126,11 +130,11 @@ INS.PRE 5: +console.log(X + Y); ``` -Delete lines 4.=5 entirely: +Delete lines 4.=5 entirely and leave them in the clipboard: ```text [a.ts#0A3B] -DEL 4.=5 +CUT 4.=5 ``` Insert at start and end of file: @@ -143,20 +147,19 @@ INS.TAIL: +// trailer ``` -Multi-file: +Move line 4 from `src/a.ts` to after line 20 in `src/b.ts`: ```text [src/a.ts#0A3B] -SWAP 4.=4: -+const enabled = true; +CUT 4 [src/b.ts#1F7C] -DEL 20 +PASTE.POST 20 ``` ## Limits & Caps - File snapshot tags are exactly four uppercase-hex chars — content-derived hashes (`computeFileHash()`) recorded in the per-session snapshot store. - The visible mismatch report shows 2 lines of context on each side (`MISMATCH_CONTEXT`) in `packages/hashline/src/messages.ts`. - Stale-anchor recovery uses `fuzzFactor: 0` in `packages/hashline/src/recovery.ts`. -- `HL_FILE_PREFIX` is `[`, `HL_FILE_SUFFIX` is `]`, `HL_PAYLOAD_REPLACE` is `+`, `HL_RANGE_SEP` is `.=`, `HL_FILE_HASH_SEP` is `#`, and hunk keyword constants are `SWAP` / `DEL` / `INS` (`packages/hashline/src/format.ts`). +- `HL_FILE_PREFIX` is `[`, `HL_FILE_SUFFIX` is `]`, `HL_PAYLOAD_REPLACE` is `+`, `HL_RANGE_SEP` is `.=`, `HL_FILE_HASH_SEP` is `#`, and line/clipboard hunk keyword constants are `SWAP` / `CUT` / `INS` / `PASTE` (`packages/hashline/src/format.ts`). ## Errors - Missing section header: @@ -164,28 +167,29 @@ DEL 20 - Missing tag for any section: - `Missing hashline snapshot tag for ; use \`[#tag]\` from your latest read/search output. To create a new file, use the write tool.` - Stray payload line: - - `line N: payload line has no preceding hunk header. Use \`SWAP N.=M:\`, \`DEL N.=M\`, or \`INS.PRE|POST|HEAD|TAIL:\` above the body. Got "...".` + - `line N: payload line has no preceding hunk header. Use \`SWAP N.=M:\`, \`CUT N.=M\`, or \`INS.PRE|POST|HEAD|TAIL:\` above the body. Got "...".` - Minus row (unless auto-piped as an unambiguous Markdown bullet — see Tolerated input shapes): - ``line N: `-` rows are not valid; the range already names the lines being changed. For Markdown bullets or other literal `-` lines, prefix the literal row with `+`: `+- item`.`` - Empty body-bearing hunk: - `line N: \`INS\` needs at least one \`+TEXT\` body row.` - - `line N: \`SWAP.BLK N:\` needs at least one \`+TEXT\` body row. To delete a block, use \`DEL.BLK N\`.` -- Unresolvable block anchor — `SWAP.BLK` / `DEL.BLK` only (apply / final-preview path; the streaming preview silently drops the op instead): - - `line N: \`SWAP.BLK X:\` could not resolve a syntactic block beginning on line X (unsupported language, blank/closer line, or parse error). Use \`SWAP X.=M:\` with explicit lines.` — followed by a blank line and numbered `*`-marked context rows around line X (same shape as the mismatch preview). `DEL.BLK X` produces the same message with a `DEL X.=M` fallback. - - `INS.BLK.POST X:` never reaches this error — an unresolvable anchor is lowered to plain `INS.POST X:` with a warning (see Tolerated input shapes). -- Delete with body: - - `line N: \`DEL N.=M\` does not take body rows. Remove the body, or use \`SWAP N.=M:\`.` - - `line N: \`DEL.BLK N\` does not take body rows. Remove the body, or use \`SWAP.BLK N:\`.` + - `line N: \`SWAP.BLK N:\` needs at least one \`+TEXT\` body row. To delete a block, use \`CUT.BLK N\`.` +- Unresolvable block anchor — `SWAP.BLK` / `CUT.BLK` only (apply / final-preview path; the streaming preview silently drops the op instead): + - `line N: \`SWAP.BLK X:\` could not resolve a syntactic block beginning on line X (unsupported language, blank/closer line, or parse error). Use \`SWAP X.=M:\` with explicit lines.` — followed by numbered context and, when available, a nearby block suggestion. `CUT.BLK X` produces the corresponding message with a `CUT X.=M` fallback. + - `INS.BLK.POST X:` and `PASTE.BLK.POST X` never reach this error when no block resolves — they lower to plain `INS.POST X:` / `PASTE.POST X` with a warning. +- Clipboard operation errors: + - `line N: \`CUT N.=M\` captures + deletes lines and takes no body rows. To replace lines with new content, use \`SWAP N.=M:\`.` + - `line N: \`PASTE\` inserts the clipboard content and takes no \`+\` body rows. To insert literal text, use \`INS\`.` + - `line N: \`PASTE\` found nothing in the clipboard. Ops run top-to-bottom across the whole patch (sections included): put \`CUT N.=M\` or \`CUT.BLK N\` above the \`PASTE\`.` - Range out of order: - `line N: range A.=B ends before it starts.` - Overlapping hunks on the same anchor: - `line N: anchor line X is already targeted by another hunk on line Y. Issue ONE hunk per range; payload is only the final desired content, never a before/after pair.` - apply_patch / unified-diff contamination: - - `line N: apply_patch sentinel "*** …" is not valid in hashline. File sections start with \`[path#HASH]\` (no \`Update File:\` / \`Add File:\` keyword). Use \`SWAP N.=M:\`, \`DEL N.=M\`, or \`INS.PRE|POST|HEAD|TAIL:\` ops.` - - `line N: unified-diff hunk header (\`@@ -N,M +N,M @@\`) is not valid in hashline. Use \`SWAP N.=M:\`, \`DEL N.=M\`, or \`INS.PRE|POST|HEAD|TAIL:\` ops.` + - `line N: apply_patch sentinel "*** …" is not valid in hashline. File sections start with \`[path#HASH]\` (no \`Update File:\` / \`Add File:\` keyword). Use \`SWAP N.=M:\`, \`CUT N.=M\`, or \`INS.PRE|POST|HEAD|TAIL:\` ops.` + - `line N: unified-diff hunk header (\`@@ -N,M +N,M @@\`) is not valid in hashline. Use \`SWAP N.=M:\`, \`CUT N.=M\`, or \`INS.PRE|POST|HEAD|TAIL:\` ops.` - `line N: \`@@\`-bracketed hunk header "@@ …" is not valid in hashline. Drop the \`@@ ... @@\` brackets and write a verb header such as \`SWAP N.=M:\`.` - - `line N: hunk headers need a verb. Use \`SWAP N.=N:\` to replace, or \`DEL N\` to delete.` - - `line N: bare range hunk header "N M" is not valid. Hunk headers need a verb: write \`SWAP ${bareRange[1]}.=${bareRange[2]}:\` or \`DEL ${bareRange[1]}.=${bareRange[2]}\`.` + - `line N: hunk headers need a verb. Use \`SWAP N.=N:\` to replace, or \`CUT N\` to delete.` + - `line N: bare range hunk header "N M" is not valid. Hunk headers need a verb: write \`SWAP ${bareRange[1]}.=${bareRange[2]}:\` or \`CUT ${bareRange[1]}.=${bareRange[2]}\`.` - Out-of-range anchor: - `Line N does not exist (file has M lines)` - Stale snapshot tag: the `Patcher` first attempts snapshot-based recovery. When recovery cannot prove a valid result it throws `MismatchError`, which distinguishes recognized-but-drifted hashes from never-recorded hashes. The error includes the current file hash plus context around each anchor. diff --git a/infra/docs/04-arc-and-caching.md b/infra/docs/04-arc-and-caching.md index 59ec20097..6c20776e0 100644 --- a/infra/docs/04-arc-and-caching.md +++ b/infra/docs/04-arc-and-caching.md @@ -161,7 +161,7 @@ githubConfigUrl: "https://github.com//" githubConfigSecret: arc-github runnerScaleSetName: omp-kata minRunners: 0 -maxRunners: 4 +maxRunners: 8 # none: each job runs inside the runner container, which itself lives in a Kata microVM containerMode: type: "" @@ -201,12 +201,15 @@ template: mountPath: /opt/bazel-repo-cache subPath: bazel-repo-cache resources: + # Burstable on purpose: requests bin-pack 8 runners onto the + # 32-vCPU / 125 GiB host; limits are each Kata VM's hotplug + # ceiling. Keep sum(memory limits) under host RAM. requests: - cpu: "8" - memory: "24Gi" + cpu: "3" + memory: "10Gi" limits: cpu: "8" - memory: "24Gi" + memory: "14Gi" volumes: - name: runner-cache persistentVolumeClaim: @@ -220,10 +223,14 @@ Field by field: - **`githubConfigSecret: arc-github`** - the auth secret from [step 1](#1-github-app-and-the-arc-github-secret). - **`runnerScaleSetName: omp-kata`** - the runner label. This is the string that goes in a workflow's `runs-on:`. -- **`minRunners: 0` / `maxRunners: 4`** - **scale-to-zero**. With no queued jobs - there are zero runner microVMs. Each admitted runner gets an honest 8-vCPU, - 24-GiB request and limit; excess jobs queue instead of ten 16-vCPU guests - fighting over the reference host's 32 physical CPUs. +- **`minRunners: 0` / `maxRunners: 8`** - **scale-to-zero**. With no queued jobs + there are zero runner microVMs. Runner pods are **burstable**: a small + request (3 vCPU / 10 GiB) bin-packs eight runners onto the reference host, + while the limit (8 vCPU / 14 GiB) is each Kata VM's hotplug ceiling, so a + lone heavy job still gets 8 vCPUs. Keep the sum of memory *limits* under + host RAM — host OOM under Kata kills VMs unpredictably. (The original + guaranteed sizing, 4 x 8 vCPU / 24 GiB requests=limits, reserved the whole + host and queued every >4-job workflow fan-out for minutes.) - **`containerMode.type: ""`** - **none**. The default chart offers `dind` (Docker-in-Docker sidecar) or `kubernetes` mode for job-container isolation; both are unnecessary here because the *whole runner pod* is already isolated in @@ -255,14 +262,17 @@ Field by field: mounts to the `arc-runners/runner-cache` PVC. `ReadWriteOnce` is enough on this single-node k3s host; use a RWX-capable storage class before spreading runners across nodes. -- **`resources`** - requests `8` CPU / `24Gi`, limits `8` CPU / `24Gi`. Kata reads - these and sizes the guest accordingly: the VM now boots at the same - guaranteed floor (`default_vcpus: 2`, `default_memory: 4096`) and only - hotplugs beyond that toward the limits, with `default_maxvcpus: 0` allowing up - to all host CPUs. Effectively the **requests are the boot-time VM size** and - the **limits are the hotplug ceiling**. See [02-kata-runtime.md](02-kata-runtime.md) - for the runtime knobs and [`infra/tune-kata-runtime.sh`](../tune-kata-runtime.sh) - for the SSH-driven patch helper. +- **`resources`** - requests `3` CPU / `10Gi`, limits `8` CPU / `14Gi` + (burstable; see the `maxRunners` bullet above). Kata sizes the guest from + these: every VM boots at the fixed floor from the runtime config + (`default_vcpus: 2`, `default_memory: 4096` — deliberately at or below the + pod request so boot stays cheap) and hotplugs beyond it toward the pod + **limits**, with `default_maxvcpus: 0` allowing up to all host CPUs. + Effectively the **boot shape is a fixed floor**, the **requests are the + scheduler's bin-packing unit**, and the **limits are the hotplug ceiling**. + See [02-kata-runtime.md](02-kata-runtime.md) for the runtime knobs and + [`infra/tune-kata-runtime.sh`](../tune-kata-runtime.sh) for the SSH-driven + patch helper. --- diff --git a/infra/docs/README.md b/infra/docs/README.md index 4c4e95ef4..132fd99d5 100644 --- a/infra/docs/README.md +++ b/infra/docs/README.md @@ -47,7 +47,7 @@ flowchart LR Key properties baked into this design: - **One job = one VM.** Runner pods are ephemeral and JIT-registered; there is no VM templating or pooling, so a job never inherits state from a previous job. -- **Scale-to-zero.** `minRunners: 0` / `maxRunners: 4` — when no jobs are queued, zero runner pods (and zero microVMs) exist. +- **Scale-to-zero.** `minRunners: 0` / `maxRunners: 8` — when no jobs are queued, zero runner pods (and zero microVMs) exist. Runners are burstable (3-vCPU/10-GiB requests, 8-vCPU/14-GiB limits) so a full workflow fan-out runs 8-wide while a lone heavy job still bursts to 8 vCPUs. - **Host-kernel isolation.** Jobs see the microVM's guest kernel, not the host kernel, so a kernel exploit in a job does not reach the host. - **No external registry.** The runner image is built on the host and imported straight into k3s' containerd. - **Shared, in-cluster cache.** bazel-remote stores Bazel action results and CAS blobs (Rust compilation, tests, native `.node` addons) behind TLS + htpasswd auth, with a public read-mostly NodePort for GitHub-hosted runners; the runner-cache PVC stores Bun/Cargo downloads. Cache traffic stays on the host. diff --git a/infra/reload-runner.sh b/infra/reload-runner.sh index 58be241ab..87f7704ea 100755 --- a/infra/reload-runner.sh +++ b/infra/reload-runner.sh @@ -32,9 +32,20 @@ # CONTAINERD_SOCKET_REMOTE remote containerd socket [/run/k3s/containerd/containerd.sock] # NERDCTL_VERSION nerdctl release to bootstrap on demand [2.1.6] # BUILDKIT_VERSION BuildKit release to bootstrap on demand [0.25.1] -# RUNNER_MAX_RUNNERS maximum concurrent Kata runner pods [4] -# RUNNER_CPU requested and limited CPU cores per runner [8] -# RUNNER_MEMORY requested and limited memory per runner [24Gi] +# RUNNER_MAX_RUNNERS maximum concurrent Kata runner pods [8] +# RUNNER_CPU_REQUEST requested CPU cores per runner [3] +# RUNNER_CPU_LIMIT CPU-core limit per runner (Kata hotplug ceiling) [8] +# RUNNER_MEMORY_REQUEST requested memory per runner [10Gi] +# RUNNER_MEMORY_LIMIT memory limit per runner (Kata hotplug ceiling) [14Gi] +# +# Runner pods are deliberately BURSTABLE, not guaranteed: requests size the +# scheduler's bin-packing (8 x 3 cpu / 10Gi fits the 32-vCPU / 125 GiB host +# with headroom), while limits set each Kata VM's hotplug ceiling so a lone +# native build still gets 8 vCPUs. requests==limits previously capped the +# host at 4 runners and queued every >4-job workflow fan-out for minutes. +# Worst-case sum of memory limits (8 x 14Gi = 112Gi) stays under the host's +# 125 GiB because host OOM under Kata kills VMs unpredictably — keep it that +# way when retuning. set -euo pipefail : "${CI_HOST:?set CI_HOST to the ssh target of your CI host, e.g. CI_HOST=my-ci-host}" @@ -48,9 +59,11 @@ BUILD_BACKEND="${BUILD_BACKEND:-auto}" CONTAINERD_SOCKET_REMOTE="${CONTAINERD_SOCKET_REMOTE:-/run/k3s/containerd/containerd.sock}" NERDCTL_VERSION="${NERDCTL_VERSION:-2.1.6}" BUILDKIT_VERSION="${BUILDKIT_VERSION:-0.25.1}" -RUNNER_MAX_RUNNERS="${RUNNER_MAX_RUNNERS:-4}" -RUNNER_CPU="${RUNNER_CPU:-8}" -RUNNER_MEMORY="${RUNNER_MEMORY:-24Gi}" +RUNNER_MAX_RUNNERS="${RUNNER_MAX_RUNNERS:-8}" +RUNNER_CPU_REQUEST="${RUNNER_CPU_REQUEST:-3}" +RUNNER_CPU_LIMIT="${RUNNER_CPU_LIMIT:-8}" +RUNNER_MEMORY_REQUEST="${RUNNER_MEMORY_REQUEST:-10Gi}" +RUNNER_MEMORY_LIMIT="${RUNNER_MEMORY_LIMIT:-14Gi}" arg="${1:-$(date +%Y-%m-%d-%H%M%S)}" case "$arg" in *:*) IMAGE="$arg";; *) IMAGE="omp-kata-runner:$arg";; esac @@ -70,12 +83,12 @@ scp -q "$here/runner.Dockerfile" "${CI_HOST}:${REMOTE_CTX}/Dockerfile" ssh "$CI_HOST" bash -s -- \ "$IMAGE" "$REMOTE_CTX" "$ARC_VALUES" "$ARC_RELEASE" "$ARC_NAMESPACE" "$ARC_CHART_VERSION" \ "$KUBECONFIG_REMOTE" "$BUILD_BACKEND" "$CONTAINERD_SOCKET_REMOTE" "$NERDCTL_VERSION" "$BUILDKIT_VERSION" \ - "$RUNNER_MAX_RUNNERS" "$RUNNER_CPU" "$RUNNER_MEMORY" <<'REMOTE' + "$RUNNER_MAX_RUNNERS" "$RUNNER_CPU_REQUEST" "$RUNNER_CPU_LIMIT" "$RUNNER_MEMORY_REQUEST" "$RUNNER_MEMORY_LIMIT" <<'REMOTE' set -euo pipefail IMAGE="$1"; REMOTE_CTX="$2"; ARC_VALUES="$3"; ARC_RELEASE="$4"; ARC_NAMESPACE="$5"; ARC_CHART_VERSION="$6" export KUBECONFIG="$7" BUILD_BACKEND="$8"; CONTAINERD_SOCKET="$9"; NERDCTL_VERSION="${10}"; BUILDKIT_VERSION="${11}" -RUNNER_MAX_RUNNERS="${12}"; RUNNER_CPU="${13}"; RUNNER_MEMORY="${14}" +RUNNER_MAX_RUNNERS="${12}"; RUNNER_CPU_REQUEST="${13}"; RUNNER_CPU_LIMIT="${14}"; RUNNER_MEMORY_REQUEST="${15}"; RUNNER_MEMORY_LIMIT="${16}" cd "$REMOTE_CTX" TOOLS_DIR="$REMOTE_CTX/.containerd-build-tools" @@ -244,10 +257,10 @@ if ! grep -q 'name: bazel-remote-ci' "$ARC_VALUES"; then fi helm upgrade "$ARC_RELEASE" --namespace "$ARC_NAMESPACE" --version "$ARC_CHART_VERSION" \ -f "$ARC_VALUES" \ - --set-string "template.spec.containers[0].resources.requests.cpu=$RUNNER_CPU" \ - --set-string "template.spec.containers[0].resources.limits.cpu=$RUNNER_CPU" \ - --set-string "template.spec.containers[0].resources.requests.memory=$RUNNER_MEMORY" \ - --set-string "template.spec.containers[0].resources.limits.memory=$RUNNER_MEMORY" \ + --set-string "template.spec.containers[0].resources.requests.cpu=$RUNNER_CPU_REQUEST" \ + --set-string "template.spec.containers[0].resources.limits.cpu=$RUNNER_CPU_LIMIT" \ + --set-string "template.spec.containers[0].resources.requests.memory=$RUNNER_MEMORY_REQUEST" \ + --set-string "template.spec.containers[0].resources.limits.memory=$RUNNER_MEMORY_LIMIT" \ oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set >/dev/null echo "==> [5/5] verifying rollout" @@ -256,7 +269,7 @@ live="$(kubectl get autoscalingrunnerset "$ARC_RELEASE" -n "$ARC_NAMESPACE" \ live_max="$(kubectl get autoscalingrunnerset "$ARC_RELEASE" -n "$ARC_NAMESPACE" -o jsonpath='{.spec.maxRunners}')" live_resources="$(kubectl get autoscalingrunnerset "$ARC_RELEASE" -n "$ARC_NAMESPACE" \ -o jsonpath='{.spec.template.spec.containers[0].resources.requests.cpu}/{.spec.template.spec.containers[0].resources.limits.cpu} {.spec.template.spec.containers[0].resources.requests.memory}/{.spec.template.spec.containers[0].resources.limits.memory}')" -expected_resources="$RUNNER_CPU/$RUNNER_CPU $RUNNER_MEMORY/$RUNNER_MEMORY" +expected_resources="$RUNNER_CPU_REQUEST/$RUNNER_CPU_LIMIT $RUNNER_MEMORY_REQUEST/$RUNNER_MEMORY_LIMIT" echo "ARC runner image/resources: $live | max=$live_max | $live_resources" [ "$live" = "$IMAGE" ] || { echo "MISMATCH: expected image $IMAGE"; exit 1; } [ "$live_max" = "$RUNNER_MAX_RUNNERS" ] || { echo "MISMATCH: expected maxRunners $RUNNER_MAX_RUNNERS"; exit 1; } diff --git a/infra/tune-kata-runtime.sh b/infra/tune-kata-runtime.sh index 2766d7c24..9eda821e2 100755 --- a/infra/tune-kata-runtime.sh +++ b/infra/tune-kata-runtime.sh @@ -1,6 +1,11 @@ #!/usr/bin/env bash -# Patch the live Kata QEMU config to match the runner pod's guaranteed boot -# shape, raise guest and host open-file limits, and enlarge the virtiofsd worker pool. +# Patch the live Kata QEMU config: set the guest BOOT floor (default_vcpus / +# default_memory), raise guest and host open-file limits, and enlarge the +# virtiofsd worker pool. Runner pods are burstable (see reload-runner.sh): +# the boot floor stays deliberately at or below the pod's CPU/memory REQUEST +# so VMs boot small and fast, and Kata hotplugs each guest toward the pod +# LIMIT under load. Keep BOOT_VCPUS/BOOT_MEMORY_MIB <= the request when +# retuning either side. # The script runs over SSH, which keeps the desired values version-controlled. # It then smoke-tests a new kata-qemu pod. # diff --git a/package.json b/package.json index cea6799a3..b56e69151 100644 --- a/package.json +++ b/package.json @@ -26,18 +26,18 @@ "@huggingface/transformers": "^4.2.0", "@mozilla/readability": "^0.6.0", "@napi-rs/cli": "3.7.2", - "@oh-my-pi/hashline": "17.1.8", - "@oh-my-pi/omp-stats": "17.1.8", - "@oh-my-pi/pi-agent-core": "17.1.8", - "@oh-my-pi/pi-ai": "17.1.8", - "@oh-my-pi/pi-catalog": "17.1.8", - "@oh-my-pi/pi-coding-agent": "17.1.8", - "@oh-my-pi/pi-mnemopi": "17.1.8", - "@oh-my-pi/pi-natives": "17.1.8", - "@oh-my-pi/pi-tui": "17.1.8", - "@oh-my-pi/pi-utils": "17.1.8", - "@oh-my-pi/pi-wire": "17.1.8", - "@oh-my-pi/snapcompact": "17.1.8", + "@oh-my-pi/hashline": "17.2.0", + "@oh-my-pi/omp-stats": "17.2.0", + "@oh-my-pi/pi-agent-core": "17.2.0", + "@oh-my-pi/pi-ai": "17.2.0", + "@oh-my-pi/pi-catalog": "17.2.0", + "@oh-my-pi/pi-coding-agent": "17.2.0", + "@oh-my-pi/pi-mnemopi": "17.2.0", + "@oh-my-pi/pi-natives": "17.2.0", + "@oh-my-pi/pi-tui": "17.2.0", + "@oh-my-pi/pi-utils": "17.2.0", + "@oh-my-pi/pi-wire": "17.2.0", + "@oh-my-pi/snapcompact": "17.2.0", "@opentelemetry/api": "^1.9.1", "@opentelemetry/api-logs": "^0.220.0", "@opentelemetry/context-async-hooks": "^2.9.0", diff --git a/packages/agent/CHANGELOG.md b/packages/agent/CHANGELOG.md index e97272a65..cb2a34ddc 100644 --- a/packages/agent/CHANGELOG.md +++ b/packages/agent/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.2.0] - 2026-07-30 + ### Fixed - Provider-native compaction failures now surface their transport error instead of silently switching to generic summarization; streaming V2 still falls back to native V1 when available. diff --git a/packages/agent/package.json b/packages/agent/package.json index 629db42fb..ac3f064e7 100644 --- a/packages/agent/package.json +++ b/packages/agent/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-agent-core", - "version": "17.1.8", + "version": "17.2.0", "description": "General-purpose agent with transport abstraction, state management, and attachment support", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 90a84d279..40bf7274f 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.2.0] - 2026-07-30 + ### Added - Added first-class parentTurnId support for nested Codex requests, allowing stream options and metadata helpers to accept and safely propagate the initiating turn's ID. @@ -10,6 +12,7 @@ - Added interactive Exa API-key login through `/login exa`, opening the official API-key dashboard and saving pasted keys to the credential store ([#1798](https://github.com/can1357/oh-my-pi/issues/1798)). - Cursor's modern exec wire protocol is now handled end to end. `agent.proto` models the frames current Cursor CLI builds emit — the seven Pi tools (`ExecServerMessage` 45-51), hooks, subagents, allowlist prechecks, MCP state, smart-mode classification, canvas diagnostics, conversation search, agent-store conflicts and git diff — and every one of them gets a typed answer. The Pi frames run their local equivalents (`read`/`bash`/`edit`/`write`/`grep`/`glob`); the rest answer with the error, not-found or empty-but-valid variant that is actually true of this client. Frames this build cannot name at all now raise `ExecClientControlMessage.throw` with `unknown_exec_variant`, and recognised frames with no truthful answer (`git_diff_request`, whose `GetDiffResponse` has no error variant) raise `exec_variant_unsupported`, instead of a silent ack that leaves the server waiting. - `lsp` is advertised in the MCP tool catalog again. It was filtered out as a Cursor-native tool, but the native `diagnostics` frame covers one of roughly ten LSP actions, so the other nine were unreachable. +- Added `pinSessionOAuthAccount` support for backdating the sticky's last-use timestamp (`options.lastUsedAtMs`), so pins restored from persisted sessions keep the provider's warm-window semantics: resumes inside the prompt-cache TTL reuse the account, stale resumes still re-rank. ### Changed diff --git a/packages/ai/package.json b/packages/ai/package.json index e255f59bb..607412d37 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-ai", - "version": "17.1.8", + "version": "17.2.0", "description": "Unified LLM API with automatic model discovery and provider configuration", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/ai/src/auth-storage.ts b/packages/ai/src/auth-storage.ts index df74da8c2..492cbc804 100644 --- a/packages/ai/src/auth-storage.ts +++ b/packages/ai/src/auth-storage.ts @@ -1811,15 +1811,20 @@ export class AuthStorage { } } - /** Records which credential was used for a session (for rate-limit switching). */ + /** + * Records which credential was used for a session (for rate-limit switching). + * `lastUsedAtMs` backdates the sticky (session-file pin restores on resume); + * it defaults to now for live selections. + */ #recordSessionCredential( provider: string, sessionId: string | undefined, type: AuthCredential["type"], index: number, + lastUsedAtMs?: number, ): void { if (!sessionId) return; - const nowMs = Date.now(); + const nowMs = lastUsedAtMs ?? Date.now(); const sessionMap = this.#sessionLastCredential.get(provider) ?? new Map(); sessionMap.set(sessionId, { type, index, lastUsedAtMs: nowMs }); this.#sessionLastCredential.set(provider, sessionMap); @@ -5403,8 +5408,18 @@ export class AuthStorage { * The durable credential id keeps the pin stable across credential refreshes, * storage reordering, and process restarts. Normal auth retry and usage-limit * handling may still route around an unavailable account. + * + * `options.lastUsedAtMs` backdates the sticky's last-use timestamp so a pin + * restored from a persisted session keeps the provider's warm-window + * semantics: a resume inside the prompt-cache TTL reuses the account, a + * stale resume still re-ranks. */ - pinSessionOAuthAccount(provider: string, sessionId: string, credentialId: number): boolean { + pinSessionOAuthAccount( + provider: string, + sessionId: string, + credentialId: number, + options?: { lastUsedAtMs?: number }, + ): boolean { if (!sessionId || this.#runtimeOverrides.has(provider) || this.#configOverrides.has(provider)) { return false; } @@ -5412,7 +5427,7 @@ export class AuthStorage { const index = stored.findIndex(entry => entry.id === credentialId); const target = stored[index]; if (target?.credential.type !== "oauth") return false; - this.#recordSessionCredential(provider, sessionId, "oauth", index); + this.#recordSessionCredential(provider, sessionId, "oauth", index, options?.lastUsedAtMs); return true; } diff --git a/packages/ai/src/providers/openai-codex-responses.ts b/packages/ai/src/providers/openai-codex-responses.ts index 4239673fa..20751703c 100644 --- a/packages/ai/src/providers/openai-codex-responses.ts +++ b/packages/ai/src/providers/openai-codex-responses.ts @@ -252,7 +252,7 @@ const CODEX_WEBSOCKET_IDLE_TIMEOUT_MS = Number($env.PI_CODEX_WEBSOCKET_IDLE_TIME * SSE. Generous default so legitimately slow first-token providers still get * a chance on the WS transport before falling through. */ -const CODEX_WEBSOCKET_FIRST_EVENT_TIMEOUT_MS = Number($env.PI_CODEX_WEBSOCKET_FIRST_EVENT_TIMEOUT_MS || 60_000); +const CODEX_WEBSOCKET_FIRST_EVENT_TIMEOUT_MS = Number($env.PI_CODEX_WEBSOCKET_FIRST_EVENT_TIMEOUT_MS || 300_000); const CODEX_WEBSOCKET_RETRY_BUDGET = Number($env.PI_CODEX_WEBSOCKET_RETRY_BUDGET || CODEX_MAX_RETRIES); const CODEX_WEBSOCKET_RETRY_DELAY_MS = Number($env.PI_CODEX_WEBSOCKET_RETRY_DELAY_MS || CODEX_RETRY_DELAY_MS); const CODEX_WEBSOCKET_TRANSPORT_ERROR_PREFIX = "Codex websocket transport error"; diff --git a/packages/ai/src/utils/idle-iterator.ts b/packages/ai/src/utils/idle-iterator.ts index f89da41a2..6d743bbac 100644 --- a/packages/ai/src/utils/idle-iterator.ts +++ b/packages/ai/src/utils/idle-iterator.ts @@ -1,8 +1,8 @@ import { $env } from "@oh-my-pi/pi-utils"; import * as AIError from "../error"; -const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 120_000; -const DEFAULT_STREAM_FIRST_EVENT_TIMEOUT_MS = 100_000; +const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 300_000; +const DEFAULT_STREAM_FIRST_EVENT_TIMEOUT_MS = 300_000; /** Re-mint persistent race promises every N iterations (see hoisted-racer comment). */ const RACER_REMINT_INTERVAL = 1024; diff --git a/packages/ai/test/proxy.test.ts b/packages/ai/test/proxy.test.ts index 94aff51f6..30548b25f 100644 --- a/packages/ai/test/proxy.test.ts +++ b/packages/ai/test/proxy.test.ts @@ -61,7 +61,6 @@ async function waitForSocketClose(socket: net.Socket): Promise { socket.once("close", () => closed.resolve()); await closed.promise; } - const isProxyEnvKey = (k: string): boolean => k.startsWith("PI_PROXY") || k === "HTTP_PROXY" || diff --git a/packages/ai/test/stream-timeout-defaults.test.ts b/packages/ai/test/stream-timeout-defaults.test.ts index 3674e998b..dbc63944a 100644 --- a/packages/ai/test/stream-timeout-defaults.test.ts +++ b/packages/ai/test/stream-timeout-defaults.test.ts @@ -101,8 +101,8 @@ describe("getStreamFirstEventTimeoutMs(idleTimeoutMs, fallbackMs)", () => { expect(getStreamFirstEventTimeoutMs(undefined, 300_000)).toBeUndefined(); }); - it("falls back to the 100s global default when no fallback or env is provided", () => { - expect(getStreamFirstEventTimeoutMs()).toBe(100_000); + it("falls back to the 300s global default when no fallback or env is provided", () => { + expect(getStreamFirstEventTimeoutMs()).toBe(300_000); }); }); diff --git a/packages/catalog/CHANGELOG.md b/packages/catalog/CHANGELOG.md index 828694bdb..2627d6c20 100644 --- a/packages/catalog/CHANGELOG.md +++ b/packages/catalog/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.2.0] - 2026-07-30 + ### Added - Regenerated the Cursor agent protobufs (`discovery/cursor-gen/agent_pb.ts`) against the modern `agent.proto`, adding the message and enum families current Cursor CLI builds emit: Pi tool exec frames, hook queries and responses, subagents, allowlist prechecks, MCP state, smart-mode classification, canvas diagnostics, conversation search, agent-store conflicts and git diff. Purely additive — no existing exported symbol changed shape. diff --git a/packages/catalog/package.json b/packages/catalog/package.json index 599c8a1ad..81f953db4 100644 --- a/packages/catalog/package.json +++ b/packages/catalog/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-catalog", - "version": "17.1.8", + "version": "17.2.0", "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 8a62ea323..43ae44f2b 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,12 +2,19 @@ ## [Unreleased] +## [17.2.0] - 2026-07-30 + +### Breaking Changes + +- Removed the `DEL`, `DEL.BLK`, `COPY`, and `COPY.BLK` hashline edit operations. Use `CUT` / `CUT.BLK` for deletion; removed content remains available to `PASTE`. + ### Added - Added server-name autocomplete for `/mcp` commands (`enable`, `disable`, `test`, `remove`, `reconnect`, `reauth`, `unauth`) using configured and runtime-discovered MCP servers. - Added `--from-claude` and `--from-codex` session imports, also available from `/resume @claude` and `/resume @codex`. - Added an opt-in OMP-native software-security workflow (`security.enabled`, default off) with immutable scan plans, exact-account Codex subscription affinity, native task-worker review, canonical findings/coverage/SARIF publication, project-scoped history, explicit dispositions, producer-differential comparison, and the read-only `security://` resource namespace. Generic SARIF and official Codex Security bundles normalize into the same OMP-owned store. - Added explicit Codex Security cloud operations to the opt-in security workflow: list and start account-pinned cloud scans, inspect their progress, and import current findings into OMP's canonical store and `security://` namespace without changing the native scan engine or spoofing official runtime attribution. +- Added `CUT` and `PASTE` ops to the hashline edit tool for moving code without retyping it: `CUT N.=M` (and `.BLK` block forms) capture lines into a clipboard register, and `PASTE` operations insert them. The register flows across sections within a patch (cross-file moves) and persists across edit calls per session. - Added `--from-claude` and `--from-codex` session imports (including compaction state for Codex), also available from `/resume @claude` and `/resume @codex`. - Added interactive Exa API-key onboarding through `/login exa`, opening the official key dashboard and saving pasted keys for authenticated web search while preserving `EXA_API_KEY` and explicit-selection public MCP fallback behavior ([#1798](https://github.com/can1357/oh-my-pi/issues/1798)). - Added `ExtensionContext.getAsyncJobSnapshot()` so extensions can read the owning session's async-job state without relying on process-global job-manager identity @@ -26,6 +33,9 @@ ### Fixed +- Fixed Anthropic prompt-cache cold misses on session resume with multiple OAuth accounts: the account that served a session is now recorded in the session file (as a `credential_pin` sha-256 of the account + org/project scope, so exports carry no plaintext identity) and re-pinned on resume with the session's effective last-use time, so a fresh process no longer re-ranks accounts by usage headroom — which systematically routed away from the just-used account and cold-missed the entire account-scoped cache prefix. Sticky routing was previously stored only in the auth store's KV cache, which is in-memory when a remote auth broker is configured. +- Fixed Anthropic prompt-cache cold misses on session resume with multiple OAuth accounts: the account that served a session is now recorded in the session file (as a PII-free `credential_pin` hash) and re-pinned on resume, so a fresh process no longer re-ranks accounts by usage headroom — which systematically routed away from the just-used account and cold-missed the entire account-scoped cache prefix. Sticky routing was previously stored only in the auth store's KV cache, which is in-memory when a remote auth broker is configured. +- Fixed concurrent `createAgentSession` calls with the default agent id failing initialization with `Agent "Main" was replaced during session initialization` — each in-process embedder (e.g. the edit benchmark runner) can now pass a private registry via the newly exported `AgentRegistry`, keeping every top-level session's "Main" out of the process-global roster race. - Fixed task tool blocks duplicating their per-agent progress rows into terminal scrollback on every update: live task frames now pin the transcript live region so mid-run rows are never recorded as frozen snapshots, and a detached background task freezes its progress the moment any of its rows commit to scrollback instead of mutating committed history. - Fixed Codex reset fireworks comparing different quota tiers or plans, preventing false celebrations when usage reports switch between Spark and base weekly limits. - Fixed Cursor ranged-read results losing the full file byte size after applying the requested window. diff --git a/packages/coding-agent/package.json b/packages/coding-agent/package.json index 781e865f3..3ccfe230d 100644 --- a/packages/coding-agent/package.json +++ b/packages/coding-agent/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-coding-agent", - "version": "17.1.8", + "version": "17.2.0", "description": "Coding agent CLI with read, bash, edit, write tools and session management", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/coding-agent/src/edit/edit-clipboard.ts b/packages/coding-agent/src/edit/edit-clipboard.ts new file mode 100644 index 000000000..fcd969f8e --- /dev/null +++ b/packages/coding-agent/src/edit/edit-clipboard.ts @@ -0,0 +1,23 @@ +/** + * Session-bound edit clipboard register. + * + * `CUT`/`PASTE` hashline ops share one {@link Clipboard} per session so + * content captured by one edit call can be pasted by a later one (and across + * files within one call). The executor works on a fork per batch and commits + * it back only after every write lands — see `executeHashlineSingle`. + */ +import type { Clipboard } from "@oh-my-pi/hashline"; + +interface EditClipboardOwner { + editClipboard?: Clipboard; +} + +/** + * Look up (or lazily create) the clipboard register attached to a session. + * Storage lives on `session.editClipboard` so it ages out exactly with the + * session itself. + */ +export function getEditClipboard(session: EditClipboardOwner): Clipboard { + session.editClipboard ??= {}; + return session.editClipboard; +} diff --git a/packages/coding-agent/src/edit/hashline/diff.ts b/packages/coding-agent/src/edit/hashline/diff.ts index d38e493eb..6d52aafaa 100644 --- a/packages/coding-agent/src/edit/hashline/diff.ts +++ b/packages/coding-agent/src/edit/hashline/diff.ts @@ -13,6 +13,7 @@ import * as path from "node:path"; import { type ApplyResult, applyEdits, + type Clipboard, type Cursor, computeFileHash, type Edit, @@ -26,8 +27,10 @@ import { parsePatchStreaming, Recovery, resolveBlockEdits, + resolveClipboardEdits, type SnapshotStore, stripBom, + validateClipboardSequence, } from "@oh-my-pi/hashline"; import { resolveToCwd } from "../../tools/path-utils"; import { generateDiffString } from "../diff"; @@ -48,6 +51,14 @@ export interface HashlineDiffOptions { * authoring input; the final apply path still validates through Patcher. */ skipHashValidation?: boolean; + /** + * Clipboard register shared across the sections of one patch preview. + * `CUT` in an earlier section feeds `PASTE` in a later one, so the preview + * matches apply. Multi-section previews MUST thread one register through + * sections in patch order; omitted, each section gets a + * private register (same-file cut/paste still previews correctly). + */ + clipboard?: Clipboard; } async function readSectionText(absolutePath: string, sectionPath: string): Promise { @@ -144,6 +155,7 @@ function hasAnchorScopedEdit(edits: readonly Edit[]): boolean { return edits.some(edit => { if (edit.kind === "delete") return true; if (edit.kind === "block") return true; + if (edit.kind === "cut") return true; return edit.cursor.kind === "before_anchor" || edit.cursor.kind === "after_anchor"; }); } @@ -204,14 +216,24 @@ function applyPreviewEdits(args: { const liveMatches = expected !== undefined && computeFileHash(normalized) === expected; const edits = parsePreviewEdits(section, options.streaming); const resolved = resolvePreviewEdits({ section, absolutePath, normalized, snapshots, expected, liveMatches, edits }); - if (options.skipHashValidation || expected === undefined || liveMatches) return applyEdits(normalized, resolved); - if (!hasAnchorScopedEdit(resolved)) return applyEdits(normalized, resolved); + const clipboard = options.clipboard ?? {}; + // Mirror the Patcher: surface clipboard sequencing mistakes with their + // targeted message before the recovery path below swallows them. Streaming + // previews stay lenient — a mid-typed op transiently violating sequencing + // must not flash an error frame. + if (!options.streaming) validateClipboardSequence(resolved, clipboard); + const applyOptions = { clipboard, ...(options.streaming ? { onEmptyPaste: "drop" as const } : {}) }; + if (options.skipHashValidation || expected === undefined || liveMatches) { + return applyEdits(normalized, resolved, applyOptions); + } + if (!hasAnchorScopedEdit(resolved)) return applyEdits(normalized, resolved, applyOptions); const recovered = new Recovery(snapshots).tryRecover({ path: absolutePath, currentText: normalized, fileHash: expected, edits: resolved, + clipboard, }); if (recovered) return recovered; throw createMismatchError(section, absolutePath, normalized, snapshots, expected); @@ -250,18 +272,36 @@ function insertCursorLine(cursor: Cursor, fileLineCount: number): number { function buildStreamingSectionDiff( section: PatchSection, normalized: string, + clipboard: Clipboard, ): { diff: string; firstChangedLine: number | undefined } | { error: string } { const { edits, fileOp } = parsePatchStreaming(section.diff); - const resolved = resolveBlockEdits(edits, normalized, section.path, nativeBlockResolver, { onUnresolved: "drop" }); + const blockResolved = resolveBlockEdits(edits, normalized, section.path, nativeBlockResolver, { + onUnresolved: "drop", + }); + const fileLines = normalized.split("\n"); + // Expand clipboard ops so a `PASTE` previews the moved rows. Resolve into + // a scratch register and commit it back only on success: a mid-typed + // capture (out-of-range while the range digits are still streaming, + // transient sequencing violations) throws AFTER earlier captures may have + // landed, and leaking those into the shared register would let a later + // section preview a paste that never happened. On failure, fall back to + // filtering the clipboard edits out of this section's frame. + const scratch: Clipboard = { ...clipboard }; + let resolved: readonly Edit[]; + try { + resolved = resolveClipboardEdits(blockResolved, fileLines, scratch, { onEmptyPaste: "drop" }); + if (scratch.lines === undefined) delete clipboard.lines; + else clipboard.lines = scratch.lines; + } catch { + resolved = blockResolved.filter(edit => edit.kind !== "cut" && edit.kind !== "paste"); + } if (resolved.length === 0) { - // A whole-file op (REM / MV) carries no line edits: the change is the - // delete/move itself, conveyed by the result header, so emit an empty - // diff rather than a misleading "No changes" error. + // A whole-file op (REM / MV) carries no line edits; the result header + // conveys the change, so emit an empty diff. if (fileOp) return { diff: "", firstChangedLine: undefined }; return { error: `No changes would be made to ${section.path}.` }; } - const fileLines = normalized.split("\n"); const rows: string[] = []; let firstChangedLine: number | undefined; @@ -323,11 +363,10 @@ export async function computeHashlineSectionDiff( // diff: feed the in-flight ops through the natural-order builder so the // streamed cursor stays pinned to the bottom. The args-complete pass // (`streaming` unset) falls through to the real Myers diff below. - if (options.streaming) return buildStreamingSectionDiff(section, normalized); + if (options.streaming) return buildStreamingSectionDiff(section, normalized, options.clipboard ?? {}); const result = applyPreviewEdits({ section, absolutePath, normalized, snapshots, options }); if (normalized === result.text) { - // REM/MV-only sections change no text; the header conveys the - // delete/move, so don't surface a "No changes" error. + // REM/MV-only sections change no text; the header conveys the op. if (section.fileOp) return { diff: "", firstChangedLine: undefined }; return { error: `No changes would be made to ${section.path}.` }; } diff --git a/packages/coding-agent/src/edit/hashline/execute.ts b/packages/coding-agent/src/edit/hashline/execute.ts index fc3d4fc78..a2cfde969 100644 --- a/packages/coding-agent/src/edit/hashline/execute.ts +++ b/packages/coding-agent/src/edit/hashline/execute.ts @@ -13,6 +13,9 @@ import { type BlockResolution, buildCompactDiffPreview, + type Clipboard, + commitClipboard, + forkClipboard, MismatchError as HashlineMismatchError, Patch, Patcher, @@ -25,6 +28,7 @@ import type { ToolSession } from "../../tools"; import { outputMeta } from "../../tools/output-meta"; import { ToolError } from "../../tools/tool-errors"; import { generateDiffString } from "../diff"; +import { getEditClipboard } from "../edit-clipboard"; import { getFileSnapshotStore } from "../file-snapshot-store"; import type { EditToolDetails, EditToolPerFileResult, LspBatchRequest } from "../renderer"; import { pruneOversizedEditSnapshots } from "../snapshot-details"; @@ -98,12 +102,24 @@ interface RenderedSection { perFileResult: EditToolPerFileResult; } +const BLOCK_OP_LABELS: Record = { + replace: "SWAP.BLK", + insert_after: "INS.BLK.POST", + cut: "CUT.BLK", + paste_after: "PASTE.BLK.POST", +}; + function formatBlockResolution(resolution: BlockResolution): string { - const op = resolution.op === "delete" ? "DEL.BLK" : resolution.op === "insert_after" ? "INS.BLK.POST" : "SWAP.BLK"; + const op = BLOCK_OP_LABELS[resolution.op]; const lines = resolution.end - resolution.start + 1; const span = resolution.start === resolution.end ? `line ${resolution.start}` : `lines ${resolution.start}-${resolution.end}`; - const suffix = resolution.op === "insert_after" ? `; body lands after line ${resolution.end}` : ""; + const suffix = + resolution.op === "insert_after" + ? `; body lands after line ${resolution.end}` + : resolution.op === "paste_after" + ? `; clipboard lands after line ${resolution.end}` + : ""; return `${op} ${resolution.anchorLine} → resolved ${span} (${lines} line${lines === 1 ? "" : "s"})${suffix}`; } @@ -213,12 +229,19 @@ export async function executeHashlineSingle( const enforceSeenLines = options.session.settings.get("edit.enforceSeenLines"); const patcher = new Patcher({ fs, snapshots, blockResolver: nativeBlockResolver, enforceSeenLines }); + // The clipboard register is session-persistent: `CUT` in one edit call can + // `PASTE` in a later one. Each batch works on a fork and publishes it back + // only after writes land. + const sessionClipboard = getEditClipboard(options.session); + const clipboard = forkClipboard(sessionClipboard); + // Single-section fast path: prepare, commit, render. const inputHash = hashPatchInput(options.input); if (patch.sections.length === 1) { fs.setBatchRequest(narrowBatchRequest(options.batchRequest, true)); - const prepared = await patcher.prepare(patch.sections[0]); + const prepared = await patcher.prepare(patch.sections[0], clipboard); const sectionResult = await patcher.commit(prepared); + commitClipboard(clipboard, sessionClipboard); if (sectionResult.op === "noop") { const { count, escalate } = recordNoopEdit(options.session, sectionResult.canonicalPath, inputHash); if (escalate) { @@ -231,9 +254,18 @@ export async function executeHashlineSingle( } // Multi-section: prepare every section up front so we fail fast before - // any write hits the filesystem. + // any write hits the filesystem. One clipboard register spans the batch, + // so `CUT` in one section feeds `PASTE` in a later one. const prepared: PreparedSection[] = []; - for (const section of patch.sections) prepared.push(await patcher.prepare(section)); + // Register state after each section's prepare. Commits are non-atomic: a + // mid-batch write failure leaves earlier sections on disk, so the session + // register must reflect exactly the landed prefix — content a landed CUT + // deleted would otherwise be lost. + const sectionStates: Clipboard[] = []; + for (const section of patch.sections) { + prepared.push(await patcher.prepare(section, clipboard)); + sectionStates.push(forkClipboard(clipboard)); + } assertUniqueCanonicalPaths(prepared); for (const entry of prepared) { if (entry.isNoop) { @@ -251,6 +283,7 @@ export async function executeHashlineSingle( const isLast = i === prepared.length - 1; fs.setBatchRequest(narrowBatchRequest(options.batchRequest, isLast)); const sectionResult = await patcher.commit(prepared[i]); + commitClipboard(sectionStates[i], sessionClipboard); if (sectionResult.op === "noop") { const { count, escalate } = recordNoopEdit(options.session, sectionResult.canonicalPath, inputHash); throw escalate @@ -260,7 +293,6 @@ export async function executeHashlineSingle( resetNoopEdit(options.session, sectionResult.canonicalPath); rendered.push(renderSection(sectionResult, fs.consumeDiagnostics(sectionResult.path), prepared[i].section.path)); } - return { content: [ { diff --git a/packages/coding-agent/src/edit/renderer.ts b/packages/coding-agent/src/edit/renderer.ts index cd11ab3c5..507b6e4ea 100644 --- a/packages/coding-agent/src/edit/renderer.ts +++ b/packages/coding-agent/src/edit/renderer.ts @@ -140,7 +140,7 @@ interface HashlineInputEntry { path: string; op?: Operation; rename?: string; - /** A SWAP/DEL/INS line-editing op precedes the file op — keeps a move framed. */ + /** A SWAP/CUT/INS line-editing op precedes the file op — keeps a move framed. */ hasLineEdits?: boolean; } @@ -568,9 +568,9 @@ function parseHashlineInputPreviewHeader(line: string): string | null { return previewPath.length > 0 ? previewPath : null; } -// Line-editing op headers (SWAP/DEL/INS family), distinct from the file-level -// REM/MV ops. Body rows are always `+TEXT`, so this only matches real headers. -const HL_LINE_OP_HEADER = /^(?:SWAP|DEL|INS)\b/; +// Line-editing op headers (SWAP/CUT/INS family), distinct from file-level +// REM/MV ops. Body rows are `+TEXT`, so this only matches real headers. +const HL_LINE_OP_HEADER = /^(?:SWAP|CUT|INS)\b/; /** * Walk a (possibly mid-stream) hashline payload into per-section descriptors: diff --git a/packages/coding-agent/src/edit/streaming.ts b/packages/coding-agent/src/edit/streaming.ts index ebbd93299..02bee2f90 100644 --- a/packages/coding-agent/src/edit/streaming.ts +++ b/packages/coding-agent/src/edit/streaming.ts @@ -16,8 +16,10 @@ import { ABORT_MARKER, BEGIN_PATCH_MARKER, + type Clipboard, containsRecognizableHashlineOperations, END_PATCH_MARKER, + forkClipboard, type PatchSection as HashlineInputSection, Patch as HashlinePatch, type SnapshotStore, @@ -50,6 +52,13 @@ export interface StreamingDiffContext { * not flicker in the preview. */ isStreaming?: boolean; + /** + * Session-persistent clipboard register (`CUT`/`PASTE`). Previews + * fork it per frame — never mutating it — so a `PASTE` of content cut in + * an earlier edit call (or an earlier section of this patch) renders the + * real rows. + */ + clipboard?: Clipboard; } /** @@ -542,7 +551,9 @@ const hashlineStrategy: EditStreamingStrategy = { // to parse; suppress until the next chunk arrives. Once args are // complete, surface the error so the model sees what went wrong. if (ctx.isStreaming) return null; - const result = await computeHashlineDiff({ input }, ctx.cwd, ctx.snapshots); + const result = await computeHashlineDiff({ input }, ctx.cwd, ctx.snapshots, { + clipboard: forkClipboard(ctx.clipboard), + }); ctx.signal.throwIfAborted(); return [toPerFilePreview("", result)]; } @@ -558,12 +569,16 @@ const hashlineStrategy: EditStreamingStrategy = { const trailingProcessedIndex = sectionsToProcess.length - 1; const previews: PerFileDiffPreview[] = []; + // Fork the session register per preview frame: sections feed each other + // in patch order, but a preview must never mutate the live register. + const clipboard = forkClipboard(ctx.clipboard); for (let i = 0; i < sectionsToProcess.length; i++) { ctx.signal.throwIfAborted(); const section = sectionsToProcess[i]; const result = await computeHashlineSectionDiff(section, ctx.cwd, ctx.snapshots, { streaming: ctx.isStreaming, skipHashValidation: ctx.isStreaming === true, + clipboard, }); ctx.signal.throwIfAborted(); // Ignore parse/apply errors from the trailing (actively-typed) diff --git a/packages/coding-agent/src/export/html/template.js b/packages/coding-agent/src/export/html/template.js index d111cbb55..f3a4be6ab 100644 --- a/packages/coding-agent/src/export/html/template.js +++ b/packages/coding-agent/src/export/html/template.js @@ -395,7 +395,7 @@ } // Apply filter mode - const isSettingsEntry = ['label', 'custom', 'model_change', 'thinking_level_change', 'mode_change', 'ttsr_injection', 'session_init'].includes(entry.type); + const isSettingsEntry = ['label', 'custom', 'model_change', 'thinking_level_change', 'mode_change', 'ttsr_injection', 'session_init', 'credential_pin'].includes(entry.type); let passesFilter = true; switch (filterMode) { diff --git a/packages/coding-agent/src/modes/components/tool-execution.ts b/packages/coding-agent/src/modes/components/tool-execution.ts index 061f890ed..a0920407b 100644 --- a/packages/coding-agent/src/modes/components/tool-execution.ts +++ b/packages/coding-agent/src/modes/components/tool-execution.ts @@ -1,4 +1,4 @@ -import type { SnapshotStore } from "@oh-my-pi/hashline"; +import type { Clipboard, SnapshotStore } from "@oh-my-pi/hashline"; import type { AgentTool } from "@oh-my-pi/pi-agent-core"; import { Box, @@ -222,6 +222,8 @@ export interface ToolExecutionUi { export interface ToolExecutionOptions { snapshots?: SnapshotStore; + /** Session-persistent edit clipboard register, forked per preview frame. */ + clipboard?: Clipboard; showImages?: boolean; // default: true (only used if terminal supports images) editFuzzyThreshold?: number; editAllowFuzzy?: boolean; @@ -285,6 +287,7 @@ export class ToolExecutionComponent extends Container implements NativeScrollbac #editFuzzyThreshold: number | undefined; #editAllowFuzzy: boolean | undefined; #snapshots?: SnapshotStore; + #clipboard?: Clipboard; #isPartial = true; #resultVersion = 0; #lastDisplayKey: string | undefined; @@ -393,6 +396,7 @@ export class ToolExecutionComponent extends Container implements NativeScrollbac this.#editFuzzyThreshold = options.editFuzzyThreshold; this.#editAllowFuzzy = options.editAllowFuzzy; this.#snapshots = options.snapshots; + this.#clipboard = options.clipboard; this.#liveRegion = options.liveRegion; this.#tool = tool; this.#ui = ui; @@ -550,6 +554,7 @@ export class ToolExecutionComponent extends Container implements NativeScrollbac cwd: this.#cwd, signal: controller.signal, snapshots: this.#snapshots!, + clipboard: this.#clipboard, fuzzyThreshold: this.#editFuzzyThreshold, allowFuzzy: this.#editAllowFuzzy, isStreaming, diff --git a/packages/coding-agent/src/modes/controllers/event-controller.ts b/packages/coding-agent/src/modes/controllers/event-controller.ts index 62eb79b67..546b6057a 100644 --- a/packages/coding-agent/src/modes/controllers/event-controller.ts +++ b/packages/coding-agent/src/modes/controllers/event-controller.ts @@ -6,6 +6,7 @@ import { logger, prompt, sanitizeText } from "@oh-my-pi/pi-utils"; import { INTENT_FIELD } from "@oh-my-pi/pi-wire"; import { extractTextContent } from "../../commit/utils"; import { settings } from "../../config/settings"; +import { getEditClipboard } from "../../edit/edit-clipboard"; import { getFileSnapshotStore } from "../../edit/file-snapshot-store"; import { AssistantMessageComponent } from "../../modes/components/assistant-message"; import { detectCacheInvalidation } from "../../modes/components/cache-invalidation-marker"; @@ -810,6 +811,7 @@ export class EventController { renderArgs, { snapshots: getFileSnapshotStore(this.ctx.viewSession), + clipboard: getEditClipboard(this.ctx.viewSession), showImages: settings.get("terminal.showImages"), editFuzzyThreshold: settings.get("edit.fuzzyThreshold"), editAllowFuzzy: settings.get("edit.fuzzyMatch"), @@ -1033,6 +1035,7 @@ export class EventController { event.args, { snapshots: getFileSnapshotStore(this.ctx.viewSession), + clipboard: getEditClipboard(this.ctx.viewSession), showImages: settings.get("terminal.showImages"), editFuzzyThreshold: settings.get("edit.fuzzyThreshold"), editAllowFuzzy: settings.get("edit.fuzzyMatch"), diff --git a/packages/coding-agent/src/modes/utils/ui-helpers.ts b/packages/coding-agent/src/modes/utils/ui-helpers.ts index 5482d6df4..608cc89ea 100644 --- a/packages/coding-agent/src/modes/utils/ui-helpers.ts +++ b/packages/coding-agent/src/modes/utils/ui-helpers.ts @@ -5,6 +5,7 @@ import { type Component, Spacer, Text, TruncatedText } from "@oh-my-pi/pi-tui"; import type { AdvisorMessageDetails } from "../../advisor"; import { COLLAB_PROMPT_MESSAGE_TYPE, type CollabPromptDetails } from "../../collab/protocol"; import { settings } from "../../config/settings"; +import { getEditClipboard } from "../../edit/edit-clipboard"; import { getFileSnapshotStore } from "../../edit/file-snapshot-store"; import { createAdvisorMessageCard } from "../../modes/components/advisor-message"; import { AssistantMessageComponent } from "../../modes/components/assistant-message"; @@ -497,6 +498,7 @@ export class UiHelpers { renderArgs, { snapshots: getFileSnapshotStore(this.ctx.viewSession), + clipboard: getEditClipboard(this.ctx.viewSession), showImages: settings.get("terminal.showImages"), editFuzzyThreshold: settings.get("edit.fuzzyThreshold"), editAllowFuzzy: settings.get("edit.fuzzyMatch"), diff --git a/packages/coding-agent/src/prompts/system/plan-mode-active.md b/packages/coding-agent/src/prompts/system/plan-mode-active.md index e03e0dadc..fe1a1b862 100644 --- a/packages/coding-agent/src/prompts/system/plan-mode-active.md +++ b/packages/coding-agent/src/prompts/system/plan-mode-active.md @@ -30,10 +30,10 @@ Use `{{editToolName}}` for incremental edits and `{{writeToolName}}` only to cre {{#if isHashlineEditMode}} Structure the plan as `##`/`###` markdown sections so you can revise it section-by-section: with `{{editToolName}}`, a heading anchors its WHOLE section (through every nested deeper heading, up to the next same-or-higher heading). Rely on the block ops to grow the plan without rewriting the file: - `SWAP.BLK N:` on a heading line — rewrite that entire section in place. -- `DEL.BLK N` on a heading line — drop the whole section. +- `CUT.BLK N` on a heading line — drop the whole section. - `INS.BLK.POST N:` on a heading line — add a new section AFTER that one (end the inserted body with a blank line so the next heading stays separated). -Write each section together with its body — block ops need a multi-line section; a bare heading with no body falls back to plain `INS.POST`/`DEL`/`SWAP`. +Write each section together with its body — block ops need a multi-line section; a bare heading with no body falls back to plain `INS.POST`/`CUT`/`SWAP`. {{/if}} ## Ground every claim diff --git a/packages/coding-agent/src/sdk.ts b/packages/coding-agent/src/sdk.ts index ef35ff0a3..53ac1bb6e 100644 --- a/packages/coding-agent/src/sdk.ts +++ b/packages/coding-agent/src/sdk.ts @@ -625,6 +625,10 @@ export type * from "./extensibility/extensions"; export type { Skill } from "./extensibility/skills"; export type { FileSlashCommand } from "./extensibility/slash-commands"; export type { MCPManager, MCPServerConfig, MCPServerConnection, MCPToolsLoadResult } from "./mcp"; +// Agent registry: pass a private instance per `createAgentSession` when +// embedding several concurrent top-level sessions in one process (the default +// global registry admits only one "Main" per process generation). +export { type AgentRef, AgentRegistry, MAIN_AGENT_ID } from "./registry/agent-registry"; export type { Tool } from "./tools"; export { buildDirectoryTree, buildWorkspaceTree, type DirectoryTree, type WorkspaceTree } from "./workspace-tree"; diff --git a/packages/coding-agent/src/session/agent-session.ts b/packages/coding-agent/src/session/agent-session.ts index 4117c17aa..e5658acac 100644 --- a/packages/coding-agent/src/session/agent-session.ts +++ b/packages/coding-agent/src/session/agent-session.ts @@ -19,7 +19,7 @@ import * as path from "node:path"; import { scheduler } from "node:timers/promises"; import { isPromise } from "node:util/types"; -import type { InMemorySnapshotStore } from "@oh-my-pi/hashline"; +import type { Clipboard, InMemorySnapshotStore } from "@oh-my-pi/hashline"; import { type AfterToolCallContext, type AfterToolCallResult, @@ -249,6 +249,7 @@ import { shouldEvaluateCodexAutoRedeem, shouldPromptCodexAutoRedeem, } from "./codex-auto-reset"; +import { recordCredentialPin, seedCredentialPins } from "./credential-pin"; import { EvalRunner, type EvalRunnerHost } from "./eval-runner"; import { collectPendingToolCalls, @@ -409,6 +410,8 @@ export class AgentSession { getXdevToolEntries: () => Array<{ name: string; summary: string }>; readonly yieldQueue: YieldQueue; fileSnapshotStore?: InMemorySnapshotStore; + /** Per-session `CUT`/`PASTE` clipboard register shared across edit calls. */ + editClipboard?: Clipboard; #powerAssertion: MacOSPowerAssertion | undefined; @@ -2428,6 +2431,15 @@ export class AgentSession { }, costUsd: assistantMsg.usage.cost.total, }); + // Persist which account served this turn so a resumed process can + // re-pin it and keep the provider's account-scoped prompt cache + // warm (broker-mode sticky routing is process-local). + recordCredentialPin( + this.#modelRegistry.authStorage, + this.sessionManager, + this.sessionId, + assistantMsg.provider, + ); } if (event.message.role === "toolResult") { const { toolName, toolCallId, isError, content } = event.message; @@ -3400,6 +3412,14 @@ export class AgentSession { this.agent.setMetadataResolver((provider: string) => buildSessionMetadata(sid, provider, this.#modelRegistry.authStorage), ); + // Restore the session's recorded provider accounts before the first + // request routes: sticky rows are process-local under a remote auth + // broker, and losing them re-ranks onto a different account, cold-missing + // the account-scoped prompt cache. Skipped for fresh provider sessions — + // those explicitly want new routing identity. + if (!this.#freshProviderSessionId) { + seedCredentialPins(this.#modelRegistry.authStorage, this.sessionManager, sid); + } // Keep every live advisor's provider identity in lockstep with the primary's // across every session-boundary transition — including branch paths that // skip conversation restore — so advisors never emit the previous diff --git a/packages/coding-agent/src/session/credential-pin.ts b/packages/coding-agent/src/session/credential-pin.ts new file mode 100644 index 000000000..c7c6b99f2 --- /dev/null +++ b/packages/coding-agent/src/session/credential-pin.ts @@ -0,0 +1,93 @@ +/** + * Session-file persistence of the OAuth account that served a session. + * + * Provider prompt caches are account-scoped (Anthropic bills a full cache + * re-write after an account flip), and the auth store's session-sticky routing + * is process-local when a remote auth broker is configured — the broker + * store's KV cache is in-memory, so sticky rows die with the CLI process. + * Resuming a session in a fresh process then re-ranks accounts by usage + * headroom, which is biased *away* from the account that just served the + * session (it has the highest recent burn), cold-missing the entire prefix. + * + * These helpers close the loop through the session file itself: after each + * assistant turn the serving account is recorded as a `credential_pin` entry, + * and on session adoption the pin is matched against the stored accounts and + * seeded back into the auth store with the session's effective last-use + * timestamp, so the provider's warm-window semantics still decide whether to + * stick or re-rank. + */ + +import type { AuthStorage } from "./auth-storage"; +import type { SessionManager } from "./session-manager"; + +/** Account fields shared by `OAuthAccountIdentity` and `OAuthAccountSummary`. */ +interface CredentialPinIdentity { + accountId?: string; + email?: string; + projectId?: string; + orgId?: string; +} + +/** + * Stable identifier for a provider account within its billing scope. The + * digest covers the full scope tuple — the same account in two orgs (Anthropic + * multi-subscription) or projects (Gemini) is two distinct cache domains and + * must produce two distinct pins. The digest input is the persisted contract + * for `CredentialPinEntry.hash` — changing it orphans every recorded pin. + * + * Hashing avoids embedding raw emails/uuids in session files, but an unsalted + * digest of a guessable email is still linkable — treat exported sessions + * accordingly. + * + * Returns `undefined` when the identity carries no account key at all. + */ +export function credentialPinHash(provider: string, identity: CredentialPinIdentity): string | undefined { + if (!identity.accountId && !identity.email) return undefined; + const key = [ + provider, + identity.accountId ?? "", + identity.email ?? "", + identity.orgId ?? "", + identity.projectId ?? "", + ].join("\0"); + return new Bun.CryptoHasher("sha256").update(key).digest("hex"); +} + +/** + * Record the account that served the latest assistant turn for `provider`. + * Appends a `credential_pin` entry only when the account differs from the + * branch's latest pin, so steady-state sessions add a single entry; the + * effective last-use time is derived from later assistant turns on read + * (see `SessionManager.getCredentialPins`). + */ +export function recordCredentialPin( + authStorage: AuthStorage, + sessionManager: SessionManager, + sessionId: string, + provider: string, +): void { + const identity = authStorage.getOAuthAccountIdentity(provider, sessionId); + if (!identity) return; + const hash = credentialPinHash(provider, identity); + if (!hash || sessionManager.getCredentialPins().get(provider)?.hash === hash) return; + sessionManager.appendCredentialPin(provider, hash); +} + +/** + * Re-pin the accounts recorded in the session file onto the auth store's + * session stickiness. No-op per provider when the account is gone (logged out) + * or when a live sticky already exists (same-process branch/session switches + * must not clobber fresher routing). Seeds with the session's effective + * last-use time so stale resumes still fall through to usage ranking. + */ +export function seedCredentialPins(authStorage: AuthStorage, sessionManager: SessionManager, sessionId: string): void { + for (const [provider, pin] of sessionManager.getCredentialPins()) { + const accounts = authStorage.listOAuthAccounts(provider, sessionId); + if (accounts.length === 0 || accounts.some(account => account.active)) continue; + const match = accounts.find(account => credentialPinHash(provider, account) === pin.hash); + if (!match) continue; + authStorage.pinSessionOAuthAccount(provider, sessionId, match.credentialId, { + lastUsedAtMs: pin.lastUsedAt, + }); + } +} diff --git a/packages/coding-agent/src/session/session-entries.ts b/packages/coding-agent/src/session/session-entries.ts index 630361a8f..2386ed829 100644 --- a/packages/coding-agent/src/session/session-entries.ts +++ b/packages/coding-agent/src/session/session-entries.ts @@ -154,6 +154,7 @@ export interface TitleChangeEntry extends SessionEntryBase { declare module "@oh-my-pi/pi-agent-core/compaction/entries" { interface CustomCompactionSessionEntries { titleChange: TitleChangeEntry; + credentialPin: CredentialPinEntry; } } @@ -164,6 +165,24 @@ export interface TtsrInjectionEntry extends SessionEntryBase { injectedRules: string[]; } +/** + * Records which OAuth account served this session's requests for a provider. + * + * Provider prompt caches (Anthropic in particular) are account-scoped, and the + * auth store's session-sticky routing is process-local under a remote auth + * broker, so resume must re-pin the same account to reuse the warm cache + * prefix. Stores a sha-256 of the account + billing-scope tuple instead of + * the raw email/uuid/org; note an unsalted digest of a guessable email is + * still linkable, so exported sessions are pseudonymous, not anonymous. + */ +export interface CredentialPinEntry extends SessionEntryBase { + type: "credential_pin"; + /** Provider id the pin applies to (e.g. "anthropic"). */ + provider: string; + /** `credentialPinHash()` of the serving account's identity + scope tuple. */ + hash: string; +} + /** Session init entry - captures initial context for subagent sessions (debugging/replay). */ export interface SessionInitEntry extends SessionEntryBase { type: "session_init"; @@ -230,7 +249,8 @@ export type SessionEntry = | TitleChangeEntry | TtsrInjectionEntry | SessionInitEntry - | ModeChangeEntry; + | ModeChangeEntry + | CredentialPinEntry; /** Raw logical file entry after loaders strip any fixed-width title slot. */ export type FileEntry = SessionHeader | SessionEntry; diff --git a/packages/coding-agent/src/session/session-manager.ts b/packages/coding-agent/src/session/session-manager.ts index 083d6cd2a..ffe1dd712 100644 --- a/packages/coding-agent/src/session/session-manager.ts +++ b/packages/coding-agent/src/session/session-manager.ts @@ -35,6 +35,7 @@ import { type BuildSessionContextOptions, buildSessionContext, type SessionConte import { type BranchSummaryEntry, type CompactionEntry, + type CredentialPinEntry, CURRENT_SESSION_VERSION, type CustomEntry, type CustomMessageEntry, @@ -179,6 +180,7 @@ function isDraftOnlyMetadataEntry(entry: SessionEntry): boolean { case "thinking_level_change": case "service_tier_change": case "mode_change": + case "credential_pin": return true; default: return false; @@ -2062,6 +2064,41 @@ export class SessionManager { return [...names]; } + /** Append a credential pin recording which OAuth account served `provider`. */ + appendCredentialPin(provider: string, hash: string): string { + const entry: CredentialPinEntry = { + type: "credential_pin", + ...this.#freshEntryFields(), + provider, + hash, + }; + this.#recordEntry(entry); + return entry.id; + } + + /** + * Latest credential pin per provider on the current branch (root → leaf), + * with the effective last-use time of the pinned account. + * + * Pins are appended only when the serving account *changes*, so a long + * session on one account carries a single old pin entry. Any assistant turn + * for the same provider after that pin was necessarily served by the pinned + * account, so its timestamp advances `lastUsedAt` — a resume seconds after + * the last turn seeds a warm sticky instead of a stale one. + */ + getCredentialPins(): Map { + const pins = new Map(); + for (const entry of this.getBranch()) { + if (entry.type === "credential_pin") { + pins.set(entry.provider, { hash: entry.hash, lastUsedAt: new Date(entry.timestamp).getTime() }); + } else if (entry.type === "message" && entry.message.role === "assistant") { + const pin = pins.get(entry.message.provider); + if (pin) pin.lastUsedAt = Math.max(pin.lastUsedAt, entry.message.timestamp); + } + } + return pins; + } + getLeafId(): string | null { return this.#index.leafId(); } diff --git a/packages/coding-agent/src/tools/index.ts b/packages/coding-agent/src/tools/index.ts index 21c38dff6..162ae41e0 100644 --- a/packages/coding-agent/src/tools/index.ts +++ b/packages/coding-agent/src/tools/index.ts @@ -1,4 +1,4 @@ -import type { InMemorySnapshotStore } from "@oh-my-pi/hashline"; +import type { Clipboard, InMemorySnapshotStore } from "@oh-my-pi/hashline"; import type { AgentOptions, AgentTelemetryConfig, AgentTool } from "@oh-my-pi/pi-agent-core"; import type { FetchImpl, ImageContent, Model, ServiceTierByFamily, ToolChoice } from "@oh-my-pi/pi-ai"; import { logger } from "@oh-my-pi/pi-utils"; @@ -357,6 +357,10 @@ export interface ToolSession { * file changed out-of-band. Lazily initialized by `getFileSnapshotStore`. */ fileSnapshotStore?: InMemorySnapshotStore; + /** Per-session `CUT`/`PASTE` clipboard register shared across edit + * calls. Lazily initialized by `getEditClipboard`. */ + editClipboard?: Clipboard; + /** Per-session log of unresolved git merge conflict regions surfaced by * `read`. Each entry gets a stable id N referenced by `write conflict://N` * to splice the recorded region with replacement content. Lazily initialized diff --git a/packages/coding-agent/src/utils/git.ts b/packages/coding-agent/src/utils/git.ts index 556423baa..35342a75e 100644 --- a/packages/coding-agent/src/utils/git.ts +++ b/packages/coding-agent/src/utils/git.ts @@ -1727,6 +1727,12 @@ export const revList = { async range(cwd: string, base: string, head: string, signal?: AbortSignal): Promise { return splitLines(await runText(cwd, ["rev-list", "--reverse", `${base}..${head}`], { readOnly: true, signal })); }, + /** Commits reachable from `ref` that touched `file`, newest first, capped at `limit`. */ + async touching(cwd: string, ref: string, file: string, limit: number, signal?: AbortSignal): Promise { + return splitLines( + await runText(cwd, ["rev-list", `--max-count=${limit}`, ref, "--", file], { readOnly: true, signal }), + ); + }, }; // ════════════════════════════════════════════════════════════════════════════ diff --git a/packages/coding-agent/test/core/block-replace.test.ts b/packages/coding-agent/test/core/block-replace.test.ts index 99e563944..c3e35058f 100644 --- a/packages/coding-agent/test/core/block-replace.test.ts +++ b/packages/coding-agent/test/core/block-replace.test.ts @@ -90,11 +90,11 @@ describe("SWAP.BLK — native tree-sitter resolution end-to-end", () => { }); }); - it("deletes the resolved `if` block (line 2) end-to-end via `DEL.BLK`", async () => { + it("deletes the resolved `if` block (line 2) end-to-end via `CUT.BLK`", async () => { await withTempDir(async tempDir => { const session = makeSession(tempDir); const { filePath, header } = await seedFile(tempDir, session, "x.ts", TS_SOURCE); - const input = `${header}\nDEL.BLK 2`; + const input = `${header}\nCUT.BLK 2`; await executeHashlineSingle(executeOptions(tempDir, input, session)); @@ -166,17 +166,17 @@ describe("SWAP.BLK — native tree-sitter resolution end-to-end", () => { }); }); - it("echoes the resolved span in the result text for DEL.BLK", async () => { + it("echoes the resolved span in the result text for CUT.BLK", async () => { await withTempDir(async tempDir => { const session = makeSession(tempDir); const { header } = await seedFile(tempDir, session, "x.ts", TS_SOURCE); - const input = `${header}\nDEL.BLK 2`; + const input = `${header}\nCUT.BLK 2`; const result = await executeHashlineSingle(executeOptions(tempDir, input, session)); const text = result.content.map(part => (part.type === "text" ? part.text : "")).join("\n"); // `if (y) {` opens on line 2; resolves lines 2-3. - expect(text).toContain("DEL.BLK 2 → resolved lines 2-3 (2 lines)"); + expect(text).toContain("CUT.BLK 2 → resolved lines 2-3 (2 lines)"); }); }); @@ -256,13 +256,13 @@ const MD_PLAN = [ ].join("\n"); describe("block ops on markdown headings — whole-section resolution end-to-end", () => { - it("DEL.BLK at a `## H2` deletes the entire section, including nested subsections", async () => { + it("CUT.BLK at a `## H2` deletes the entire section, including nested subsections", async () => { await withTempDir(async tempDir => { const session = makeSession(tempDir); // Line 4 is `## Context`; its section runs through `### Detail` and // the trailing blank, up to `## Approach`. const { filePath, header } = await seedFile(tempDir, session, "plan.md", MD_PLAN); - const input = `${header}\nDEL.BLK 4`; + const input = `${header}\nCUT.BLK 4`; const result = await executeHashlineSingle(executeOptions(tempDir, input, session)); const text = result.content.map(part => (part.type === "text" ? part.text : "")).join("\n"); @@ -270,7 +270,7 @@ describe("block ops on markdown headings — whole-section resolution end-to-end expect(await Bun.file(filePath).text()).toBe( ["# Plan", "intro", "", "## Approach", "step one", ""].join("\n"), ); - expect(text).toContain("DEL.BLK 4 → resolved lines 4-10 (7 lines)"); + expect(text).toContain("CUT.BLK 4 → resolved lines 4-10 (7 lines)"); }); }); diff --git a/packages/coding-agent/test/credential-pin.test.ts b/packages/coding-agent/test/credential-pin.test.ts new file mode 100644 index 000000000..5763976b1 --- /dev/null +++ b/packages/coding-agent/test/credential-pin.test.ts @@ -0,0 +1,185 @@ +import { Database } from "bun:sqlite"; +import { afterEach, beforeEach, describe, expect, test } from "bun:test"; +import { TempDir } from "@oh-my-pi/pi-utils"; +import { AuthStorage, SqliteAuthCredentialStore } from "../src/session/auth-storage"; +import { credentialPinHash, recordCredentialPin, seedCredentialPins } from "../src/session/credential-pin"; +import { SessionManager } from "../src/session/session-manager"; + +const ANTHROPIC_ENV = ["ANTHROPIC_API_KEY", "ANTHROPIC_OAUTH_TOKEN"] as const; +const savedEnv: Partial> = {}; + +function mintOAuthCredential(suffix: string, extra?: { orgId?: string }) { + return { + type: "oauth" as const, + access: `access-${suffix}`, + refresh: `refresh-${suffix}`, + expires: Date.now() + 60_000, + accountId: `account-${suffix}`, + email: `${suffix}@example.com`, + ...extra, + }; +} + +function assistantMessage(provider: string, timestamp: number) { + return { + role: "assistant" as const, + content: [{ type: "text" as const, text: "hi" }], + api: "anthropic-messages", + provider, + model: "claude-test", + usage: { + input: 1, + output: 1, + cacheRead: 0, + cacheWrite: 0, + totalTokens: 2, + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, + }, + stopReason: "stop" as const, + timestamp, + }; +} + +describe("credential pins", () => { + let tempDir: TempDir; + let storage: AuthStorage; + + beforeEach(async () => { + for (const key of ANTHROPIC_ENV) { + savedEnv[key] = process.env[key]; + delete process.env[key]; + } + tempDir = TempDir.createSync("@pi-credential-pin-"); + const store = new SqliteAuthCredentialStore(new Database(":memory:")); + store.saveOAuth("anthropic", mintOAuthCredential("a")); + store.saveOAuth("anthropic", mintOAuthCredential("b")); + storage = new AuthStorage(store); + await storage.reload(); + }); + + afterEach(() => { + for (const key of ANTHROPIC_ENV) { + const value = savedEnv[key]; + if (value === undefined) delete process.env[key]; + else process.env[key] = value; + } + tempDir[Symbol.dispose](); + }); + + test("pin entries survive a session reload and the latest pin per provider wins", async () => { + const manager = SessionManager.create(tempDir.path(), tempDir.path()); + manager.appendMessage({ role: "user", content: "hello", timestamp: Date.now() }); + manager.appendMessage(assistantMessage("anthropic", Date.now())); + manager.appendCredentialPin("anthropic", "hash-old"); + manager.appendCredentialPin("openai-codex", "hash-codex"); + manager.appendCredentialPin("anthropic", "hash-new"); + await manager.flush(); + const file = manager.getSessionFile(); + if (!file) throw new Error("expected a persisted session file"); + + const reopened = await SessionManager.open(file); + const pins = reopened.getCredentialPins(); + expect(pins.get("anthropic")?.hash).toBe("hash-new"); + expect(pins.get("openai-codex")?.hash).toBe("hash-codex"); + }); + + test("later assistant turns advance the pin's effective last-use; other providers and new pins do not", () => { + const manager = SessionManager.create(tempDir.path(), tempDir.path()); + const pinId = manager.appendCredentialPin("anthropic", "hash-a"); + const pinnedAt = new Date(manager.getEntry(pinId)!.timestamp).getTime(); + + // Long session on one account: no new pin entries, only assistant turns. + const lastTurnAt = pinnedAt + 3 * 60 * 60 * 1000; + manager.appendMessage(assistantMessage("anthropic", pinnedAt + 60_000)); + manager.appendMessage(assistantMessage("anthropic", lastTurnAt)); + expect(manager.getCredentialPins().get("anthropic")?.lastUsedAt).toBe(lastTurnAt); + + // A different provider's turn never advances this provider's pin. + manager.appendMessage(assistantMessage("openai-codex", lastTurnAt + 60_000)); + expect(manager.getCredentialPins().get("anthropic")?.lastUsedAt).toBe(lastTurnAt); + + // An account change re-bases last-use at the new pin. + const newPinId = manager.appendCredentialPin("anthropic", "hash-b"); + const newPinnedAt = new Date(manager.getEntry(newPinId)!.timestamp).getTime(); + expect(manager.getCredentialPins().get("anthropic")?.lastUsedAt).toBe(newPinnedAt); + }); + + test("seeding re-pins the recorded account in a store with no session stickiness", () => { + const manager = SessionManager.create(tempDir.path(), tempDir.path()); + const sessionId = manager.getSessionId(); + const hash = credentialPinHash("anthropic", { accountId: "account-b", email: "b@example.com" }); + if (!hash) throw new Error("expected a pin hash"); + manager.appendCredentialPin("anthropic", hash); + + // Fresh process: no sticky exists yet (the broker-mode resume scenario). + expect(storage.listOAuthAccounts("anthropic", sessionId).some(account => account.active)).toBe(false); + + seedCredentialPins(storage, manager, sessionId); + + const active = storage.listOAuthAccounts("anthropic", sessionId).find(account => account.active); + expect(active?.accountId).toBe("account-b"); + }); + + test("pins are org-scoped: the same account in two orgs re-pins the matching org credential", async () => { + const store = new SqliteAuthCredentialStore(new Database(":memory:")); + store.saveOAuth("anthropic", mintOAuthCredential("x", { orgId: "org-1" })); + store.saveOAuth("anthropic", mintOAuthCredential("x", { orgId: "org-2" })); + const orgStorage = new AuthStorage(store); + await orgStorage.reload(); + + const manager = SessionManager.create(tempDir.path(), tempDir.path()); + const sessionId = manager.getSessionId(); + const identity = { accountId: "account-x", email: "x@example.com" }; + const orgTwoHash = credentialPinHash("anthropic", { ...identity, orgId: "org-2" }); + if (!orgTwoHash) throw new Error("expected a pin hash"); + expect(orgTwoHash).not.toBe(credentialPinHash("anthropic", { ...identity, orgId: "org-1" })); + manager.appendCredentialPin("anthropic", orgTwoHash); + + seedCredentialPins(orgStorage, manager, sessionId); + + const active = orgStorage.listOAuthAccounts("anthropic", sessionId).find(account => account.active); + expect(active?.orgId).toBe("org-2"); + }); + + test("seeding never clobbers a live sticky from the same process", () => { + const manager = SessionManager.create(tempDir.path(), tempDir.path()); + const sessionId = manager.getSessionId(); + const accounts = storage.listOAuthAccounts("anthropic", sessionId); + const accountA = accounts.find(account => account.accountId === "account-a"); + expect(storage.pinSessionOAuthAccount("anthropic", sessionId, accountA!.credentialId)).toBe(true); + + const hash = credentialPinHash("anthropic", { accountId: "account-b", email: "b@example.com" }); + manager.appendCredentialPin("anthropic", hash!); + seedCredentialPins(storage, manager, sessionId); + + const active = storage.listOAuthAccounts("anthropic", sessionId).find(account => account.active); + expect(active?.accountId).toBe("account-a"); + }); + + test("seeding is a no-op when the pinned account is no longer stored", () => { + const manager = SessionManager.create(tempDir.path(), tempDir.path()); + const sessionId = manager.getSessionId(); + const hash = credentialPinHash("anthropic", { accountId: "account-gone" }); + manager.appendCredentialPin("anthropic", hash!); + + seedCredentialPins(storage, manager, sessionId); + + expect(storage.listOAuthAccounts("anthropic", sessionId).some(account => account.active)).toBe(false); + }); + + test("recording appends the serving account's hash once and dedupes repeats", () => { + const manager = SessionManager.create(tempDir.path(), tempDir.path()); + const sessionId = manager.getSessionId(); + const accounts = storage.listOAuthAccounts("anthropic", sessionId); + const accountA = accounts.find(account => account.accountId === "account-a"); + storage.pinSessionOAuthAccount("anthropic", sessionId, accountA!.credentialId); + + recordCredentialPin(storage, manager, sessionId, "anthropic"); + recordCredentialPin(storage, manager, sessionId, "anthropic"); + + const entries = manager.getBranch().filter(entry => entry.type === "credential_pin"); + expect(entries).toHaveLength(1); + const identity = storage.getOAuthAccountIdentity("anthropic", sessionId); + expect(manager.getCredentialPins().get("anthropic")?.hash).toBe(credentialPinHash("anthropic", identity!)); + }); +}); diff --git a/packages/coding-agent/test/edit-diff.test.ts b/packages/coding-agent/test/edit-diff.test.ts index 10cbace63..6d9b119a2 100644 --- a/packages/coding-agent/test/edit-diff.test.ts +++ b/packages/coding-agent/test/edit-diff.test.ts @@ -2,7 +2,12 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test"; import * as fs from "node:fs/promises"; import * as os from "node:os"; import * as path from "node:path"; -import { formatHashlineHeader, InMemorySnapshotStore, missingSnapshotTagMessage } from "@oh-my-pi/hashline"; +import { + forkClipboard, + formatHashlineHeader, + InMemorySnapshotStore, + missingSnapshotTagMessage, +} from "@oh-my-pi/hashline"; import { adjustIndentation, computeEditDiff, @@ -268,6 +273,68 @@ describe("computeHashlineDiff", () => { } }); + test("previews a same-file CUT + PASTE as the moved content", async () => { + const sourcePath = path.join(tempDir, "source.txt"); + const text = "l1\nl2\nl3\n"; + await Bun.write(sourcePath, text); + + const snapshotStore = new InMemorySnapshotStore(); + const tag = snapshotStore.record(sourcePath, text); + const result = await computeHashlineDiff( + { input: `${formatHashlineHeader(sourcePath, tag)}\nCUT 1.=1\nPASTE.TAIL` }, + tempDir, + snapshotStore, + ); + expect("diff" in result).toBe(true); + if ("diff" in result) { + expect(result.diff).toContain("-1|l1"); + expect(result.diff).toContain("+3|l1"); + } + }); + + test("previews a PASTE from a forked session register without touching the source", async () => { + const sourcePath = path.join(tempDir, "source.txt"); + const text = "l1\n"; + await Bun.write(sourcePath, text); + + const snapshotStore = new InMemorySnapshotStore(); + const tag = snapshotStore.record(sourcePath, text); + // Mirror the streaming-strategy contract: the session register is forked + // once per preview frame; sections then thread the fork in patch order. + const sessionRegister = { lines: ["carried"] }; + const result = await computeHashlineDiff( + { input: `${formatHashlineHeader(sourcePath, tag)}\nPASTE.TAIL` }, + tempDir, + snapshotStore, + { clipboard: forkClipboard(sessionRegister) }, + ); + expect("diff" in result).toBe(true); + if ("diff" in result) { + expect(result.diff).toContain("|carried"); + } + expect(sessionRegister.lines).toEqual(["carried"]); + }); + + test("streams paste rows in the natural-order preview", async () => { + const sourcePath = path.join(tempDir, "source.txt"); + const text = "l1\nl2\nl3\n"; + await Bun.write(sourcePath, text); + + const snapshotStore = new InMemorySnapshotStore(); + const tag = snapshotStore.record(sourcePath, text); + const result = await computeHashlineDiff( + { input: `${formatHashlineHeader(sourcePath, tag)}\nCUT 2.=2\nPASTE.HEAD` }, + tempDir, + snapshotStore, + { streaming: true, skipHashValidation: true }, + ); + expect("diff" in result).toBe(true); + if ("diff" in result) { + expect(result.diff).toContain("-2|l2"); + expect(result.diff).toContain("+1|l2"); + } + }); + test("rejects a tagless head/tail insert in the preview path, matching apply", async () => { const relativePath = "source.txt"; await Bun.write(path.join(tempDir, relativePath), "first\n"); diff --git a/packages/coding-agent/test/edit-streaming-preview.test.ts b/packages/coding-agent/test/edit-streaming-preview.test.ts index 9898e2b48..b7e4ce59b 100644 --- a/packages/coding-agent/test/edit-streaming-preview.test.ts +++ b/packages/coding-agent/test/edit-streaming-preview.test.ts @@ -305,12 +305,12 @@ describe("apply_patch streaming preview (trailing partial line)", () => { describe("matcherDigest", () => { test("hashline: digests stripped `+` body rows only, never headers or op lines", () => { - const input = ["[a.ts#AB12]", "SWAP 1.=2:", "+const x = 1;", "+const y = 2;", "DEL 5", ""].join("\n"); + const input = ["[a.ts#AB12]", "SWAP 1.=2:", "+const x = 1;", "+const y = 2;", "CUT 5", ""].join("\n"); expect(EDIT_MODE_STRATEGIES.hashline.matcherDigest({ input })).toBe("const x = 1;\nconst y = 2;"); }); test("hashline: grammar-only payload digests to empty, missing input to undefined", () => { - expect(EDIT_MODE_STRATEGIES.hashline.matcherDigest({ input: "[a.ts#AB12]\nDEL 3\n" })).toBe(""); + expect(EDIT_MODE_STRATEGIES.hashline.matcherDigest({ input: "[a.ts#AB12]\nCUT 3\n" })).toBe(""); expect(EDIT_MODE_STRATEGIES.hashline.matcherDigest({})).toBeUndefined(); }); diff --git a/packages/coding-agent/test/edit/seen-line-guard.test.ts b/packages/coding-agent/test/edit/seen-line-guard.test.ts index bc317dcd6..f387de660 100644 --- a/packages/coding-agent/test/edit/seen-line-guard.test.ts +++ b/packages/coding-agent/test/edit/seen-line-guard.test.ts @@ -262,7 +262,7 @@ describe("read → edit seen-line guard", () => { expect(seen?.has(1122)).toBe(true); await executeHashlineSingle( execOptions( - `[src/main.c#${tag}]\nINS.POST 1122:\n+\tbeep_3k8hz_on();\n+\tk_sleep(K_MSEC(300));\n+\tbeep_3k8hz_off();\nDEL 1288.=1291`, + `[src/main.c#${tag}]\nINS.POST 1122:\n+\tbeep_3k8hz_on();\n+\tk_sleep(K_MSEC(300));\n+\tbeep_3k8hz_off();\nCUT 1288.=1291`, session, ), ); @@ -313,7 +313,7 @@ describe("read → edit seen-line guard", () => { const tag = tagFromOutput(resultText(read)); // Anchor 60 unseen lines — deliberately over the 40-line cap. - const dels = Array.from({ length: 60 }, (_, i) => `DEL ${100 + i}`).join("\n"); + const dels = Array.from({ length: 60 }, (_, i) => `CUT ${100 + i}`).join("\n"); let message: string | undefined; try { await executeHashlineSingle(execOptions(`[long.txt#${tag}]\n${dels}`, session)); diff --git a/packages/coding-agent/test/export-html-template.test.ts b/packages/coding-agent/test/export-html-template.test.ts index f1261ceb8..2ff61a5b0 100644 --- a/packages/coding-agent/test/export-html-template.test.ts +++ b/packages/coding-agent/test/export-html-template.test.ts @@ -19,9 +19,9 @@ interface TemplateProbeResult { } const expectedTemplate: TemplateProbeResult = { - chars: 377_268, - bytes: 377_446, - sha256: "023cf3773498db52ff0ec508b22ef2c002710f9e9fcb90fea361659d5b0205df", + chars: 377_286, + bytes: 377_464, + sha256: "6598b2d74f905e3105474ea8033c938e92df4c33035421603ea363d72d1c81c1", stableCache: true, assetsRemoved: 0, }; @@ -78,6 +78,7 @@ function composeExpectedTemplate(): string { async function runProbe(command: string[]): Promise { const proc = Bun.spawn(command, { cwd: unrelatedCwd, + stdin: "ignore", stderr: "pipe", stdout: "pipe", }); @@ -149,8 +150,9 @@ describe("HTML export template", () => { fs.writeFileSync(staleAssetPath, "stale"); const build = Bun.spawn([process.execPath, "run", "gen:bundle"], { cwd: packageDir, - stderr: "pipe", + stdin: "ignore", stdout: "pipe", + stderr: "pipe", }); const [buildStdout, buildStderr, buildExitCode] = await Promise.all([ new Response(build.stdout).text(), @@ -162,8 +164,9 @@ describe("HTML export template", () => { const proc = Bun.spawn([process.execPath, "pm", "pack", "--dry-run", "--ignore-scripts"], { cwd: packageDir, - stderr: "pipe", + stdin: "ignore", stdout: "pipe", + stderr: "pipe", }); const [stdout, stderr, exitCode] = await Promise.all([ new Response(proc.stdout).text(), @@ -195,6 +198,7 @@ describe("HTML export template", () => { test("does not retain source asset strings during a static import", async () => { const proc = Bun.spawn([process.execPath, heapProbePath], { + stdin: "ignore", stderr: "pipe", stdout: "pipe", }); diff --git a/packages/coding-agent/test/modes/controllers/resume-preflight.test.ts b/packages/coding-agent/test/modes/controllers/resume-preflight.test.ts index c9d177d2b..7633d575b 100644 --- a/packages/coding-agent/test/modes/controllers/resume-preflight.test.ts +++ b/packages/coding-agent/test/modes/controllers/resume-preflight.test.ts @@ -220,8 +220,9 @@ describe("SelectorController.handleResumeSession preflight flush", () => { selector!.handleInput("\n"); expect(selectionPromise).toBeDefined(); - await expect(selectionPromise!).rejects.toBe(switchError); + await selectionPromise; + expect(ctx.showError).toHaveBeenCalledWith("switch failed"); expect(ctx.settings.flush).toHaveBeenCalledTimes(1); expect(switchSession).toHaveBeenCalledWith(session.path); expect(hide).toHaveBeenCalledTimes(1); diff --git a/packages/collab-web/CHANGELOG.md b/packages/collab-web/CHANGELOG.md index f59801390..db8f19482 100644 --- a/packages/collab-web/CHANGELOG.md +++ b/packages/collab-web/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.2.0] - 2026-07-30 + ### Fixed - Fixed an issue where the agent would stop silently without a message by ensuring terminal auto-retry failures are properly surfaced as error notices. diff --git a/packages/hashline/CHANGELOG.md b/packages/hashline/CHANGELOG.md index 94a51b69f..23879f828 100644 --- a/packages/hashline/CHANGELOG.md +++ b/packages/hashline/CHANGELOG.md @@ -2,6 +2,22 @@ ## [Unreleased] +## [17.2.0] - 2026-07-30 + +### Breaking Changes + +- Removed `DEL`, `DEL.BLK`, `COPY`, and `COPY.BLK` from the patch language. Use `CUT` / `CUT.BLK` for deletion; a cut does not require a following `PASTE` and leaves the removed content available to later pastes. + +### Added + +- Added clipboard ops: `CUT N.=M` captures lines into a register (and deletes them), `CUT.BLK N` captures tree-sitter blocks, and `PASTE.PRE|POST N` / `PASTE.HEAD|TAIL` / `PASTE.BLK.POST N` insert the captured lines without retyping. The register flows top-to-bottom across sections, so content moves between files in one patch; `PASTE` does not consume it and the last capture wins. +- Added `PatcherOptions.clipboard` for a host-owned register that persists across `Patcher.apply` batches. Batches work on a fork (`forkClipboard`) published per landed section (`commitClipboard`), so failed batches never poison the register and a mid-batch write failure still preserves content already cut from disk. +- Added clipboard safety guards: a `PASTE` with an empty register, a capture overwriting un-pasted `CUT` content, and clipboard ops in same-path sections interleaved across another file's section are all rejected with targeted diagnostics. `CUT` ranges participate in overlap validation, the seen-lines guard, and drift recovery (every captured line must remap). + +### Changed + +- Simplified `grammar.lark` around shared target and position shapes, collapsing the concrete and block `CUT` forms plus the `INS` / `PASTE` position variants into their common grammar rules. + ### Fixed - Prevented CPU and memory exhaustion in streaming previews by rejecting line anchors above Number.MAX_SAFE_INTEGER and ranges spanning more than 100,000 lines. diff --git a/packages/hashline/README.md b/packages/hashline/README.md index 934030f6d..04f511fd6 100644 --- a/packages/hashline/README.md +++ b/packages/hashline/README.md @@ -49,9 +49,10 @@ session-aware recovery on mismatch. Inside a section: - `SWAP A.=B:` — replace lines A.=B with following `+TEXT` body rows. - `SWAP.BLK A:` — replace the syntactic block beginning on line A. -- `DEL A.=B` / `DEL.BLK A` — delete concrete lines or a resolved block. +- `CUT A.=B` / `CUT.BLK A` — delete concrete lines or a resolved block and capture them for `PASTE`. - `INS.PRE A:` / `INS.POST A:` / `INS.HEAD:` / `INS.TAIL:` — insert following body rows. - `INS.BLK.POST A:` — insert following body rows after the resolved block's last line. +- `PASTE.PRE A` / `PASTE.POST A` / `PASTE.HEAD` / `PASTE.TAIL` / `PASTE.BLK.POST A` — insert the clipboard; no body rows. The register flows top-to-bottom across sections (cross-file moves) and can be host-persisted across batches via `PatcherOptions.clipboard`. - `REM` — delete the whole file named by the section header. - `MV DEST` — move/rename the section file to `DEST` (optionally after line edits). - `+TEXT` — literal body row (use `+` alone for a blank line). diff --git a/packages/hashline/package.json b/packages/hashline/package.json index e3ecde917..354c1e891 100644 --- a/packages/hashline/package.json +++ b/packages/hashline/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/hashline", - "version": "17.1.8", + "version": "17.2.0", "description": "Hashline: a compact, line-anchored patch language and applier. Pluggable FS/IO so it works over disk, in-memory, or any custom backend.", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/hashline/src/apply.ts b/packages/hashline/src/apply.ts index eff2175e9..3eeb589e5 100644 --- a/packages/hashline/src/apply.ts +++ b/packages/hashline/src/apply.ts @@ -7,6 +7,8 @@ * which absorbs common model mistakes where a payload restates unchanged range * boundaries or duplicates/drops structural closers. */ + +import { resolveClipboardEdits } from "./clipboard"; import { afterInsertLandingShiftWarning, ambiguousBoundaryEchoMessage, @@ -15,7 +17,7 @@ import { UNRESOLVED_BLOCK_INTERNAL, } from "./messages"; import { cloneCursor } from "./tokenizer"; -import type { Anchor, ApplyResult, Cursor, Edit } from "./types"; +import type { Anchor, ApplyResult, Clipboard, Cursor, Edit } from "./types"; type LineOrigin = "original" | "insert" | "replacement"; @@ -1221,24 +1223,43 @@ function repairAfterInsertLandings( return { edits: out ?? edits, warnings }; } +/** Optional knobs for {@link applyEdits}. */ +export interface ApplyEditsOptions { + /** + * Clipboard register filled by `cut` edits and read by `paste` edits. + * Thread one register through every section of a batch to move content + * across files; omitted, the call gets a private register. + */ + clipboard?: Clipboard; + /** `PASTE` with an empty register: `throw` (default) or `drop` (streaming previews). */ + onEmptyPaste?: "throw" | "drop"; +} + /** * Apply a parsed list of edits to a text body. Pure function — no I/O. * * Returns the post-edit text and the first changed line number (1-indexed). * Throws if an anchor is out of bounds. */ -export function applyEdits(text: string, edits: readonly Edit[]): ApplyResult { +export function applyEdits(text: string, edits: readonly Edit[], options: ApplyEditsOptions = {}): ApplyResult { if (edits.length === 0) return { text, firstChangedLine: undefined }; + const fileLines = text.split("\n"); + + // Clipboard pre-pass: capture `cut` ranges from the original lines and + // expand `paste` edits into plain inserts in authored order. + const concrete = resolveClipboardEdits(edits, fileLines, options.clipboard ?? {}, { + ...(options.onEmptyPaste === undefined ? {} : { onEmptyPaste: options.onEmptyPaste }), + }); + // Block edits are deferred until `resolveBlockEdits` expands them into // concrete inserts + deletes. Reaching the applier with one still present // is an internal wiring bug, not authored-input error. - for (const edit of edits) { + for (const edit of concrete) { if (edit.kind === "block") throw new Error(UNRESOLVED_BLOCK_INTERNAL); } - const appliedEdits = edits as readonly AppliedEdit[]; + const appliedEdits = concrete as readonly AppliedEdit[]; - const fileLines = text.split("\n"); const lineOrigins: LineOrigin[] = fileLines.map(() => "original"); let firstChangedLine: number | undefined; diff --git a/packages/hashline/src/block.ts b/packages/hashline/src/block.ts index 4e6c95b42..67cdd0728 100644 --- a/packages/hashline/src/block.ts +++ b/packages/hashline/src/block.ts @@ -1,25 +1,22 @@ /** - * Expand deferred block edits (`replace_block N:` / `delete_block N` / - * `insert_after_block N:`) into concrete inserts + deletes. + * Expand deferred block edits into concrete inserts, cuts, pastes, and deletes. * - * The hashline parser cannot expand a block edit on its own — the line span is - * unknown until file text + path (→ language) are available. This transform - * runs at every apply/preview boundary that has text: it calls the injected - * {@link BlockResolver} to resolve each block's `[start, end]` span, then emits - * the exact same edits the concrete form produces in the parser: `replace - * start.=end:` inserts + deletes for a replace, a pure range delete for a - * delete, and plain `after_anchor` inserts at `end` for an insert-after. After - * it runs, no `block` edits remain, so {@link applyEdits} (and recovery) only - * ever see resolved edits. + * The parser cannot expand a block edit until file text and language are + * available. This transform resolves each anchored span, then emits the same + * low-level edits as the corresponding concrete operation. After it runs, no + * `block` edits remain, so {@link applyEdits} and recovery see concrete edits. */ import { STRUCTURAL_CLOSER_RE } from "./apply"; import { BLOCK_RESOLVER_UNAVAILABLE, type BlockDiagnosticSuggestions, + type BlockOp, blockSingleLineMessage, blockUnresolvedMessage, insertAfterBlockCloserLoweredWarning, insertAfterBlockUnresolvedLoweredWarning, + pasteAfterBlockCloserLoweredWarning, + pasteAfterBlockUnresolvedLoweredWarning, } from "./messages"; import type { BlockResolution, BlockResolver, BlockSpan, Cursor, Edit } from "./types"; @@ -67,15 +64,12 @@ function findEnclosingBlock( return null; } +/** Optional knobs for {@link resolveBlockEdits}. */ export interface ResolveBlockEditsOptions { /** - * How to handle a replace/delete block edit that cannot be resolved - * (missing resolver or a `null` span). `"throw"` (default) raises a - * `blockUnresolvedMessage` error — used by the authoritative apply + final - * preview paths. `"drop"` silently skips the edit — used by the streaming - * preview, where a half-written file or transient parse error must not - * throw. Unresolvable `insert_after_block N:` edits never reach this: they - * are lowered to plain `insert after N:` with a warning. + * How to handle a replace/cut block edit that cannot be resolved. `"throw"` + * (default) raises a block error; `"drop"` skips it for streaming previews. + * Unresolvable after-block edits lower to their plain after-line form. */ onUnresolved?: "throw" | "drop"; /** @@ -124,7 +118,7 @@ export function resolveBlockEdits( resolved.push(edit); continue; } - const op = edit.mode === "insert_after" ? "insert_after" : edit.payloads.length === 0 ? "delete" : "replace"; + const op: BlockOp = edit.mode ?? "replace"; const span = resolver ? resolver({ path, text, line: edit.anchor.line }) : null; if (span === null) { // `insert_after_block N:` never fails the patch — lower it to plain @@ -135,9 +129,19 @@ export function resolveBlockEdits( // - otherwise (unsupported language, blank line, unparsable block, // or no resolver wired): "after the block at N" degrades to // "after line N" — warn to verify the landing line. - if (op === "insert_after") { + if (op === "insert_after" || op === "paste_after") { const anchorText = text.split("\n")[edit.anchor.line - 1]; const isCloser = anchorText !== undefined && STRUCTURAL_CLOSER_RE.test(anchorText); + if (op === "paste_after") { + options.onWarning?.( + isCloser + ? pasteAfterBlockCloserLoweredWarning(edit.anchor.line) + : pasteAfterBlockUnresolvedLoweredWarning(edit.anchor.line), + ); + const cursor: Cursor = { kind: "after_anchor", anchor: { line: edit.anchor.line } }; + resolved.push({ kind: "paste", cursor, lineNum: edit.lineNum, index: synthIndex++ }); + continue; + } options.onWarning?.( isCloser ? insertAfterBlockCloserLoweredWarning(edit.anchor.line) @@ -183,6 +187,32 @@ export function resolveBlockEdits( end: span.end, op, }); + if (op === "paste_after") { + // Mirror the block-lowered insert: paste after the block's last + // line, tagging `blockStart` so landing correction can slide a body + // claiming a depth inside the block back across its trailing closers. + resolved.push({ + kind: "paste", + cursor: { kind: "after_anchor", anchor: { line: span.end } }, + lineNum: edit.lineNum, + index: synthIndex++, + blockStart: span.start, + }); + continue; + } + if (op === "cut") { + // Capture the resolved span before deleting it line-by-line. + resolved.push({ + kind: "cut", + range: { start: { line: span.start }, end: { line: span.end } }, + lineNum: edit.lineNum, + index: synthIndex++, + }); + for (let line = span.start; line <= span.end; line++) { + resolved.push({ kind: "delete", anchor: { line }, lineNum: edit.lineNum, index: synthIndex++ }); + } + continue; + } if (op === "insert_after") { // Mirror the parser's `insert after N:` lowering: one `after_anchor` // insert per payload row, anchored on the block's last line. The @@ -202,10 +232,8 @@ export function resolveBlockEdits( } continue; } - // Mirror the parser's `replace start.=end:` expansion exactly: one - // `before_anchor` replacement insert per payload row at `span.start`, - // then one delete per line across `[span.start, span.end]`. An empty - // `payloads` (from `delete_block N`) emits no inserts — a pure deletion. + // Mirror `SWAP start.=end:`: replacement inserts at `span.start`, then + // one delete per line across the resolved span. for (const payload of edit.payloads) { const cursor: Cursor = { kind: "before_anchor", anchor: { line: span.start } }; resolved.push({ diff --git a/packages/hashline/src/clipboard.ts b/packages/hashline/src/clipboard.ts new file mode 100644 index 000000000..bed55af25 --- /dev/null +++ b/packages/hashline/src/clipboard.ts @@ -0,0 +1,110 @@ +/** + * Clipboard register support for `CUT` / `PASTE` ops. + * + * `CUT` captures its current source lines before ordinary delete edits apply. + * `PASTE` expands the latest capture into inserts. One register flows through + * patch sections in authored order, so content moves across files; the latest + * cut wins and paste does not consume it. + */ +import { HL_CUT_KEYWORD, HL_RANGE_SEP } from "./format"; +import { EMPTY_PASTE } from "./messages"; +import { cloneCursor } from "./tokenizer"; +import type { Clipboard, Edit } from "./types"; + +type CutEdit = Extract; + +function describeCutEdit(edit: CutEdit): string { + const { start, end } = edit.range; + const range = start.line === end.line ? `${start.line}` : `${start.line}${HL_RANGE_SEP}${end.line}`; + return `${HL_CUT_KEYWORD} ${range}`; +} + +/** True when at least one edit reads or writes the clipboard register. */ +export function hasClipboardEdit(edits: readonly Edit[]): boolean { + return edits.some( + edit => + edit.kind === "cut" || + edit.kind === "paste" || + (edit.kind === "block" && (edit.mode === "cut" || edit.mode === "paste_after")), + ); +} + +/** Optional knobs for {@link resolveClipboardEdits}. */ +export interface ResolveClipboardEditsOptions { + /** `PASTE` with an empty register: `throw` (default) or `drop` (streaming previews). */ + onEmptyPaste?: "throw" | "drop"; +} + +/** + * Resolve clipboard edits against the original file lines in authored order. + * Cuts fill the register and emit nothing; pastes become plain inserts. + */ +export function resolveClipboardEdits( + edits: readonly Edit[], + fileLines: readonly string[], + clipboard: Clipboard, + options: ResolveClipboardEditsOptions = {}, +): readonly Edit[] { + if (!hasClipboardEdit(edits)) return edits; + const onEmptyPaste = options.onEmptyPaste ?? "throw"; + const resolved: Edit[] = []; + let synthIndex = 0; + for (const edit of edits) { + if (edit.kind === "cut") { + const { start, end } = edit.range; + if (start.line < 1 || end.line > fileLines.length) { + throw new Error( + `line ${edit.lineNum}: \`${describeCutEdit(edit)}\` is out of range (file has ${fileLines.length} lines).`, + ); + } + clipboard.lines = fileLines.slice(start.line - 1, end.line); + continue; + } + if (edit.kind === "paste") { + const lines = clipboard.lines; + if (lines === undefined) { + if (onEmptyPaste === "drop") continue; + throw new Error(`line ${edit.lineNum}: ${EMPTY_PASTE}`); + } + for (const text of lines) { + resolved.push({ + kind: "insert", + cursor: cloneCursor(edit.cursor), + text, + lineNum: edit.lineNum, + index: synthIndex++, + ...(edit.blockStart === undefined ? {} : { blockStart: edit.blockStart }), + }); + } + continue; + } + resolved.push(edit); + } + return resolved; +} + +/** Create a transactional working copy of a clipboard register. */ +export function forkClipboard(source?: Clipboard): Clipboard { + return source === undefined ? {} : { ...source }; +} + +/** Publish a clipboard fork back to its source register. */ +export function commitClipboard(fork: Clipboard, target: Clipboard): void { + if (fork.lines === undefined) delete target.lines; + else target.lines = fork.lines; +} + +/** + * Validate that every paste has a preceding or persisted capture without + * mutating the register or reading file content. + */ +export function validateClipboardSequence(edits: readonly Edit[], clipboard: Clipboard): void { + let hasLines = clipboard.lines !== undefined; + for (const edit of edits) { + if (edit.kind === "cut") { + hasLines = true; + } else if (edit.kind === "paste" && !hasLines) { + throw new Error(`line ${edit.lineNum}: ${EMPTY_PASTE}`); + } + } +} diff --git a/packages/hashline/src/format.ts b/packages/hashline/src/format.ts index ff782ac68..f30de3106 100644 --- a/packages/hashline/src/format.ts +++ b/packages/hashline/src/format.ts @@ -15,8 +15,6 @@ export const HL_PAYLOAD_REPLACE = "+"; /** Hunk-header keyword for concrete line replacement. */ export const HL_REPLACE_KEYWORD = "SWAP"; -/** Hunk-header keyword for concrete line deletion. */ -export const HL_DELETE_KEYWORD = "DEL"; /** Hunk-header keyword for insertion operations. */ export const HL_INSERT_KEYWORD = "INS"; /** Insert position keyword for inserting before a concrete line. */ @@ -29,10 +27,16 @@ export const HL_INSERT_HEAD = "HEAD"; export const HL_INSERT_TAIL = "TAIL"; /** Hunk-header keyword: `SWAP.BLK N:` resolves N to a tree-sitter block range and replaces its span. */ export const HL_REPLACE_BLOCK_KEYWORD = "SWAP.BLK"; -/** Hunk-header keyword: `DEL.BLK N` resolves N to a tree-sitter block range and deletes its span. */ -export const HL_DELETE_BLOCK_KEYWORD = "DEL.BLK"; /** Hunk-header keyword: `INS.BLK.POST N:` inserts after the last line of the tree-sitter block at N. */ export const HL_INSERT_AFTER_BLOCK_KEYWORD = "INS.BLK.POST"; +/** Hunk-header keyword: `CUT N.=M` captures lines into the clipboard register and deletes them. */ +export const HL_CUT_KEYWORD = "CUT"; +/** Hunk-header keyword: `CUT.BLK N` captures the tree-sitter block at N and deletes its span. */ +export const HL_CUT_BLOCK_KEYWORD = "CUT.BLK"; +/** Hunk-header keyword prefix: `PASTE.PRE|POST N` / `PASTE.HEAD|TAIL` inserts the clipboard. */ +export const HL_PASTE_KEYWORD = "PASTE"; +/** Hunk-header keyword: `PASTE.BLK.POST N` inserts the clipboard after the tree-sitter block at N. */ +export const HL_PASTE_AFTER_BLOCK_KEYWORD = "PASTE.BLK.POST"; /** File-level keyword: `REM` deletes the whole file named by the section header. */ export const HL_REM_KEYWORD = "REM"; /** File-level keyword: `MV DEST` renames/moves the section file to `DEST`. */ @@ -63,9 +67,9 @@ export function formatReplaceHeader(start: number, end: number): string { return `${HL_REPLACE_KEYWORD} ${start}${HL_RANGE_SEP}${end}${HL_HEADER_COLON}`; } -/** Format a concrete deletion hunk header. */ -export function formatDeleteHeader(start: number, end = start): string { - return start === end ? `${HL_DELETE_KEYWORD} ${start}` : `${HL_DELETE_KEYWORD} ${start}${HL_RANGE_SEP}${end}`; +/** Format a concrete cut hunk header. */ +export function formatCutHeader(start: number, end = start): string { + return start === end ? `${HL_CUT_KEYWORD} ${start}` : `${HL_CUT_KEYWORD} ${start}${HL_RANGE_SEP}${end}`; } /** Format an insertion hunk header for a cursor position. */ diff --git a/packages/hashline/src/grammar.lark b/packages/hashline/src/grammar.lark index 41c7a2a32..e66c2afa5 100644 --- a/packages/hashline/src/grammar.lark +++ b/packages/hashline/src/grammar.lark @@ -7,21 +7,18 @@ file_header: "[" filename "#" file_hash "]" LF file_hash: /[0-9A-F]{4}/ filename: /[^#\r\n]+/ -hunk: replace_hunk | replace_block_hunk | insert_hunk | insert_block_hunk | delete_hunk | delete_block_hunk | remove_hunk | move_hunk -replace_hunk: replace_anchor LF emit_op* -replace_block_hunk: replace_block_anchor LF emit_op+ -insert_hunk: insert_anchor LF emit_op+ -insert_block_hunk: insert_block_anchor LF emit_op+ -delete_hunk: "DEL " header_range LF -delete_block_hunk: "DEL.BLK " LID LF -remove_hunk: "REM" LF -move_hunk: "MV " filename LF emit_op* -replace_anchor: "SWAP " header_range ":" -replace_block_anchor: "SWAP.BLK " LID ":" -insert_anchor: "INS." insert_pos ":" -insert_block_anchor: "INS.BLK.POST " LID ":" -insert_pos: "PRE " LID | "POST " LID | "HEAD" | "TAIL" -emit_op: "+" /(.*)/ LF +hunk: swap_hunk | ins_hunk | cut_hunk | paste_hunk | rem_hunk | mv_hunk +swap_hunk: "SWAP " header_range ":" LF body* + | "SWAP.BLK " LID ":" LF body+ +ins_hunk: "INS." pos ":" LF body+ +cut_hunk: "CUT" target LF +paste_hunk: "PASTE." pos LF +rem_hunk: "REM" LF +mv_hunk: "MV " filename LF body* + +target: " " header_range | ".BLK " LID +pos: "PRE " LID | "POST " LID | "BLK.POST " LID | "HEAD" | "TAIL" +body: "+" /(.*)/ LF header_range: LID ".=" LID LID: /[1-9]\d*/ diff --git a/packages/hashline/src/index.ts b/packages/hashline/src/index.ts index b7e61b17a..def2ee798 100644 --- a/packages/hashline/src/index.ts +++ b/packages/hashline/src/index.ts @@ -1,5 +1,6 @@ export * from "./apply"; export * from "./block"; +export * from "./clipboard"; export * from "./diff-preview"; export * from "./format"; export * from "./fs"; diff --git a/packages/hashline/src/input.ts b/packages/hashline/src/input.ts index e2b3f9455..fc918f113 100644 --- a/packages/hashline/src/input.ts +++ b/packages/hashline/src/input.ts @@ -10,10 +10,12 @@ import * as path from "node:path"; import { applyEdits } from "./apply"; import { resolveBlockEdits } from "./block"; +import { hasClipboardEdit } from "./clipboard"; import { HL_FILE_HASH_EXAMPLES, HL_FILE_HASH_LENGTH, HL_FILE_HASH_SEP, HL_FILE_PREFIX, HL_FILE_SUFFIX } from "./format"; +import { CLIPBOARD_INTERLEAVED_SECTIONS } from "./messages"; import { parsePatch, parsePatchStreaming } from "./parser"; import { Tokenizer } from "./tokenizer"; -import type { ApplyResult, BlockResolver, Edit, FileOp, SplitOptions } from "./types"; +import type { ApplyResult, BlockResolver, Clipboard, Edit, FileOp, SplitOptions } from "./types"; // Pure classification — single shared tokenizer is safe. const TOKENIZER = new Tokenizer(); @@ -97,6 +99,14 @@ interface RawSection { path: string; fileHash?: string; diff: string; + /** + * True when this section coalesced same-path sections that were NOT + * adjacent in the authored input (another file's section sat between + * them). Merging moves the later ops up to the first occurrence, which + * would silently reorder the clipboard register sequence — so clipboard + * ops are rejected in such sections. + */ + interleaved?: boolean; } /** @@ -239,10 +249,13 @@ export class PatchSection { readonly diff: string; #parsed: { edits: Edit[]; fileOp?: FileOp; warnings: string[] } | undefined; + #interleavedMerge: boolean; + constructor(raw: RawSection) { this.path = raw.path; this.fileHash = raw.fileHash; this.diff = raw.diff; + this.#interleavedMerge = raw.interleaved === true; } /** @@ -253,6 +266,12 @@ export class PatchSection { parse(): { edits: Edit[]; fileOp?: FileOp; warnings: readonly string[] } { this.#parsed ??= parsePatch(this.diff); const parsed = this.#parsed; + // Same-path sections merge into their first occurrence; when that merge + // crossed another file's section, the authored top-to-bottom register + // order is gone, so clipboard ops cannot apply deterministically. + if (this.#interleavedMerge && hasClipboardEdit(parsed.edits)) { + throw new Error(CLIPBOARD_INTERLEAVED_SECTIONS); + } const fileOp = parsed.fileOp === undefined ? undefined @@ -289,6 +308,8 @@ export class PatchSection { if (edit.kind === "delete") return true; // A `replace_block N:` edit is anchored to concrete content on line N. if (edit.kind === "block") return true; + // A `CUT` range reads concrete content. + if (edit.kind === "cut") return true; return edit.cursor.kind === "before_anchor" || edit.cursor.kind === "after_anchor"; }); } @@ -305,6 +326,10 @@ export class PatchSection { lines.add(edit.anchor.line); continue; } + if (edit.kind === "cut") { + for (let line = edit.range.start.line; line <= edit.range.end.line; line++) lines.add(line); + continue; + } if (edit.cursor.kind === "before_anchor" || edit.cursor.kind === "after_anchor") { lines.add(edit.cursor.anchor.line); } @@ -321,15 +346,18 @@ export class PatchSection { * * `blockResolver` resolves any `replace_block N:` edits against `text`; an * unresolvable block throws (this is the final, authoritative preview path). + * + * `clipboard` is the register shared by `CUT`/`PASTE` ops. Pass one when + * applying several sections so content can move across files. */ - applyTo(text: string, blockResolver?: BlockResolver): ApplyResult { + applyTo(text: string, blockResolver?: BlockResolver, clipboard?: Clipboard): ApplyResult { const { edits, warnings } = this.parse(); const resolveWarnings: string[] = []; const resolved = resolveBlockEdits(edits, text, this.path, blockResolver, { onUnresolved: "throw", onWarning: warning => resolveWarnings.push(warning), }); - const result = applyEdits(text, resolved); + const result = applyEdits(text, resolved, { clipboard: clipboard ?? {} }); // Preserve parse warnings so consumers don't need to call `parse()` // separately. const merged = [...warnings, ...resolveWarnings, ...(result.warnings ?? [])]; @@ -347,16 +375,16 @@ export class PatchSection { * * `blockResolver` resolves any `replace_block N:` edits against `text`; an * unresolvable block is silently dropped so a half-written file does not - * throw mid-stream. + * throw mid-stream. A `PASTE` with an empty register is dropped too. */ - applyPartialTo(text: string, blockResolver?: BlockResolver): ApplyResult { + applyPartialTo(text: string, blockResolver?: BlockResolver, clipboard?: Clipboard): ApplyResult { const { edits, warnings } = parsePatchStreaming(this.diff); const resolveWarnings: string[] = []; const resolved = resolveBlockEdits(edits, text, this.path, blockResolver, { onUnresolved: "drop", onWarning: warning => resolveWarnings.push(warning), }); - const result = applyEdits(text, resolved); + const result = applyEdits(text, resolved, { clipboard: clipboard ?? {}, onEmptyPaste: "drop" }); const merged = [...warnings, ...resolveWarnings, ...(result.warnings ?? [])]; return merged.length > 0 ? { ...result, warnings: merged } @@ -374,6 +402,7 @@ export class PatchSection { path, ...(this.fileHash !== undefined ? { fileHash: this.fileHash } : {}), diff: this.diff, + ...(this.#interleavedMerge ? { interleaved: true } : {}), }); next.#parsed = this.#parsed; return next; @@ -432,7 +461,8 @@ export class Patch { * fails. Path order is preserved by first occurrence. */ function mergeSamePathSections(sections: RawSection[]): RawSection[] { - const byPath = new Map(); + const byPath = new Map(); + let previousPath: string | undefined; for (const section of sections) { const existing = byPath.get(section.path); if (existing) { @@ -446,17 +476,24 @@ function mergeSamePathSections(sections: RawSection[]): RawSection[] { ); } if (existing.fileHash === undefined && section.fileHash !== undefined) existing.fileHash = section.fileHash; + // Merging across another file's section moves these ops up to the + // first occurrence; flag it so clipboard ops can refuse the reorder. + if (previousPath !== section.path) existing.interleaved = true; existing.diffs.push(section.diff); + previousPath = section.path; continue; } byPath.set(section.path, { ...(section.fileHash !== undefined ? { fileHash: section.fileHash } : {}), diffs: [section.diff], + interleaved: false, }); + previousPath = section.path; } return Array.from(byPath, ([sectionPath, entry]) => ({ path: sectionPath, ...(entry.fileHash !== undefined ? { fileHash: entry.fileHash } : {}), diff: entry.diffs.join("\n"), + ...(entry.interleaved ? { interleaved: true } : {}), })); } diff --git a/packages/hashline/src/messages.ts b/packages/hashline/src/messages.ts index d3a7e249a..673a7d7fa 100644 --- a/packages/hashline/src/messages.ts +++ b/packages/hashline/src/messages.ts @@ -31,7 +31,19 @@ export function formatAnchoredContext(anchorLines: readonly number[], fileLines: return rows; } /** Concrete range operation rejected because its absolute end precedes its start. */ -export type AbsoluteRangeOp = "replace" | "delete"; +export type AbsoluteRangeOp = "replace" | "cut"; + +/** Header forms per concrete-range op, used to compose retry suggestions. */ +const RANGE_OP_FORMS: Record = { + replace: { keyword: "SWAP", colon: ":", blockKeyword: "SWAP.BLK" }, + cut: { keyword: "CUT", colon: "", blockKeyword: "CUT.BLK" }, +}; + +/** `OP.BLK N`-style header for a concrete-range op (`SWAP.BLK 5:` / `CUT.BLK 5`). */ +function blockFormAt(op: AbsoluteRangeOp, line: number): string { + const forms = RANGE_OP_FORMS[op]; + return `${forms.blockKeyword} ${line}${forms.colon}`; +} /** Explain absolute range endpoints and provide safe, non-applying retry forms. */ export function invalidAbsoluteRangeMessage( @@ -41,15 +53,14 @@ export function invalidAbsoluteRangeMessage( op: AbsoluteRangeOp, block?: BlockSpan, ): string { - const single = op === "replace" ? `SWAP ${start}${HL_RANGE_SEP}${start}:` : `DEL ${start}`; + const forms = RANGE_OP_FORMS[op]; + const single = op === "replace" ? `SWAP ${start}${HL_RANGE_SEP}${start}:` : `${forms.keyword} ${start}`; const countedEnd = start + end - 1; const counted = Number.isSafeInteger(countedEnd) && countedEnd >= start - ? op === "replace" - ? `SWAP ${start}${HL_RANGE_SEP}${countedEnd}:` - : `DEL ${start}${HL_RANGE_SEP}${countedEnd}` + ? `${forms.keyword} ${start}${HL_RANGE_SEP}${countedEnd}${forms.colon}` : null; - const blockForm = op === "replace" ? `SWAP.BLK ${start}:` : `DEL.BLK ${start}`; + const blockForm = blockFormAt(op, start); let message = `line ${patchLine}: Invalid absolute range: start ${start}, end ${end}. ` + `The value after \`${HL_RANGE_SEP}\` is an absolute source line, not a line count or replacement length. ` + @@ -99,10 +110,10 @@ export const MINUS_ROW_REJECTED = "`-` rows are not valid; the range already names the lines being changed. For Markdown bullets or other literal `-` lines, prefix the literal row with `+`: `+- item`."; /** Replace hunk with no body. */ -export const EMPTY_REPLACE = `\`SWAP N${HL_RANGE_SEP}M:\` needs at least one \`+TEXT\` body row. To delete lines, use \`DEL N${HL_RANGE_SEP}M\`.`; +export const EMPTY_REPLACE = `\`SWAP N${HL_RANGE_SEP}M:\` needs at least one \`+TEXT\` body row. To delete lines, use \`CUT N${HL_RANGE_SEP}M\`.`; -/** `replace_block N:` hunk with no body. */ -export const EMPTY_BLOCK = "`SWAP.BLK N:` needs at least one `+TEXT` body row. To delete a block, use `DEL.BLK N`."; +/** `SWAP.BLK N:` hunk with no body. */ +export const EMPTY_BLOCK = "`SWAP.BLK N:` needs at least one `+TEXT` body row. To delete a block, use `CUT.BLK N`."; /** Optional source-aware suggestions appended to block-anchor diagnostics. */ export interface BlockDiagnosticSuggestions { @@ -113,26 +124,24 @@ export interface BlockDiagnosticSuggestions { } /** - * Block-anchored replace/delete could not resolve to a syntactic block - * (unsupported language, blank/out-of-range line, no node beginning on N, or - * parse error). Appends a {@link formatAnchoredContext} preview when - * `fileLines` is given. `insert_after_block N:` never reaches this — it is - * lowered to plain `insert after N:` instead (see - * {@link insertAfterBlockUnresolvedLoweredWarning}). + * A block-anchored replace/cut could not resolve to a syntactic block. + * Appends a {@link formatAnchoredContext} preview when `fileLines` is given. + * `INS.BLK.POST N:` never reaches this path; it lowers to `INS.POST N:`. */ export function blockUnresolvedMessage( line: number, - op: "replace" | "delete" = "replace", + op: AbsoluteRangeOp = "replace", fileLines?: readonly string[], suggestions: BlockDiagnosticSuggestions = {}, ): string { - const phrase = op === "delete" ? `DEL.BLK ${line}` : `SWAP.BLK ${line}:`; - const fallback = op === "delete" ? `DEL ${line}${HL_RANGE_SEP}M` : `SWAP ${line}${HL_RANGE_SEP}M:`; + const forms = RANGE_OP_FORMS[op]; + const phrase = blockFormAt(op, line); + const fallback = `${forms.keyword} ${line}${HL_RANGE_SEP}M${forms.colon}`; const anchorText = fileLines?.[line - 1]; const nextBlock = suggestions.nextBlock; let message: string; if (anchorText !== undefined && anchorText.trim().length === 0 && nextBlock) { - const retry = op === "delete" ? `DEL.BLK ${nextBlock.start}` : `SWAP.BLK ${nextBlock.start}:`; + const retry = blockFormAt(op, nextBlock.start); message = `Line ${line} is blank; no syntactic block can begin there. ` + `The next multi-line block begins at line ${nextBlock.start} and ends at line ${nextBlock.end}. ` + @@ -144,7 +153,7 @@ export function blockUnresolvedMessage( } const enclosingBlock = suggestions.enclosingBlock; if (enclosingBlock) { - const retry = op === "delete" ? `DEL.BLK ${enclosingBlock.start}` : `SWAP.BLK ${enclosingBlock.start}:`; + const retry = blockFormAt(op, enclosingBlock.start); message += ` The nearest enclosing multi-line block begins at line ${enclosingBlock.start} ` + `and ends at line ${enclosingBlock.end}; use \`${retry}\` to target it.`; @@ -156,26 +165,46 @@ export function blockUnresolvedMessage( return message; } -/** Block-anchored edit reached a path with no {@link BlockResolver} wired in — a host-configuration bug. */ +/** Block-anchored edit reached a path with no {@link BlockResolver} wired in. */ export const BLOCK_RESOLVER_UNAVAILABLE = - "`SWAP.BLK`/`DEL.BLK`/`INS.BLK.POST` are not available here (no block resolver configured). Use a concrete line range."; + "Block ops (`SWAP.BLK`, `INS.BLK.POST`, `CUT.BLK`, `PASTE.BLK.POST`) are not available here (no block resolver configured). Use a concrete line range."; /** - * `insert_after_block N:` anchored on a closing-delimiter line, lowered to - * plain `insert after N:` — the closer ends a block, and inserting after it - * is exactly what the plain form does. + * An after-block op anchored on a closing-delimiter line, lowered to its + * plain after-line form — the closer ends a block, and inserting after it is + * exactly what the plain form does. */ -export function insertAfterBlockCloserLoweredWarning(line: number): string { - return `\`INS.BLK.POST ${line}:\` anchors on a closing delimiter, so it was applied as plain \`INS.POST ${line}:\`. Anchor on the line that OPENS the construct.`; +function closerLoweredWarning(blockForm: string, plainForm: string): string { + return `\`${blockForm}\` anchors on a closing delimiter, so it was applied as plain \`${plainForm}\`. Anchor on the line that OPENS the construct.`; } /** - * `insert_after_block N:` anchor unresolvable (unsupported language, blank - * line, parse error, or no resolver), lowered to plain `insert after N:` — - * applying with a warning beats failing the patch. + * An after-block op whose anchor was unresolvable (unsupported language, + * blank line, parse error, or no resolver), lowered to its plain after-line + * form — applying with a warning beats failing the patch. */ +function unresolvedLoweredWarning(blockForm: string, line: number, plainForm: string): string { + return `\`${blockForm}\` could not resolve a syntactic block on line ${line}, so it was applied as plain \`${plainForm}\`. Verify the landing line; anchor on a line that OPENS a construct.`; +} + +/** `INS.BLK.POST N:` anchored on a closing-delimiter line; applied as `INS.POST N:`. */ +export function insertAfterBlockCloserLoweredWarning(line: number): string { + return closerLoweredWarning(`INS.BLK.POST ${line}:`, `INS.POST ${line}:`); +} + +/** `INS.BLK.POST N:` anchor unresolvable; applied as `INS.POST N:`. */ export function insertAfterBlockUnresolvedLoweredWarning(line: number): string { - return `\`INS.BLK.POST ${line}:\` could not resolve a syntactic block on line ${line}, so it was applied as plain \`INS.POST ${line}:\`. Verify the landing line; anchor on a line that OPENS a construct.`; + return unresolvedLoweredWarning(`INS.BLK.POST ${line}:`, line, `INS.POST ${line}:`); +} + +/** `PASTE.BLK.POST N` anchored on a closing-delimiter line; applied as `PASTE.POST N`. */ +export function pasteAfterBlockCloserLoweredWarning(line: number): string { + return closerLoweredWarning(`PASTE.BLK.POST ${line}`, `PASTE.POST ${line}`); +} + +/** `PASTE.BLK.POST N` anchor unresolvable; applied as `PASTE.POST N`. */ +export function pasteAfterBlockUnresolvedLoweredWarning(line: number): string { + return unresolvedLoweredWarning(`PASTE.BLK.POST ${line}`, line, `PASTE.POST ${line}`); } /** * A one-sided boundary echo whose payload is too short to be the widened @@ -228,14 +257,11 @@ export function ambiguousCloserSpareMessage( } /** - * Internal invariant: `applyEdits` received an unresolved `replace_block N:` - * edit; `resolveBlockEdits` must run first. Wiring bug, not authored input. + * Internal invariant: `applyEdits` received an unresolved block edit; + * `resolveBlockEdits` must run first. */ export const UNRESOLVED_BLOCK_INTERNAL = - "internal error: unresolved `SWAP.BLK` edit reached the applier (resolveBlockEdits was not run)."; - -/** Delete hunk received a body row. */ -export const DELETE_TAKES_NO_BODY = `\`DEL N${HL_RANGE_SEP}M\` does not take body rows. Remove the body, or use \`SWAP N${HL_RANGE_SEP}M:\`.`; + "internal error: unresolved block edit reached the applier (resolveBlockEdits was not run)."; /** `REM` received a body row or coexists with line edits. */ export const REM_TAKES_NO_BODY = @@ -245,8 +271,23 @@ export const REM_TAKES_NO_BODY = export const MOVE_TAKES_NO_BODY = "`MV DEST` does not take body rows. Put line edits above the `MV` row; the destination path follows `MV` on the same line."; -/** `delete_block N` hunk received a body row. */ -export const DELETE_BLOCK_TAKES_NO_BODY = "`DEL.BLK N` does not take body rows. Remove the body, or use `SWAP.BLK N:`."; +/** `CUT N.=M` hunk received a body row. */ +export const CUT_TAKES_NO_BODY = `\`CUT N${HL_RANGE_SEP}M\` captures + deletes lines and takes no body rows. To replace lines with new content, use \`SWAP N${HL_RANGE_SEP}M:\`.`; + +/** `PASTE` hunk received a body row. */ +export const PASTE_TAKES_NO_BODY = + "`PASTE` inserts the clipboard content and takes no `+` body rows. To insert literal text, use `INS`."; + +/** `PASTE` ran with an empty clipboard register. */ +export const EMPTY_PASTE = `\`PASTE\` found nothing in the clipboard. Ops run top-to-bottom across the whole patch (sections included): put \`CUT N${HL_RANGE_SEP}M\` or \`CUT.BLK N\` above the \`PASTE\`.`; + +/** + * Clipboard ops inside a same-path section that was merged across another + * file's section. Same-path sections coalesce into their first occurrence, so + * an interleaved layout would silently reorder the register sequence. + */ +export const CLIPBOARD_INTERLEAVED_SECTIONS = + "`CUT`/`PASTE` cannot be used in a file whose sections are interleaved with another file's: same-path sections merge into the first occurrence, which would reorder the clipboard sequence. Keep each file's ops under ONE `[path#TAG]` header."; /** Insert hunk with no body. */ export const EMPTY_INSERT = "`INS` needs at least one `+TEXT` body row."; @@ -413,33 +454,29 @@ export function unseenLinesMessage( } /** Op kind of a deferred block edit, for {@link blockSingleLineMessage}. */ -export type BlockOp = "replace" | "delete" | "insert_after"; +export type BlockOp = "replace" | "insert_after" | "cut" | "paste_after"; + +/** Display forms per deferred-block op: block keyword, trailing colon, and single-line plain form. */ +const BLOCK_OP_FORMS: Record string }> = { + replace: { keyword: "SWAP.BLK", colon: ":", plain: line => `SWAP ${line}${HL_RANGE_SEP}${line}:` }, + insert_after: { keyword: "INS.BLK.POST", colon: ":", plain: line => `INS.POST ${line}:` }, + cut: { keyword: "CUT.BLK", colon: "", plain: line => `CUT ${line}` }, + paste_after: { keyword: "PASTE.BLK.POST", colon: "", plain: line => `PASTE.POST ${line}` }, +}; /** - * A `replace_block`/`delete_block`/`insert_after_block` anchor resolved to a - * single line — almost always a bare statement the model mis-anchored, not a - * multi-line construct. The plain op is unambiguous for one line; the block - * form only earns its keep when it spares counting a closing line you cannot - * see. Reject and point at both fixes. + * A block-op anchor resolved to a single line: line N is a bare statement, + * not the opening line of a multi-line construct. The plain op is exact for + * one line, so reject and point at it. */ export function blockSingleLineMessage(line: number, op: BlockOp, enclosingBlock?: BlockSpan): string { - const blockForm = op === "insert_after" ? "INS.BLK.POST" : op === "delete" ? "DEL.BLK" : "SWAP.BLK"; - const plainForm = - op === "insert_after" - ? `INS.POST ${line}:` - : op === "delete" - ? `DEL ${line}` - : `SWAP ${line}${HL_RANGE_SEP}${line}:`; + const forms = BLOCK_OP_FORMS[op]; + const plainForm = forms.plain(line); let message = - `\`${blockForm} ${line}\` resolved a single-line block — line ${line} is a bare statement, not the opening line ` + + `\`${forms.keyword} ${line}\` resolved a single-line block — line ${line} is a bare statement, not the opening line ` + `of a multi-line construct. For only this statement use \`${plainForm}\`.`; if (enclosingBlock) { - const enclosingForm = - op === "insert_after" - ? `INS.BLK.POST ${enclosingBlock.start}:` - : op === "delete" - ? `DEL.BLK ${enclosingBlock.start}` - : `SWAP.BLK ${enclosingBlock.start}:`; + const enclosingForm = `${forms.keyword} ${enclosingBlock.start}${forms.colon}`; message += ` The nearest enclosing multi-line block begins at line ${enclosingBlock.start} ` + `and ends at line ${enclosingBlock.end}; use \`${enclosingForm}\` to target it.`; diff --git a/packages/hashline/src/parser.ts b/packages/hashline/src/parser.ts index 13751113b..b6d77a6b6 100644 --- a/packages/hashline/src/parser.ts +++ b/packages/hashline/src/parser.ts @@ -7,14 +7,14 @@ import { HL_PAYLOAD_REPLACE, HL_RANGE_SEP } from "./format"; import { type AbsoluteRangeOp, BARE_BODY_AUTO_PIPED_WARNING, - DELETE_BLOCK_TAKES_NO_BODY, - DELETE_TAKES_NO_BODY, + CUT_TAKES_NO_BODY, EMPTY_BLOCK, EMPTY_INSERT, invalidAbsoluteRangeMessage, MINUS_BULLET_AUTO_PIPED_WARNING, MINUS_ROW_REJECTED, MOVE_TAKES_NO_BODY, + PASTE_TAKES_NO_BODY, REM_TAKES_NO_BODY, } from "./messages"; import { stripOneLeadingHashlinePrefix } from "./prefixes"; @@ -75,6 +75,23 @@ function isSkippableCommentLine(line: string): boolean { return line.trimStart().startsWith("#"); } +/** + * Body-row rejection message for targets that take no `+TEXT` rows, or `null` + * for targets whose header is followed by a body. + */ +function bodylessTargetMessage(target: BlockTarget): string | null { + switch (target.kind) { + case "cut": + case "cut_block": + return CUT_TAKES_NO_BODY; + case "paste": + case "paste_after_block": + return PASTE_TAKES_NO_BODY; + default: + return null; + } +} + /** * Stripped remainder of a bare `N: ` row that is a lone quoted or * numeric literal (optionally comma-terminated) — the shape of a numeric-keyed @@ -102,13 +119,13 @@ function detectApplyPatchContamination(text: string, _hasPending: boolean): stri return ( `apply_patch sentinel ${JSON.stringify(preview)} is not valid in hashline. ` + "File sections start with `[path#HASH]` (no `Update File:` / `Add File:` keyword). " + - `Use \`SWAP N${HL_RANGE_SEP}M:\`, \`DEL N${HL_RANGE_SEP}M\`, or \`INS.PRE|POST|HEAD|TAIL:\` ops.` + `Use \`SWAP N${HL_RANGE_SEP}M:\`, \`CUT N${HL_RANGE_SEP}M\`, or \`INS.PRE|POST|HEAD|TAIL:\` ops.` ); } if (/^@@\s+[-+]?\d+,\d+\s+[-+]?\d+,\d+\s+@@/.test(trimmed)) { return ( "unified-diff hunk header (`@@ -N,M +N,M @@`) is not valid in hashline. " + - `Use \`SWAP N${HL_RANGE_SEP}M:\`, \`DEL N${HL_RANGE_SEP}M\`, or \`INS.PRE|POST|HEAD|TAIL:\` ops.` + `Use \`SWAP N${HL_RANGE_SEP}M:\`, \`CUT N${HL_RANGE_SEP}M\`, or \`INS.PRE|POST|HEAD|TAIL:\` ops.` ); } if (trimmed.startsWith("@@")) { @@ -118,17 +135,20 @@ function detectApplyPatchContamination(text: string, _hasPending: boolean): stri `Drop the \`@@ ... @@\` brackets and write a verb header such as \`SWAP N${HL_RANGE_SEP}M:\`.` ); } - if (/^DEL\s+[1-9]\d*(?:\s*(?:\.\.|\.=|-|…|\s)\s*[1-9]\d*)?\s*:/.test(trimmed)) { - return `\`DEL N${HL_RANGE_SEP}M\` has no colon and no body. Remove the colon and body rows.`; + // Bare `PASTE` (optionally `PASTE 5` / `PASTE:`) — the op requires an + // explicit position suffix; a bare form would otherwise surface as a + // confusing body-row rejection under the preceding hunk. + if (/^PASTE(?:\s+[1-9]\d*)?\s*:?\s*$/.test(trimmed)) { + return "`PASTE` needs a position: use `PASTE.PRE N` / `PASTE.POST N` / `PASTE.HEAD` / `PASTE.TAIL` / `PASTE.BLK.POST N`."; } if (/^[1-9]\d*\s*$/.test(trimmed)) { - return `hunk headers need a verb. Use \`SWAP ${trimmed}${HL_RANGE_SEP}${trimmed}:\` to replace, or \`DEL ${trimmed}\` to delete.`; + return `hunk headers need a verb. Use \`SWAP ${trimmed}${HL_RANGE_SEP}${trimmed}:\` to replace, or \`CUT ${trimmed}\` to delete.`; } const bareRange = /^([1-9]\d*)\s*[-. …=]+\s*([1-9]\d*)\s*:?$/.exec(trimmed); if (bareRange !== null) { return ( `bare range hunk header ${JSON.stringify(trimmed)} is not valid. ` + - `Hunk headers need a verb: write \`SWAP ${bareRange[1]}${HL_RANGE_SEP}${bareRange[2]}:\` or \`DEL ${bareRange[1]}${HL_RANGE_SEP}${bareRange[2]}\`.` + `Hunk headers need a verb: write \`SWAP ${bareRange[1]}${HL_RANGE_SEP}${bareRange[2]}:\` or \`CUT ${bareRange[1]}${HL_RANGE_SEP}${bareRange[2]}\`.` ); } return null; @@ -207,8 +227,11 @@ export class Executor { return; case "op-block": this.#discardPendingSkippableComments(); - if (token.target.kind === "replace" || token.target.kind === "delete") { - validateRange(token.target.range, token.lineNum, token.target.kind); + if (token.target.kind === "replace") { + validateRange(token.target.range, token.lineNum, "replace"); + } + if (token.target.kind === "cut") { + validateRange(token.target.range, token.lineNum, "cut"); } if (token.target.kind === "rem") { this.#flushPending(); @@ -241,8 +264,7 @@ export class Executor { endStreaming(): { edits: Edit[]; fileOp?: FileOp; warnings: string[] } { this.#consumePendingSkippableComments(); if (this.#pending && this.#pending.payloads.length > 0) this.#flushPending(); - else if (this.#pending?.target.kind === "delete" || this.#pending?.target.kind === "delete_block") - this.#flushPending(); + else if (this.#pending && bodylessTargetMessage(this.#pending.target) !== null) this.#flushPending(); else this.#pending = undefined; this.#validateFileOp(); this.#validateNoOverlappingDeletes(); @@ -312,8 +334,8 @@ export class Executor { `Got ${JSON.stringify(`${HL_PAYLOAD_REPLACE}${text}`)}.`, ); } - if (pending.target.kind === "delete") throw new Error(`line ${lineNum}: ${DELETE_TAKES_NO_BODY}`); - if (pending.target.kind === "delete_block") throw new Error(`line ${lineNum}: ${DELETE_BLOCK_TAKES_NO_BODY}`); + const noBodyOnLiteral = bodylessTargetMessage(pending.target); + if (noBodyOnLiteral !== null) throw new Error(`line ${lineNum}: ${noBodyOnLiteral}`); this.#commitDeferredBlanks(pending); pending.payloads.push({ kind: "literal", text, lineNum }); } @@ -327,9 +349,8 @@ export class Executor { this.#handleBlank(text, lineNum); return; } - if (this.#pending.target.kind === "delete") throw new Error(`line ${lineNum}: ${DELETE_TAKES_NO_BODY}`); - if (this.#pending.target.kind === "delete_block") - throw new Error(`line ${lineNum}: ${DELETE_BLOCK_TAKES_NO_BODY}`); + const noBodyOnRaw = bodylessTargetMessage(this.#pending.target); + if (noBodyOnRaw !== null) throw new Error(`line ${lineNum}: ${noBodyOnRaw}`); const row: PayloadRow = { kind: "literal", text, lineNum, bare: true }; // `-` rows are held and judged at flush time by #resolveMinusRows, // once the whole body is visible. @@ -350,7 +371,7 @@ export class Executor { if (text.trim().length === 0) return; throw new Error( `line ${lineNum}: payload line has no preceding hunk header. ` + - `Use \`SWAP N${HL_RANGE_SEP}M:\`, \`DEL N${HL_RANGE_SEP}M\`, or \`INS.PRE|POST|HEAD|TAIL:\` above the body. Got ${JSON.stringify(text)}.`, + `Use \`SWAP N${HL_RANGE_SEP}M:\`, \`CUT N${HL_RANGE_SEP}M\`, or \`INS.PRE|POST|HEAD|TAIL:\` above the body. Got ${JSON.stringify(text)}.`, ); } @@ -364,7 +385,7 @@ export class Executor { #handleBlank(text: string, lineNum: number): void { const pending = this.#pending; if (!pending) return; - if (pending.target.kind === "delete" || pending.target.kind === "delete_block") return; + if (bodylessTargetMessage(pending.target) !== null) return; if (pending.payloads.length === 0) return; pending.deferredBlanks.push({ kind: "literal", text, lineNum, bare: true }); } @@ -455,7 +476,24 @@ export class Executor { for (let line = range.start.line; line <= range.end.line; line++) this.#pushDelete({ line }, lineNum); } - #pushBlock(anchor: Anchor, payloads: readonly PayloadRow[], lineNum: number, mode?: "insert_after"): void { + #pushCut(range: ParsedRange, lineNum: number): void { + this.#edits.push({ + kind: "cut", + range: { start: { ...range.start }, end: { ...range.end } }, + lineNum, + index: this.#editIndex++, + }); + // Capture before ordinary per-line deletes are applied. Keeping deletion + // as low-level edits preserves overlap validation and recovery remapping. + this.#pushDeleteRange(range, lineNum); + } + + #pushBlock( + anchor: Anchor, + payloads: readonly PayloadRow[], + lineNum: number, + mode?: "insert_after" | "cut" | "paste_after", + ): void { this.#edits.push({ kind: "block", anchor: { ...anchor }, @@ -477,13 +515,20 @@ export class Executor { this.#resolveMinusRows(payloads); this.#stripBarePrefixesIfUniform(payloads); this.#pending = undefined; - if (target.kind === "delete") { - this.#pushDeleteRange(target.range, lineNum); + if (target.kind === "cut") { + this.#pushCut(target.range, lineNum); return; } - if (target.kind === "delete_block") { - // A block edit with no payloads resolves to a pure block deletion. - this.#pushBlock(target.anchor, [], lineNum); + if (target.kind === "cut_block") { + this.#pushBlock(target.anchor, [], lineNum, "cut"); + return; + } + if (target.kind === "paste") { + this.#edits.push({ kind: "paste", cursor: cloneCursor(target.cursor), lineNum, index: this.#editIndex++ }); + return; + } + if (target.kind === "paste_after_block") { + this.#pushBlock(target.anchor, [], lineNum, "paste_after"); return; } if (target.kind === "block") { diff --git a/packages/hashline/src/patcher.ts b/packages/hashline/src/patcher.ts index 162aee2ad..f391809bc 100644 --- a/packages/hashline/src/patcher.ts +++ b/packages/hashline/src/patcher.ts @@ -25,6 +25,7 @@ import * as path from "node:path"; import { applyEdits } from "./apply"; import { hasBlockEdit, resolveBlockEdits } from "./block"; +import { commitClipboard, forkClipboard, validateClipboardSequence } from "./clipboard"; import { computeFileHash, formatHashlineHeader } from "./format"; import type { Filesystem, WriteResult } from "./fs"; import { isNotFound } from "./fs"; @@ -42,7 +43,7 @@ import { detectLineEnding, type LineEnding, normalizeToLF, restoreLineEndings, s import { InvalidAbsoluteRangeError } from "./parser"; import { Recovery, type RecoveryResult } from "./recovery"; import type { Snapshot, SnapshotStore } from "./snapshots"; -import type { ApplyResult, BlockResolution, BlockResolver, BlockSpan, Edit, FileOp } from "./types"; +import type { ApplyResult, BlockResolution, BlockResolver, BlockSpan, Clipboard, Edit, FileOp } from "./types"; /** * Upper bound on the number of unseen anchor lines whose actual file content @@ -81,6 +82,12 @@ export interface PatcherOptions { * validate on content hash alone and any anchor into the tagged content applies. */ enforceSeenLines?: boolean; + /** + * Host-owned clipboard register shared across batches, so `CUT` content + * can be `PASTE`d by a later {@link Patcher.apply} call. Each batch works + * on a fork and publishes it back only after writes land. + */ + clipboard?: Clipboard; } /** Per-section result returned by {@link Patcher.apply} / {@link Patcher.commit}. */ @@ -116,9 +123,8 @@ export interface PatchSectionResult { /** Destination path when this section includes `MV DEST`. */ moveDest?: string; /** - * Resolved spans for any `replace_block`/`delete_block` ops, present when the - * apply matched the tagged content. Undefined for patches with no block ops - * (and for resolutions routed through drift recovery, where numbers shift). + * Resolved spans for block ops, present when the apply matched the tagged + * content. Undefined for patches with no block ops and for drift recovery. */ blockResolutions?: BlockResolution[]; } @@ -158,6 +164,8 @@ function hasAnchorScopedEdit(edits: readonly Edit[]): boolean { if (edit.kind === "delete") return true; // A `replace_block N:` edit anchors to concrete content on line N. if (edit.kind === "block") return true; + // A `CUT` range reads concrete content. + if (edit.kind === "cut") return true; return edit.cursor.kind === "before_anchor" || edit.cursor.kind === "after_anchor"; }); } @@ -211,6 +219,7 @@ export class Patcher { readonly snapshots: SnapshotStore; readonly recovery: Recovery; readonly blockResolver: BlockResolver | undefined; + readonly clipboard: Clipboard | undefined; readonly #enforceSeenLines: boolean; constructor(options: PatcherOptions) { @@ -221,6 +230,7 @@ export class Patcher { this.snapshots = options.snapshots; this.recovery = new Recovery(options.snapshots); this.blockResolver = options.blockResolver; + this.clipboard = options.clipboard; this.#enforceSeenLines = options.enforceSeenLines ?? true; } @@ -231,16 +241,34 @@ export class Patcher { * {@link PatchSectionResult} per section in the original patch order. */ async apply(patch: Patch): Promise { + // One register per batch: `CUT` in one section feeds `PASTE` in a later + // one, so content can move across files. A host-owned register + // (see PatcherOptions.clipboard) additionally persists across batches: + // work on a fork and publish it per landed section, so a failed batch + // never poisons the persistent register and a mid-batch failure still + // preserves content already cut from disk. + const clipboard = forkClipboard(this.clipboard); + // Single-section fast path. if (patch.sections.length === 1) { - const prepared = await this.prepare(patch.sections[0]); - return { sections: [await this.commit(prepared)] }; + const prepared = await this.prepare(patch.sections[0], clipboard); + const result = await this.commit(prepared); + if (this.clipboard !== undefined) commitClipboard(clipboard, this.clipboard); + return { sections: [result] }; } // Prepare every section first so any failure (stale hash, missing // file, parse error, in-memory no-op) surfaces before any write. const prepared: PreparedSection[] = []; - for (const section of patch.sections) prepared.push(await this.prepare(section)); + // Register state after each section's prepare. Commits are non-atomic: + // when a later write fails, the sections before it are already on disk, + // so the host register must reflect exactly the landed prefix — content + // a landed CUT deleted would otherwise be lost. + const sectionStates: Clipboard[] = []; + for (const section of patch.sections) { + prepared.push(await this.prepare(section, clipboard)); + sectionStates.push(forkClipboard(clipboard)); + } assertUniqueCanonicalPaths(prepared); for (const entry of prepared) { if (entry.isNoop) { @@ -266,6 +294,7 @@ export class Patcher { { cause: error }, ); } + if (this.clipboard !== undefined) commitClipboard(sectionStates[index], this.clipboard); } return { sections: results }; } @@ -275,8 +304,10 @@ export class Patcher { * No writes hit the filesystem. Use for CI checks and dry runs. */ async preflight(patch: Patch): Promise { + // Dry run: fork the register and never publish it back. + const clipboard = forkClipboard(this.clipboard); const prepared: PreparedSection[] = []; - for (const section of patch.sections) prepared.push(await this.prepare(section)); + for (const section of patch.sections) prepared.push(await this.prepare(section, clipboard)); assertUniqueCanonicalPaths(prepared); for (const entry of prepared) { if (entry.isNoop) { @@ -310,10 +341,13 @@ export class Patcher { * {@link PreparedSection} which can be fed to {@link commit} to land * the result on the filesystem. * + * `clipboard` is the register shared by `CUT`/`PASTE` ops. Pass the batch + * register when preparing several sections so content can move across files. + * * Throws on parse error, missing-file-for-anchored-edit, or unrecovered * tag mismatch ({@link MismatchError}). */ - async prepare(section: PatchSection): Promise { + async prepare(section: PatchSection, clipboard?: Clipboard): Promise { const parsed = await this.#parseWithRangeDiagnostics(section); const parseWarnings = [...parsed.warnings]; const fileOp = parsed.fileOp; @@ -360,6 +394,7 @@ export class Patcher { const lineEnding = detectLineEnding(text); const normalized = normalizeToLF(text); + const register = clipboard ?? {}; const applyResult = fileOp?.kind === "rem" ? this.#applyWithRecovery({ @@ -368,6 +403,7 @@ export class Patcher { exists: read.exists, normalized, edits: [], + clipboard: register, }) : this.#applyWithRecovery({ section: target, @@ -375,6 +411,7 @@ export class Patcher { exists: read.exists, normalized, edits: parsed.edits, + clipboard: register, }); return new PreparedSection( @@ -639,8 +676,9 @@ export class Patcher { exists: boolean; normalized: string; edits: readonly Edit[]; + clipboard: Clipboard; }): ApplyResult { - const { section, canonicalPath, exists, normalized, edits } = args; + const { section, canonicalPath, exists, normalized, edits, clipboard } = args; const expected = exists ? section.fileHash : undefined; // The 4-hex tag is content-derived: when the live text hashes to it, // trust the match and apply directly. `storedSnapshotForTag` feeds the @@ -673,6 +711,11 @@ export class Patcher { onWarning: warning => resolveWarnings.push(warning), }); } + // Surface clipboard sequencing mistakes (`PASTE` before any capture, + // capturing over un-pasted `CUT` content) with their targeted message + // before the recovery path below, which swallows apply failures and + // re-surfaces them as tag-mismatch errors. + validateClipboardSequence(resolved, clipboard); const withResolveWarnings = (result: ApplyResult): ApplyResult => resolveWarnings.length === 0 ? result @@ -689,7 +732,7 @@ export class Patcher { if (expected !== undefined && this.#enforceSeenLines) { this.#assertSeenLines(section, expected, matchedSnapshot); } - const result = applyEdits(normalized, resolved); + const result = applyEdits(normalized, resolved, { clipboard }); return withResolveWarnings(blockResolutions.length > 0 ? { ...result, blockResolutions } : result); } // Head/tail-only inserts are position-stable: "start"/"end" cannot move @@ -697,7 +740,7 @@ export class Patcher { // content and warn instead of hard-failing — unlike an anchored // mismatch, which cannot be safely relocated and must reject. if (!hasAnchorScopedEdit(resolved)) { - const result = applyEdits(normalized, resolved); + const result = applyEdits(normalized, resolved, { clipboard }); return withResolveWarnings({ ...result, warnings: [HEADTAIL_DRIFT_WARNING, ...(result.warnings ?? [])] }); } // File drifted: map every anchor from the tagged snapshot to unchanged @@ -707,6 +750,7 @@ export class Patcher { currentText: normalized, fileHash: expected, edits: resolved, + clipboard, }); if (recovered) return withResolveWarnings(recoveryToApplyResult(recovered)); const hashRecognized = this.snapshots.byHash(canonicalPath, expected) !== null; diff --git a/packages/hashline/src/prompt.md b/packages/hashline/src/prompt.md index 655401689..a24c7fd8a 100644 --- a/packages/hashline/src/prompt.md +++ b/packages/hashline/src/prompt.md @@ -1,49 +1,43 @@ -Your patch language names lines to replace, delete, or insert at, then lists the new content. Rule of thumb: a header ending in `:` is followed by `+` body rows; `DEL` has no body. +Line-anchored patch language: name original lines to replace, cut, or insert at, then list new content. A header ending in `:` takes `+` body rows; `CUT`, `PASTE`, `REM`, `MV` take none. -Every file section starts with `[PATH#TAG]`. `TAG` = 4-hex snapshot tag from your latest `read`/`search`, REQUIRED on every section — no hashless form. Create new files with `write`; hashline only edits existing files. +Every file section starts `[PATH#TAG]`. `TAG` = 4-hex snapshot tag from your latest `read`/`search` — REQUIRED on every section. Create new files with `write`; hashline only edits existing files. -`SWAP N.=M:` — replace original lines N.=M with the body rows below. INCLUSIVE — line M is consumed too. -`SWAP.BLK N:` — replace the whole syntactic block that BEGINS on line N; tree-sitter resolves the closing line. Body rows below. -`DEL N.=M` — delete original lines N.=M. No body. -`DEL.BLK N` — delete the whole syntactic block that BEGINS on line N. -`INS.PRE N:` — insert the body rows immediately before line N. -`INS.POST N:` — insert the body rows immediately after line N. -`INS.BLK.POST N:` — insert the body rows after the END of the block that BEGINS on line N — outside it, at sibling depth. To append inside a block, use `INS.POST`. -`INS.HEAD:` / `INS.TAIL:` — insert the body rows at the very start / end of the file. -`REM` — delete the whole file named by the section header. No body, no line ops. -`MV DEST` — move/rename the section file to `DEST` (a path, quoted when it contains spaces). Line edits above `MV` land on the source first, then the final content is written at `DEST`. -Single line: `SWAP N.=N:` / `DEL N`. The range is the ORIGINAL lines you touch; body length is irrelevant (replacing 1 line with 10 is still `SWAP N.=N:`). +`SWAP N.=M:` — replace original lines N.=M (INCLUSIVE). +`SWAP.BLK N:` — replace the whole syntactic block BEGINNING on line N; its closing line is resolved for you. +`CUT N.=M` / `CUT.BLK N` — delete lines N.=M / the block beginning at N, and capture them for `PASTE`. +`INS.PRE N:` / `INS.POST N:` — insert immediately before / after line N. +`INS.BLK.POST N:` — insert after the END of the block beginning at N, outside it at sibling depth. Append inside a block → `INS.POST`. +`INS.HEAD:` / `INS.TAIL:` — insert at the very start / end of the file. +`PASTE.PRE N` / `PASTE.POST N` / `PASTE.HEAD` / `PASTE.TAIL` / `PASTE.BLK.POST N` — insert the clipboard at the position (the clipboard IS the body). +`REM` — delete the whole section file. `MV DEST` — move/rename to `DEST` (quote paths with spaces); edits above `MV` land on the source first, final content written at `DEST`. +Single line: `SWAP N.=N:` / `CUT N`. Range = ORIGINAL lines touched; body length irrelevant (1 line → 10 is still `SWAP N.=N:`). -Body rows appear only under a `:` header. Every body row is `+TEXT` — add a literal line `TEXT`, verbatim (leading whitespace kept); `+` alone adds a blank line. No other row kind. NEVER write `-old` or a bare/context line. To keep a line, leave it out of every range. Literal lines starting with `-`/`+` still need the body prefix: Markdown `- item` → `+- item`, `+ item` → `++ item`. +Only under a `:` header. Every row is `+TEXT`, verbatim (leading whitespace kept); `+` alone = blank line. NEVER `-old` or bare/context rows — the range deletes; the body is only the final content. Keep a line: leave it out of every range. Literal leading `-`/`+` keeps the prefix: `- item` → `+- item`, `+ item` → `++ item`. -- Line numbers + `[PATH#TAG]` header come from your latest `read`/`search` (`LINE:TEXT` rows). -- Numbers refer to the ORIGINAL file; never shift as hunks apply. -- They die with the call: every applied edit mints a fresh `#TAG` and renumbers — anchor the next edit on the edit response or a fresh `read`. -- Touch only lines your latest `read`/`search` literally displayed as `LINE:TEXT`; the tag certifies the snapshot, not your memory. A hunk anchored on a line you never displayed is REJECTED — re-`read` first. Seeing a line ≠ it holds the code you mean; confirm numbers map to the construct you intend, especially far from your read window. -- Elided regions are UNSEEN: `…`/`..` markers and a collapsed `N-M:` summary row (only boundary lines N and M shown) hide their interior. NEVER place or span a hunk inside one — `read` the range first. -- Never start or end a range mid-expression or mid-block. -- Indent body rows exactly for the depth they should live at. -- On a stale-tag rejection or any surprising result: STOP and re-`read` before further edits. -- One hunk per range; body = final content, never an old/new pair. -- Ranges cover ONLY lines whose content changes. Never widen over unchanged lines — a stale wide range shreds everything it spans. -- Whole construct → `SWAP.BLK N` (tree-sitter resolves the end); lines inside it → `SWAP N.=M`. -- `SWAP.BLK N` resolves EXACTLY the node at N. Leading decorators/attributes/doc-comments are separate nodes: point N at the FIRST decorator to sweep both; standalone line-comments are never swept — use `SWAP N.=M`. -- Block ops (`SWAP.BLK`/`DEL.BLK`/`INS.BLK.POST`) anchor the OPENING line of a MULTI-LINE construct — never its closer, last line, or a bare inner statement. Anchoring one statement resolves to ONE line and is REJECTED: use the plain op (`SWAP N.=N` / `DEL N` / `INS.POST N`), or point N at the real opener. Saw the closer? Use plain `INS.POST M:`. -- Markdown: a heading line IS a block opener — `SWAP.BLK`/`DEL.BLK`/`INS.BLK.POST` on a `##`/`###` heading resolves its WHOLE section (heading through every nested deeper heading, up to the next same-or-higher heading). So `DEL.BLK` drops the section, `SWAP.BLK` rewrites it, `INS.BLK.POST` lands after it (end the inserted body with a blank line to keep the next heading separated). -- Non-adjacent changes = separate hunks; untouched lines stay out of every range. -- Pure additions use `INS.PRE` / `INS.POST` / `INS.HEAD` / `INS.TAIL`, never a widened `SWAP` — retyped keepers are exactly what gets dropped. (A multi-line `SWAP` whose body restates the line just past the range is auto-dropped as an off-by-one keeper with a warning — issue the payload for the range only; never lean on the repair.) -- NEVER format/restyle code with this tool; run the project formatter instead. +- Line numbers + `#TAG` come from your latest `read`/`search` (`LINE:TEXT` rows); numbers name ORIGINAL lines, never shifted by applied hunks. +- Applied edits renumber the file and change the `#TAG` — take the next edit's numbers from the edit response or a fresh `read`. +- Touch only displayed lines — hunks on undisplayed lines are REJECTED. Far from your read window? Re-`read`; confirm numbers map to the intended construct. +- Elided regions are UNSEEN (`…`/`..` markers, collapsed `N-M:` summary rows) — NEVER place or span a hunk inside one; `read` the range first. +- NEVER start or end a range mid-expression or mid-block. +- Ranges cover ONLY changed lines — never widen over keepers. Non-adjacent changes = separate hunks. +- Whole construct → `SWAP.BLK N`; lines inside one → `SWAP N.=M`. +- `SWAP.BLK` resolves EXACTLY the node at N: leading decorators/attributes/doc-comments are separate nodes — point N at the FIRST decorator to sweep both; standalone line-comments are never swept (use `SWAP N.=M`). +- Block ops anchor the OPENING line of a MULTI-LINE construct — never the closer, last line, or a bare inner statement; one statement → plain op (`SWAP N.=N:` / `CUT N` / `INS.POST N:`). Saw the closer? `INS.POST M:`. +- Markdown: a heading IS a block opener — block ops on `##`/`###` resolve the WHOLE section (through deeper nested headings, up to the next same-or-higher heading). `INS.BLK.POST` after a section: end the body with a blank line to keep the next heading separated. +- Pure additions → `INS.PRE`/`INS.POST`/`INS.HEAD`/`INS.TAIL`, never a widened `SWAP`. +- Move code with `CUT`+`PASTE`, never retype. Clipboard: top-to-bottom across the whole patch (cross-file moves), persists across edit calls, latest `CUT` wins, and `PASTE` repeats freely. Pasted indentation is verbatim; re-indent via `SWAP`. +- NEVER format/restyle code with this tool; run the project formatter. -Original (the exact shape `read` returns): +`read` output shape: ``` [greet.py#A1B2] 1:def greet(name): @@ -52,40 +46,7 @@ Original (the exact shape `read` returns): 4:greet("world") ``` -Insert a guard after line 1: -``` -[greet.py#A1B2] -INS.POST 1: -+ if not name: name = "stranger" -``` - -Replace line 2 with two lines: -``` -[greet.py#A1B2] -SWAP 2.=2: -+ greeting = "Hi" -+ msg = f"{greeting}, {name}" -``` - -Delete line 3: -``` -[greet.py#A1B2] -DEL 3 -``` - -Delete the whole file: -``` -[greet.py#A1B2] -REM -``` - -Rename or move the file: -``` -[greet.py#A1B2] -MV greet_v2.py -``` - -Move after editing: +Edit, then move: ``` [greet.py#A1B2] SWAP 1.=3: @@ -94,16 +55,7 @@ SWAP 1.=3: MV lib/greet.py ``` -Add a header and trailer: -``` -[greet.py#A1B2] -INS.HEAD: -+# generated header -INS.TAIL: -+greet("everyone") -``` - -Insert Markdown bullets — the leading `+` is the body-row marker; the file receives `- task`: +Markdown bullets — the file receives `- task`: ``` [PLAN.md#A1B2] INS.POST 2: @@ -111,7 +63,15 @@ INS.POST 2: + - nested task ``` -Replace the whole `greet` function block — `SWAP.BLK 1:` resolves lines 1–3 (the `def` header through `print(msg)`); line 4 is a separate statement and stays: +Move `greet` to a sibling file — clipboard flows across sections: +``` +[greet.py#A1B2] +CUT.BLK 1 +[other.py#3C4D] +PASTE.HEAD +``` + +`SWAP.BLK 1:` resolves lines 1–3 (`def` header through `print(msg)`); line 4 is a separate statement and stays: ``` [greet.py#A1B2] SWAP.BLK 1: @@ -119,7 +79,7 @@ SWAP.BLK 1: + print(f"Hello, {name}") ``` -A decorator/doc-comment is a SEPARATE block — `SWAP.BLK` on the `def`/`fn` line keeps it. Point N at the decorator to take both; here line 1 is `@cache`, so anchoring on the `def` (line 2) would orphan `@cache`: +Decorator/doc-comment = SEPARATE block — point N at the decorator to take both; anchoring the `def` (line 2) would orphan `@cache`: ``` [svc.py#C3D4] SWAP.BLK 1: @@ -130,14 +90,14 @@ SWAP.BLK 1: -# WRONG — empty `SWAP` to delete. RIGHT: DEL 4 +# WRONG — empty `SWAP` to delete. RIGHT: CUT 4 SWAP 4.=4: -# WRONG — range describes post-edit size. RIGHT: SWAP 1.=1: (body length is irrelevant) +# WRONG — range sized to the post-edit content. RIGHT: SWAP 1.=1: (body length irrelevant) SWAP 1.=2: +def greet(name): -# WRONG — `-` rows / bare context lines do not exist. The range deletes; the body is only the new content. +# WRONG — `-` rows / bare context lines do not exist; the range deletes, the body is only new content. SWAP 3.=3: msg = "Hello, " + name - print(msg) @@ -146,27 +106,29 @@ SWAP 3.=3: SWAP 3.=3: + return msg -# WRONG — a pure insertion done as a widened `SWAP`: you want to add one line after 2, -# but you replace 2.=4, retype the keepers, and drop one (here line 4, `greet("world")`). +# WRONG — pure insertion as a widened `SWAP`: retyped keepers get dropped (here line 4). SWAP 2.=4: + msg = "Hello, " + name + extra = compute(name) + print(msg) -# RIGHT — touch nothing you keep; the new line is the whole body. +# RIGHT — touch nothing you keep. INS.POST 2: + extra = compute(name) -# WRONG — `INS.BLK.POST N:` anchored on a closing delimiter / last visible line. RIGHT: plain `INS.POST M:` +# WRONG — `INS.BLK.POST` anchored on the closing delimiter / last visible line. RIGHT: plain `INS.POST M:` INS.BLK.POST 3: +after() # RIGHT INS.POST 3: +after() + +# WRONG — body rows under PASTE; the clipboard is the body. RIGHT: capture first, then a bodyless `PASTE.POST 20`. +PASTE.POST 20: ++function f() {} -If you remember nothing else: -1. RE-GROUND AFTER EVERY EDIT. Every apply mints a fresh `#TAG` and renumbers — take the next edit's numbers from the edit response or a fresh `read`. Stale tag or surprise? STOP, re-`read`. -2. RANGES ARE TIGHT. Cover only lines that change; a stale wide range shreds everything it spans. Whole construct → `SWAP.BLK N`. -3. THE BODY IS THE FINAL CONTENT. Every body row starts with `+`; Markdown bullets use `+- item`, not `- item`. +1. RE-GROUND AFTER EVERY EDIT — applied edits renumber the file and change the `#TAG`; take next numbers from the edit response or a fresh `read`. Stale tag or surprise? STOP, re-`read`. +2. RANGES ARE TIGHT — cover only lines that change. Whole construct → `SWAP.BLK N`. +3. BODY = FINAL CONTENT — every body row starts with `+`; Markdown bullets use `+- item`, not `- item`. diff --git a/packages/hashline/src/recovery.ts b/packages/hashline/src/recovery.ts index f6456b23f..239c48695 100644 --- a/packages/hashline/src/recovery.ts +++ b/packages/hashline/src/recovery.ts @@ -10,13 +10,15 @@ import { diffLineRuns } from "@oh-my-pi/pi-natives"; import { applyEdits } from "./apply"; import { RECOVERY_EXTERNAL_WARNING, RECOVERY_LINE_REMAP_WARNING, RECOVERY_SESSION_CHAIN_WARNING } from "./messages"; import type { SnapshotStore } from "./snapshots"; -import type { Anchor, ApplyResult, Edit } from "./types"; +import type { Anchor, ApplyResult, Clipboard, Edit } from "./types"; export interface RecoveryArgs { path: string; currentText: string; fileHash: string; edits: readonly Edit[]; + /** Shared clipboard register for `cut`/`paste` edits, threaded into the replay apply. */ + clipboard?: Clipboard; } export interface RecoveryResult { @@ -41,6 +43,12 @@ function getEditAnchors(edit: Edit): Anchor[] { // Recovery only ever receives already-resolved edits (no `block`); this arm // exists for type-exhaustiveness over the full `Edit` union. if (edit.kind === "block") return [edit.anchor]; + if (edit.kind === "cut") { + // Every captured line is an anchor: changed interior content is unsafe. + const anchors: Anchor[] = []; + for (let line = edit.range.start.line; line <= edit.range.end.line; line++) anchors.push({ line }); + return anchors; + } return edit.cursor.kind === "before_anchor" || edit.cursor.kind === "after_anchor" ? [edit.cursor.anchor] : []; } @@ -213,6 +221,21 @@ function remapEditsToCurrent(previousText: string, currentText: string, edits: r remapped.push({ ...edit, anchor }); continue; } + if (edit.kind === "cut") { + // Map every captured line; an unmapped interior line means the + // content drifted and cannot be moved safely. Uniform offsets keep + // the mapped range contiguous. + const start = mapLine(edit.range.start.line); + if (start === null) return null; + let end = start; + for (let line = edit.range.start.line + 1; line <= edit.range.end.line; line++) { + const mapped = mapLine(line); + if (mapped === null) return null; + end = mapped; + } + remapped.push({ ...edit, range: { start: { line: start }, end: { line: end } } }); + continue; + } let blockStart = edit.blockStart; if (blockStart !== undefined) { @@ -243,12 +266,13 @@ function replayRemappedAnchorsOnCurrent( currentText: string, edits: readonly Edit[], recoveryWarning: string, + clipboard: Clipboard | undefined, ): RecoveryResult | null { const remapped = remapEditsToCurrent(previousText, currentText, edits); if (remapped === null) return null; let applied: ApplyResult; try { - applied = applyEdits(currentText, remapped.edits); + applied = applyEdits(currentText, remapped.edits, clipboard === undefined ? {} : { clipboard }); } catch { return null; } @@ -276,13 +300,13 @@ export class Recovery { * caller should then surface a {@link MismatchError}. */ tryRecover(args: RecoveryArgs): RecoveryResult | null { - const { path, currentText, fileHash, edits } = args; + const { path, currentText, fileHash, edits, clipboard } = args; // When retained texts collide on the 16-bit tag, use the latest one. // Recovery still requires its anchors and context to map unambiguously. const snapshot = this.store.byHash(path, fileHash); if (!snapshot) return null; const recoveryWarning = this.store.head(path) === snapshot ? RECOVERY_EXTERNAL_WARNING : RECOVERY_SESSION_CHAIN_WARNING; - return replayRemappedAnchorsOnCurrent(snapshot.text, currentText, edits, recoveryWarning); + return replayRemappedAnchorsOnCurrent(snapshot.text, currentText, edits, recoveryWarning, clipboard); } } diff --git a/packages/hashline/src/tokenizer.ts b/packages/hashline/src/tokenizer.ts index ad6a8e6ac..616d7a1e9 100644 --- a/packages/hashline/src/tokenizer.ts +++ b/packages/hashline/src/tokenizer.ts @@ -10,8 +10,8 @@ */ import { describeAnchorExamples, - HL_DELETE_BLOCK_KEYWORD, - HL_DELETE_KEYWORD, + HL_CUT_BLOCK_KEYWORD, + HL_CUT_KEYWORD, HL_FILE_HASH_LENGTH, HL_FILE_HASH_SEP, HL_FILE_PREFIX, @@ -24,6 +24,8 @@ import { HL_INSERT_KEYWORD, HL_INSERT_TAIL, HL_MOVE_KEYWORD, + HL_PASTE_AFTER_BLOCK_KEYWORD, + HL_PASTE_KEYWORD, HL_PAYLOAD_REPLACE, HL_REM_KEYWORD, HL_REPLACE_BLOCK_KEYWORD, @@ -215,11 +217,13 @@ function scanHeaderRange(line: string, index = 0, end = trimEndIndex(line), allo export type BlockTarget = | { kind: "replace"; range: ParsedRange } | { kind: "block"; anchor: Anchor } - | { kind: "delete"; range: ParsedRange } - | { kind: "delete_block"; anchor: Anchor } | { kind: "insert_before"; anchor: Anchor } | { kind: "insert_after"; anchor: Anchor } | { kind: "insert_after_block"; anchor: Anchor } + | { kind: "cut"; range: ParsedRange } + | { kind: "cut_block"; anchor: Anchor } + | { kind: "paste"; cursor: Cursor } + | { kind: "paste_after_block"; anchor: Anchor } | { kind: "rem" } | { kind: "move"; dest: string } | { kind: "bof" } @@ -270,30 +274,52 @@ function consumeReplaceColon(line: string, index: number, end: number): number { return skipWhitespace(line, afterEquals + 1, end); } -function scanInsertTarget(line: string, index: number, end: number): TargetScan | null { +interface PositionScan { + cursor: Cursor; + nextIndex: number; +} + +/** Scan the `.PRE N` / `.POST N` / `.HEAD` / `.TAIL` positional suffix shared by `INS` and `PASTE`. */ +function scanPositionalSuffix(line: string, index: number, end: number): PositionScan | null { if (index >= end || line.charCodeAt(index) !== CHAR_DOT) return null; - const cursor = skipWhitespace(line, index + 1, end); - const beforeEnd = scanKeyword(line, cursor, end, HL_INSERT_BEFORE); + const probe = skipWhitespace(line, index + 1, end); + const beforeEnd = scanKeyword(line, probe, end, HL_INSERT_BEFORE); if (beforeEnd !== null) { const anchor = scanLineNumber(line, skipWhitespace(line, beforeEnd, end), end); if (anchor === null) return null; const nextIndex = consumeOptionalColon(line, anchor.nextIndex, end); - return { target: { kind: "insert_before", anchor: { line: anchor.line } }, nextIndex }; + return { cursor: { kind: "before_anchor", anchor: { line: anchor.line } }, nextIndex }; } - const afterEnd = scanKeyword(line, cursor, end, HL_INSERT_AFTER); + const afterEnd = scanKeyword(line, probe, end, HL_INSERT_AFTER); if (afterEnd !== null) { const anchor = scanLineNumber(line, skipWhitespace(line, afterEnd, end), end); if (anchor === null) return null; const nextIndex = consumeOptionalColon(line, anchor.nextIndex, end); - return { target: { kind: "insert_after", anchor: { line: anchor.line } }, nextIndex }; + return { cursor: { kind: "after_anchor", anchor: { line: anchor.line } }, nextIndex }; } - const headEnd = scanKeyword(line, cursor, end, HL_INSERT_HEAD); - if (headEnd !== null) return { target: { kind: "bof" }, nextIndex: consumeOptionalColon(line, headEnd, end) }; - const tailEnd = scanKeyword(line, cursor, end, HL_INSERT_TAIL); - if (tailEnd !== null) return { target: { kind: "eof" }, nextIndex: consumeOptionalColon(line, tailEnd, end) }; + const headEnd = scanKeyword(line, probe, end, HL_INSERT_HEAD); + if (headEnd !== null) return { cursor: { kind: "bof" }, nextIndex: consumeOptionalColon(line, headEnd, end) }; + const tailEnd = scanKeyword(line, probe, end, HL_INSERT_TAIL); + if (tailEnd !== null) return { cursor: { kind: "eof" }, nextIndex: consumeOptionalColon(line, tailEnd, end) }; return null; } +function scanInsertTarget(line: string, index: number, end: number): TargetScan | null { + const scan = scanPositionalSuffix(line, index, end); + if (scan === null) return null; + const { cursor, nextIndex } = scan; + switch (cursor.kind) { + case "before_anchor": + return { target: { kind: "insert_before", anchor: cursor.anchor }, nextIndex }; + case "after_anchor": + return { target: { kind: "insert_after", anchor: cursor.anchor }, nextIndex }; + case "bof": + return { target: { kind: "bof" }, nextIndex }; + case "eof": + return { target: { kind: "eof" }, nextIndex }; + } +} + function unquotePath(pathText: string): string { if (pathText.length < 2) return pathText; const first = pathText[0]; @@ -361,28 +387,6 @@ function scanHunkAnchor(line: string, start: number, end: number): TargetScan | nextIndex: consumeReplaceColon(line, range.nextIndex, end), }; } - // `delete_block N` — resolve N to a tree-sitter block range at apply time - // and delete its whole span. Like `delete N.=M`, it takes no body and no - // trailing colon. - const deleteBlockEnd = scanKeyword(line, cursor, end, HL_DELETE_BLOCK_KEYWORD); - if (deleteBlockEnd !== null) { - const anchor = scanLineNumber(line, skipWhitespace(line, deleteBlockEnd, end), end); - if (anchor === null) return null; - let next = skipWhitespace(line, anchor.nextIndex, end); - next = skipStrayDot(line, next, end); - if (next < end && line.charCodeAt(next) === CHAR_COLON) return null; - return { target: { kind: "delete_block", anchor: { line: anchor.line } }, nextIndex: next }; - } - // `delete N.=M` — like `delete_block N`, takes no body and no trailing - // colon; a colon here falls through to contamination detection. - const deleteEnd = scanKeyword(line, cursor, end, HL_DELETE_KEYWORD); - if (deleteEnd !== null) { - const range = scanHeaderRange(line, deleteEnd, end, true); - if (range === null) return null; - const next = skipStrayDot(line, range.nextIndex, end); - if (next < end && line.charCodeAt(next) === CHAR_COLON) return null; - return { target: { kind: "delete", range: range.range }, nextIndex: next }; - } // `insert_after_block N:` — insert after the last line of the tree-sitter // block at N. const insertAfterBlockEnd = scanKeyword(line, cursor, end, HL_INSERT_AFTER_BLOCK_KEYWORD); @@ -394,6 +398,47 @@ function scanHunkAnchor(line: string, start: number, end: number): TargetScan | nextIndex: consumeOptionalColon(line, anchor.nextIndex, end), }; } + // `PASTE.BLK.POST N` — insert the clipboard after the tree-sitter block + // at N. Like all clipboard ops, takes no body rows. + const pasteAfterBlockEnd = scanKeyword(line, cursor, end, HL_PASTE_AFTER_BLOCK_KEYWORD); + if (pasteAfterBlockEnd !== null) { + const anchor = scanLineNumber(line, skipWhitespace(line, pasteAfterBlockEnd, end), end); + if (anchor === null) return null; + return { + target: { kind: "paste_after_block", anchor: { line: anchor.line } }, + nextIndex: consumeOptionalColon(line, anchor.nextIndex, end), + }; + } + // `PASTE.PRE|POST N` / `PASTE.HEAD|TAIL` — insert the clipboard at the position. + const pasteEnd = scanKeyword(line, cursor, end, HL_PASTE_KEYWORD); + if (pasteEnd !== null) { + const scan = scanPositionalSuffix(line, pasteEnd, end); + if (scan === null) return null; + return { target: { kind: "paste", cursor: scan.cursor }, nextIndex: scan.nextIndex }; + } + // `CUT.BLK N` captures and deletes the tree-sitter block beginning at N. + // Scan it before the plain form so `.BLK` is not parsed as a range. + const cutBlockEnd = scanKeyword(line, cursor, end, HL_CUT_BLOCK_KEYWORD); + if (cutBlockEnd !== null) { + const anchor = scanLineNumber(line, skipWhitespace(line, cutBlockEnd, end), end); + if (anchor === null) return null; + return { + target: { kind: "cut_block", anchor: { line: anchor.line } }, + nextIndex: consumeOptionalColon(line, anchor.nextIndex, end), + }; + } + // `CUT N.=M` captures and deletes concrete lines. A trailing colon is + // tolerated and ignored; body rows are rejected by the parser. + const cutEnd = scanKeyword(line, cursor, end, HL_CUT_KEYWORD); + if (cutEnd !== null) { + const range = scanHeaderRange(line, cutEnd, end, true); + if (range === null) return null; + const next = skipStrayDot(line, range.nextIndex, end); + return { + target: { kind: "cut", range: range.range }, + nextIndex: consumeOptionalColon(line, next, end), + }; + } const insertEnd = scanKeyword(line, cursor, end, HL_INSERT_KEYWORD); if (insertEnd !== null) return scanInsertTarget(line, insertEnd, end); return null; @@ -488,10 +533,11 @@ function classifyLine(line: string, lineNum: number): Token { const lead = skipWhitespace(line, 0); const isHunkLead = line.startsWith(HL_REPLACE_KEYWORD, lead) || - line.startsWith(HL_DELETE_KEYWORD, lead) || line.startsWith(HL_INSERT_KEYWORD, lead) || line.startsWith(HL_REM_KEYWORD, lead) || - line.startsWith(HL_MOVE_KEYWORD, lead); + line.startsWith(HL_MOVE_KEYWORD, lead) || + line.startsWith(HL_CUT_KEYWORD, lead) || + line.startsWith(HL_PASTE_KEYWORD, lead); if (isHunkLead) { const hunk = tryParseHunkHeader(line); if (hunk !== null) return { kind: "op-block", lineNum, target: hunk.target }; diff --git a/packages/hashline/src/types.ts b/packages/hashline/src/types.ts index 72d7e66fe..bf86e99b7 100644 --- a/packages/hashline/src/types.ts +++ b/packages/hashline/src/types.ts @@ -42,21 +42,46 @@ export type Edit = | { kind: "delete"; anchor: Anchor; lineNum: number; index: number; oldAssertion?: string } | { /** - * Deferred block edit (`replace_block N:` / `delete_block N` / - * `insert_after_block N:`). The exact line span is unknown at parse - * time — it is computed by {@link resolveBlockEdits} once file text + - * path (→ language) are available, then expanded into concrete edits: - * a non-empty `payloads` without `mode` (from `replace_block`) becomes - * the same `replacement` inserts + deletes that `replace start.=end:` - * produces; an empty `payloads` (from `delete_block`) becomes a pure - * range deletion; `mode: "insert_after"` becomes plain `after_anchor` - * inserts at the block's last line. `applyEdits` never sees this - * variant. + * Clipboard cut (`CUT N.=M`, or the resolved form of `CUT.BLK N`). + * Captures the range's current lines into the {@link Clipboard} + * register during the applier's clipboard pre-pass and lowers to one + * `delete` per range line at parse/resolve time. + */ + kind: "cut"; + range: ParsedRange; + lineNum: number; + index: number; + } + | { + /** + * Clipboard insertion (`PASTE.PRE N` / `PASTE.POST N` / `PASTE.HEAD` / + * `PASTE.TAIL`, or the resolved form of `PASTE.BLK.POST N`). Expanded + * by the clipboard pre-pass into one plain insert per captured line. + * `blockStart` mirrors the insert variant's field for block-lowered + * pastes so landing correction can slide the body across trailing + * closer lines. + */ + kind: "paste"; + cursor: Cursor; + lineNum: number; + index: number; + blockStart?: number; + } + | { + /** + * Deferred block edit (`SWAP.BLK N:`, `INS.BLK.POST N:`, + * `CUT.BLK N`, or `PASTE.BLK.POST N`). The exact line span is + * unknown at parse time; {@link resolveBlockEdits} computes it once + * file text and language are available, then expands it into + * concrete edits. `mode: "insert_after"` becomes plain + * `after_anchor` inserts, `"cut"` becomes a clipboard cut plus + * per-line deletes, and `"paste_after"` becomes a paste after the + * resolved block. No mode denotes a block replacement. */ kind: "block"; anchor: Anchor; payloads: string[]; - mode?: "insert_after"; + mode?: "insert_after" | "cut" | "paste_after"; lineNum: number; index: number; }; @@ -73,10 +98,9 @@ export interface ApplyResult { /** Diagnostic warnings collected by the parser, patcher, or recovery. */ warnings?: string[]; /** - * Resolved spans for each `replace_block`/`delete_block` op in this apply, - * in patch order. Present only when the apply matched the tagged content - * (the common no-drift path), so the line numbers line up with what the - * caller read. Absent when there were no block ops. + * Resolved spans for each block op in this apply, in patch order. Present + * only when the apply matched the tagged content, so the line numbers match + * what the caller read. Absent when there were no block ops. */ blockResolutions?: BlockResolution[]; } @@ -124,9 +148,7 @@ export interface CompactDiffOptions { maxUnchangedRun?: number; } -/** - * Resolved 1-indexed inclusive line span of a `replace_block N:` target. - */ +/** Resolved 1-indexed inclusive line span of a block target. */ export interface BlockSpan { /** First line of the block (1-indexed, inclusive). */ start: number; @@ -135,11 +157,9 @@ export interface BlockSpan { } /** - * One `replace_block N:` / `delete_block N` / `insert_after_block N:` anchor - * resolved to its concrete line span. Surfaced on {@link ApplyResult} so the - * host can echo "block N → lines start.=end" and let the model catch a wrong - * opener — e.g. a decorator or doc-comment that sits in a separate node - * outside the resolved block. + * One block-op anchor resolved to its concrete line span. Surfaced on + * {@link ApplyResult} so the host can echo the resolved range and let the + * model catch an anchor on the wrong opener. */ export interface BlockResolution { /** The 1-indexed line the block op was anchored on (the `N`). */ @@ -149,10 +169,10 @@ export interface BlockResolution { /** Last line of the resolved span (1-indexed, inclusive). */ end: number; /** Which block op produced this resolution. */ - op: "replace" | "delete" | "insert_after"; + op: "replace" | "insert_after" | "cut" | "paste_after"; } -/** Request handed to a {@link BlockResolver} to resolve one `replace_block N:` anchor. */ +/** Request handed to a {@link BlockResolver} to resolve one block-op anchor. */ export interface BlockResolverRequest { /** Target file path (used to infer language by extension). */ path: string; @@ -163,10 +183,20 @@ export interface BlockResolverRequest { } /** - * Resolves a `replace_block N:` anchor to the line span of the syntactic block - * that begins on line N. Returns `null` when no block can be resolved - * (unrecognized language, blank/out-of-range line, no node begins there, or the - * resolved subtree has a syntax error). Pure seam: the hashline core declares - * the contract; the host injects a tree-sitter-backed implementation. + * Resolves a block-op anchor to the line span of the syntactic block beginning + * on that line. Returns `null` for an unsupported language, invalid line, absent + * opener, or syntax error. The host injects the tree-sitter-backed implementation. */ export type BlockResolver = (request: BlockResolverRequest) => BlockSpan | null; + +/** + * Mutable clipboard register threaded through one patch application. Filled + * by `CUT` edits and read by `PASTE` edits in patch source order, across + * sections, so content can move between files. Create one per batch (`{}`) + * and hand it to every {@link Patcher.prepare} / `applyTo` call in that batch; + * callers that omit it get a private per-call register. + */ +export interface Clipboard { + /** Lines captured by the most recent `CUT`, or unset. */ + lines?: readonly string[]; +} diff --git a/packages/hashline/test/block.test.ts b/packages/hashline/test/block.test.ts index 7da7fa5ed..8d988322f 100644 --- a/packages/hashline/test/block.test.ts +++ b/packages/hashline/test/block.test.ts @@ -140,19 +140,19 @@ describe("resolveBlockEdits", () => { expect(error?.message).not.toContain("\n\n"); }); - it("fires onResolved with the resolved span for replace and delete blocks", () => { + it("fires onResolved with the resolved span for replace and cut blocks", () => { const seen: BlockResolution[] = []; // stubResolver maps line N → span [N, N+1]. resolveBlockEdits(parsePatch("SWAP.BLK 2:\n+A\n+B").edits, "ignored", PATH, stubResolver, { onResolved: resolution => seen.push(resolution), }); - resolveBlockEdits(parsePatch("DEL.BLK 5").edits, "ignored", PATH, stubResolver, { + resolveBlockEdits(parsePatch("CUT.BLK 5").edits, "ignored", PATH, stubResolver, { onResolved: resolution => seen.push(resolution), }); expect(seen).toEqual([ { anchorLine: 2, start: 2, end: 3, op: "replace" }, - { anchorLine: 5, start: 5, end: 6, op: "delete" }, + { anchorLine: 5, start: 5, end: 6, op: "cut" }, ]); }); @@ -305,11 +305,11 @@ describe("Patcher with a block resolver", () => { }); }); -describe("DEL.BLK", () => { +describe("CUT.BLK", () => { const text = "function x() {\n if (y) {\n }\n}\n"; - it("parses `DEL.BLK N` into a block edit with no payloads", () => { - const { edits } = parsePatch("DEL.BLK 2"); + it("parses `CUT.BLK N` into a cut block edit", () => { + const { edits } = parsePatch("CUT.BLK 2"); expect(edits).toHaveLength(1); const edit = edits[0]; @@ -317,38 +317,38 @@ describe("DEL.BLK", () => { if (edit?.kind !== "block") throw new Error("expected a block edit"); expect(edit.anchor.line).toBe(2); expect(edit.payloads).toEqual([]); + expect(edit.mode).toBe("cut"); }); - it("rejects body rows under `DEL.BLK N`", () => { - expect(() => parsePatch("DEL.BLK 2\n+X")).toThrow("`DEL.BLK N` does not take body rows"); + it("rejects body rows under `CUT.BLK N`", () => { + expect(() => parsePatch("CUT.BLK 2\n+X")).toThrow("`CUT N.=M` captures + deletes lines"); }); - it("resolveBlockEdits expands a delete-block edit into pure deletes", () => { - const edits = parsePatch("DEL.BLK 2").edits; - const resolved = resolveBlockEdits(edits, "ignored", PATH, stubResolver); + it("resolveBlockEdits expands a cut block into capture and deletes", () => { + const resolved = resolveBlockEdits(parsePatch("CUT.BLK 2").edits, "ignored", PATH, stubResolver); - expect(resolved.every(edit => edit.kind === "delete")).toBe(true); - expect(resolved.map(edit => (edit.kind === "delete" ? edit.anchor.line : -1))).toEqual([2, 3]); + expect(resolved.map(edit => edit.kind)).toEqual(["cut", "delete", "delete"]); + expect(resolved.flatMap(edit => (edit.kind === "delete" ? [edit.anchor.line] : []))).toEqual([2, 3]); }); it("applyTo deletes the resolved block span", () => { - const section = Patch.parseSingle(`[${PATH}#1A2B]\nDEL.BLK 2`); + const section = Patch.parseSingle(`[${PATH}#1A2B]\nCUT.BLK 2`); // stub span [2,3] → drop " if (y) {" and " }". expect(section.applyTo(text, stubResolver).text).toBe("function x() {\n}\n"); }); - it("applyPartialTo drops an unresolvable delete-block edit instead of throwing", () => { - const section = Patch.parseSingle(`[${PATH}#1A2B]\nDEL.BLK 2`); + it("applyPartialTo drops an unresolvable cut-block edit", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nCUT.BLK 2`); expect(section.applyPartialTo(text).text).toBe(text); }); - it("Patcher applies a delete-block edit on the hash-match path", async () => { + it("Patcher applies a cut-block edit on the hash-match path", async () => { const fs = new InMemoryFilesystem([[PATH, text]]); const snapshots = new InMemorySnapshotStore(); const tag = snapshots.record(PATH, text); const patcher = new Patcher({ fs, snapshots, blockResolver: stubResolver }); - const result = await patcher.apply(Patch.parse(`[${PATH}#${tag}]\nDEL.BLK 2`)); + const result = await patcher.apply(Patch.parse(`[${PATH}#${tag}]\nCUT.BLK 2`)); expect(result.sections[0]?.op).toBe("update"); expect(fs.get(PATH)).toBe("function x() {\n}\n"); diff --git a/packages/hashline/test/boundary-repair.test.ts b/packages/hashline/test/boundary-repair.test.ts index 6c53e9a06..f5d043203 100644 --- a/packages/hashline/test/boundary-repair.test.ts +++ b/packages/hashline/test/boundary-repair.test.ts @@ -400,11 +400,11 @@ describe("boundary-balance repair", () => { expect(warnings.filter(warning => /structural closing line/.test(warning))).toHaveLength(1); }); // #3142: the range's deleted `}` is matched by an opener another hunk deletes - // (`DEL 1`). The patch nets to balanced, so the closer must stay deleted — + // (`CUT 1`). The patch nets to balanced, so the closer must stay deleted — // the per-group repair wrongly kept it, leaving a stray `}`. it("does not keep a deleted closer when another hunk removes its opener (#3142)", () => { const file = ["if enabled {", '\tText("Old")', "}", '\tText("Tail")'].join("\n"); - const diff = ["DEL 1", "SWAP 2.=3:", '+Text("New")'].join("\n"); + const diff = ["CUT 1", "SWAP 2.=3:", '+Text("New")'].join("\n"); const { text, warnings } = apply(file, diff); expect(text).toBe(['Text("New")', '\tText("Tail")'].join("\n")); expect(warnings.filter(warning => /structural closing line/.test(warning))).toHaveLength(0); @@ -414,7 +414,7 @@ describe("boundary-balance repair", () => { // residual must be spent on the genuine hunk, not the wrapper-removed one. it("spends the missing-closer residual on the genuine hunk, not an earlier wrapper removal", () => { const file = ["if enabled {", '\tText("Old")', "}", "const config = {", "\ta: 1,", "};"].join("\n"); - const diff = ["DEL 1", "SWAP 2.=3:", '+Text("New")', "SWAP 6.=6:", "+\tb: 2,"].join("\n"); + const diff = ["CUT 1", "SWAP 2.=3:", '+Text("New")', "SWAP 6.=6:", "+\tb: 2,"].join("\n"); const { text, warnings } = apply(file, diff); expect(text).toBe(['Text("New")', "const config = {", "\ta: 1,", "\tb: 2,", "};"].join("\n")); expect(warnings.filter(warning => /structural closing line/.test(warning))).toHaveLength(1); @@ -470,7 +470,7 @@ describe("boundary-balance repair", () => { it("ignores non-contiguously deleted openers when choosing which closer to keep", () => { const file = ["if (a) {", "\told();", "\tmore();", "}", "const obj = {", "\ta: 1,", "};"].join("\n"); - const diff = ["DEL 1", "SWAP 3.=4:", "+\tnew();", "SWAP 7.=7:", "+\tb: 2,"].join("\n"); + const diff = ["CUT 1", "SWAP 3.=4:", "+\tnew();", "SWAP 7.=7:", "+\tb: 2,"].join("\n"); const { text, warnings } = apply(file, diff); expect(text).toBe(["\told();", "\tnew();", "const obj = {", "\ta: 1,", "\tb: 2,", "};"].join("\n")); expect(warnings.filter(warning => /structural closing line/.test(warning))).toHaveLength(1); diff --git a/packages/hashline/test/clipboard.test.ts b/packages/hashline/test/clipboard.test.ts new file mode 100644 index 000000000..7b755b6bf --- /dev/null +++ b/packages/hashline/test/clipboard.test.ts @@ -0,0 +1,288 @@ +import { describe, expect, it } from "bun:test"; +import { + applyEdits, + type BlockResolver, + type BlockSpan, + type Clipboard, + computeFileHash, + InMemoryFilesystem, + InMemorySnapshotStore, + Patch, + Patcher, + parsePatch, + parsePatchStreaming, + resolveBlockEdits, +} from "@oh-my-pi/hashline"; + +const PATH = "x.ts"; + +// Deterministic stub: the block beginning on line N spans [N, N+1]. +const stubResolver: BlockResolver = ({ line }): BlockSpan => ({ start: line, end: line + 1 }); + +function taggedPatcher(files: Array<[string, string]>): { + fs: InMemoryFilesystem; + snapshots: InMemorySnapshotStore; + patcher: Patcher; + tags: Map; +} { + const fs = new InMemoryFilesystem(files); + const snapshots = new InMemorySnapshotStore(); + const tags = new Map(); + for (const [path, text] of files) tags.set(path, snapshots.record(path, text)); + return { fs, snapshots, patcher: new Patcher({ fs, snapshots }), tags }; +} + +describe("clipboard parsing", () => { + it("lowers `CUT N.=M` to a capture plus per-line deletes", () => { + const cut = parsePatch("CUT 2.=3").edits; + expect(cut.map(edit => edit.kind)).toEqual(["cut", "delete", "delete"]); + expect(cut[0]).toMatchObject({ kind: "cut", range: { start: { line: 2 }, end: { line: 3 } } }); + }); + + it("parses every PASTE position, tolerating a trailing colon", () => { + const cursors = parsePatch("CUT 1\nPASTE.PRE 2\nPASTE.POST 3:\nPASTE.HEAD\nPASTE.TAIL:").edits.flatMap(edit => + edit.kind === "paste" ? [edit.cursor] : [], + ); + expect(cursors).toEqual([ + { kind: "before_anchor", anchor: { line: 2 } }, + { kind: "after_anchor", anchor: { line: 3 } }, + { kind: "bof" }, + { kind: "eof" }, + ]); + }); + + it("rejects bare `PASTE` without a position", () => { + expect(() => parsePatch("PASTE")).toThrow(/`PASTE` needs a position/); + }); + + it("rejects body rows under clipboard ops", () => { + expect(() => parsePatch("CUT 1.=2\n+x")).toThrow(/`CUT N.=M` captures \+ deletes/); + expect(() => parsePatch("CUT 1\nPASTE.POST 1\n+x")).toThrow(/`PASTE` inserts the clipboard content/); + }); + + it("rejects a CUT range overlapping another hunk's range", () => { + expect(() => parsePatch("CUT 2.=4\nSWAP 3.=3:\n+x")).toThrow(/already targeted by another hunk/); + }); + + it("reports inverted CUT ranges with op-specific retry forms", () => { + expect(() => parsePatch("CUT 5.=2")).toThrow(/`CUT 5`.*`CUT 5.=6`/); + }); + + it("flushes a trailing bodyless clipboard op in streaming mode", () => { + const { edits } = parsePatchStreaming("CUT 1\nPASTE.TAIL"); + expect(edits.map(edit => edit.kind)).toEqual(["cut", "delete", "paste"]); + }); +}); + +describe("clipboard apply semantics", () => { + it("moves a range within a file (CUT + PASTE)", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nCUT 2.=3\nPASTE.POST 5`); + expect(section.applyTo("l1\nl2\nl3\nl4\nl5\n").text).toBe("l1\nl4\nl5\nl2\nl3\n"); + }); + + it("repeats CUT content without consuming the clipboard", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nCUT 2.=2\nPASTE.HEAD\nPASTE.TAIL`); + expect(section.applyTo("l1\nl2\nl3\n").text).toBe("l2\nl1\nl3\nl2\n"); + }); + + it("swaps two regions with sequential CUT/PASTE pairs on original coordinates", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nCUT 1.=2\nPASTE.POST 4\nCUT 3.=4\nPASTE.PRE 1`); + expect(section.applyTo("a1\na2\nb1\nb2").text).toBe("b1\nb2\na1\na2"); + }); + + it("rejects PASTE with an empty register", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nPASTE.POST 1`); + expect(() => section.applyTo("l1\nl2\n")).toThrow(/found nothing in the clipboard/); + }); + + it("drops an empty-register PASTE on the streaming-tolerant path", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nPASTE.POST 1`); + expect(section.applyPartialTo("l1\nl2\n").text).toBe("l1\nl2\n"); + }); + + it("allows a CUT without a following PASTE", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nCUT 2.=2`); + expect(section.applyTo("l1\nl2\nl3\n").text).toBe("l1\nl3\n"); + }); + + it("allows consecutive CUTs and pastes the latest capture", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nCUT 1.=1\nCUT 3.=3\nPASTE.TAIL`); + expect(section.applyTo("l1\nl2\nl3\n").text).toBe("l2\nl3\n"); + }); + + it("rejects an out-of-range capture", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nCUT 8.=9\nPASTE.HEAD`); + expect(() => section.applyTo("l1\nl2\n")).toThrow(/out of range \(file has 3 lines\)/); + }); + + it("threads a caller-owned register across applyEdits calls", () => { + const clipboard: Clipboard = {}; + const cut = parsePatch("CUT 1.=1").edits; + const paste = parsePatch("PASTE.TAIL").edits; + expect(applyEdits("a\nb", cut, { clipboard }).text).toBe("b"); + expect(applyEdits("x\ny", paste, { clipboard }).text).toBe("x\ny\na"); + }); +}); + +describe("clipboard block ops", () => { + it("expands CUT.BLK to a span capture plus per-line deletes", () => { + const edits = parsePatch("CUT.BLK 2\nPASTE.TAIL").edits; + const resolved = resolveBlockEdits(edits, "l1\nl2\nl3\nl4", PATH, stubResolver); + expect(resolved.map(edit => edit.kind)).toEqual(["cut", "delete", "delete", "paste"]); + expect(resolved[0]).toMatchObject({ kind: "cut", range: { start: { line: 2 }, end: { line: 3 } } }); + }); + + it("moves a block after another block via PASTE.BLK.POST", () => { + const section = Patch.parseSingle(`[${PATH}#1A2B]\nCUT.BLK 1\nPASTE.BLK.POST 3`); + // stub blocks: [1,2] and [3,4]. + expect(section.applyTo("a1\na2\nb1\nb2\nrest", stubResolver).text).toBe("b1\nb2\na1\na2\nrest"); + }); + + it("echoes clipboard block resolutions with their op", () => { + const seen: string[] = []; + resolveBlockEdits(parsePatch("CUT.BLK 2\nPASTE.TAIL").edits, "l1\nl2\nl3", PATH, stubResolver, { + onResolved: resolution => seen.push(resolution.op), + }); + expect(seen).toEqual(["cut"]); + }); + + it("rejects a single-line CUT.BLK resolution with the plain-op retry", () => { + const single: BlockResolver = ({ line }): BlockSpan => ({ start: line, end: line }); + const edits = parsePatch("CUT.BLK 2\nPASTE.TAIL").edits; + expect(() => resolveBlockEdits(edits, "a\nb\nc", PATH, single)).toThrow(/use `CUT 2`/); + }); + + it("lowers an unresolvable PASTE.BLK.POST to a plain paste with a warning", () => { + const warnings: string[] = []; + const resolved = resolveBlockEdits(parsePatch("CUT 1\nPASTE.BLK.POST 2").edits, "a\nb\nc", PATH, () => null, { + onWarning: warning => warnings.push(warning), + }); + expect(resolved.map(edit => edit.kind)).toEqual(["cut", "delete", "paste"]); + expect(warnings.some(warning => warning.includes("`PASTE.BLK.POST 2`"))).toBe(true); + }); +}); + +describe("clipboard across sections and batches", () => { + it("moves lines between files within one patch", async () => { + const a = "keep\nmove1\nmove2\n"; + const b = "b1\n"; + const { fs, patcher, tags } = taggedPatcher([ + ["a.ts", a], + ["b.ts", b], + ]); + + const patch = Patch.parse(`[a.ts#${tags.get("a.ts")}]\nCUT 2.=3\n[b.ts#${tags.get("b.ts")}]\nPASTE.TAIL`); + await patcher.apply(patch); + + expect(fs.get("a.ts")).toBe("keep\n"); + expect(fs.get("b.ts")).toBe("b1\nmove1\nmove2\n"); + }); + + it("applies a batch-local CUT without requiring PASTE", async () => { + const a = "l1\nl2\n"; + const { fs, patcher, tags } = taggedPatcher([["a.ts", a]]); + + await patcher.apply(Patch.parse(`[a.ts#${tags.get("a.ts")}]\nCUT 1.=1`)); + expect(fs.get("a.ts")).toBe("l2\n"); + }); + + it("persists a host-owned register across apply calls", async () => { + const a = "l1\nl2\n"; + const b = "b1\n"; + const fs = new InMemoryFilesystem([ + ["a.ts", a], + ["b.ts", b], + ]); + const snapshots = new InMemorySnapshotStore(); + const tagA = snapshots.record("a.ts", a); + const tagB = snapshots.record("b.ts", b); + const clipboard: Clipboard = {}; + const patcher = new Patcher({ fs, snapshots, clipboard }); + + const first = await patcher.apply(Patch.parse(`[a.ts#${tagA}]\nCUT 1.=1`)); + expect(fs.get("a.ts")).toBe("l2\n"); + expect(first.sections[0]?.warnings).toEqual([]); + expect(clipboard).toEqual({ lines: ["l1"] }); + + await patcher.apply(Patch.parse(`[b.ts#${tagB}]\nPASTE.TAIL`)); + expect(fs.get("b.ts")).toBe("b1\nl1\n"); + expect(clipboard).toEqual({ lines: ["l1"] }); + }); + + it("does not publish register changes from a failed batch", async () => { + const a = "l1\nl2\n"; + const b = "b1\n"; + const fs = new InMemoryFilesystem([ + ["a.ts", a], + ["b.ts", b], + ]); + const snapshots = new InMemorySnapshotStore(); + const tagA = snapshots.record("a.ts", a); + snapshots.record("b.ts", b); + const clipboard: Clipboard = {}; + const patcher = new Patcher({ fs, snapshots, clipboard }); + + // Second section carries a bogus tag, so the batch fails in prepare. + const patch = Patch.parse(`[a.ts#${tagA}]\nCUT 1.=1\n[b.ts#0000]\nSWAP 1.=1:\n+x`); + await expect(patcher.apply(patch)).rejects.toThrow(); + + expect(fs.get("a.ts")).toBe(a); + expect(clipboard.lines).toBeUndefined(); + }); + + it("recovers clipboard anchors when the file drifted by a uniform offset", async () => { + const original = "x1\nx2\nx3\n"; + const live = "new\nx1\nx2\nx3\n"; + const fs = new InMemoryFilesystem([["a.ts", live]]); + const snapshots = new InMemorySnapshotStore(); + const tag = snapshots.record("a.ts", original); + const patcher = new Patcher({ fs, snapshots }); + + const result = await patcher.apply(Patch.parse(`[a.ts#${tag}]\nCUT 2.=2\nPASTE.TAIL`)); + + expect(fs.get("a.ts")).toBe("new\nx1\nx3\nx2\n"); + expect(result.sections[0]?.warnings.length).toBeGreaterThan(0); + }); + + it("rejects clipboard ops in same-path sections interleaved across another file", () => { + const patch = Patch.parse(`[a.ts#1A2B]\nCUT 1.=1\n[b.ts#3C4D]\nSWAP 1.=1:\n+x\n[a.ts#1A2B]\nPASTE.TAIL`); + expect(() => patch.sections[0]?.edits).toThrow(/interleaved with another file/); + }); + + it("still merges interleaved same-path sections without clipboard ops", () => { + const patch = Patch.parse( + `[a.ts#1A2B]\nSWAP 1.=1:\n+a1\n[b.ts#3C4D]\nSWAP 1.=1:\n+b1\n[a.ts#1A2B]\nSWAP 3.=3:\n+a3`, + ); + expect(patch.sections).toHaveLength(2); + expect(patch.sections[0]?.edits.map(edit => edit.kind)).toEqual(["insert", "delete", "insert", "delete"]); + }); + + it("surfaces a targeted sequencing error instead of a mismatch on the drift path", async () => { + const original = "x1\nx2\nx3\n"; + const live = "new\nx1\nx2\nx3\n"; + const fs = new InMemoryFilesystem([["a.ts", live]]); + const snapshots = new InMemorySnapshotStore(); + const tag = snapshots.record("a.ts", original); + const patcher = new Patcher({ fs, snapshots }); + + // PASTE with nothing captured, against a drifted tag: the recovery path + // swallows apply errors, so the sequencing check must fire first. + await expect(patcher.apply(Patch.parse(`[a.ts#${tag}]\nPASTE.POST 2\nCUT 2.=2`))).rejects.toThrow( + /found nothing in the clipboard/, + ); + }); +}); + +describe("clipboard header hash interplay", () => { + it("applies a paste-only section on the clean-tag fast path", async () => { + const text = "l1\nl2\n"; + const fs = new InMemoryFilesystem([["a.ts", text]]); + const snapshots = new InMemorySnapshotStore(); + expect(computeFileHash(text)).toBe(snapshots.record("a.ts", text)); + const clipboard: Clipboard = { lines: ["from-before"] }; + const patcher = new Patcher({ fs, snapshots, clipboard }); + + await patcher.apply(Patch.parse(`[a.ts#${computeFileHash(text)}]\nPASTE.POST 1`)); + expect(fs.get("a.ts")).toBe("l1\nfrom-before\nl2\n"); + }); +}); diff --git a/packages/hashline/test/core-contracts.test.ts b/packages/hashline/test/core-contracts.test.ts index 2d44ae747..12b92bd48 100644 --- a/packages/hashline/test/core-contracts.test.ts +++ b/packages/hashline/test/core-contracts.test.ts @@ -93,7 +93,7 @@ describe("hashline parser — range-anchor contracts", () => { expect(section.applyTo("aaa\nbbb\nccc").text).toBe("aaa\nbbb\ntail\nccc"); }); - it("applies replace/delete/insert operations against concrete anchors", () => { + it("applies replace/cut/insert operations against concrete anchors", () => { const diff = [ `INS.PRE ${tag(2)}:`, repl("before b"), @@ -105,8 +105,8 @@ describe("hashline parser — range-anchor contracts", () => { repl("tail"), ].join("\n"); expect(applyDiff(content, diff)).toBe("top\naaa\nbefore b\nbbb\nafter b\nccc\ntail"); - expect(applyDiff(content, `DEL ${tag(2)}`)).toBe("aaa\nccc"); - expect(applyDiff(content, `DEL ${tag(2)}..${tag(3)}`)).toBe("aaa"); + expect(applyDiff(content, `CUT ${tag(2)}`)).toBe("aaa\nccc"); + expect(applyDiff(content, `CUT ${tag(2)}..${tag(3)}`)).toBe("aaa"); expect(applyDiff(content, `${sameLineRange(tag(2))}\n${repl("BBB")}`)).toBe("aaa\nBBB\nccc"); }); @@ -283,10 +283,10 @@ describe("hashline abort sentinel", () => { }); }); -describe("hashline parser — delete and blank payload semantics", () => { - it("applies inline delete and empty replace operations", () => { - expect(applyDiff("line1\nline2\nline3\n", splitHashlineInput("[a.ts]\nDEL 2\n").diff)).toBe("line1\nline3\n"); - expect(applyDiff("line1\nline2\nline3\nline4\n", splitHashlineInput("[a.ts]\nDEL 2.=3\n").diff)).toBe( +describe("hashline parser — cut and blank payload semantics", () => { + it("applies inline cut and empty replace operations", () => { + expect(applyDiff("line1\nline2\nline3\n", splitHashlineInput("[a.ts]\nCUT 2\n").diff)).toBe("line1\nline3\n"); + expect(applyDiff("line1\nline2\nline3\nline4\n", splitHashlineInput("[a.ts]\nCUT 2.=3\n").diff)).toBe( "line1\nline4\n", ); expect(applyDiff("line1\nline2\nline3\n", splitHashlineInput("[a.ts]\nSWAP 2.=2:\n").diff)).toBe( diff --git a/packages/hashline/test/format-v2.test.ts b/packages/hashline/test/format-v2.test.ts index 672b247fe..007b68b40 100644 --- a/packages/hashline/test/format-v2.test.ts +++ b/packages/hashline/test/format-v2.test.ts @@ -15,17 +15,17 @@ describe("hashline format v4", () => { it("deletes a single source line", () => { const text = "a\nb\nc"; - expect(applyPatch(text, "DEL 2")).toBe("a\nc"); + expect(applyPatch(text, "CUT 2")).toBe("a\nc"); }); it("deletes a concrete range", () => { const text = "a\nb\nc\nd"; - expect(applyPatch(text, "DEL 2.=3")).toBe("a\nd"); + expect(applyPatch(text, "CUT 2.=3")).toBe("a\nd"); }); it("accepts a single dot between integer range endpoints", () => { const text = "a\nb\nc\nd"; - expect(applyPatch(text, "DEL 2.3")).toBe("a\nd"); + expect(applyPatch(text, "CUT 2.3")).toBe("a\nd"); expect(applyPatch(text, "SWAP 2.3:\n+middle")).toBe("a\nmiddle\nd"); }); @@ -47,8 +47,14 @@ describe("hashline format v4", () => { expect(() => parsePatch("INS.HEAD:")).toThrow(/needs at least one/); }); - it("rejects body rows under delete", () => { - expect(() => parsePatch("DEL 2\n+replacement")).toThrow(/does not take body rows/); + it("rejects body rows under cut", () => { + expect(() => parsePatch("CUT 2\n+replacement")).toThrow(/takes no body rows/); + }); + + it("does not recognize removed DEL or COPY headers", () => { + for (const header of ["DEL 2", "DEL.BLK 2", "COPY 2", "COPY.BLK 2"]) { + expect(() => parsePatch(header)).toThrow(/payload line has no preceding hunk header/); + } }); it("auto-pipes bare body rows as literal text", () => { @@ -85,14 +91,14 @@ describe("hashline format v4", () => { ); }); - it("ignores deleting the trailing blank sentinel of a newline-terminated file", () => { + it("ignores cutting the trailing blank sentinel of a newline-terminated file", () => { // "a\nb\n" splits into ["a", "b", ""]; line 3 is the phantom sentinel. - const edits = parsePatch("DEL 3").edits; + const edits = parsePatch("CUT 3").edits; expect(applyEdits("a\nb\n", edits).text).toBe("a\nb\n"); }); - it("treats a delete range ending at the trailing sentinel as ending at the last real line", () => { - const edits = parsePatch("DEL 2.=3").edits; + it("treats a cut range ending at the trailing sentinel as ending at the last real line", () => { + const edits = parsePatch("CUT 2.=3").edits; expect(applyEdits("a\nb\n", edits).text).toBe("a\n"); }); @@ -106,9 +112,9 @@ describe("hashline format v4", () => { expect(applyEdits("a\nb\n", edits).text).toBe("a\nb\n\ntail"); }); - it("still deletes a genuine empty last line of a non-newline-terminated file", () => { + it("still cuts a genuine last line of a non-newline-terminated file", () => { // "a\nb" has no sentinel; line 2 is real content. - const edits = parsePatch("DEL 2").edits; + const edits = parsePatch("CUT 2").edits; expect(applyEdits("a\nb", edits).text).toBe("a"); }); diff --git a/packages/hashline/test/landing-shift.test.ts b/packages/hashline/test/landing-shift.test.ts index 1b41ddc09..99e0fcac0 100644 --- a/packages/hashline/test/landing-shift.test.ts +++ b/packages/hashline/test/landing-shift.test.ts @@ -85,8 +85,8 @@ describe("after-insert landing shift", () => { }); it("refuses to cross a line targeted by another hunk", () => { - const { text, warnings } = apply(FILE, "INS.POST 3:\n+ c();\nDEL 4"); - // The closer on line 4 is owned by the delete; the insert stays put. + const { text, warnings } = apply(FILE, "INS.POST 3:\n+ c();\nCUT 4"); + // The closer on line 4 is owned by the cut; the insert stays put. expect(text).toBe(["function f() {", " if (x) {", " a();", " c();", " b();", "}", ""].join("\n")); expect(warnings).toHaveLength(0); }); diff --git a/packages/hashline/test/leniency.test.ts b/packages/hashline/test/leniency.test.ts index 2138a2ce9..3f009fa9b 100644 --- a/packages/hashline/test/leniency.test.ts +++ b/packages/hashline/test/leniency.test.ts @@ -48,7 +48,7 @@ describe("hashline section headers", () => { it("reports bracket syntax with a 4-hex example when the header is missing", () => { try { - Patch.parse("DEL 38.=40"); + Patch.parse("CUT 38.=40"); throw new Error("expected missing-header error"); } catch (error) { const message = error instanceof Error ? error.message : String(error); @@ -68,18 +68,18 @@ describe("hashline core — verb header forms", () => { expect(() => parsePatch("2 3\n+X")).toThrow(/Hunk headers need a verb/); }); - it("accepts canonical replace/delete/insert forms", () => { + it("accepts canonical replace/cut/insert forms", () => { expect(applyPatch(FILE, "SWAP 2.=3:\n+X")).toBe("a\nX\nd\ne"); - expect(applyPatch(FILE, "DEL 2.=3")).toBe("a\nd\ne"); + expect(applyPatch(FILE, "CUT 2.=3")).toBe("a\nd\ne"); expect(applyPatch(FILE, "INS.PRE 2:\n+X")).toBe("a\nX\nb\nc\nd\ne"); expect(applyPatch(FILE, "INS.POST 2:\n+X")).toBe("a\nb\nX\nc\nd\ne"); expect(applyPatch(FILE, "INS.HEAD:\n+X")).toBe("X\na\nb\nc\nd\ne"); expect(applyPatch(FILE, "INS.TAIL:\n+X")).toBe("a\nb\nc\nd\ne\nX"); }); - it("accepts single-number replace and delete shorthand", () => { + it("accepts single-number replace and cut shorthand", () => { expect(applyPatch(FILE, "SWAP 2:\n+X")).toBe("a\nX\nc\nd\ne"); - expect(applyPatch(FILE, "DEL 2")).toBe("a\nc\nd\ne"); + expect(applyPatch(FILE, "CUT 2")).toBe("a\nc\nd\ne"); }); it("accepts alternate replace range separators and missing colon", () => { @@ -103,8 +103,8 @@ describe("hashline core — verb header forms", () => { // `INS.POST 2.:` instead of `INS.POST 2:` expect(applyPatch(FILE, "INS.POST 2.:\n+X")).toBe("a\nb\nX\nc\nd\ne"); expect(applyPatch(FILE, "INS.PRE 2.:\n+X")).toBe("a\nX\nb\nc\nd\ne"); - // `DEL 2.=3.` instead of `DEL 2.=3` (stray dot, no colon) - expect(applyPatch(FILE, "DEL 2.=3.")).toBe("a\nd\ne"); + // `CUT 2.=3.` instead of `CUT 2.=3` + expect(applyPatch(FILE, "CUT 2.=3.")).toBe("a\nd\ne"); // `INS.HEAD.:` and `INS.TAIL.:` with stray dot expect(applyPatch(FILE, "INS.HEAD.:\n+X")).toBe("X\na\nb\nc\nd\ne"); expect(applyPatch(FILE, "INS.TAIL.:\n+X")).toBe("a\nb\nc\nd\ne\nX"); @@ -202,12 +202,8 @@ describe("hashline body contracts", () => { expect(() => parsePatch("INS.TAIL:")).toThrow(/`INS` needs/); }); - it("rejects delete with a body", () => { - expect(() => parsePatch("DEL 2\n+X")).toThrow(/does not take body rows/); - }); - - it("rejects delete with a colon", () => { - expect(() => parsePatch("DEL 2:\n+X")).toThrow(/has no colon/); + it("rejects cut with a body", () => { + expect(() => parsePatch("CUT 2\n+X")).toThrow(/takes no body rows/); }); }); diff --git a/packages/hashline/test/patcher.test.ts b/packages/hashline/test/patcher.test.ts index 10436845b..4d9c6d3b3 100644 --- a/packages/hashline/test/patcher.test.ts +++ b/packages/hashline/test/patcher.test.ts @@ -337,7 +337,7 @@ describe("Patcher seen-line provenance", () => { const patcher = new Patcher({ fs, snapshots }); // Anchor 60 unseen lines — over the 40-line inline reveal cap. - const dels = Array.from({ length: 60 }, (_, i) => `DEL ${100 + i}`).join("\n"); + const dels = Array.from({ length: 60 }, (_, i) => `CUT ${100 + i}`).join("\n"); let message: string | undefined; try { await patcher.apply(Patch.parse(`[${PATH}#${tag}]\n${dels}`)); diff --git a/packages/metaharness/adapters/edit/cli.ts b/packages/metaharness/adapters/edit/cli.ts old mode 100644 new mode 100755 index eff9e91de..cb3fa3bc5 --- a/packages/metaharness/adapters/edit/cli.ts +++ b/packages/metaharness/adapters/edit/cli.ts @@ -1,97 +1,363 @@ #!/usr/bin/env bun -/** Manager-owned executable adapter for the TypeScript edit benchmark. */ +/** + * Executable adapter for the TypeScript edit benchmark. + * + * Two audiences share this entry point: + * - The metaharness manager spawns it headless (`--model … --output result.json`) + * and consumes only the continuously-rewritten report file. + * - Humans run it directly and get the interactive experience: a config + * banner, a live progress bar with per-run failure diffs (stderr, TTY-aware), + * a runtime-stats summary, and a markdown or JSON report. + */ import * as fs from "node:fs/promises"; import * as path from "node:path"; import { parseArgs } from "node:util"; -import { TempDir } from "@oh-my-pi/pi-utils"; -import { loadTasksFromDir } from "@oh-my-pi/typescript-edit-benchmark/tasks"; -import { generateJsonReport } from "./report"; -import { type BenchmarkConfig, runBenchmark } from "./runner"; +import { type ResolvedThinkingLevel, ThinkingLevel } from "@oh-my-pi/pi-agent-core"; +import { THINKING_EFFORTS } from "@oh-my-pi/pi-ai"; +import { postmortem, TempDir } from "@oh-my-pi/pi-utils"; +import { loadTasksFromDir, validateFixturesFromDir } from "@oh-my-pi/typescript-edit-benchmark/tasks"; +import { LiveProgress } from "./live-progress"; +import { generateJsonReport, generateReport } from "./report"; +import { type BenchmarkConfig, type BenchmarkResult, buildBenchmarkResult, runBenchmark } from "./runner"; const EDIT_PACKAGE = path.resolve(import.meta.dir, "..", "..", "..", "typescript-edit-benchmark"); +const RUNS_DIR = path.resolve(import.meta.dir, "..", "..", "..", "..", "runs"); -async function extractFixtures(): Promise<{ dir: string; temp: TempDir }> { +type ReportFormat = "markdown" | "json"; + +function log(line = ""): void { + process.stderr.write(`${line}\n`); +} + +function fail(message: string): never { + throw new Error(message); +} + +function parseThinkingLevel(value: string): ResolvedThinkingLevel { + if ([ThinkingLevel.Off, ...THINKING_EFFORTS].includes(value as ResolvedThinkingLevel)) { + return value as ResolvedThinkingLevel; + } + return fail(`Invalid thinking level: ${value}. Valid levels: ${[ThinkingLevel.Off, ...THINKING_EFFORTS].join(", ")}`); +} + +function parsePositiveInt(raw: string | undefined, flag: string, fallback: number): number { + if (raw === undefined) return fallback; + const parsed = Number.parseInt(raw, 10); + if (Number.isNaN(parsed) || parsed < 1) fail(`Invalid ${flag} value: ${raw}. Must be a positive integer.`); + return parsed; +} + +function parseFuzzy(raw: string | undefined): boolean | "auto" | undefined { + if (raw === undefined) return undefined; + if (raw === "auto") return "auto"; + if (raw === "true" || raw === "1") return true; + if (raw === "false" || raw === "0") return false; + return fail(`Invalid --edit-fuzzy: ${raw}. Must be true, false, 1, 0, or auto.`); +} + +function parseFuzzyThreshold(raw: string | undefined): number | "auto" | undefined { + if (raw === undefined) return undefined; + if (raw === "auto") return "auto"; + const parsed = Number.parseFloat(raw); + if (Number.isNaN(parsed) || parsed < 0 || parsed > 1) { + fail(`Invalid --edit-fuzzy-threshold: ${raw}. Must be 0-1 or auto.`); + } + return parsed; +} + +function resolveFormat(explicit: string | undefined, outputPath: string): ReportFormat { + if (explicit === "markdown" || explicit === "json") return explicit; + if (explicit !== undefined) fail(`Invalid --format: ${explicit}. Must be markdown or json.`); + return outputPath.endsWith(".md") || outputPath.endsWith(".markdown") ? "markdown" : "json"; +} + +function generateReportFilename(config: BenchmarkConfig): string { + const modelName = config.model + .split("/") + .pop()! + .replace(/[^a-zA-Z0-9-]/g, "_"); + const variant = config.editVariant ?? "auto"; + const timestamp = new Date().toISOString().replace(/:/g, "-").replace(/\..+$/, "Z"); + return path.join(RUNS_DIR, `${modelName}_${variant}_${timestamp}.md`); +} + +/** Sibling `.dump` directory for an output path, timestamped on collision. */ +async function resolveConversationDumpDir(outputPath: string): Promise { + const parsed = path.parse(outputPath); + const preferred = path.join(parsed.dir, `${parsed.name}.dump`); + try { + await fs.stat(preferred); + } catch { + return preferred; + } + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + return path.join(parsed.dir, `${parsed.name}.${timestamp}.dump`); +} + +interface ResolvedFixtures { + dir: string; + cleanup?: () => Promise; +} + +/** Resolve `--fixtures` (directory or tarball; default: the built-in tarball). */ +async function resolveFixtures(fixturesArg: string | undefined): Promise { + const source = fixturesArg ?? path.join(EDIT_PACKAGE, "fixtures.tar.gz"); + if (!source.endsWith(".tar.gz") && !source.endsWith(".tgz")) { + return { dir: source }; + } const temp = await TempDir.create("@metaharness-edit-fixtures-"); - const archive = new Bun.Archive(await Bun.file(path.join(EDIT_PACKAGE, "fixtures.tar.gz")).arrayBuffer()); + const archive = new Bun.Archive(await Bun.file(source).arrayBuffer()); for (const [filePath, file] of await archive.files()) { await Bun.write(path.join(temp.path(), filePath), file); } const entries = await fs.readdir(temp.path(), { withFileTypes: true }); const directories = entries.filter(entry => entry.isDirectory()); const files = entries.filter(entry => entry.isFile()); - return { dir: directories.length === 1 && files.length === 0 ? path.join(temp.path(), directories[0]!.name) : temp.path(), temp }; + const dir = directories.length === 1 && files.length === 0 ? path.join(temp.path(), directories[0]!.name) : temp.path(); + return { dir, cleanup: () => temp.remove() }; } -/** Execute an edit benchmark and continuously materialize its normalized source artifact. */ +function printUsage(): void { + log(` +Edit Benchmark - Evaluate patch application success rates + +Usage: + bun adapters/edit/cli.ts --model [options] + +Options: + --model Provider/model ID, e.g. anthropic/claude-sonnet-4 (required) + --provider Override provider (auto-detected from model prefix) + --thinking Thinking level: off, minimal, low, medium, high, xhigh, max + --runs Runs per task (default: 1) + --timeout Timeout per run in ms (default: 120000) + --connection-timeout Timeout for first event before fast-retry (default: 30000) + --max-turns Max turns per attempt before failing (default: 30) + --task-concurrency Max tasks to run in parallel (default: 32) + --tasks Comma-separated task IDs to run (default: sampled) + --max-tasks Max tasks to sample evenly (default: 80, 0 = all) + --fixtures Fixtures directory or .tar.gz archive (default: built-in) + --edit-variant Edit variant, e.g. hashline, replace, apply_patch (default: auto) + --edit-fuzzy Fuzzy matching: true, false, auto + --edit-fuzzy-threshold Fuzzy threshold 0-1 or auto + --guided Include an authoritative suggested edit payload + --max-attempts Max prompt attempts per run (default: 1) + --no-early-stop-on-match Don't short-circuit when output matches expected + --output Report file (default: runs/__.md) + --format Report format: markdown, json (default: by extension) + --check-fixtures Validate fixtures and exit + --quiet Suppress the live progress view + --list Print task ids as JSON and exit + --help Show this help message + +Examples: + # Full run against the default sample of 80 tasks + bun adapters/edit/cli.ts --model anthropic/claude-sonnet-4 + + # Compare edit variants + bun adapters/edit/cli.ts --model openai/gpt-5 --edit-variant hashline --output hashline.md + bun adapters/edit/cli.ts --model openai/gpt-5 --edit-variant apply_patch --output apply_patch.md + + # Specific tasks, more runs + bun adapters/edit/cli.ts --model anthropic/claude-sonnet-4 --tasks logic-flip-strict-equality-001 --runs 5 +`); +} + +/** Execute an edit benchmark and continuously materialize its report artifact. */ export async function main(argv = process.argv.slice(2)): Promise { const { values } = parseArgs({ args: argv, options: { model: { type: "string" }, - output: { type: "string" }, - "max-tasks": { type: "string", default: "80" }, - tasks: { type: "string" }, - "task-concurrency": { type: "string", default: "32" }, + provider: { type: "string" }, + thinking: { type: "string" }, runs: { type: "string", default: "1" }, + timeout: { type: "string", default: "120000" }, + "connection-timeout": { type: "string", default: "30000" }, + "max-turns": { type: "string", default: "30" }, + "task-concurrency": { type: "string", default: "32" }, + tasks: { type: "string" }, + "max-tasks": { type: "string", default: "80" }, + fixtures: { type: "string" }, + "edit-variant": { type: "string" }, + "edit-fuzzy": { type: "string" }, + "edit-fuzzy-threshold": { type: "string" }, + guided: { type: "boolean", default: false }, + "max-attempts": { type: "string", default: "1" }, + "no-op-retry-limit": { type: "string", default: "2" }, + "max-timeout-retries": { type: "string", default: "3" }, + "max-provider-retries": { type: "string", default: "3" }, + "mutation-scope-window": { type: "string", default: "20" }, + "no-early-stop-on-match": { type: "boolean", default: false }, + output: { type: "string" }, + format: { type: "string" }, + "check-fixtures": { type: "boolean", default: false }, + quiet: { type: "boolean", default: false }, list: { type: "boolean", default: false }, + help: { type: "boolean", default: false }, }, strict: true, }); - const fixtures = await extractFixtures(); + + if (values.help) { + printUsage(); + return; + } + + const fixtures = await resolveFixtures(values.fixtures); try { + if (values["check-fixtures"]) { + const issues = await validateFixturesFromDir(fixtures.dir); + if (issues.length === 0) { + log("Fixtures OK"); + return; + } + log("Fixture validation failed:"); + for (const issue of issues) log(` - ${issue.taskId}: ${issue.message}`); + process.exitCode = 1; + return; + } + let tasks = await loadTasksFromDir(fixtures.dir); if (values.list) { process.stdout.write(`${JSON.stringify(tasks.map(task => ({ id: task.id, name: task.name })))}\n`); return; } - if (!values.model || !values.output) throw new Error("edit adapter requires --model and --output"); + if (!values.model) fail("edit adapter requires --model (see --help)"); + if (values.tasks) { const selected = new Set(values.tasks.split(",").map(value => value.trim())); tasks = tasks.filter(task => selected.has(task.id)); - if (tasks.length !== selected.size) throw new Error("one or more edit task ids were not found"); + if (tasks.length !== selected.size) fail("one or more edit task ids were not found (see --list)"); } else { const limit = Number(values["max-tasks"]); if (limit > 0 && tasks.length > limit) { + // Deterministic even sampling across the id-sorted list keeps + // mutation-category coverage representative. const sorted = tasks.slice().sort((a, b) => a.id.localeCompare(b.id)); const step = sorted.length / limit; tasks = Array.from({ length: limit }, (_, index) => sorted[Math.floor(index * step)]!); } } - const slash = values.model.indexOf("/"); + + const model = values.model; + const slash = model.indexOf("/"); const config: BenchmarkConfig = { - provider: slash === -1 ? "anthropic" : values.model.slice(0, slash), - model: values.model, - runsPerTask: Number(values.runs), - timeout: 120_000, - connectionTimeout: 30_000, - maxTurns: 30, - taskConcurrency: Number(values["task-concurrency"]), - guided: false, - maxAttempts: 1, - noOpRetryLimit: 2, - maxTimeoutRetries: 3, - maxProviderFailureRetries: 3, - mutationScopeWindow: 20, - conversationDumpDir: path.join(path.dirname(values.output), "result.dump"), + provider: values.provider ?? (slash === -1 ? "anthropic" : model.slice(0, slash)), + model, + ...(values.thinking === undefined ? {} : { thinkingLevel: parseThinkingLevel(values.thinking) }), + runsPerTask: parsePositiveInt(values.runs, "--runs", 1), + timeout: parsePositiveInt(values.timeout, "--timeout", 120_000), + connectionTimeout: parsePositiveInt(values["connection-timeout"], "--connection-timeout", 30_000), + maxTurns: parsePositiveInt(values["max-turns"], "--max-turns", 30), + taskConcurrency: parsePositiveInt(values["task-concurrency"], "--task-concurrency", 32), + guided: values.guided, + maxAttempts: parsePositiveInt(values["max-attempts"], "--max-attempts", 1), + noOpRetryLimit: parsePositiveInt(values["no-op-retry-limit"], "--no-op-retry-limit", 2), + maxTimeoutRetries: parsePositiveInt(values["max-timeout-retries"], "--max-timeout-retries", 3), + maxProviderFailureRetries: parsePositiveInt(values["max-provider-retries"], "--max-provider-retries", 3), + mutationScopeWindow: parsePositiveInt(values["mutation-scope-window"], "--mutation-scope-window", 20), inProcess: true, - earlyStopOnMatch: true, + earlyStopOnMatch: !values["no-early-stop-on-match"], }; - let writes = Promise.resolve(); - const result = await runBenchmark(tasks, config, undefined, snapshot => { - writes = writes.then(async () => { - await Bun.write(values.output!, generateJsonReport(snapshot)); - }); + const editVariant = values["edit-variant"]; + if (editVariant) config.editVariant = editVariant; + const editFuzzy = parseFuzzy(values["edit-fuzzy"]); + if (editFuzzy !== undefined) config.editFuzzy = editFuzzy; + const editFuzzyThreshold = parseFuzzyThreshold(values["edit-fuzzy-threshold"]); + if (editFuzzyThreshold !== undefined) config.editFuzzyThreshold = editFuzzyThreshold; + + let outputPath = values.output; + if (outputPath === undefined) { + await fs.mkdir(RUNS_DIR, { recursive: true }); + outputPath = generateReportFilename(config); + } + const format = resolveFormat(values.format, outputPath); + config.conversationDumpDir = await resolveConversationDumpDir(outputPath); + + log("Edit Benchmark"); + log("=============="); + log(`Provider: ${config.provider}`); + log(`Model: ${config.model}`); + if (config.thinkingLevel) log(`Thinking: ${config.thinkingLevel}`); + log(`Runs per task: ${config.runsPerTask}`); + log(`Timeout: ${config.timeout}ms`); + log(`Task concurrency: ${config.taskConcurrency}`); + log(`Guided mode: ${config.guided ? "enabled" : "disabled"}`); + if (config.editVariant) log(`Edit variant: ${config.editVariant}`); + if (config.editFuzzy !== undefined) log(`Edit fuzzy: ${config.editFuzzy}`); + if (config.editFuzzyThreshold !== undefined) log(`Edit fuzzy threshold: ${config.editFuzzyThreshold}`); + log(`Tasks: ${tasks.length}`); + log(`Report: ${outputPath}`); + log(`Conversation dumps: ${config.conversationDumpDir}`); + log(); + + const renderReport = (result: BenchmarkResult): string => + format === "json" ? generateJsonReport(result) : generateReport(result); + + const progress = values.quiet ? undefined : new LiveProgress(tasks.length * config.runsPerTask, config.runsPerTask); + let latestResult = buildBenchmarkResult({ + tasks, + config, + resultsByTask: new Map(), + startTime: new Date().toISOString(), }); + let writes = Promise.resolve(); + const queueReportWrite = (result: BenchmarkResult) => { + writes = writes.then(async () => { + await Bun.write(outputPath, renderReport(result)); + }); + }; + // A killed/interrupted run still leaves a usable partial report behind. + const unregisterCleanup = postmortem.register("edit-benchmark-report", async reason => { + if (reason === postmortem.Reason.EXIT) return; + progress?.finish(); + log("Benchmark interrupted; writing partial report..."); + await Bun.write(outputPath, renderReport(latestResult)); + await fixtures.cleanup?.(); + }); + + const result = await runBenchmark( + tasks, + config, + event => progress?.handleEvent(event), + snapshot => { + latestResult = snapshot; + queueReportWrite(snapshot); + }, + ); + latestResult = result; + progress?.finish(); + queueReportWrite(result); await writes; - await Bun.write(values.output, generateJsonReport(result)); + unregisterCleanup(); + + log(); + log("Benchmark complete!"); + log( + ` Task success rate (best of ${config.runsPerTask}): ${(result.summary.taskSuccessRate * 100).toFixed(1)}% (${result.summary.successfulTasks}/${result.summary.totalTasks})`, + ); + log(` Total tokens (best): ${result.summary.totalTokens.input} in / ${result.summary.totalTokens.output} out`); + log( + ` Tokens/task (best): mean=${result.summary.avgTokensPerTask.total} median=${result.summary.medianTokensPerTask.total} p1=${result.summary.p1TokensPerTask.total} p99=${result.summary.p99TokensPerTask.total} reasoning=${result.summary.avgTokensPerTask.reasoning}`, + ); + if (result.summary.ghostRuns > 0) log(` Ghost runs (0/0/0): ${result.summary.ghostRuns}`); + if (result.summary.timeoutRuns > 0) log(` Timeout runs: ${result.summary.timeoutRuns}`); + log(`Report written to: ${outputPath}`); } finally { - await fixtures.temp.remove(); + await fixtures.cleanup?.(); } } if (import.meta.main) { - main().catch(error => { - process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`); - process.exitCode = 1; - }); + main() + .then(async () => { + // In-process benchmark runs can leave provider keep-alive sockets and + // background AgentSession timers alive after the report is written. + // Treat the final report as the CLI boundary. + await postmortem.quit(Number(process.exitCode ?? 0)); + }) + .catch(async error => { + process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`); + await postmortem.quit(1); + }); } diff --git a/packages/metaharness/adapters/edit/live-progress.ts b/packages/metaharness/adapters/edit/live-progress.ts new file mode 100644 index 000000000..efdc65bc7 --- /dev/null +++ b/packages/metaharness/adapters/edit/live-progress.ts @@ -0,0 +1,241 @@ +/** + * Live terminal renderer for edit benchmark runs. + * + * Thin view over {@link runBenchmark}'s `onProgress` stream: a single + * in-place progress line (bar, pass rates, token/latency averages, in-flight + * count) on a TTY, plain per-run lines otherwise, plus inline colored diffs + * for failed runs and a runtime-stats block at the end. Renders to stderr so + * stdout stays free for machine output (`--list` JSON), and the report file + * remains the only artifact the manager consumes. + */ +import { percentile, type ProgressEvent } from "./runner"; + +const ANSI = { + reset: "\x1b[0m", + bold: "\x1b[1m", + dim: "\x1b[2m", + red: "\x1b[31m", + green: "\x1b[32m", + yellow: "\x1b[33m", + cyan: "\x1b[36m", +} as const; + +function rateColor(percent: number): string { + if (percent >= 80) return ANSI.green; + if (percent >= 50) return ANSI.yellow; + return ANSI.red; +} + +export class LiveProgress { + readonly #totalRuns: number; + readonly #runsPerTask: number; + readonly #isTty: boolean; + readonly #colors: boolean; + #started = 0; + #completed = 0; + #success = 0; + #totalInput = 0; + #totalOutput = 0; + #totalDuration = 0; + #totalReads = 0; + #totalEdits = 0; + #totalWrites = 0; + #totalEditSuccesses = 0; + #totalToolInputChars = 0; + #indentScores: number[] = []; + #inputTokens: number[] = []; + #outputTokens: number[] = []; + #totalTokens: number[] = []; + #oneShotSuccessTokens: number[] = []; + #lastLineLength = 0; + + constructor(totalRuns: number, runsPerTask: number) { + this.#totalRuns = totalRuns; + this.#runsPerTask = runsPerTask; + this.#isTty = Boolean(process.stderr.isTTY); + this.#colors = this.#isTty && !process.env.NO_COLOR; + } + + #paint(code: string, text: string): string { + return this.#colors ? `${code}${text}${ANSI.reset}` : text; + } + + #log(line: string): void { + process.stderr.write(`${line}\n`); + } + + handleEvent(event: ProgressEvent): void { + if (event.status === "started") { + this.#started += 1; + if (!this.#isTty) { + this.#log(` [${event.taskId}] Run ${event.runIndex + 1}/${this.#runsPerTask} started...`); + } + this.#renderLine(); + return; + } + + this.#completed += 1; + if (event.result) { + if (event.result.success) { + this.#success += 1; + } + if (event.result.success && event.runIndex === 0) { + this.#oneShotSuccessTokens.push(event.result.tokens.total); + } + this.#totalInput += event.result.tokens.input; + this.#totalOutput += event.result.tokens.output; + this.#inputTokens.push(event.result.tokens.input); + this.#outputTokens.push(event.result.tokens.output); + this.#totalTokens.push(event.result.tokens.total); + this.#totalDuration += event.result.duration; + this.#totalReads += event.result.toolCalls.read; + this.#totalEdits += event.result.toolCalls.edit; + this.#totalWrites += event.result.toolCalls.write; + this.#totalEditSuccesses += event.result.toolCalls.editSuccesses; + this.#totalToolInputChars += event.result.toolCalls.totalInputChars; + if (typeof event.result.indentScore === "number") { + this.#indentScores.push(event.result.indentScore); + } + } + + const result = event.result; + if (result && !result.success && result.error) { + this.#flushLine(); + const header = this.#paint( + ANSI.red, + `[${event.taskId}] Run ${event.runIndex + 1}/${this.#runsPerTask} failed:`, + ); + this.#log(` ${header} ${result.error}`); + if (result.diff) { + const changeLines = result.diff + .split("\n") + .filter(line => /^[-+@]/.test(line) && !/^(---|\+\+\+)/.test(line)); + const maxLines = 40; + for (const line of changeLines.slice(0, maxLines)) { + let color: string | undefined; + if (line.startsWith("@@")) color = ANSI.cyan; + else if (line.startsWith("-")) color = ANSI.red; + else if (line.startsWith("+")) color = ANSI.green; + this.#log(` ${color ? this.#paint(color, line) : line}`); + } + if (changeLines.length > maxLines) { + this.#log(this.#paint(ANSI.dim, ` ... (${changeLines.length - maxLines} more change lines)`)); + } + } + } + + if (result?.editFailures && result.editFailures.length > 0) { + this.#flushLine(); + for (const [i, failure] of result.editFailures.entries()) { + const args = (failure.args ?? {}) as Record; + const target = + typeof args.path === "string" ? args.path : typeof args.file === "string" ? args.file : undefined; + const op = typeof args.operation === "string" ? args.operation : undefined; + const oneLine = failure.error.replace(/\s+/g, " ").trim(); + const clipped = oneLine.length > 240 ? `${oneLine.slice(0, 237)}...` : oneLine; + const tag = this.#paint(ANSI.yellow, `[${event.taskId}] schema #${i + 1}`); + const metaParts = [op, target].filter((value): value is string => Boolean(value)); + const meta = metaParts.length > 0 ? this.#paint(ANSI.dim, metaParts.join(" ")) : ""; + this.#log(` ${tag}${meta ? ` ${meta}` : ""} ${clipped}`); + if (failure.rawBlock) { + const rawLine = failure.rawBlock.replace(/\s+/g, " ").trim(); + const clippedRaw = rawLine.length > 240 ? `${rawLine.slice(0, 237)}...` : rawLine; + this.#log(` ${this.#paint(ANSI.dim, "raw")} ${clippedRaw}`); + } + } + } + + if (!this.#isTty) { + const status = event.result?.success ? "completed" : "failed"; + this.#log(` [${event.taskId}] Run ${event.runIndex + 1}/${this.#runsPerTask} ${status}`); + } + + this.#renderLine(); + } + + finish(): void { + this.#flushLine(); + this.#printSummary(); + } + + #printSummary(): void { + const n = this.#completed; + const denom = n || 1; + + const successRate = (this.#success / denom) * 100; + const editSuccessRate = this.#totalEdits > 0 ? (this.#totalEditSuccesses / this.#totalEdits) * 100 : 100; + const avgIndent = + this.#indentScores.length > 0 ? this.#indentScores.reduce((a, b) => a + b, 0) / this.#indentScores.length : 0; + + this.#log(""); + this.#log(this.#paint(ANSI.bold, "Runtime Stats:")); + this.#log( + ` Task success: ${this.#paint(rateColor(successRate), `${successRate.toFixed(1)}% (${this.#success}/${n})`)}`, + ); + this.#log( + ` Edit success: ${this.#paint(rateColor(editSuccessRate), `${editSuccessRate.toFixed(1)}% (${this.#totalEditSuccesses}/${this.#totalEdits})`)}`, + ); + this.#log(` Avg indent score: ${avgIndent.toFixed(2)}`); + this.#log(` Tool calls: read=${this.#totalReads} edit=${this.#totalEdits} write=${this.#totalWrites}`); + this.#log(` Tool input chars: ${this.#totalToolInputChars.toLocaleString()}`); + const fmtTokens = (samples: number[]): string => { + if (samples.length === 0) return "mean=0 median=0 p1=0 p99=0"; + const sorted = [...samples].sort((a, b) => a - b); + const mean = Math.round(sorted.reduce((a, b) => a + b, 0) / sorted.length); + return `mean=${mean} median=${Math.round(percentile(sorted, 50))} p1=${Math.round(percentile(sorted, 1))} p99=${Math.round(percentile(sorted, 99))}`; + }; + this.#log(` Tokens/task in: ${fmtTokens(this.#inputTokens)}`); + this.#log(` Tokens/task out: ${fmtTokens(this.#outputTokens)}`); + this.#log(` Tokens/task tot: ${fmtTokens(this.#totalTokens)}`); + this.#log(` Tokens/task (one-shot successes): ${fmtTokens(this.#oneShotSuccessTokens)}`); + this.#log(` Avg time/task: ${Math.round(this.#totalDuration / denom)}ms`); + } + + #renderLine(): void { + if (!this.#isTty) { + return; + } + const successRate = this.#completed > 0 ? (this.#success / this.#completed) * 100 : 0; + const editRate = this.#totalEdits > 0 ? (this.#totalEditSuccesses / this.#totalEdits) * 100 : 100; + const avgInput = this.#completed > 0 ? Math.round(this.#totalInput / this.#completed) : 0; + const avgOutput = this.#completed > 0 ? Math.round(this.#totalOutput / this.#completed) : 0; + const avgDuration = this.#completed > 0 ? Math.round(this.#totalDuration / this.#completed) : 0; + const inFlight = this.#started - this.#completed; + const bar = this.#renderBar(this.#completed, this.#totalRuns, 20); + const progress = this.#paint(ANSI.bold, `${this.#completed}/${this.#totalRuns}`); + const taskCol = `task=${this.#paint(rateColor(successRate), `${successRate.toFixed(0)}%`)}`; + const editCol = `edit=${this.#paint(rateColor(editRate), `${editRate.toFixed(0)}%`)}`; + const tokCol = this.#paint(ANSI.dim, `tok=${avgInput}/${avgOutput}`); + const durCol = this.#paint(ANSI.dim, `${avgDuration}ms`); + const rewCol = this.#paint(ANSI.dim, `r/e/w=${this.#totalReads}/${this.#totalEdits}/${this.#totalWrites}`); + const flyCol = `fly=${this.#paint(ANSI.cyan, String(inFlight))}`; + const line = ` ${bar} ${progress} ${taskCol} ${editCol} ${tokCol} ${durCol} ${rewCol} ${flyCol}`; + this.#writeLine(line); + } + + #renderBar(done: number, total: number, width: number): string { + const ratio = total === 0 ? 0 : done / total; + const filled = Math.round(ratio * width); + const empty = Math.max(0, width - filled); + const filledPart = this.#paint(ANSI.green, "#".repeat(filled)); + const emptyPart = this.#paint(ANSI.dim, "-".repeat(empty)); + return `[${filledPart}${emptyPart}]`; + } + + #writeLine(line: string): void { + const lineWidth = Bun.stringWidth(line); + const pad = this.#lastLineLength > lineWidth ? " ".repeat(this.#lastLineLength - lineWidth) : ""; + process.stderr.write(`\r${line}${pad}`); + this.#lastLineLength = lineWidth; + } + + #flushLine(): void { + if (!this.#isTty) { + return; + } + if (this.#lastLineLength > 0) { + process.stderr.write(`\r${" ".repeat(this.#lastLineLength)}\r`); + this.#lastLineLength = 0; + } + } +} diff --git a/packages/metaharness/adapters/edit/prompts/benchmark-system.md b/packages/metaharness/adapters/edit/prompts/benchmark-system.md index 992e4487c..6881ea6b0 100644 --- a/packages/metaharness/adapters/edit/prompts/benchmark-system.md +++ b/packages/metaharness/adapters/edit/prompts/benchmark-system.md @@ -3,13 +3,12 @@ You are participating in a code-edit benchmark inside a repository with {{#if mu This benchmark is scored on exactness. Get the edit right. ## Important constraints -- Make the minimum change necessary. Do not refactor, improve, or clean up other code. -- If you see multiple similar patterns, only change the ONE that is buggy (there is only one intended mutation). -- Preserve exact code structure. Do not rearrange statements or change formatting. +- Make exactly the change the task specifies — nothing more. Do not refactor, improve, or clean up other code. +- Tasks range from single-token fixes to multi-hunk block rewrites. When the task shows replacement code, reproduce it byte-for-byte: indentation, tabs vs spaces, and blank lines included. +- If the file contains multiple similar regions, change only the one(s) the task identifies. - Your output is verified by exact text diff against an expected fixture. Equivalent code, reordered imports, reordered object keys, or formatting changes will fail. -- Prefer copying the original line(s) and changing only the specific token(s) required. Do not rewrite whole statements. - Never modify comments or license headers unless the task explicitly asks. -- Re-read the changed region after editing to confirm you only touched the intended line(s). +- Re-read the changed region after editing to confirm it matches the task exactly. {{#if multiFile}}- Only modify the file(s) referenced by the task or follow-up messages. Leave all other files unchanged. {{/if}} ## Process diff --git a/packages/metaharness/adapters/edit/report.ts b/packages/metaharness/adapters/edit/report.ts index bf0274cd3..5943587bf 100644 --- a/packages/metaharness/adapters/edit/report.ts +++ b/packages/metaharness/adapters/edit/report.ts @@ -212,17 +212,19 @@ export function generateReport(result: BenchmarkResult): string { lines.push(""); if (summary.hashlineEditSubtypes) { - const order = ["set", "set_range", "insert"] as const; - const total = order.reduce((sum, key) => sum + (summary.hashlineEditSubtypes?.[key] ?? 0), 0); + const rows = Object.entries(summary.hashlineEditSubtypes) + .filter(([, count]) => count > 0) + .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])); + const total = rows.reduce((sum, [, count]) => sum + count, 0); if (total > 0) { - lines.push("### Hashline Edit Subtypes"); + lines.push("### Hashline Op Breakdown"); + lines.push(""); + lines.push("All attempted edit calls across all runs (retries and failed calls included)."); lines.push(""); lines.push("| Operation | Count | % |"); lines.push("|-----------|-------|---|"); - for (const key of order) { - const count = summary.hashlineEditSubtypes[key] ?? 0; - const pct = formatPercent(count / total); - lines.push(`| ${key} | ${count} | ${pct} |`); + for (const [op, count] of rows) { + lines.push(`| \`${op}\` | ${count} | ${formatPercent(count / total)} |`); } lines.push(`| **Total** | **${total}** | 100% |`); lines.push(""); diff --git a/packages/metaharness/adapters/edit/runner.ts b/packages/metaharness/adapters/edit/runner.ts index 47568e6af..ef7e962ed 100644 --- a/packages/metaharness/adapters/edit/runner.ts +++ b/packages/metaharness/adapters/edit/runner.ts @@ -7,7 +7,12 @@ /// import * as fs from "node:fs"; import * as path from "node:path"; -import { formatHashlineHeader, InMemorySnapshotStore } from "@oh-my-pi/hashline"; +import { + type BlockTarget as HashlineBlockTarget, + formatHashlineHeader, + InMemorySnapshotStore, + Tokenizer as HashlineTokenizer, +} from "@oh-my-pi/hashline"; import type { AgentMessage, ResolvedThinkingLevel, ThinkingLevel } from "@oh-my-pi/pi-agent-core"; import type { Model, ToolExample } from "@oh-my-pi/pi-ai"; import { formatSessionDumpText, RpcClient } from "@oh-my-pi/pi-coding-agent"; @@ -262,7 +267,6 @@ function countEditFailureCategories(runs: TaskRunResult[]): Record { - const counts: Record = Object.fromEntries(HL_SUBTYPES.map(k => [k, 0])); - if (!args || typeof args !== "object") return counts; - const edits = (args as { edits?: unknown[] }).edits; - if (!Array.isArray(edits)) return counts; - for (const edit of edits) { - if (!edit || typeof edit !== "object") continue; - for (const key of HL_SUBTYPES) { - if (key in edit) { - counts[key]++; - break; +// Pure classification — single shared tokenizer is safe. +const HASHLINE_OP_TOKENIZER = new HashlineTokenizer(); + +/** Display label for a hashline op header, e.g. `SWAP.BLK` or `PASTE.POST`. */ +function hashlineOpLabel(target: HashlineBlockTarget): string { + switch (target.kind) { + case "replace": + return "SWAP"; + case "block": + return "SWAP.BLK"; + case "insert_before": + return "INS.PRE"; + case "insert_after": + return "INS.POST"; + case "bof": + return "INS.HEAD"; + case "eof": + return "INS.TAIL"; + case "insert_after_block": + return "INS.BLK.POST"; + case "cut": + return "CUT"; + case "cut_block": + return "CUT.BLK"; + case "paste": + switch (target.cursor.kind) { + case "before_anchor": + return "PASTE.PRE"; + case "after_anchor": + return "PASTE.POST"; + case "bof": + return "PASTE.HEAD"; + case "eof": + return "PASTE.TAIL"; } - } + case "paste_after_block": + return "PASTE.BLK.POST"; + case "rem": + return "REM"; + case "move": + return "MV"; } - return counts; +} + +/** + * Count hashline op headers (`SWAP`, `CUT.BLK`, `PASTE.POST`, …) in an + * edit call's patch input. Returns `null` when the args carry no hashline + * patch — non-hashline edit variants and malformed calls contribute nothing. + */ +function countHashlineOps(args: unknown): Record | null { + if (!args || typeof args !== "object" || !("input" in args)) return null; + const input = args.input; + if (typeof input !== "string" || input.length === 0) return null; + const counts: Record = {}; + for (const token of HASHLINE_OP_TOKENIZER.tokenizeAll(input)) { + if (token.kind !== "op-block") continue; + const label = hashlineOpLabel(token.target); + counts[label] = (counts[label] ?? 0) + 1; + } + return Object.keys(counts).length > 0 ? counts : null; } async function collectOriginalFileContents(cwd: string, files: string[]): Promise> { @@ -829,7 +878,7 @@ export interface TaskRunResult { editFailures: EditFailure[]; editWarnings: string[]; editAutocorrectCount: number; - /** Hashline edit subtype counts (replaceLine, replaceLines, etc.) — only when editVariant is hashline */ + /** Hashline op counts (`SWAP`, `CUT.BLK`, `PASTE.POST`, …) — present when edit calls carried hashline patches. */ hashlineEditSubtypes?: Record; mutationIntentMatched?: boolean; mutationIntentReason?: string; @@ -945,7 +994,7 @@ export interface BenchmarkSummary { mutationIntentMatchRate?: number; /** Edit failure categories across all runs. */ editFailureCategories: Record; - /** Hashline edit subtype totals across all runs — only when editVariant is hashline. */ + /** Hashline op totals across all runs — present when any run's edit calls carried hashline patches. */ hashlineEditSubtypes?: Record; } @@ -1037,7 +1086,7 @@ async function runSingleTask( editAutocorrects: 0, totalInputChars: 0, }; - const hashlineSubtypes: Record = Object.fromEntries(HL_SUBTYPES.map(k => [k, 0])); + const hashlineSubtypes: Record = {}; const logFile = path.join(TMP, `run-${task.id}-${runIndex}.jsonl`); const logEvent = async (event: unknown) => { @@ -1271,10 +1320,10 @@ async function runSingleTask( const pendingEdit = pendingEdits.get(e.toolCallId) ?? { args: null }; const args = pendingEdit.args; pendingEdits.delete(e.toolCallId); - if (config.editVariant === "hashline" && args) { - const counts = countHashlineEditSubtypes(args); - for (const key of HL_SUBTYPES) { - hashlineSubtypes[key] += counts[key]; + const hashlineOpCounts = countHashlineOps(args); + if (hashlineOpCounts) { + for (const key in hashlineOpCounts) { + hashlineSubtypes[key] = (hashlineSubtypes[key] ?? 0) + hashlineOpCounts[key]; } } if (e.isError) { @@ -1422,7 +1471,7 @@ async function runSingleTask( editFailures, editWarnings, editAutocorrectCount, - hashlineEditSubtypes: config.editVariant === "hashline" ? hashlineSubtypes : undefined, + hashlineEditSubtypes: Object.keys(hashlineSubtypes).length > 0 ? hashlineSubtypes : undefined, mutationIntentMatched: mutationIntentValidation?.matched, mutationIntentReason: mutationIntentValidation?.reason, timeoutTelemetry, @@ -1936,12 +1985,20 @@ export function buildBenchmarkResult(params: { 0, ); const editFailureCategories = countEditFailureCategories(nonGhostRuns); + // Op counts aggregate every attempted edit call across ALL runs (retries and + // failed calls included) — deliberately: the mix shows what the model reaches + // for, not just what landed. Best-run-only would hide exactly the flailing + // (failed SWAPs before a successful retry) this table exists to expose. + const hashlineEditSubtypeTotals: Record = {}; + for (const run of allRuns) { + const runOps = run.hashlineEditSubtypes; + if (!runOps) continue; + for (const key in runOps) { + hashlineEditSubtypeTotals[key] = (hashlineEditSubtypeTotals[key] ?? 0) + runOps[key]; + } + } const hashlineEditSubtypes: Record | undefined = - params.config.editVariant === "hashline" - ? Object.fromEntries( - HL_SUBTYPES.map(key => [key, allRuns.reduce((sum, r) => sum + (r.hashlineEditSubtypes?.[key] ?? 0), 0)]), - ) - : undefined; + Object.keys(hashlineEditSubtypeTotals).length > 0 ? hashlineEditSubtypeTotals : undefined; // Primary aggregates run over the *best* run of each completed task. const bestRuns: TaskRunResult[] = []; diff --git a/packages/metaharness/package.json b/packages/metaharness/package.json index c41e98cb0..cbbedf4fc 100644 --- a/packages/metaharness/package.json +++ b/packages/metaharness/package.json @@ -20,6 +20,7 @@ "check:types": "tsgo -p tsconfig.json --noEmit && tsgo -p adapters/edit/tsconfig.json --noEmit && tsgo -p scripts/tsconfig.json --noEmit", "lint": "biome lint .", "serve": "bun run src/server.ts", + "bench:edit": "bun adapters/edit/cli.ts", "dev": "bun --hot src/server.ts", "test": "bun test" }, diff --git a/packages/mnemopi/package.json b/packages/mnemopi/package.json index 62e92457c..5fec03805 100644 --- a/packages/mnemopi/package.json +++ b/packages/mnemopi/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-mnemopi", - "version": "17.1.8", + "version": "17.2.0", "description": "Local SQLite memory engine for Oh My Pi agents", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/natives/CHANGELOG.md b/packages/natives/CHANGELOG.md index bd46c8b4c..1b54462fb 100644 --- a/packages/natives/CHANGELOG.md +++ b/packages/natives/CHANGELOG.md @@ -2,6 +2,13 @@ ## [Unreleased] +## [17.2.0] - 2026-07-30 + +### Changed + +- Split the native voice engine (miniaudio capture/playback, WebRTC peer, Opus media) out of the `pi-natives` addon crate into a napi-free `pi-voice` rlib. The addon keeps thin `#[napi]` adapters, so the JS API is unchanged; the webrtc/opus/miniaudio dependency graph now compiles once into the library and no longer rebuilds with the addon leaf (which recompiles every release via its version-sentinel edit). +- Release binaries now build in parallel with the test fan-out; npm leaf publishing moved to a dedicated post-validation job (`release_native_leaves`), and darwin release bazel caches are pre-warmed on native-affecting main pushes — cutting release wall time from the previous serialized tests → cold darwin build pipeline. + ## [17.1.8] - 2026-07-28 ### Fixed diff --git a/packages/natives/native/index.d.ts b/packages/natives/native/index.d.ts index 55d86029a..df50fcd93 100644 --- a/packages/natives/native/index.d.ts +++ b/packages/natives/native/index.d.ts @@ -246,7 +246,7 @@ export declare function __ompInstallTokioRuntime(): void * `packages/natives/native/index.js` (which derives the name from * `package.json#version`). */ -export declare function __piNativesV17_1_8(): void +export declare function __piNativesV17_2_0(): void /** * Apply ast-grep rewrite rules to matching files; honors `dryRun` and returns diff --git a/packages/natives/native/index.js b/packages/natives/native/index.js index a28605375..0676478c7 100644 --- a/packages/natives/native/index.js +++ b/packages/natives/native/index.js @@ -28,7 +28,7 @@ export const Shell = nativeBindings.Shell; // functions export const __ompInstallTokioRuntime = nativeBindings.__ompInstallTokioRuntime; -export const __piNativesV17_1_8 = nativeBindings.__piNativesV17_1_8; +export const __piNativesV17_2_0 = nativeBindings.__piNativesV17_2_0; export const astEdit = nativeBindings.astEdit; export const astGrep = nativeBindings.astGrep; export const astMatch = nativeBindings.astMatch; diff --git a/packages/natives/package.json b/packages/natives/package.json index 03de3d365..7423af327 100644 --- a/packages/natives/package.json +++ b/packages/natives/package.json @@ -1,6 +1,6 @@ { "name": "@oh-my-pi/pi-natives", - "version": "17.1.8", + "version": "17.2.0", "description": "Native Rust bindings for audio, WebRTC, grep, clipboard, image processing, syntax highlighting, PTY, and shell operations via N-API", "type": "module", "homepage": "https://omp.sh", diff --git a/packages/snapcompact/package.json b/packages/snapcompact/package.json index 743a08569..9dbb1d9df 100644 --- a/packages/snapcompact/package.json +++ b/packages/snapcompact/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/snapcompact", - "version": "17.1.8", + "version": "17.2.0", "description": "Bitmap-frame context compression for vision-capable LLMs", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/stats/package.json b/packages/stats/package.json index 07bcd00da..586e3650c 100644 --- a/packages/stats/package.json +++ b/packages/stats/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/omp-stats", - "version": "17.1.8", + "version": "17.2.0", "description": "Local observability dashboard for pi AI usage statistics", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/swarm-extension/package.json b/packages/swarm-extension/package.json index e4d99127e..8ded5b31a 100644 --- a/packages/swarm-extension/package.json +++ b/packages/swarm-extension/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/swarm-extension", - "version": "17.1.8", + "version": "17.2.0", "description": "Swarm orchestration extension for omp", "homepage": "https://omp.sh", "author": "Derek Rynd", diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index a6ccc3129..8fe3749e0 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [17.2.0] - 2026-07-30 + ### Added - Added response-level OSC 11 appearance subscriptions to help terminal consumers distinguish confirmed unchanged background classifications from missing replies. diff --git a/packages/tui/package.json b/packages/tui/package.json index 475092c09..9bf56eb2e 100644 --- a/packages/tui/package.json +++ b/packages/tui/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-tui", - "version": "17.1.8", + "version": "17.2.0", "description": "Terminal User Interface library with differential rendering for efficient text-based applications", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/typescript-edit-benchmark/fixtures.tar.gz b/packages/typescript-edit-benchmark/fixtures.tar.gz index 324f11bb4..16e68e207 100644 Binary files a/packages/typescript-edit-benchmark/fixtures.tar.gz and b/packages/typescript-edit-benchmark/fixtures.tar.gz differ diff --git a/packages/typescript-edit-benchmark/package.json b/packages/typescript-edit-benchmark/package.json index 8ec81cceb..f286c6020 100644 --- a/packages/typescript-edit-benchmark/package.json +++ b/packages/typescript-edit-benchmark/package.json @@ -26,7 +26,8 @@ "test": "bun test --parallel", "fix": "biome check --write --unsafe .", "fmt": "biome format --write .", - "generate": "bun run src/generate.ts --typescript-dir /tmp/pi-mono-source --count-per-type 4" + "generate": "bun run src/generate.ts --typescript-dir /tmp/pi-mono-source", + "edit-shapes": "bun run src/edit-shape-stats.ts" }, "dependencies": { "@babel/generator": "catalog:", diff --git a/packages/typescript-edit-benchmark/src/edit-shape-stats.ts b/packages/typescript-edit-benchmark/src/edit-shape-stats.ts new file mode 100755 index 000000000..5184b9882 --- /dev/null +++ b/packages/typescript-edit-benchmark/src/edit-shape-stats.ts @@ -0,0 +1,352 @@ +#!/usr/bin/env bun +/** + * Measure the empirical shape of real agent edits from session logs. + * + * Scans session JSONL files for successful `edit`/`apply_patch` tool calls and + * parses the diff in each tool result (both the numbered ` NNN|` format and + * unified `@@` diffs) into change runs — maximal runs of `-`/`+` rows with no + * context row between them — so unchanged context never counts as changed and + * every run counts as its own hunk. + * + * Shapes are reported at two levels: + * - per tool call — one sample per edit call. Fixtures are scored on the + * final input→expected diff, and a single call's diff is the closest + * measured proxy for a net diff, so **this is the calibration reference** + * for `generate.ts`. + * - per request × file — all edit calls to one file between one user message + * and the next, concatenated. This double-counts retries, overlapping + * edits, and reversals (no per-file net reconstruction), so treat it as an + * **upper bound** on how much a single-prompt fixture could plausibly ask + * for, not as a target. + * + * Parse coverage is printed so a format skew cannot silently bias the numbers. + * Reference measurement (2026-07, 2,000 newest sessions against this repo, + * 99.9% coverage): + * + * per call: changed lines: 1 → 23% 2-5 → 30% 6-20 → 29% 21-60 → 14% 61+ → 5% + * hunks: 1 → 48% 2 → 21% 3+ → 31% (median 5 changed lines) + * request×file: changed lines: 1 → 18% 2-5 → 28% 6-20 → 28% 21-60 → 17% 61+ → 9% + * hunks: 1 → 37% 2 → 21% 3+ → 43% (median 7; upper bound) + * op mix (both levels): replace 55% insert 32% delete 12% + */ +import * as fs from "node:fs/promises"; +import * as path from "node:path"; +import { parseArgs } from "node:util"; +import { computeDefaultSessionDir } from "@oh-my-pi/pi-coding-agent/session/session-paths"; +import { FileSessionStorage } from "@oh-my-pi/pi-coding-agent/session/session-storage"; + +const EDIT_TOOL_NAMES: Record = { edit: true, apply_patch: true }; +const SIZE_BUCKETS: Array<[string, number]> = [ + ["1", 1], + ["2-5", 5], + ["6-20", 20], + ["21-60", 60], + ["61+", Number.POSITIVE_INFINITY], +]; + +/** One maximal run of removed/added rows with no context row in between. */ +interface ChangeRun { + oldCount: number; + newCount: number; +} + +interface Args { + sessionsDir: string; + maxSessions: number; +} + +function parseArguments(): Args { + const { values } = parseArgs({ + options: { + "sessions-dir": { type: "string" }, + repo: { type: "string", default: path.resolve(import.meta.dir, "../../..") }, + "max-sessions": { type: "string", default: "2000" }, + }, + }); + const repo = path.resolve(values.repo ?? "."); + return { + sessionsDir: values["sessions-dir"] ?? computeDefaultSessionDir(repo, new FileSessionStorage()), + maxSessions: parseInt(values["max-sessions"] ?? "2000", 10), + }; +} + +const ROW_PIPE_RE = /^([ +-])\s*\d+\|/; +const ROW_SPACE_RE = /^([ +-])\s*\d+( |$)/; + +/** Collects change runs; a context row or elision closes the current run. */ +class RunCollector { + runs: ChangeRun[] = []; + #current: ChangeRun | null = null; + + mark(kind: string): void { + if (kind === " ") { + this.flush(); + return; + } + this.#current ??= { oldCount: 0, newCount: 0 }; + if (kind === "-") this.#current.oldCount++; + else this.#current.newCount++; + } + + flush(): void { + if (this.#current && (this.#current.oldCount > 0 || this.#current.newCount > 0)) { + this.runs.push(this.#current); + } + this.#current = null; + } + + finish(): ChangeRun[] | null { + this.flush(); + return this.runs.length > 0 ? this.runs : null; + } +} + +/** + * Parse the numbered diff format emitted in edit tool-result details + * (` NNN|context`, `-NNN|removed`, `+NNN|added`; older space-delimited rows). + * Elisions appear as blank rows or `...` rows. Returns null when any row is + * unparseable. + */ +function runsFromNumberedDiff(diff: string): ChangeRun[] | null { + const lines = diff.split("\n"); + const usesPipe = lines.slice(0, 10).some(line => ROW_PIPE_RE.test(line)); + const collector = new RunCollector(); + for (const line of lines) { + const row = ROW_PIPE_RE.exec(line) ?? (usesPipe ? null : ROW_SPACE_RE.exec(line)); + if (row) { + collector.mark(row[1]); + } else if (line.trim() === "" || line.trim() === "..." || line.trim() === "…" || line.trim().endsWith("|...")) { + collector.flush(); + } else { + return null; + } + } + return collector.finish(); +} + +/** + * Parse a unified diff (standard `@@ -a,b +c,d @@` hunks or anchor-style `@@` + * headers): `-` old, `+` new, leading space or blank = context. + */ +function runsFromUnifiedDiff(diff: string): ChangeRun[] | null { + const collector = new RunCollector(); + for (const line of diff.split("\n")) { + if (line.startsWith("@@")) { + collector.flush(); + } else if (line.startsWith("--- ") || line.startsWith("+++ ") || line.startsWith("Index:")) { + // File headers. + } else if (line.startsWith("-") || line.startsWith("+")) { + collector.mark(line[0]); + } else if (line.startsWith(" ") || line === "") { + collector.mark(" "); + } else { + return null; + } + } + return collector.finish(); +} + +/** Parse a tool-result diff in whichever format it uses. */ +function runsFromDiff(diff: string): { runs: ChangeRun[] | null; format: "numbered" | "unified" } { + const head = diff.trimStart(); + if (head.startsWith("@@") || head.startsWith("--- ")) { + return { runs: runsFromUnifiedDiff(diff), format: "unified" }; + } + return { runs: runsFromNumberedDiff(diff), format: "numbered" }; +} + +/** Per-session parse results: change runs per edit call and per request×file, plus coverage counters. */ +interface SessionScan { + edits: ChangeRun[][]; + /** All edit-call runs targeting one file between one user message and the next, concatenated. */ + requestFiles: ChangeRun[][]; + formats: Map; + skipped: number; +} + +/** Resolve the edited file path from tool-call args across edit-tool variants. */ +function extractCallPath(args: Record): string | null { + if (typeof args.path === "string" && args.path) return args.path; + if (typeof args.input === "string") { + const header = + args.input.match(/^\u00b6([^#\n]+)#/) ?? + args.input.match(/^\[([^#\]\n]+)#/) ?? + args.input.match(/^@@ ([^\n]+)$/m); + if (header) return header[1].trim(); + } + if (Array.isArray(args.edits) && args.edits.length > 0 && args.edits[0] && typeof args.edits[0] === "object") { + const nested = (args.edits[0] as Record).path; + if (typeof nested === "string" && nested) return nested; + } + return null; +} + +/** Extract change runs for every successful edit in one session JSONL file. */ +async function collectSessionEdits(sessionFile: string): Promise { + const scan: SessionScan = { edits: [], requestFiles: [], formats: new Map(), skipped: 0 }; + const stream = Bun.file(sessionFile).stream(); + const decoder = new TextDecoder(); + let buffer = ""; + const callPaths = new Map(); + let currentRequest = new Map(); + + const flushRequest = (): void => { + for (const runs of currentRequest.values()) { + if (runs.length > 0) scan.requestFiles.push(runs); + } + currentRequest = new Map(); + }; + + const handleRecord = (record: unknown): void => { + if (!record || typeof record !== "object") return; + const rec = record as Record; + if (rec.type !== "message" || !rec.message || typeof rec.message !== "object") return; + const message = rec.message as Record; + // A user message starts a new request; everything until the next one + // belongs to the same prompt (one benchmark fixture ≙ one prompt on one file). + if (message.role === "user") { + flushRequest(); + return; + } + if (message.role === "assistant" && Array.isArray(message.content)) { + for (const block of message.content) { + if (!block || typeof block !== "object") continue; + const call = block as Record; + if (call.type !== "toolCall" || !EDIT_TOOL_NAMES[String(call.name)]) continue; + const args = + call.arguments && typeof call.arguments === "object" ? (call.arguments as Record) : {}; + const callPath = extractCallPath(args); + if (typeof call.id === "string" && callPath) callPaths.set(call.id, callPath); + } + return; + } + if (message.role !== "toolResult" || !EDIT_TOOL_NAMES[String(message.toolName)] || message.isError) return; + const details = + message.details && typeof message.details === "object" + ? (message.details as Record) + : undefined; + const diff = details && typeof details.diff === "string" ? details.diff : null; + const op = details && typeof details.op === "string" ? details.op : null; + if (!diff || (op && op !== "update")) return; + const { runs, format } = runsFromDiff(diff); + if (runs) { + scan.edits.push(runs); + // Unknown path → each call is its own group (conservative: no false merging). + const callId = typeof message.toolCallId === "string" ? message.toolCallId : `#${scan.edits.length}`; + const fileKey = callPaths.get(callId) ?? `call:${callId}`; + const group = currentRequest.get(fileKey) ?? []; + group.push(...runs); + currentRequest.set(fileKey, group); + scan.formats.set(format, (scan.formats.get(format) ?? 0) + 1); + } else { + scan.skipped++; + } + }; + + for await (const chunk of stream) { + buffer += decoder.decode(chunk, { stream: true }); + const parsed = Bun.JSONL.parseChunk(buffer); + for (const value of parsed.values) handleRecord(value); + buffer = buffer.slice(parsed.read); + } + for (const value of Bun.JSONL.parse(`${buffer}\n`)) handleRecord(value); + flushRequest(); + return scan; +} + +function sizeBucket(changedLines: number): string { + for (const [label, max] of SIZE_BUCKETS) { + if (changedLines <= max) return label; + } + return SIZE_BUCKETS[SIZE_BUCKETS.length - 1][0]; +} + +function printDistribution(title: string, counts: Map, order?: string[]): void { + const total = [...counts.values()].reduce((a, b) => a + b, 0); + const keys = order ?? [...counts.keys()].sort(); + console.log(title); + for (const key of keys) { + const count = counts.get(key) ?? 0; + console.log(` ${key.padEnd(6)} ${String(count).padStart(6)} ${((count / total) * 100).toFixed(1)}%`); + } +} + +async function main(): Promise { + const args = parseArguments(); + const sessionFiles = (await fs.readdir(args.sessionsDir)) + .filter(name => name.endsWith(".jsonl")) + .sort() + .reverse() + .slice(0, args.maxSessions > 0 ? args.maxSessions : undefined) + .map(name => path.join(args.sessionsDir, name)); + console.log(`Scanning ${sessionFiles.length} session files in ${args.sessionsDir}`); + + interface ShapeCounters { + sizes: Map; + hunks: Map; + ops: Map; + changed: number[]; + } + const newCounters = (): ShapeCounters => ({ sizes: new Map(), hunks: new Map(), ops: new Map(), changed: [] }); + const accumulate = (counters: ShapeCounters, runs: ChangeRun[]): void => { + const changed = runs.reduce((sum, run) => sum + Math.max(run.oldCount, run.newCount), 0); + counters.changed.push(changed); + counters.sizes.set(sizeBucket(changed), (counters.sizes.get(sizeBucket(changed)) ?? 0) + 1); + const hunkKey = runs.length >= 3 ? "3+" : String(runs.length); + counters.hunks.set(hunkKey, (counters.hunks.get(hunkKey) ?? 0) + 1); + for (const run of runs) { + const op = run.oldCount === 0 ? "insert" : run.newCount === 0 ? "delete" : "replace"; + counters.ops.set(op, (counters.ops.get(op) ?? 0) + 1); + } + }; + const report = (label: string, counters: ShapeCounters): void => { + counters.changed.sort((a, b) => a - b); + const median = counters.changed[Math.floor(counters.changed.length / 2)] ?? 0; + console.log(`\n=== ${label}: ${counters.changed.length} samples, median changed lines: ${median}`); + printDistribution( + "changed lines:", + counters.sizes, + SIZE_BUCKETS.map(([bucketLabel]) => bucketLabel), + ); + printDistribution("hunks:", counters.hunks, ["1", "2", "3+"]); + printDistribution("op mix:", counters.ops, ["replace", "insert", "delete"]); + }; + + const perCall = newCounters(); + const perRequestFile = newCounters(); + const formatCounts = new Map(); + let skipped = 0; + + let next = 0; + const workers = Array.from({ length: 16 }, async () => { + while (next < sessionFiles.length) { + const file = sessionFiles[next++]; + const scan = await collectSessionEdits(file).catch( + (): SessionScan => ({ edits: [], requestFiles: [], formats: new Map(), skipped: 0 }), + ); + skipped += scan.skipped; + for (const [format, count] of scan.formats) { + formatCounts.set(format, (formatCounts.get(format) ?? 0) + count); + } + for (const runs of scan.edits) accumulate(perCall, runs); + for (const runs of scan.requestFiles) accumulate(perRequestFile, runs); + } + }); + await Promise.all(workers); + + if (perCall.changed.length === 0) { + console.error("No parseable edits found."); + return 1; + } + const parsedTotal = [...formatCounts.values()].reduce((a, b) => a + b, 0); + const coverage = parsedTotal + skipped > 0 ? parsedTotal / (parsedTotal + skipped) : 0; + const formatSummary = [...formatCounts.entries()].map(([format, count]) => `${format}=${count}`).join(", "); + console.log( + `\nParse coverage: ${parsedTotal}/${parsedTotal + skipped} diff results (${(coverage * 100).toFixed(1)}%; ${formatSummary})`, + ); + report("per tool call (calibration reference)", perCall); + report("per request × file (cumulative activity — upper bound)", perRequestFile); + return 0; +} + +process.exit(await main()); diff --git a/packages/typescript-edit-benchmark/src/generate.ts b/packages/typescript-edit-benchmark/src/generate.ts index 96ddf71d7..79ffacc37 100644 --- a/packages/typescript-edit-benchmark/src/generate.ts +++ b/packages/typescript-edit-benchmark/src/generate.ts @@ -12,20 +12,38 @@ * - Dense code: Minimal whitespace makes context harder to read * - Deep nesting: Whitespace-sensitive edits at high indent levels * - * Difficulty modes control both FILE SELECTION and PROMPT DETAIL: - * - easy: Short files, unique lines, line number given - * - medium: Medium files, function context given + * Difficulty modes control both FILE SELECTION and PROMPT DETAIL. Every prompt + * fully determines the byte-exact fix (before/after blocks, validated by + * re-solving them against the expected output); tiers vary how much locating + * the model must do: + * - easy: Short files, unique lines, exact line number given + * - medium: Medium files, containing function given * - hard: Long files with similar blocks, no location hint - * - nightmare: Long files where target line repeats, minimal info + * - nightmare: Long files where nearly identical regions repeat, no location hint */ import * as fs from "node:fs"; import * as path from "node:path"; import { parseArgs } from "node:util"; -import { TempDir } from "@oh-my-pi/pi-utils"; +import { prompt, TempDir } from "@oh-my-pi/pi-utils"; import { $ } from "bun"; import { diffLines } from "diff"; import { formatContent } from "./formatter"; +import { + commonPrefixLength, + commonSuffixLength, + LANGUAGE_BY_EXTENSION, + mergeNearbyPlacements, + type Placement, + pickFence, + placementsFromDiff, + type RenderedHunk, + renderHunks, + solveRenderedHunks, +} from "./hunks"; import { ALL_MUTATIONS, CATEGORY_MAP, type Mutation, type MutationInfo } from "./mutations"; +import identifierTaskTemplate from "./prompts/identifier-task.md" with { type: "text" }; +import mutationTaskTemplate from "./prompts/mutation-task.md" with { type: "text" }; +import structuralTaskTemplate from "./prompts/structural-task.md" with { type: "text" }; const SUPPORTED_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx"]); using DEFAULT_SOURCE_REPO_DIR = TempDir.createSync("@pi-mono-source"); @@ -64,6 +82,7 @@ interface CaseResult { filePath: string; formattedMutatedContent: string; formattedOriginalContent: string; + prompt: string; difficulty: Difficulty; difficultyScore: number; } @@ -71,7 +90,7 @@ interface CaseResult { interface Args { typescriptDir: string; output: string; - countPerType: number; + countScale: number; seed: number; categories: string | null; difficulty: string; @@ -84,7 +103,7 @@ function parseArguments(): Args { options: { "typescript-dir": { type: "string", default: DEFAULT_SOURCE_REPO_DIR.path() }, output: { type: "string", default: DEFAULT_OUTPUT }, - "count-per-type": { type: "string", default: "20" }, + "count-scale": { type: "string", default: "1" }, seed: { type: "string", default: "42" }, categories: { type: "string" }, difficulty: { type: "string", default: "easy,medium,hard,nightmare" }, @@ -96,7 +115,7 @@ function parseArguments(): Args { return { typescriptDir: values["typescript-dir"] ?? DEFAULT_SOURCE_REPO_DIR.path(), output: values.output ?? DEFAULT_OUTPUT, - countPerType: parseInt(values["count-per-type"] ?? "20", 10), + countScale: Number.parseFloat(values["count-scale"] ?? "1"), seed: parseInt(values.seed ?? "42", 10), categories: values.categories ?? null, difficulty: values.difficulty ?? "easy,medium,hard,nightmare", @@ -105,6 +124,62 @@ function parseArguments(): Args { }; } +/** Target changed-line range for a generated case. */ +type SizeRange = [number, number]; + +/** How many cases to generate for a mutation, and which changed-line bands to cycle through. */ +interface MutationPlan { + count: number; + sizes?: SizeRange[]; +} + +const BLOCK_SIZES: SizeRange[] = [ + [6, 20], + [21, 60], + [61, 150], + [6, 20], + [21, 60], + [6, 20], + [61, 150], + [21, 60], +]; + +/** + * Per-mutation case counts and changed-line targets, calibrated against the + * per-tool-call edit-shape distribution measured from real agent sessions + * (`edit-shape-stats.ts`, calibration reference): 1 → 23%, 2-5 → 30%, + * 6-20 → 29%, 21-60 → 14%, 61+ → 5%. The request×file cumulative numbers form + * an upper bound; the suite deliberately sits at or slightly above the + * per-call sizes. Token-level mutations supply the 1-line mass; small + * structural and multi-site mutations the 2-5 band; block-level mutations + * cycle through the larger bands via `sizes`. + */ +const MUTATION_PLANS: Record = { + "swap-comparison": { count: 1 }, + "swap-equality": { count: 1 }, + "swap-logical": { count: 1 }, + "remove-negation": { count: 1 }, + "swap-increment-decrement": { count: 1 }, + "swap-arithmetic": { count: 1 }, + "flip-boolean": { count: 1 }, + "remove-optional-chain": { count: 1 }, + "swap-call-args": { count: 1 }, + "swap-nullish": { count: 1 }, + "swap-regex-quantifier": { count: 1 }, + "unicode-hyphen": { count: 1 }, + "off-by-one": { count: 1 }, + "swap-adjacent-lines": { count: 6 }, + "duplicate-line-flip": { count: 6 }, + "identifier-multi-edit": { count: 10 }, + "swap-if-else": { count: 8 }, + "wrap-redundant-if": { count: 14, sizes: BLOCK_SIZES }, + "swap-sibling-blocks": { count: 14, sizes: BLOCK_SIZES }, + "duplicate-block": { count: 6, sizes: BLOCK_SIZES }, + "move-distant-block": { count: 10, sizes: BLOCK_SIZES }, + "remove-case-label": { count: 8 }, + "composite-multi-edit": { count: 16 }, +}; + async function ensureSourceRepo(typescriptDir: string): Promise { if (fs.existsSync(typescriptDir)) { const packagesDir = path.join(typescriptDir, "packages"); @@ -378,69 +453,295 @@ function recordRegion(usedLines: Map, filePath: string, lineNu usedLines.set(filePath, used); } +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +/** Where a bug sits for medium prompts: containing function, else file-third region. */ +function locateBug( + content: string, + lineNumber: number, + lineCount: number, +): { functionName?: string; region?: "top" | "middle" | "end" } { + for (const [name, start, end] of findFunctionRanges(content)) { + if (lineNumber >= start && lineNumber <= end) return { functionName: name }; + } + const ratio = lineCount > 0 ? lineNumber / lineCount : 0; + return { region: ratio < 0.33 ? "top" : ratio < 0.66 ? "middle" : "end" }; +} + +/** + * Rename-style prompt for identifier-multi-edit: names the misspelled and + * correct identifiers so "replace every occurrence" admits exactly one + * byte-exact answer. Returns null when a plain word-boundary rename does not + * reproduce the expected file (e.g. the misspelling collides with other text). + */ +function buildIdentifierPrompt( + filePath: string, + info: MutationInfo, + difficulty: Difficulty, + input: string, + expected: string, +): string | null { + const pair = info.identifier; + if (!pair) return null; + const wordRe = new RegExp(`(? { + if (wordRe.test(line)) affectedLines.push(index + 1); + wordRe.lastIndex = 0; + }); + if (affectedLines.length === 0) return null; + + return prompt.render(identifierTaskTemplate, { + filename: path.basename(filePath), + correct: pair.correct, + misspelled: pair.misspelled, + count: affectedLines.length, + affectedLines: difficulty === "easy" ? affectedLines : undefined, + }); +} + +/** Mutations whose fixtures read as natural instructions instead of raw before/after patches. */ +type StructuralKind = + | "case-label" + | "duplicate-block" + | "move-block" + | "wrap-if" + | "swap-blocks" + | "swap-lines" + | "swap-if-else"; + +const STRUCTURAL_KINDS: Record = { + "remove-case-label": "case-label", + "duplicate-block": "duplicate-block", + "move-distant-block": "move-block", + "wrap-redundant-if": "wrap-if", + "swap-sibling-blocks": "swap-blocks", + "swap-adjacent-lines": "swap-lines", + "swap-if-else": "swap-if-else", +}; + +function countTrimmedLine(lines: string[], needle: string): number { + let count = 0; + for (const line of lines) { + if (line.trim() === needle) count++; + } + return count; +} + +/** Whether a line is a usable prose anchor (contains an identifier, not just punctuation like `);`). */ +function isAnchorLine(line: string): boolean { + return /[A-Za-z_$]{2,}/.test(line); +} + +function firstNonEmptyTrimmed(lines: string[]): string { + for (const line of lines) { + const trimmed = line.trim(); + if (trimmed) return trimmed; + } + return ""; +} + +/** A placement reduced to its changed core (shared context trimmed away). */ +function trimPlacement( + inputLines: string[], + placement: Placement, +): { start: number; oldCore: string[]; newCore: string[] } { + const old = inputLines.slice(placement.start, placement.start + placement.oldLen); + const fresh = placement.newLines; + const prefix = commonPrefixLength(old, fresh); + const suffix = commonSuffixLength(old, fresh, Math.min(old.length, fresh.length) - prefix); + return { + start: placement.start + prefix, + oldCore: old.slice(prefix, old.length - suffix), + newCore: fresh.slice(prefix, fresh.length - suffix), + }; +} + +/** Nearest non-blank line trimmed, scanning from `index` in `direction`. */ +function nearestVisibleLine(lines: string[], index: number, direction: 1 | -1): string { + for (let i = index; i >= 0 && i < lines.length; i += direction) { + const trimmed = lines[i].trim(); + if (trimmed) return trimmed; + } + return ""; +} + +/** + * Derive instruction data for a structural mutation from its placements. + * Every referenced anchor line is validated to occur exactly the expected + * number of times, so the instruction identifies a unique edit; returns null + * when the instruction would be ambiguous (the caller then rejects the + * candidate and retries — structural kinds never ship raw-patch fallbacks). + */ +function structuralPromptData( + kind: StructuralKind, + inputLines: string[], + placements: Placement[], +): Record | null { + const cores = placements.map(placement => trimPlacement(inputLines, placement)); + const visible = (lines: string[]): string[] => lines.filter(line => line.trim() !== ""); + + switch (kind) { + case "case-label": { + if (cores.length !== 1) return null; + const { start, oldCore, newCore } = cores[0]; + const added = visible(newCore); + if (visible(oldCore).length !== 0 || added.length !== 1) return null; + const label = added[0].trim(); + const before = nearestVisibleLine(inputLines, start + oldCore.length, 1); + if (!label.startsWith("case") || !(before.startsWith("case") || before.startsWith("default"))) return null; + if (countTrimmedLine(inputLines, before) !== 1) return null; + return { label, before }; + } + case "duplicate-block": { + if (cores.length !== 1) return null; + const { oldCore, newCore } = cores[0]; + if (visible(newCore).length !== 0 || visible(oldCore).length === 0) return null; + const head = firstNonEmptyTrimmed(oldCore); + if (!head || countTrimmedLine(inputLines, head) !== 2) return null; + return { head }; + } + case "move-block": { + if (cores.length !== 2) return null; + const insert = cores.find(core => visible(core.oldCore).length === 0); + const remove = cores.find(core => visible(core.newCore).length === 0); + if (!insert || !remove || insert === remove) return null; + if (visible(remove.oldCore).join("\n") !== visible(insert.newCore).join("\n")) return null; + const head = firstNonEmptyTrimmed(remove.oldCore); + const destination = nearestVisibleLine(inputLines, insert.start + insert.oldCore.length, 1); + const currentPrev = nearestVisibleLine(inputLines, remove.start - 1, -1); + if (![head, destination, currentPrev].every(isAnchorLine)) return null; + for (const anchor of [head, destination, currentPrev]) { + if (countTrimmedLine(inputLines, anchor) !== 1) return null; + } + return { head, destination, currentPrev }; + } + case "wrap-if": { + if (cores.length !== 1) return null; + const { start, oldCore } = cores[0]; + const relative = oldCore.findIndex(line => line.trim() === "if (true) {"); + if (relative < 0) return null; + return { wrapperLine: start + relative + 1 }; + } + case "swap-blocks": + case "swap-lines": { + const merged = mergeNearbyPlacements(inputLines, placements, 2); + let firstHead = ""; + let secondHead = ""; + if (merged.length === 1) { + const { oldCore, newCore } = trimPlacement(inputLines, merged[0]); + firstHead = firstNonEmptyTrimmed(oldCore); + secondHead = firstNonEmptyTrimmed(newCore); + } else if (cores.length === 2) { + // jsdiff renders `A,B -> B,A` as insert-A-before-B plus delete-A-after-B, + // with all of B as unchanged context in between; match the moved body. + const insert = cores.find(core => visible(core.oldCore).length === 0); + const remove = cores.find(core => visible(core.newCore).length === 0); + if (!insert || !remove || insert === remove) return null; + if (visible(remove.oldCore).join("\n") !== visible(insert.newCore).join("\n")) return null; + secondHead = firstNonEmptyTrimmed(insert.newCore); + firstHead = nearestVisibleLine(inputLines, insert.start + insert.oldCore.length, 1); + } else { + return null; + } + if (!firstHead || !secondHead || firstHead === secondHead) return null; + if (!isAnchorLine(firstHead) || !isAnchorLine(secondHead)) return null; + if (countTrimmedLine(inputLines, firstHead) !== 1 || countTrimmedLine(inputLines, secondHead) !== 1) + return null; + return { firstHead, secondHead }; + } + case "swap-if-else": { + if (cores.length > 2) return null; + const condition = nearestVisibleLine(inputLines, cores[0].start - 1, -1); + if (!condition.startsWith("if") && !condition.includes(" if ")) return null; + if (countTrimmedLine(inputLines, condition) !== 1) return null; + return { condition }; + } + } +} + +/** + * Build the task prompt for a mutation case, or null when no uniquely solvable + * prompt exists (the caller then retries with a different candidate). + * + * Structural mutations render as natural instructions ("move X back before Y") + * with the expected after-state as reference; identifier renames as a + * replace-every-occurrence instruction; everything else as explicit + * before/after blocks. All variants are validated by re-solving the hunks + * against the expected output, so every prompt admits exactly one byte-exact + * answer. Difficulty only controls location detail. + */ function buildPrompt( filePath: string, mutation: Mutation, info: MutationInfo, difficulty: Difficulty, - entry: FileEntry, -): string { - const header = `# Fix the bug in \`${path.basename(filePath)}\``; - - const isStructural = mutation.category === "structural"; - const isMultiEdit = mutation.name === "identifier-multi-edit"; - - if (difficulty === "easy") { - const detail = mutation.describe(info); - const location = isStructural - ? `The issue starts around line ${info.lineNumber}.` - : `The issue is on line ${info.lineNumber}.`; - return [header, detail, location, mutation.fixHint].join("\n\n"); + input: string, + expected: string, +): string | null { + if (mutation.name === "identifier-multi-edit") { + return buildIdentifierPrompt(filePath, info, difficulty, input, expected); } - if (difficulty === "medium") { - const detail = mutation.describe(info); - const funcName = findContainingFunction(entry, info.lineNumber); - let location: string; - if (funcName) { - location = `The issue is in the \`${funcName}\` function.`; - } else { - const ratio = entry.lineCount ? info.lineNumber / entry.lineCount : 0; - if (ratio < 0.33) location = "The issue is near the top of the file."; - else if (ratio < 0.66) location = "The issue is around the middle of the file."; - else location = "The issue is near the end of the file."; - } - if (isMultiEdit) { - location += " The same error appears in multiple places."; - } - return [header, detail, location, mutation.fixHint].join("\n\n"); + const inputLines = input.replace(/\n$/, "").split("\n"); + const placements = placementsFromDiff(input, expected); + if (placements.length === 0 || placements.length > 5) return null; + const hunks = renderHunks(inputLines, placements); + if (!hunks) return null; + const solved = solveRenderedHunks(inputLines, hunks); + if (!solved || ensureTrailingNewline(solved.join("\n")) !== expected) return null; + + const language = LANGUAGE_BY_EXTENSION[path.extname(filePath).toLowerCase()] ?? ""; + const fence = pickFence(hunks); + const hunkContext = (hunk: RenderedHunk): { startLine: number | undefined } => ({ + startLine: !hunk.unique || difficulty === "easy" ? hunk.startLine : undefined, + }); + + const structuralKind = STRUCTURAL_KINDS[mutation.name]; + if (structuralKind) { + // Structural tasks read as natural instructions; a candidate whose + // instruction would be ambiguous is rejected so the caller retries — + // never downgraded to a raw before/after patch. + const data = structuralPromptData(structuralKind, inputLines, placements); + if (!data) return null; + const rendered = prompt.render(structuralTaskTemplate, { + filename: path.basename(filePath), + kind: structuralKind, + ...data, + fence, + language, + hunkCount: hunks.length, + hunks: hunks.map(hunk => ({ + // After-state regions are only interpretable with a position. + startLine: hunk.startLine, + newCode: hunk.newBlock.join("\n"), + })), + }); + return rendered.length <= 20_000 ? rendered : null; } - if (difficulty === "hard") { - const detail = mutation.describe(info); - if (isMultiEdit) { - return [header, detail, "Find and fix all occurrences of this issue."].join("\n\n"); - } - if (isStructural) { - return [header, detail, "The fix may involve multiple lines."].join("\n\n"); - } - return [header, detail, "Find and fix this issue."].join("\n\n"); - } - - // nightmare - if (isStructural) { - return [header, "There is a structural bug in this file.", "Track it down and fix it with a minimal edit."].join( - "\n\n", - ); - } - if (isMultiEdit) { - return [ - header, - "An identifier is consistently misspelled throughout this file.", - "Find all occurrences and fix them.", - ].join("\n\n"); - } - return [header, "There is a subtle bug in this file.", "Track it down and fix it with a minimal edit."].join("\n\n"); + const location = difficulty === "medium" ? locateBug(input, hunks[0].startLine, inputLines.length) : {}; + const rendered = prompt.render(mutationTaskTemplate, { + filename: path.basename(filePath), + name: mutation.name, + functionName: location.functionName, + region: location.region, + nightmare: difficulty === "nightmare", + fence, + language, + hunkCount: hunks.length, + hunks: hunks.map(hunk => ({ + ...hunkContext(hunk), + isDelete: hunk.newBlock.length === 0, + oldCode: hunk.oldBlock.join("\n"), + newCode: hunk.newBlock.join("\n"), + })), + }); + return rendered.length <= 20_000 ? rendered : null; } function createSeededRng(seed: number): () => number { @@ -625,6 +926,7 @@ function resolveFormattedMutationInfo( lineNumber, originalSnippet: snippetFromChangedLines(chosen.removedLines, originalLines, Math.max(1, chosen.oldStart)), mutatedSnippet: snippetFromChangedLines(chosen.addedLines, mutatedLines, lineNumber), + identifier: fallbackInfo.identifier, }; if (resolved.originalSnippet && !originalContent.includes(resolved.originalSnippet)) return null; @@ -640,6 +942,7 @@ async function generateCase( usedLines: Map, difficulty: Difficulty, minScore: number | null, + sizeRange: SizeRange | null, attemptLimit = 100, ): Promise { let candidates = getCandidatesForDifficulty(files, difficulty); @@ -676,12 +979,15 @@ async function generateCase( const positionalHunks = countPositionalLineHunks(entry.content, mutatedContent); const positionalChanges = countPositionalLineChanges(entry.content, mutatedContent); const isStructural = mutation.category === "structural"; - const isMultiEdit = mutation.name === "identifier-multi-edit"; + const isMultiEdit = mutation.multiHunk === true; if (!isStructural && !isMultiEdit) { if (changedHunks !== 1) continue; if (positionalHunks !== 1) continue; if (changedLines > 30 || positionalChanges > 30) continue; } + // Coarse pre-format lower bound: removed+added always >= the run-based + // metric, so anything below the minimum can be rejected before Prettier. + if (sizeRange && changedLines < sizeRange[0]) continue; if (!regionAvailable(usedLines, entry.path, rawInfo.lineNumber)) continue; @@ -707,6 +1013,26 @@ async function generateCase( const finalInfo = resolveFormattedMutationInfo(normalizedOriginal, normalizedMutated, rawInfo); if (!finalInfo) continue; + // Enforce the size target with the same metric edit-shape-stats.ts uses: + // sum of max(old, new) per change run, on the formatted input/expected. + if (sizeRange) { + const finalChanged = placementsFromDiff(normalizedMutated, normalizedOriginal).reduce( + (sum, placement) => sum + Math.max(placement.oldLen, placement.newLines.length), + 0, + ); + if (finalChanged < sizeRange[0] || finalChanged > sizeRange[1]) continue; + } + + const taskPrompt = buildPrompt( + entry.path, + mutation, + finalInfo, + difficulty, + normalizedMutated, + normalizedOriginal, + ); + if (!taskPrompt) continue; + recordRegion(usedLines, entry.path, rawInfo.lineNumber); return { caseId: "", @@ -715,6 +1041,7 @@ async function generateCase( filePath: entry.path, formattedMutatedContent: normalizedMutated, formattedOriginalContent: normalizedOriginal, + prompt: taskPrompt, difficulty, difficultyScore: diffScore, }; @@ -760,7 +1087,6 @@ async function buildCaseEntries(result: CaseResult, typescriptDir: string): Prom }; const isRepeated = entry.repeatedLines.has(lineContent); - const prompt = buildPrompt(result.filePath, result.mutation, result.finalInfo, result.difficulty, entry); const metadata = { mutation_type: result.mutation.name, @@ -796,7 +1122,7 @@ async function buildCaseEntries(result: CaseResult, typescriptDir: string): Prom return [ { name: `${caseDir}/input/${filename}`, content: result.formattedMutatedContent }, { name: `${caseDir}/expected/${filename}`, content: result.formattedOriginalContent }, - { name: `${caseDir}/prompt.md`, content: prompt }, + { name: `${caseDir}/prompt.md`, content: result.prompt }, { name: `${caseDir}/metadata.json`, content: JSON.stringify(metadata, null, 2) }, ]; } @@ -856,17 +1182,20 @@ async function main(): Promise { const fallbackOrder: Difficulty[] = ["hard", "medium", "easy"]; for (const mutation of mutations) { - const difficultiesForType = chooseDifficulties(difficulties, args.countPerType); + const plan = MUTATION_PLANS[mutation.name] ?? { count: 4 }; + const count = Math.max(1, Math.round(plan.count * args.countScale)); + const difficultiesForType = chooseDifficulties(difficulties, count); let generated = 0; - for (let index = 0; index < args.countPerType; index++) { + for (let index = 0; index < count; index++) { const difficulty = difficultiesForType[index]; - let result = await generateCase(rng, mutation, files, usedLines, difficulty, args.minScore); + const sizeRange = plan.sizes ? plan.sizes[index % plan.sizes.length] : null; + let result = await generateCase(rng, mutation, files, usedLines, difficulty, args.minScore, sizeRange); if (!result) { for (const fallback of fallbackOrder) { if (fallback === difficulty) continue; - result = await generateCase(rng, mutation, files, usedLines, fallback, 0); + result = await generateCase(rng, mutation, files, usedLines, fallback, 0, sizeRange); if (result) { console.log(`Note: ${mutation.name} case ${index + 1} fell back from ${difficulty} to ${fallback}`); break; @@ -889,8 +1218,8 @@ async function main(): Promise { if (generated === 0) { console.log(`Warning: No cases generated for ${mutation.name} (mutation may be too rare)`); - } else if (generated < args.countPerType) { - console.log(`Note: Only ${generated}/${args.countPerType} cases generated for ${mutation.name}`); + } else if (generated < count) { + console.log(`Note: Only ${generated}/${count} cases generated for ${mutation.name}`); } } diff --git a/packages/typescript-edit-benchmark/src/hunks.ts b/packages/typescript-edit-benchmark/src/hunks.ts new file mode 100644 index 000000000..bc04c15af --- /dev/null +++ b/packages/typescript-edit-benchmark/src/hunks.ts @@ -0,0 +1,264 @@ +/** + * Shared hunk machinery for fixture generation. + * + * `generate.ts` expresses every task as "replace these exact blocks in the + * input file". This module locates changed blocks, prepares prompt-visible + * before/after blocks whose old side occurs exactly once in the input + * (re-padding with context, or falling back to an explicit line number), and + * re-solves prepared hunks to prove a prompt admits exactly one byte-exact + * answer. Prompt prose itself lives in the Handlebars templates under + * `src/prompts/`; this module only supplies the block data. + */ +import { diffLines } from "diff"; + +/** Replace `oldLen` lines at `start` (0-based index into the input) with `newLines`. */ +export interface Placement { + start: number; + oldLen: number; + newLines: string[]; +} + +/** A prompt-visible change: replace (or delete) `oldBlock`, verbatim, with `newBlock`. */ +export interface RenderedHunk { + oldBlock: string[]; + newBlock: string[]; + /** 1-based line where `oldBlock` starts in the input file. */ + startLine: number; + /** Whether `oldBlock` occurs exactly once in the input; when false, prompts must state `startLine`. */ + unique: boolean; +} + +const MAX_UNIQUENESS_EXTENSION = 10; + +export function findBlockOccurrences(lines: string[], block: string[]): number[] { + if (block.length === 0 || block.length > lines.length) return []; + const hits: number[] = []; + const first = block[0]; + outer: for (let i = 0; i <= lines.length - block.length; i++) { + if (lines[i] !== first) continue; + for (let j = 1; j < block.length; j++) { + if (lines[i + j] !== block[j]) continue outer; + } + hits.push(i); + } + return hits; +} + +export function applyPlacements(lines: string[], placements: Placement[]): string[] { + const out: string[] = []; + let cursor = 0; + for (const placement of placements) { + out.push(...lines.slice(cursor, placement.start), ...placement.newLines); + cursor = placement.start + placement.oldLen; + } + out.push(...lines.slice(cursor)); + return out; +} + +export function commonPrefixLength(a: string[], b: string[]): number { + let n = 0; + while (n < a.length && n < b.length && a[n] === b[n]) n++; + return n; +} + +export function commonSuffixLength(a: string[], b: string[], maxLength: number): number { + let n = 0; + while (n < maxLength && a[a.length - 1 - n] === b[b.length - 1 - n]) n++; + return n; +} + +function splitDiffValue(value: string): string[] { + const lines = value.split("\n"); + if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop(); + return lines; +} + +/** + * Compute placements that transform `inputText` into `expectedText` via a + * line diff. Adjacent removed/added runs merge into one placement. + */ +export function placementsFromDiff(inputText: string, expectedText: string): Placement[] { + const placements: Placement[] = []; + let inputLine = 0; + let pendingStart = -1; + let pendingOldLen = 0; + let pendingNewLines: string[] = []; + + const flush = (): void => { + if (pendingStart < 0) return; + placements.push({ start: pendingStart, oldLen: pendingOldLen, newLines: pendingNewLines }); + pendingStart = -1; + pendingOldLen = 0; + pendingNewLines = []; + }; + + for (const change of diffLines(inputText, expectedText)) { + const lines = splitDiffValue(change.value); + if (!change.added && !change.removed) { + flush(); + inputLine += lines.length; + continue; + } + if (pendingStart < 0) pendingStart = inputLine; + if (change.removed) { + pendingOldLen += lines.length; + inputLine += lines.length; + } else { + pendingNewLines.push(...lines); + } + } + flush(); + return placements; +} + +/** + * Merge placements separated by at most `maxGap` context lines into one, so a + * moved statement renders as a single natural replace instead of a delete plus + * a re-insert whose blocks end on invisible blank lines. + */ +export function mergeNearbyPlacements(inputLines: string[], placements: Placement[], maxGap: number): Placement[] { + const merged: Placement[] = []; + for (const placement of placements) { + const previous = merged[merged.length - 1]; + const gap = previous ? placement.start - (previous.start + previous.oldLen) : -1; + if (previous && gap >= 0 && gap <= maxGap) { + const bridge = inputLines.slice(previous.start + previous.oldLen, placement.start); + previous.oldLen += gap + placement.oldLen; + previous.newLines = [...previous.newLines, ...bridge, ...placement.newLines]; + continue; + } + merged.push({ ...placement }); + } + return merged; +} + +/** + * Turn placements into prompt-visible hunks. Each hunk's blocks are trimmed to + * the changed core, anchored on context when either side would be empty, then + * re-padded with context lines until the old block occurs exactly once in the + * input; when the input has no room to disambiguate, the hunk is marked + * non-unique and prompts must state its start line. Blocks never start or end + * on a blank line when a visible context line is available — a blank line at a + * fence edge is invisible. Returns null when a hunk cannot be rendered at all. + */ +export function renderHunks(inputLines: string[], placements: Placement[]): RenderedHunk[] | null { + const merged = mergeNearbyPlacements(inputLines, placements, 2); + const hunks: RenderedHunk[] = []; + let previousEnd = -1; + + for (let index = 0; index < merged.length; index++) { + const placement = merged[index]; + const nextStart = index + 1 < merged.length ? merged[index + 1].start : inputLines.length; + const old = inputLines.slice(placement.start, placement.start + placement.oldLen); + const fresh = placement.newLines; + const prefix = commonPrefixLength(old, fresh); + const suffix = commonSuffixLength(old, fresh, Math.min(old.length, fresh.length) - prefix); + let shownStart = placement.start + prefix; + let oldBlock = old.slice(prefix, old.length - suffix); + let newBlock = fresh.slice(prefix, fresh.length - suffix); + if (oldBlock.length === 0 && newBlock.length === 0) continue; + + const takeAbove = (): boolean => { + const above = shownStart - 1; + if (above < 0 || above <= previousEnd) return false; + shownStart = above; + oldBlock = [inputLines[above], ...oldBlock]; + newBlock = [inputLines[above], ...newBlock]; + return true; + }; + const takeBelow = (): boolean => { + const below = shownStart + oldBlock.length; + if (below >= nextStart || below >= inputLines.length) return false; + oldBlock = [...oldBlock, inputLines[below]]; + newBlock = [...newBlock, inputLines[below]]; + return true; + }; + + // Pure insertion or pure deletion: anchor on a context line so neither + // block is empty. Prefer a non-blank anchor. + if (oldBlock.length === 0 || newBlock.length === 0) { + const aboveIndex = shownStart - 1; + const aboveVisible = aboveIndex >= 0 && aboveIndex > previousEnd && inputLines[aboveIndex].trim() !== ""; + if (aboveVisible) { + takeAbove(); + } else if (!takeBelow() && !takeAbove()) { + return null; + } + } + + let unique = true; + for (let extension = 0; findBlockOccurrences(inputLines, oldBlock).length > 1; extension++) { + if (extension >= MAX_UNIQUENESS_EXTENSION || !takeAbove()) { + unique = false; + break; + } + } + + // Pad blank fence edges with visible context (bounded; best effort). + for (let guard = 0; guard < 2 && (oldBlock[0].trim() === "" || newBlock[0]?.trim() === ""); guard++) { + if (!takeAbove()) break; + } + for ( + let guard = 0; + guard < 2 && (oldBlock[oldBlock.length - 1].trim() === "" || newBlock[newBlock.length - 1]?.trim() === ""); + guard++ + ) { + if (!takeBelow()) break; + } + + previousEnd = placement.start + placement.oldLen - 1; + hunks.push({ oldBlock, newBlock, startLine: shownStart + 1, unique }); + } + return hunks.length > 0 ? hunks : null; +} + +/** + * Re-solve the prompt from scratch: locate every hunk's old block in the input + * (unique occurrence, or the stated start line) and apply the replacements. + * Guarantees the prompt admits exactly one byte-exact answer. + */ +export function solveRenderedHunks(inputLines: string[], hunks: RenderedHunk[]): string[] | null { + const placements: Placement[] = []; + for (const hunk of hunks) { + const occurrences = findBlockOccurrences(inputLines, hunk.oldBlock); + let start: number; + if (hunk.unique) { + if (occurrences.length !== 1) return null; + start = occurrences[0]; + } else { + start = hunk.startLine - 1; + if (!occurrences.includes(start)) return null; + } + placements.push({ start, oldLen: hunk.oldBlock.length, newLines: hunk.newBlock }); + } + placements.sort((a, b) => a.start - b.start); + let previousEnd = -1; + for (const placement of placements) { + if (placement.start <= previousEnd) return null; + previousEnd = placement.start + placement.oldLen - 1; + } + return applyPlacements(inputLines, placements); +} + +export const LANGUAGE_BY_EXTENSION: Record = { + ".ts": "ts", + ".tsx": "tsx", + ".js": "js", + ".jsx": "jsx", + ".mjs": "js", + ".md": "markdown", + ".rs": "rust", + ".py": "python", + ".json": "json", + ".yml": "yaml", + ".yaml": "yaml", + ".toml": "toml", +}; + +/** Fence that safely wraps every block in `hunks` (upgrades when content embeds triple backticks). */ +export function pickFence(hunks: RenderedHunk[]): string { + const hasTripleBacktick = hunks.some(hunk => + [...hunk.oldBlock, ...hunk.newBlock].some(line => line.includes("```")), + ); + return hasTripleBacktick ? "````" : "```"; +} diff --git a/packages/typescript-edit-benchmark/src/in-process-client.ts b/packages/typescript-edit-benchmark/src/in-process-client.ts index 39995efbf..99f17fde7 100644 --- a/packages/typescript-edit-benchmark/src/in-process-client.ts +++ b/packages/typescript-edit-benchmark/src/in-process-client.ts @@ -9,6 +9,7 @@ import type { AgentEvent, AgentMessage, ResolvedThinkingLevel, ThinkingLevel } f import type { Model, ToolExample } from "@oh-my-pi/pi-ai"; import type { AgentSession, AgentSessionEvent, AuthStorage, SessionStats } from "@oh-my-pi/pi-coding-agent"; import { + AgentRegistry, type CreateAgentSessionResult, createAgentSession, discoverAuthStorage, @@ -97,6 +98,11 @@ export class InProcessClient { authStorage: shared?.authStorage, modelRegistry: shared?.modelRegistry, sessionManager: SessionManager.inMemory(this.#options.cwd), + // Benchmark tasks run many top-level sessions concurrently in one + // process. The global registry admits only one "Main" per process + // generation (later registrations replace earlier refs, which then + // fail session initialization), so each client gets its own registry. + agentRegistry: new AgentRegistry(), systemPrompt: this.#options.appendSystemPrompt ? (defaultPrompt: string[]) => [...defaultPrompt, this.#options.appendSystemPrompt!] : undefined, diff --git a/packages/typescript-edit-benchmark/src/mutations.ts b/packages/typescript-edit-benchmark/src/mutations.ts index c7eb1fb83..27d308e55 100644 --- a/packages/typescript-edit-benchmark/src/mutations.ts +++ b/packages/typescript-edit-benchmark/src/mutations.ts @@ -21,16 +21,18 @@ export interface MutationInfo { lineNumber: number; originalSnippet: string; mutatedSnippet: string; + /** Correct/misspelled rename pair; set by identifier-multi-edit for rename-style prompts. */ + identifier?: { correct: string; misspelled: string }; } export interface Mutation { name: string; category: string; - fixHint: string; + /** Whether this mutation intentionally produces multiple separated hunks. */ + multiHunk?: boolean; canApply(content: string): boolean; mutate(content: string, rng: () => number): [string, MutationInfo]; - describe(info: MutationInfo): string; } type Candidate = { @@ -234,12 +236,6 @@ function isLengthMemberExpression(node: t.Node): node is t.MemberExpression { abstract class BaseAstMutation implements Mutation { abstract name: string; abstract category: string; - abstract fixHint: string; - abstract description: string; - - describe(_info: MutationInfo): string { - return this.description; - } abstract collectCandidates(parsed: Parsed): Candidate[]; abstract applyCandidate(parsed: Parsed, candidate: Candidate, rng: () => number): MutationInfo; @@ -281,8 +277,6 @@ abstract class BaseAstMutation implements Mutation { class SwapComparisonMutation extends BaseAstMutation { name = "swap-comparison"; category = "operator"; - fixHint = "Swap the comparison operator to the correct variant."; - description = "A comparison operator is subtly wrong."; #swap: Record = { "<=": "<", @@ -310,8 +304,6 @@ class SwapComparisonMutation extends BaseAstMutation { class SwapEqualityMutation extends BaseAstMutation { name = "swap-equality"; category = "operator"; - fixHint = "Fix the equality comparison operator."; - description = "An equality operator is inverted."; #swap: Record = { "===": "!==", @@ -339,8 +331,6 @@ class SwapEqualityMutation extends BaseAstMutation { class SwapLogicalMutation extends BaseAstMutation { name = "swap-logical"; category = "operator"; - fixHint = "Use the intended boolean operator."; - description = "A boolean operator is incorrect."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -364,8 +354,6 @@ class SwapLogicalMutation extends BaseAstMutation { class RemoveNegationMutation extends BaseAstMutation { name = "remove-negation"; category = "operator"; - fixHint = "Add back the missing logical negation (`!`)."; - description = "A logical negation (`!`) was accidentally removed."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -393,8 +381,6 @@ class RemoveNegationMutation extends BaseAstMutation { class SwapIncDecMutation extends BaseAstMutation { name = "swap-increment-decrement"; category = "operator"; - fixHint = "Replace the increment/decrement operator with the intended one."; - description = "An increment/decrement operator points the wrong direction."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -417,8 +403,6 @@ class SwapIncDecMutation extends BaseAstMutation { class SwapArithmeticMutation extends BaseAstMutation { name = "swap-arithmetic"; category = "operator"; - fixHint = "Correct the arithmetic operator."; - description = "An arithmetic operator was swapped."; #swap: Record = { "+": "-", "-": "+", "*": "/", "/": "*" }; @@ -441,8 +425,6 @@ class SwapArithmeticMutation extends BaseAstMutation { class BooleanLiteralFlipMutation extends BaseAstMutation { name = "flip-boolean"; category = "literal"; - fixHint = "Flip the boolean literal to the intended value."; - description = "A boolean literal is inverted."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -465,9 +447,6 @@ class BooleanLiteralFlipMutation extends BaseAstMutation { class OptionalChainRemovalMutation extends BaseAstMutation { name = "remove-optional-chain"; category = "access"; - fixHint = - "Restore the optional chaining operator (`?.`) at the ONE location where it was removed. Do not add optional chaining elsewhere."; - description = "Optional chaining was removed from a property access."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -498,8 +477,6 @@ class OptionalChainRemovalMutation extends BaseAstMutation { class CallArgumentSwapMutation extends BaseAstMutation { name = "swap-call-args"; category = "call"; - fixHint = "Swap the two arguments to their original order."; - description = "Two arguments in a call are swapped."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -563,8 +540,6 @@ class CallArgumentSwapMutation extends BaseAstMutation { class NullishCoalescingSwapMutation extends BaseAstMutation { name = "swap-nullish"; category = "operator"; - fixHint = "Use the intended nullish/logical operator."; - description = "A nullish coalescing operator was swapped."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -588,8 +563,6 @@ class NullishCoalescingSwapMutation extends BaseAstMutation { class RegexQuantifierSwapMutation extends BaseAstMutation { name = "swap-regex-quantifier"; category = "regex"; - fixHint = "Fix the ONE regex quantifier that was swapped (between `+` and `*`). Do not modify other quantifiers."; - description = "A regex quantifier was swapped, changing whitespace matching."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -650,8 +623,6 @@ class RegexQuantifierSwapMutation extends BaseAstMutation { class UnicodeHyphenMutation extends BaseAstMutation { name = "unicode-hyphen"; category = "unicode"; - fixHint = "Replace the unicode dash with a plain ASCII hyphen."; - description = "A string literal contains a lookalike unicode dash."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -690,8 +661,7 @@ class UnicodeHyphenMutation extends BaseAstMutation { class IdentifierMultiEditMutation extends BaseAstMutation { name = "identifier-multi-edit"; category = "identifier"; - fixHint = "Restore the identifier to its original spelling in all affected locations."; - description = "An identifier is misspelled in multiple separate locations."; + multiHunk = true; #keywords = new Set([ "await", @@ -850,6 +820,7 @@ class IdentifierMultiEditMutation extends BaseAstMutation { lineNumber: selectedPaths[0]?.node.loc?.start.line ?? 0, originalSnippet: chosen.name, mutatedSnippet: mutated, + identifier: { correct: chosen.name, misspelled: mutated }, }, ]; } @@ -928,6 +899,7 @@ class IdentifierMultiEditMutation extends BaseAstMutation { lineNumber: selectedPaths[0]?.node.loc?.start.line ?? 0, originalSnippet: chosen.name, mutatedSnippet: mutated, + identifier: { correct: chosen.name, misspelled: mutated }, }; } } @@ -935,8 +907,6 @@ class IdentifierMultiEditMutation extends BaseAstMutation { class DuplicateLineLiteralFlipMutation extends BaseAstMutation { name = "duplicate-line-flip"; category = "duplicate"; - fixHint = "Fix the literal or operator on the duplicated line."; - description = "A duplicated line contains a subtle literal/operator change."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -1025,8 +995,6 @@ class DuplicateLineLiteralFlipMutation extends BaseAstMutation { class SwapAdjacentLinesMutation extends BaseAstMutation { name = "swap-adjacent-lines"; category = "structural"; - fixHint = "Swap the two adjacent lines back to their original order."; - description = "Two adjacent statements are in the wrong order."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -1134,8 +1102,6 @@ class SwapAdjacentLinesMutation extends BaseAstMutation { class SwapIfElseBranchesMutation extends BaseAstMutation { name = "swap-if-else"; category = "structural"; - fixHint = "Swap the if and else branch bodies back to their original positions."; - description = "The if and else branches are swapped."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -1163,29 +1129,31 @@ class SwapIfElseBranchesMutation extends BaseAstMutation { } } -class RemoveEarlyReturnMutation extends BaseAstMutation { - name = "remove-early-return"; +/** + * Remove one label from a fall-through `case A: case B:` pair. The fix inserts + * the missing label back — a deterministic pure-insertion task whose content + * is dictated by the visible sibling label, not by hidden deleted code. + */ +class RemoveCaseLabelMutation extends BaseAstMutation { + name = "remove-case-label"; category = "structural"; - fixHint = - "Restore the missing guard clause (if statement with early return). Add back the exact 3-line pattern: if condition, return statement, closing brace."; - description = "A guard clause (early return) was removed."; - collectCandidates(parsed: Parsed): Candidate[] { - const out: Candidate[] = []; + collectCandidates(parsed: Parsed): Candidate[] { + const out: Candidate[] = []; traverse(parsed.ast, { - IfStatement: path => { + SwitchCase: path => { const node = path.node; - if (node.alternate) return; - if (!t.isBlockStatement(node.consequent)) return; - if (node.consequent.body.length !== 1) return; - if (!t.isReturnStatement(node.consequent.body[0])) return; + if (!node.test || node.consequent.length > 0) return; + if (!t.isSwitchStatement(path.parent)) return; + const index = path.parent.cases.indexOf(node); + if (index < 0 || index >= path.parent.cases.length - 1) return; out.push({ path }); }, }); return out; } - applyCandidate(parsed: Parsed, candidate: Candidate): MutationInfo { + applyCandidate(parsed: Parsed, candidate: Candidate): MutationInfo { const node = candidate.path.node; const before = snippetFromSource(parsed.code, node, snippetFromNode(node)); candidate.path.remove(); @@ -1193,131 +1161,331 @@ class RemoveEarlyReturnMutation extends BaseAstMutation { } } -class SwapNamedImportsMutation extends BaseAstMutation { - name = "swap-named-imports"; - category = "import"; - fixHint = - "Swap ONLY the two imported names that are in the wrong order. Do not reorder other imports or modify other import statements."; - description = "Two named imports are swapped in a destructuring import."; +/** + * Wrap a block's body in a redundant `if (true) { ... }`. The fix removes the + * wrapper and dedents — an indentation-shifting multi-line edit whose entire + * content stays visible in the buggy file (no invisible-code reconstruction). + */ +class WrapRedundantIfMutation extends BaseAstMutation { + name = "wrap-redundant-if"; + category = "structural"; - collectCandidates(parsed: Parsed): Candidate[] { - const out: Candidate[] = []; + #lineSpan(node: t.Node): number { + if (!node.loc) return 0; + return node.loc.end.line - node.loc.start.line + 1; + } + + collectCandidates(parsed: Parsed): Candidate[] { + const out: Candidate[] = []; traverse(parsed.ast, { - ImportDeclaration: path => { - const named = path.node.specifiers - .map((spec, idx) => ({ spec, idx })) - .filter((entry): entry is { spec: t.ImportSpecifier; idx: number } => t.isImportSpecifier(entry.spec)) - .filter(({ spec }) => t.isIdentifier(spec.imported) && t.isIdentifier(spec.local)) - .filter( - ({ spec }) => - t.isIdentifier(spec.imported) && - t.isIdentifier(spec.local) && - spec.imported.name === spec.local.name, - ); - if (named.length < 2) return; - for (let i = 0; i < named.length; i++) { - for (let j = i + 1; j < named.length; j++) { - out.push({ path, meta: { i: named[i]!.idx, j: named[j]!.idx } }); - } - } + BlockStatement: path => { + const span = this.#lineSpan(path.node); + if (span < 4 || span > 160) return; + if (path.node.body.length === 0) return; + if (path.node.directives.length > 0) return; + // Don't wrap a body that is itself just an `if (true)` (repeated mutation noise). + if (path.node.body.length === 1 && t.isIfStatement(path.node.body[0])) return; + out.push({ path }); }, }); return out; } + applyCandidate(_parsed: Parsed, candidate: Candidate): MutationInfo { + const node = candidate.path.node; + const line = nodeLine(node); + node.body = [t.ifStatement(t.booleanLiteral(true), t.blockStatement(node.body))]; + return { lineNumber: line, originalSnippet: "", mutatedSnippet: "if (true) {" }; + } +} + +/** + * Swap two adjacent multi-line sibling statements (functions, if-chains, + * loops). The fix swaps them back — a large contiguous replace whose content + * is fully visible. + */ +class SwapSiblingBlocksMutation implements Mutation { + name = "swap-sibling-blocks"; + category = "structural"; + + #collect(parsed: Parsed): Array<{ left: t.Statement; right: t.Statement }> { + const out: Array<{ left: t.Statement; right: t.Statement }> = []; + const lineSpan = (node: t.Node): number => (node.loc ? node.loc.end.line - node.loc.start.line + 1 : 0); + + const considerList = (body: Array): void => { + for (let i = 0; i < body.length - 1; i++) { + const left = body[i]; + const right = body[i + 1]; + if (!left || !right || !t.isStatement(left) || !t.isStatement(right)) continue; + if (!left.loc || !right.loc) continue; + if (t.isImportDeclaration(left) || t.isImportDeclaration(right)) continue; + const leftSpan = lineSpan(left); + const rightSpan = lineSpan(right); + // At least one true block; bounded total so prompts stay readable. + if (Math.max(leftSpan, rightSpan) < 3) continue; + if (leftSpan > 80 || rightSpan > 80 || leftSpan + rightSpan > 120) continue; + const gap = right.loc.start.line - left.loc.end.line; + if (gap > 2) continue; + const leftText = snippetFromSource(parsed.code, left, "").trim(); + const rightText = snippetFromSource(parsed.code, right, "").trim(); + if (!leftText || !rightText || leftText === rightText) continue; + out.push({ left, right }); + } + }; + + traverse(parsed.ast, { + Program: path => considerList(path.node.body), + BlockStatement: path => considerList(path.node.body), + }); + return out; + } + + canApply(content: string): boolean { + const parsed = parseCode(content); + return parsed !== null && this.#collect(parsed).length > 0; + } + mutate(content: string, rng: () => number): [string, MutationInfo] { const parsed = parseCode(content); if (!parsed) return [content, noopInfo()]; - const candidates = this.collectCandidates(parsed); + const candidates = this.#collect(parsed); if (candidates.length === 0) return [content, noopInfo()]; - const chosen = randomChoice(candidates, rng); - const node = chosen.path.node; - const indices = chosen.meta; - if (!indices) return [content, noopInfo()]; - const { i, j } = indices; - if (i < 0 || j < 0 || i >= node.specifiers.length || j >= node.specifiers.length) return [content, noopInfo()]; - - const left = node.specifiers[i]; - const right = node.specifiers[j]; - if (!left || !right) return [content, noopInfo()]; + const { left, right } = randomChoice(candidates, rng); const leftRange = nodeRange(left); const rightRange = nodeRange(right); - const importRange = nodeRange(node); - if (!leftRange || !rightRange || !importRange) return [content, noopInfo()]; - if (leftRange.end > rightRange.start) return [content, noopInfo()]; + if (!leftRange || !rightRange || leftRange.end > rightRange.start) return [content, noopInfo()]; - const leftText = content.slice(leftRange.start, leftRange.end); - const rightText = content.slice(rightRange.start, rightRange.end); + const between = content.slice(leftRange.end, rightRange.start); + const swapped = `${content.slice(rightRange.start, rightRange.end)}${between}${content.slice(leftRange.start, leftRange.end)}`; const mutated = applySourceEdits(content, [ - { start: leftRange.start, end: leftRange.end, replacement: rightText }, - { start: rightRange.start, end: rightRange.end, replacement: leftText }, + { start: leftRange.start, end: rightRange.end, replacement: swapped }, ]); if (!mutated || mutated === content) return [content, noopInfo()]; return [ mutated, { - lineNumber: nodeLine(node), - originalSnippet: content.slice(importRange.start, importRange.end).trim(), - mutatedSnippet: mutated.slice(importRange.start, importRange.end).trim(), + lineNumber: left.loc?.start.line ?? 0, + originalSnippet: `lines ${left.loc?.start.line ?? 0}-${right.loc?.end.line ?? 0}`, + mutatedSnippet: "[swapped]", }, ]; } - - applyCandidate(parsed: Parsed, candidate: Candidate): MutationInfo { - const node = candidate.path.node; - const indices = candidate.meta; - if (!indices) return noopInfo(); - const before = snippetFromSource(parsed.code, node, snippetFromNode(node)); - const { i, j } = indices; - if (i < 0 || j < 0 || i >= node.specifiers.length || j >= node.specifiers.length) return noopInfo(); - [node.specifiers[i], node.specifiers[j]] = [node.specifiers[j]!, node.specifiers[i]!]; - return { - lineNumber: nodeLine(node), - originalSnippet: before.trim(), - mutatedSnippet: snippetFromNode(node).trim(), - }; - } } -class DeleteStatementMutation extends BaseAstMutation { - name = "delete-statement"; +/** + * Duplicate a multi-line statement right after itself (a copy-paste accident). + * The fix deletes the second copy — a large deletion where the surviving copy + * stays visible, so the task is deterministic without revealing hidden code. + */ +class DuplicateBlockMutation implements Mutation { + name = "duplicate-block"; category = "structural"; - fixHint = "Restore the deleted statement."; - description = "A critical statement was deleted from the code."; - collectCandidates(parsed: Parsed): Candidate[] { - const out: Candidate[] = []; + #collect(parsed: Parsed): t.Statement[] { + const out: t.Statement[] = []; + const consider = (statement: t.Statement | t.ModuleDeclaration): void => { + if (!t.isStatement(statement) || !statement.loc) return; + const span = statement.loc.end.line - statement.loc.start.line + 1; + if (span < 3 || span > 120) return; + // Duplicating lexical declarations or exports produces parse/redeclaration + // errors; stick to statements that stay syntactically valid twice. + if ( + !t.isIfStatement(statement) && + !t.isExpressionStatement(statement) && + !t.isForStatement(statement) && + !t.isForOfStatement(statement) && + !t.isWhileStatement(statement) && + !t.isTryStatement(statement) && + !t.isSwitchStatement(statement) + ) { + return; + } + out.push(statement); + }; traverse(parsed.ast, { - Statement: path => { - if (!path.node.loc) return; - if (t.isVariableDeclaration(path.node)) { - out.push({ path: path as NodePath }); - return; - } - if (!t.isExpressionStatement(path.node)) return; - if (t.isAssignmentExpression(path.node.expression) || t.isUpdateExpression(path.node.expression)) { - out.push({ path: path as NodePath }); - } + Program: path => { + for (const statement of path.node.body) consider(statement); + }, + BlockStatement: path => { + for (const statement of path.node.body) consider(statement); }, }); return out; } - applyCandidate(parsed: Parsed, candidate: Candidate): MutationInfo { - const node = candidate.path.node; - const before = snippetFromSource(parsed.code, node, snippetFromNode(node)); - candidate.path.remove(); - return { lineNumber: nodeLine(node), originalSnippet: before.trim(), mutatedSnippet: "[removed]" }; + canApply(content: string): boolean { + const parsed = parseCode(content); + return parsed !== null && this.#collect(parsed).length > 0; + } + + mutate(content: string, rng: () => number): [string, MutationInfo] { + const parsed = parseCode(content); + if (!parsed) return [content, noopInfo()]; + const candidates = this.#collect(parsed); + if (candidates.length === 0) return [content, noopInfo()]; + + const statement = randomChoice(candidates, rng); + const range = nodeRange(statement); + if (!range) return [content, noopInfo()]; + + const text = content.slice(range.start, range.end); + const mutated = applySourceEdits(content, [{ start: range.end, end: range.end, replacement: `\n\n${text}` }]); + if (!mutated || mutated === content) return [content, noopInfo()]; + // Reject mutations that no longer parse (e.g. duplicated declarations). + if (!parseCode(mutated)) return [content, noopInfo()]; + + return [ + mutated, + { + lineNumber: statement.loc?.start.line ?? 0, + originalSnippet: text.split("\n")[0]?.trim() ?? "", + mutatedSnippet: text.split("\n")[0]?.trim() ?? "", + }, + ]; + } +} + +/** + * Move a multi-line statement to a distant position in the same statement + * list. The fix moves it back — one delete hunk plus one insert hunk, the two + * dominant hunk shapes in real edits — with the moved content fully visible. + */ +class MoveDistantBlockMutation implements Mutation { + name = "move-distant-block"; + category = "structural"; + multiHunk = true; + + #collect(parsed: Parsed): Array<{ moved: t.Statement; next: t.Statement; target: t.Statement }> { + const out: Array<{ moved: t.Statement; next: t.Statement; target: t.Statement }> = []; + + const considerList = (body: Array): void => { + if (body.length < 5) return; + for (let from = 0; from < body.length - 1; from++) { + const moved = body[from]; + const next = body[from + 1]; + if (!moved || !next || !t.isStatement(moved) || !t.isStatement(next)) continue; + if (!moved.loc || t.isImportDeclaration(moved)) continue; + const span = moved.loc.end.line - moved.loc.start.line + 1; + if (span < 3 || span > 60) continue; + for (let to = from + 3; to < body.length; to++) { + const target = body[to]; + if (!target || !t.isStatement(target) || !target.loc) continue; + out.push({ moved, next, target }); + } + } + }; + + traverse(parsed.ast, { + Program: path => considerList(path.node.body), + BlockStatement: path => considerList(path.node.body), + }); + return out; + } + + canApply(content: string): boolean { + const parsed = parseCode(content); + return parsed !== null && this.#collect(parsed).length > 0; + } + + mutate(content: string, rng: () => number): [string, MutationInfo] { + const parsed = parseCode(content); + if (!parsed) return [content, noopInfo()]; + const candidates = this.#collect(parsed); + if (candidates.length === 0) return [content, noopInfo()]; + + const { moved, next, target } = randomChoice(candidates, rng); + const movedRange = nodeRange(moved); + const nextRange = nodeRange(next); + const targetRange = nodeRange(target); + if (!movedRange || !nextRange || !targetRange) return [content, noopInfo()]; + if (movedRange.end > nextRange.start || nextRange.start > targetRange.end) return [content, noopInfo()]; + + const movedText = content.slice(movedRange.start, movedRange.end); + const mutated = applySourceEdits(content, [ + // Cut the statement together with its trailing separator... + { start: movedRange.start, end: nextRange.start, replacement: "" }, + // ...and splice it back in after the distant target statement. + { start: targetRange.end, end: targetRange.end, replacement: `\n\n${movedText}` }, + ]); + if (!mutated || mutated === content) return [content, noopInfo()]; + if (!parseCode(mutated)) return [content, noopInfo()]; + + return [ + mutated, + { + lineNumber: moved.loc?.start.line ?? 0, + originalSnippet: movedText.split("\n")[0]?.trim() ?? "", + mutatedSnippet: movedText.split("\n")[0]?.trim() ?? "", + }, + ]; + } +} + +/** + * Apply several independent token-level mutations in one file — the multi-hunk + * edit shape that dominates real sessions. Each constituent bug is a + * single-line change fully specified by the task's before/after blocks. + */ +class CompositeMultiEditMutation implements Mutation { + name = "composite-multi-edit"; + category = "multi"; + multiHunk = true; + + #parts: Mutation[]; + + constructor(parts: Mutation[]) { + this.#parts = parts; + } + + canApply(content: string): boolean { + let applicable = 0; + for (const part of this.#parts) { + try { + if (part.canApply(content)) applicable++; + } catch { + // Unparseable for this part; skip. + } + if (applicable >= 2) return true; + } + return false; + } + + mutate(content: string, rng: () => number): [string, MutationInfo] { + const applicable = this.#parts.filter(part => { + try { + return part.canApply(content); + } catch { + return false; + } + }); + if (applicable.length < 2) return [content, noopInfo()]; + + const target = Math.min(3 + Math.floor(rng() * 3), applicable.length); + const parts = randomSample(applicable, target, rng); + let current = content; + let firstInfo: MutationInfo | null = null; + let applied = 0; + for (const part of parts) { + try { + const [next, info] = part.mutate(current, rng); + if (next === current || info.lineNumber === 0) continue; + current = next; + firstInfo ??= info; + applied++; + } catch { + // A part failing on already-mutated content just shrinks the composite. + } + } + if (applied < 2 || !firstInfo) return [content, noopInfo()]; + return [current, firstInfo]; } } class OffByOneMutation extends BaseAstMutation { name = "off-by-one"; category = "literal"; - fixHint = "Fix the off-by-one error in the numeric literal or comparison."; - description = "A numeric boundary has an off-by-one error."; collectCandidates(parsed: Parsed): Candidate[] { const out: Candidate[] = []; @@ -1386,7 +1554,8 @@ class OffByOneMutation extends BaseAstMutation { } } -export const ALL_MUTATIONS: Mutation[] = [ +/** Single-line token mutations; also the constituent parts of the composite. */ +const TOKEN_MUTATIONS: Mutation[] = [ new SwapComparisonMutation(), new SwapEqualityMutation(), new SwapLogicalMutation(), @@ -1399,14 +1568,21 @@ export const ALL_MUTATIONS: Mutation[] = [ new NullishCoalescingSwapMutation(), new RegexQuantifierSwapMutation(), new UnicodeHyphenMutation(), + new OffByOneMutation(), +]; + +export const ALL_MUTATIONS: Mutation[] = [ + ...TOKEN_MUTATIONS, new IdentifierMultiEditMutation(), new DuplicateLineLiteralFlipMutation(), new SwapAdjacentLinesMutation(), new SwapIfElseBranchesMutation(), - new RemoveEarlyReturnMutation(), - new SwapNamedImportsMutation(), - new DeleteStatementMutation(), - new OffByOneMutation(), + new WrapRedundantIfMutation(), + new SwapSiblingBlocksMutation(), + new DuplicateBlockMutation(), + new MoveDistantBlockMutation(), + new RemoveCaseLabelMutation(), + new CompositeMultiEditMutation(TOKEN_MUTATIONS), ]; export const CATEGORY_MAP: Record = { @@ -1419,5 +1595,5 @@ export const CATEGORY_MAP: Record = { identifier: ALL_MUTATIONS.filter(m => m.category === "identifier").map(m => m.name), duplicate: ALL_MUTATIONS.filter(m => m.category === "duplicate").map(m => m.name), structural: ALL_MUTATIONS.filter(m => m.category === "structural").map(m => m.name), - import: ALL_MUTATIONS.filter(m => m.category === "import").map(m => m.name), + multi: ALL_MUTATIONS.filter(m => m.category === "multi").map(m => m.name), }; diff --git a/packages/typescript-edit-benchmark/src/prompts/identifier-task.md b/packages/typescript-edit-benchmark/src/prompts/identifier-task.md new file mode 100644 index 000000000..34c0e1515 --- /dev/null +++ b/packages/typescript-edit-benchmark/src/prompts/identifier-task.md @@ -0,0 +1,9 @@ +# Fix a misspelled identifier in `{{filename}}` + +A recent edit misspelled the identifier `{{correct}}` as `{{misspelled}}` in {{#when count "==" 1}}one place{{else}}{{count}} places{{/when}}. +{{#if affectedLines}} + +Affected line{{#when count ">" 1}}s{{/when}}: {{join affectedLines ", "}}. +{{/if}} + +Replace every occurrence of `{{misspelled}}` with `{{correct}}`. Do not change anything else. diff --git a/packages/typescript-edit-benchmark/src/prompts/mutation-task.md b/packages/typescript-edit-benchmark/src/prompts/mutation-task.md new file mode 100644 index 000000000..e009de7e7 --- /dev/null +++ b/packages/typescript-edit-benchmark/src/prompts/mutation-task.md @@ -0,0 +1,85 @@ +# Fix a bug in `{{filename}}` + +{{#when name "==" "swap-comparison"}} +A comparison operator is subtly wrong. +{{/when}} +{{#when name "==" "swap-equality"}} +An equality operator is inverted. +{{/when}} +{{#when name "==" "swap-logical"}} +A boolean operator is incorrect. +{{/when}} +{{#when name "==" "remove-negation"}} +A logical negation (`!`) was accidentally removed. +{{/when}} +{{#when name "==" "swap-increment-decrement"}} +An increment/decrement operator points the wrong direction. +{{/when}} +{{#when name "==" "swap-arithmetic"}} +An arithmetic operator was swapped. +{{/when}} +{{#when name "==" "flip-boolean"}} +A boolean literal is inverted. +{{/when}} +{{#when name "==" "remove-optional-chain"}} +Optional chaining was removed from a property access. +{{/when}} +{{#when name "==" "swap-call-args"}} +Two arguments in a call are swapped. +{{/when}} +{{#when name "==" "swap-nullish"}} +A nullish coalescing operator was swapped. +{{/when}} +{{#when name "==" "swap-regex-quantifier"}} +A regex quantifier was swapped, changing whitespace matching. +{{/when}} +{{#when name "==" "unicode-hyphen"}} +A string literal contains a lookalike unicode dash. +{{/when}} +{{#when name "==" "off-by-one"}} +A numeric boundary has an off-by-one error. +{{/when}} +{{#when name "==" "duplicate-line-flip"}} +One copy of a line that repeats elsewhere in this file was altered. +{{/when}} +{{#when name "==" "composite-multi-edit"}} +This file contains several small, unrelated single-line bugs. +{{/when}} +{{#if functionName}} + +The bug is in the `{{functionName}}` function. +{{/if}} +{{#when region "==" "top"}} + +The bug is near the top of the file. +{{/when}} +{{#when region "==" "middle"}} + +The bug is around the middle of the file. +{{/when}} +{{#when region "==" "end"}} + +The bug is near the end of the file. +{{/when}} +{{#each hunks}} +{{#when ../hunkCount ">" 1}} + +## Change {{add @index 1}} +{{/when}} + +{{#if isDelete}}Delete this block{{#if startLine}} (starting on line {{startLine}}){{/if}}:{{else}}Replace this{{#if startLine}} (starting on line {{startLine}}){{/if}}:{{/if}} + +{{../fence}}{{../language}} +{{oldCode}} +{{../fence}} +{{#unless isDelete}} + +with: + +{{../fence}}{{../language}} +{{newCode}} +{{../fence}} +{{/unless}} +{{/each}} + +{{#if nightmare}}This file contains near-identical code in multiple places — edit exactly the block shown and nothing else.{{else}}Make exactly this change; do not modify anything else.{{/if}} diff --git a/packages/typescript-edit-benchmark/src/prompts/structural-task.md b/packages/typescript-edit-benchmark/src/prompts/structural-task.md new file mode 100644 index 000000000..3792f45eb --- /dev/null +++ b/packages/typescript-edit-benchmark/src/prompts/structural-task.md @@ -0,0 +1,37 @@ +# Fix a bug in `{{filename}}` + +{{#when kind "==" "case-label"}} +In this file's `switch`, the value in `{{label}}` must be handled exactly like the case after it: add a fall-through `{{label}}` label directly before `{{before}}`. +{{/when}} +{{#when kind "==" "duplicate-block"}} +The block starting with `{{head}}` appears twice in a row — the second copy is a copy-paste accident. Delete the second copy and keep the first. +{{/when}} +{{#when kind "==" "move-block"}} +The block starting with `{{head}}` was moved to the wrong place — it currently sits after `{{currentPrev}}`. Move it back so it comes directly before `{{destination}}`. +{{/when}} +{{#when kind "==" "wrap-if"}} +A leftover debugging wrapper is redundant: remove the `if (true) {` on line {{wrapperLine}} together with its closing brace, and dedent the wrapped body one level. +{{/when}} +{{#when kind "==" "swap-blocks"}} +Two adjacent blocks are in the wrong order: the block starting with `{{secondHead}}` belongs before the block starting with `{{firstHead}}`. Swap the two blocks. +{{/when}} +{{#when kind "==" "swap-lines"}} +Two adjacent statements are in the wrong order: `{{secondHead}}` belongs before `{{firstHead}}`. Swap the two statements. +{{/when}} +{{#when kind "==" "swap-if-else"}} +The branch bodies of `{{condition}}` are swapped: the current `else` body belongs under the `if`, and vice versa. Swap the two branch bodies. +{{/when}} + +After the fix, the affected {{#when hunkCount ">" 1}}regions must{{else}}region must{{/when}} read exactly: +{{#each hunks}} +{{#if startLine}} + +Around line {{startLine}}: +{{/if}} + +{{../fence}}{{../language}} +{{newCode}} +{{../fence}} +{{/each}} + +Make exactly this change; do not modify anything else. diff --git a/packages/typescript-edit-benchmark/test/hunks.test.ts b/packages/typescript-edit-benchmark/test/hunks.test.ts new file mode 100644 index 000000000..4518da59b --- /dev/null +++ b/packages/typescript-edit-benchmark/test/hunks.test.ts @@ -0,0 +1,96 @@ +import { describe, expect, it } from "bun:test"; +import { + placementsFromDiff, + type RenderedHunk, + renderHunks, + solveRenderedHunks, +} from "@oh-my-pi/typescript-edit-benchmark/hunks"; + +/** Round-trip an input/expected pair through the prompt machinery. */ +function roundTrip(input: string, expected: string): { hunks: RenderedHunk[]; solved: string } { + const inputLines = input.replace(/\n$/, "").split("\n"); + const placements = placementsFromDiff(input, expected); + const hunks = renderHunks(inputLines, placements); + if (!hunks) throw new Error("renderHunks returned null"); + const solved = solveRenderedHunks(inputLines, hunks); + if (!solved) throw new Error("solveRenderedHunks returned null"); + return { hunks, solved: `${solved.join("\n")}\n` }; +} + +describe("hunk round-trip", () => { + it("reproduces the expected file for a block replacement", () => { + const input = "const a = 1;\nfunction f() {\n\treturn a;\n}\nexport { f };\n"; + const expected = "const a = 1;\nfunction f() {\n\treturn a + 1;\n}\nexport { f };\n"; + const { hunks, solved } = roundTrip(input, expected); + expect(solved).toBe(expected); + expect(hunks).toHaveLength(1); + expect(hunks[0].unique).toBe(true); + }); + + it("reproduces the expected file for a pure insertion, anchored on a non-blank line", () => { + const input = "function f() {\n\n\treturn 1;\n}\n"; + const expected = "function f() {\n\n\tconst x = 0;\n\treturn 1;\n}\n"; + const { hunks, solved } = roundTrip(input, expected); + expect(solved).toBe(expected); + // The line directly above the insertion is blank; the anchor must be visible. + expect(hunks[0].oldBlock.some(line => line.trim().length > 0)).toBe(true); + }); + + it("reproduces the expected file for a pure deletion, anchored on context", () => { + const input = "a();\nb();\nc();\n"; + const expected = "a();\nc();\n"; + const { hunks, solved } = roundTrip(input, expected); + expect(solved).toBe(expected); + // Deletions keep a context anchor so the replacement is never an empty fence. + expect(hunks[0].newBlock.length).toBeGreaterThan(0); + expect(hunks[0].oldBlock.length).toBeGreaterThan(hunks[0].newBlock.length); + }); +}); + +describe("uniqueness handling", () => { + it("extends a repeated block with context until it is unique", () => { + const input = "start();\nif (x) {\n\tstop();\n}\nif (y) {\n\tstop();\n}\n"; + const expected = "start();\nif (x) {\n\tstop();\n}\nif (y) {\n\thalt();\n}\n"; + const { hunks, solved } = roundTrip(input, expected); + expect(solved).toBe(expected); + expect(hunks[0].unique).toBe(true); + // `\tstop();` alone is ambiguous; the block must carry the `if (y) {` context. + expect(hunks[0].oldBlock.length).toBeGreaterThan(1); + }); + + it("marks a hunk non-unique with its start line when context cannot disambiguate", () => { + const line = "value += 1;"; + const input = `${Array.from({ length: 4 }, () => line).join("\n")}\n`; + const expected = `${[line, line, "value += 2;", line].join("\n")}\n`; + const inputLines = input.replace(/\n$/, "").split("\n"); + const hunks = renderHunks(inputLines, placementsFromDiff(input, expected)); + if (!hunks) throw new Error("renderHunks returned null"); + expect(hunks[0].unique).toBe(false); + // startLine must locate a real occurrence of the (extended) old block, so + // a solver that trusts it lands on the right copy. + expect(inputLines.slice(hunks[0].startLine - 1, hunks[0].startLine - 1 + hunks[0].oldBlock.length)).toEqual( + hunks[0].oldBlock, + ); + const solved = solveRenderedHunks(inputLines, hunks); + expect(solved ? `${solved.join("\n")}\n` : null).toBe(expected); + }); +}); + +describe("placement merging", () => { + it("renders two adjacent swapped statements as a single hunk", () => { + const input = "setup();\nsecond();\nfirst();\nteardown();\n"; + const expected = "setup();\nfirst();\nsecond();\nteardown();\n"; + const { hunks, solved } = roundTrip(input, expected); + expect(solved).toBe(expected); + expect(hunks).toHaveLength(1); + }); + + it("keeps distant changes as separate hunks", () => { + const filler = Array.from({ length: 10 }, (_, i) => `line${i}();`).join("\n"); + const input = `alpha();\n${filler}\nomega();\n`; + const expected = `alpha2();\n${filler}\nomega2();\n`; + const { hunks, solved } = roundTrip(input, expected); + expect(solved).toBe(expected); + expect(hunks).toHaveLength(2); + }); +}); diff --git a/packages/utils/package.json b/packages/utils/package.json index e334b9fd8..358127c62 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-utils", - "version": "17.1.8", + "version": "17.2.0", "description": "Shared utilities for pi packages", "homepage": "https://omp.sh", "author": "Can Boluk", diff --git a/packages/utils/test/logger-contract.test.ts b/packages/utils/test/logger-contract.test.ts index 58881d43e..e714d1f5b 100644 --- a/packages/utils/test/logger-contract.test.ts +++ b/packages/utils/test/logger-contract.test.ts @@ -53,6 +53,9 @@ async function runScenario(scenario: string): Promise { XDG_DATA_HOME: "", XDG_STATE_HOME: "", XDG_CACHE_HOME: "", + // Empty XDG_CACHE_HOME makes Bun's transpiler cache path relative, + // spewing bun/@t@/*.pile into the repo root (the child's cwd) — disable it. + BUN_RUNTIME_TRANSPILER_CACHE_PATH: "0", OMP_LOGGER_TEST_NOW: fixedNow, TZ: "Etc/GMT+5", }, diff --git a/packages/utils/test/postmortem-epipe.test.ts b/packages/utils/test/postmortem-epipe.test.ts index 373eb47e2..79e84b469 100644 --- a/packages/utils/test/postmortem-epipe.test.ts +++ b/packages/utils/test/postmortem-epipe.test.ts @@ -21,16 +21,13 @@ if (childFlagIndex >= 0) { } else if (process.argv.includes(raceChildFlag)) { const marker = process.argv[process.argv.indexOf(raceChildFlag) + 1]; if (!marker) throw new Error("Missing cleanup marker path"); - let cleanupComplete = false; - process.on("exit", () => { - fs.writeFileSync(marker, cleanupComplete ? "after cleanup" : "before cleanup"); - }); + fs.writeFileSync(marker, "before cleanup"); postmortem.registerStdioDisconnectHandling(); postmortem.register("stdio-epipe-race-test", async () => { process.stderr.write("cleanup started\n"); void Promise.reject(Object.assign(new Error("broken pipe"), { code: "EPIPE", syscall: "write" })); await new Response(Bun.stdin.stream()).text(); - cleanupComplete = true; + fs.writeFileSync(marker, "after cleanup"); }); let rejectionCount = 0; process.on("unhandledRejection", () => { @@ -63,7 +60,7 @@ describe("postmortem broken-pipe handling", () => { it("awaits cleanup and exits successfully when a registered stdio peer disconnects", async () => { const marker = `/tmp/omp-postmortem-stdio-${process.pid}-${Date.now()}`; - const child = Bun.spawn([process.execPath, import.meta.path, childFlag, marker], { + const child = Bun.spawn([process.execPath, "run", import.meta.path, childFlag, marker], { stdin: "pipe", stdout: "pipe", stderr: "pipe", @@ -93,7 +90,7 @@ describe("postmortem broken-pipe handling", () => { it("keeps waiting for active cleanup when another stdio EPIPE arrives", async () => { const marker = `/tmp/omp-postmortem-stdio-race-${process.pid}-${Date.now()}`; - const child = Bun.spawn([process.execPath, import.meta.path, raceChildFlag, marker], { + const child = Bun.spawn([process.execPath, "run", import.meta.path, raceChildFlag, marker], { stdin: "pipe", stdout: "pipe", stderr: "pipe", diff --git a/packages/utils/test/postmortem-quit.test.ts b/packages/utils/test/postmortem-quit.test.ts deleted file mode 100644 index 3ac960495..000000000 --- a/packages/utils/test/postmortem-quit.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { describe, expect, it } from "bun:test"; -import * as postmortem from "../src/postmortem"; - -const childFlag = "--quit-without-drain-child"; - -if (process.argv.includes(childFlag)) { - Object.defineProperty(process.stdout, "writableLength", { value: 1, configurable: true }); - await postmortem.quit(23, { drainStdout: false }); -} - -describe("postmortem quit", () => { - it("exits without waiting for pending stdout when draining is disabled", async () => { - const child = Bun.spawn([process.execPath, import.meta.path, childFlag], { - stdout: "pipe", - stderr: "pipe", - }); - const timeout = Bun.sleep(500).then(() => "timeout" as const); - try { - expect(await Promise.race([child.exited, timeout])).toBe(23); - } finally { - child.kill(); - await child.exited; - } - }); -}); diff --git a/packages/wire/package.json b/packages/wire/package.json index 1f2b30dcc..1f1fc9684 100644 --- a/packages/wire/package.json +++ b/packages/wire/package.json @@ -1,7 +1,7 @@ { "type": "module", "name": "@oh-my-pi/pi-wire", - "version": "17.1.8", + "version": "17.2.0", "description": "Shared wire protocol types for Oh My Pi packages", "homepage": "https://omp.sh", "author": "Can Boluk",