From 7ad6584def618844675d35632aa0e75ade942a8c Mon Sep 17 00:00:00 2001 From: Ralph Kuepper Date: Mon, 14 Sep 2026 12:25:17 +0200 Subject: [PATCH 01/11] chore: remove unused Rust dependency declarations --- Cargo.lock | 200 +-- Cargo.toml | 3 - .../pending-rust-dependency-cleanup.md | 9 + crates/perry-codegen/Cargo.toml | 2 - crates/perry-container-compose/Cargo.toml | 4 - crates/perry-ext-fastify/Cargo.toml | 1 - crates/perry-hir/Cargo.toml | 1 - crates/perry-parser/Cargo.toml | 1 - crates/perry-runtime/Cargo.toml | 2 - crates/perry-stdlib/Cargo.toml | 11 +- crates/perry-transform/Cargo.toml | 3 - crates/perry-ui-android/Cargo.toml | 3 - crates/perry-ui-windows-winui/Cargo.toml | 2 - crates/perry-updater/Cargo.toml | 1 - docs/audits/rust-dependencies-2026-09-14.json | 1245 +++++++++++++++++ ...st-dependency-build-graphs-2026-09-14.json | 25 + .../rust-dependency-cleanup-2026-09-14.json | 297 ++++ .../rust-dependency-decisions-2026-09-14.json | 197 +++ .../rust-dependency-decisions-2026-09-14.md | 209 +++ ...ust-dependency-experiments-2026-09-14.json | 200 +++ docs/rust-dependency-audit.md | 155 ++ scripts/rust_dependency_inventory.py | 183 +++ 22 files changed, 2528 insertions(+), 226 deletions(-) create mode 100644 changelog.d/pending-rust-dependency-cleanup.md create mode 100644 docs/audits/rust-dependencies-2026-09-14.json create mode 100644 docs/audits/rust-dependency-build-graphs-2026-09-14.json create mode 100644 docs/audits/rust-dependency-cleanup-2026-09-14.json create mode 100644 docs/audits/rust-dependency-decisions-2026-09-14.json create mode 100644 docs/audits/rust-dependency-decisions-2026-09-14.md create mode 100644 docs/audits/rust-dependency-experiments-2026-09-14.json create mode 100644 docs/rust-dependency-audit.md create mode 100644 scripts/rust_dependency_inventory.py diff --git a/Cargo.lock b/Cargo.lock index 3779ae8b5d..388c342ab6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -464,17 +464,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21e4227379beff4205943696e6c3e0cd809bacdf3f0edd6e3dd153e2269571a4" -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "auto_impl" version = "1.3.0" @@ -1087,16 +1076,6 @@ dependencies = [ "windows-link 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "chrono-tz" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" -dependencies = [ - "chrono", - "phf 0.12.1", -] - [[package]] name = "chunked_transfer" version = "1.5.0" @@ -1426,17 +1405,6 @@ dependencies = [ "winnow 0.7.15", ] -[[package]] -name = "croner" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa42bcd3d846ebf66e15bd528d1087f75d1c6c1c66ebff626178a106353c576" -dependencies = [ - "chrono", - "derive_builder", - "strum", -] - [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -1622,38 +1590,14 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "darling" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core 0.20.11", - "darling_macro 0.20.11", -] - [[package]] name = "darling" version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "darling_core 0.23.0", - "darling_macro 0.23.0", -] - -[[package]] -name = "darling_core" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.117", + "darling_core", + "darling_macro", ] [[package]] @@ -1669,24 +1613,13 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "darling_macro" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core 0.20.11", - "quote", - "syn 2.0.117", -] - [[package]] name = "darling_macro" version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ - "darling_core 0.23.0", + "darling_core", "quote", "syn 2.0.117", ] @@ -1806,37 +1739,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "derive_builder" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" -dependencies = [ - "darling 0.20.11", - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "derive_builder_macro" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" -dependencies = [ - "derive_builder_core", - "syn 2.0.117", -] - [[package]] name = "derive_more" version = "2.1.1" @@ -3277,15 +3179,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.5.2" @@ -4061,7 +3954,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ - "hermit-abi 0.5.2", + "hermit-abi", "libc", "windows-sys 0.61.2", ] @@ -5156,7 +5049,7 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.5.2", + "hermit-abi", "libc", ] @@ -5784,7 +5677,6 @@ dependencies = [ "perry-hir", "serde", "serde_json", - "thiserror 1.0.69", ] [[package]] @@ -5844,14 +5736,10 @@ dependencies = [ name = "perry-container-compose" version = "0.5.1569" dependencies = [ - "anyhow", "async-trait", - "atty", "clap", "console 0.16.4", - "dashmap 6.2.1", "dialoguer 0.11.0", - "dotenvy", "hex", "indexmap", "md-5 0.11.0", @@ -6034,7 +5922,6 @@ dependencies = [ "http-body-util", "hyper", "hyper-util", - "lazy_static", "perry-ext-ws", "perry-ffi", "perry-runtime", @@ -6367,7 +6254,6 @@ dependencies = [ "swc_ecma_codegen", "swc_ecma_transforms_base", "swc_ecma_visit", - "thiserror 1.0.69", ] [[package]] @@ -6385,7 +6271,6 @@ dependencies = [ "swc_ecma_parser 32.0.0", "swc_ecma_transforms_base", "swc_ecma_visit", - "thiserror 1.0.69", ] [[package]] @@ -6401,7 +6286,6 @@ name = "perry-runtime" version = "0.5.1569" dependencies = [ "ahash", - "anyhow", "base64 0.22.1", "cc", "dirs", @@ -6442,7 +6326,6 @@ dependencies = [ "socket2", "taffy", "temporal_rs", - "thiserror 1.0.69", "timezone_provider", "toml", "unicode-normalization", @@ -6471,7 +6354,6 @@ dependencies = [ "aes 0.9.1", "aes-gcm", "aes-kw", - "anyhow", "argon2", "base64 0.22.1", "bcrypt", @@ -6481,7 +6363,6 @@ dependencies = [ "cbc 0.2.1", "chacha20poly1305", "chrono", - "clap", "cron", "ctr", "dashmap 6.2.1", @@ -6499,7 +6380,6 @@ dependencies = [ "hyper", "hyper-util", "image", - "itoa", "jsonwebtoken", "lazy_static", "lettre", @@ -6530,7 +6410,6 @@ dependencies = [ "rustls", "rustls-native-certs", "rustls-pemfile", - "ryu", "scraper", "scrypt", "serde", @@ -6545,9 +6424,7 @@ dependencies = [ "shake", "spki 0.8.0", "sqlx", - "thiserror 1.0.69", "tokio", - "tokio-cron-scheduler", "tokio-rustls", "tokio-tungstenite", "uuid", @@ -6569,9 +6446,7 @@ dependencies = [ name = "perry-transform" version = "0.5.1569" dependencies = [ - "anyhow", "perry-hir", - "thiserror 1.0.69", ] [[package]] @@ -6589,7 +6464,6 @@ name = "perry-ui-android" version = "0.5.1569" dependencies = [ "base64 0.22.1", - "itoa", "jni", "libc", "perry-audio-miniaudio", @@ -6597,8 +6471,6 @@ dependencies = [ "perry-ffi", "perry-runtime", "perry-ui", - "ryu", - "serde_json", "tungstenite 0.24.0", ] @@ -6755,8 +6627,6 @@ dependencies = [ name = "perry-ui-windows-winui" version = "0.5.1569" dependencies = [ - "base64 0.22.1", - "libc", "perry-ffi", "perry-runtime", "perry-ui-windows", @@ -6775,7 +6645,6 @@ dependencies = [ "perry-runtime", "semver", "serde", - "serde_json", "sha2 0.11.0", "tempfile", ] @@ -6817,15 +6686,6 @@ dependencies = [ "phf_shared 0.11.3", ] -[[package]] -name = "phf" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" -dependencies = [ - "phf_shared 0.12.1", -] - [[package]] name = "phf" version = "0.13.1" @@ -6902,15 +6762,6 @@ dependencies = [ "siphasher 1.0.3", ] -[[package]] -name = "phf_shared" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" -dependencies = [ - "siphasher 1.0.3", -] - [[package]] name = "phf_shared" version = "0.13.1" @@ -7022,7 +6873,7 @@ checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", - "hermit-abi 0.5.2", + "hermit-abi", "pin-project-lite", "rustix", "windows-sys 0.61.2", @@ -8208,7 +8059,7 @@ version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" dependencies = [ - "darling 0.23.0", + "darling", "proc-macro2", "quote", "syn 2.0.117", @@ -8839,27 +8690,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "subtle" version = "2.6.1" @@ -9639,22 +9469,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "tokio-cron-scheduler" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f50e41f200fd8ed426489bd356910ede4f053e30cebfbd59ef0f856f0d7432a" -dependencies = [ - "chrono", - "chrono-tz", - "croner", - "num-derive", - "num-traits", - "tokio", - "tracing", - "uuid", -] - [[package]] name = "tokio-macros" version = "2.7.0" diff --git a/Cargo.toml b/Cargo.toml index 299bcce38d..0fc54e3c34 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -426,9 +426,6 @@ dialoguer = "0.12" walkdir = "2.4" notify = "6.1" -# Diff generation -similar = "2.4" - # HTTP / WebSocket (for publish command) reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json", "multipart", "blocking"] } tokio = { version = "1", features = ["full"] } diff --git a/changelog.d/pending-rust-dependency-cleanup.md b/changelog.d/pending-rust-dependency-cleanup.md new file mode 100644 index 0000000000..138eef1aef --- /dev/null +++ b/changelog.d/pending-rust-dependency-cleanup.md @@ -0,0 +1,9 @@ +Remove 24 unused Rust dependency declarations and the unused `similar` workspace +template, including stdlib's unused Clap and Tokio cron scheduler dependencies. +The lockfile drops 15 external package versions without upgrading or adding any +packages. Existing Tokio usage and public APIs are unchanged. + +Add an assessment of all 195 baseline direct Rust dependencies, reproducible +dependency inventory tooling, and recommendations for feature trimming and +selective implementation ownership. Graph measurements are distinguished from +unmeasured binary-size and runtime-performance effects. diff --git a/crates/perry-codegen/Cargo.toml b/crates/perry-codegen/Cargo.toml index a2f64de4fd..b4ed408a75 100644 --- a/crates/perry-codegen/Cargo.toml +++ b/crates/perry-codegen/Cargo.toml @@ -47,12 +47,10 @@ perry-api-manifest.workspace = true anyhow.workspace = true aho-corasick.workspace = true -thiserror.workspace = true log.workspace = true serde.workspace = true serde_json.workspace = true - # Keep these target lists aligned with `inprocess::global_init`. Inkwell's # `target-all` default references backends Perry cannot emit and which the # official Windows LLVM archive does not build. diff --git a/crates/perry-container-compose/Cargo.toml b/crates/perry-container-compose/Cargo.toml index 7a7da44188..86b315ad67 100644 --- a/crates/perry-container-compose/Cargo.toml +++ b/crates/perry-container-compose/Cargo.toml @@ -16,18 +16,14 @@ serde_json = { workspace = true } serde_yaml = "0.9" tokio = { workspace = true } clap = { workspace = true } -anyhow = { workspace = true } thiserror = { workspace = true } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } async-trait = "0.1" md-5 = "0.11" hex.workspace = true -dotenvy = { workspace = true } indexmap = { version = "2.2", features = ["serde"] } -dashmap.workspace = true rand = "0.10" -atty = "0.2" dialoguer = "0.11" console = "0.16" once_cell.workspace = true diff --git a/crates/perry-ext-fastify/Cargo.toml b/crates/perry-ext-fastify/Cargo.toml index e49da023b1..8bfd40c715 100644 --- a/crates/perry-ext-fastify/Cargo.toml +++ b/crates/perry-ext-fastify/Cargo.toml @@ -27,7 +27,6 @@ bytes.workspace = true tokio = { workspace = true } tokio-tungstenite = { workspace = true } serde_json.workspace = true -lazy_static.workspace = true # #cluster — SO_REUSEPORT bind for `cluster.fork()` workers (unix only), # mirroring perry-ext-http's cluster_bind. The diff --git a/crates/perry-hir/Cargo.toml b/crates/perry-hir/Cargo.toml index ca37714a05..614630530c 100644 --- a/crates/perry-hir/Cargo.toml +++ b/crates/perry-hir/Cargo.toml @@ -23,7 +23,6 @@ swc_common.workspace = true swc_ecma_visit.workspace = true swc_ecma_transforms_base.workspace = true -thiserror.workspace = true anyhow.workspace = true serde = { workspace = true } serde_json = { workspace = true } diff --git a/crates/perry-parser/Cargo.toml b/crates/perry-parser/Cargo.toml index 8f0ca4e0c6..5b8de37f93 100644 --- a/crates/perry-parser/Cargo.toml +++ b/crates/perry-parser/Cargo.toml @@ -15,7 +15,6 @@ swc_ecma_visit.workspace = true swc_common.workspace = true swc_ecma_transforms_base.workspace = true -thiserror.workspace = true anyhow.workspace = true perry-diagnostics.workspace = true diff --git a/crates/perry-runtime/Cargo.toml b/crates/perry-runtime/Cargo.toml index 0d0967dd99..8b5e6d75ce 100644 --- a/crates/perry-runtime/Cargo.toml +++ b/crates/perry-runtime/Cargo.toml @@ -306,8 +306,6 @@ dyn-eval = ["dep:perry-parser", "dep:perry-diagnostics"] # with perry-hir through perry-dispatch, so the runtime's property-read and # method-call paths and the HIR's import lowering cannot drift apart. perry-dispatch.workspace = true -thiserror.workspace = true -anyhow.workspace = true libc.workspace = true rustc-demangle = "0.1" # Owned single-phase unwinder (#7302 follow-up): decodes .eh_frame CFI for diff --git a/crates/perry-stdlib/Cargo.toml b/crates/perry-stdlib/Cargo.toml index 6fff834dec..2881d64681 100644 --- a/crates/perry-stdlib/Cargo.toml +++ b/crates/perry-stdlib/Cargo.toml @@ -284,7 +284,7 @@ bundled-cheerio = ["dep:scraper"] # backwards-compat; v0.5.564's well-known flip toggles # `bundled-cron` instead. scheduler = ["bundled-cron"] -bundled-cron = ["dep:cron", "dep:tokio-cron-scheduler", "async-runtime"] +bundled-cron = ["dep:cron", "async-runtime"] # Rate limiting — `rate-limit` umbrella stays for backwards-compat; # v0.5.552's well-known flip toggles `bundled-ratelimit` instead. @@ -332,14 +332,9 @@ perry-updater = { workspace = true } # in this crate's tests/. perry-container-compose = { path = "../perry-container-compose", optional = true } -thiserror.workspace = true -anyhow.workspace = true - # Always needed serde = { workspace = true, features = ["derive"] } serde_json.workspace = true -itoa.workspace = true -ryu.workspace = true once_cell.workspace = true lazy_static.workspace = true chrono = { workspace = true, features = ["serde"] } @@ -444,7 +439,6 @@ scraper = { version = "0.27", optional = true } # Scheduler cron = { version = "0.17", optional = true } -tokio-cron-scheduler = { version = "0.15", optional = true } # Rate limiting governor = { version = "0.10", optional = true } @@ -461,9 +455,6 @@ nanoid = { version = "0.5", optional = true } # to perry-ext-lru-cache instead. lru = { version = "0.18", optional = true } -# CLI parsing (Commander) -clap = { version = "4.4", features = ["derive"] } - # Decimal math (Big.js / Decimal.js) — optional from v0.5.547 so # the well-known flip can strip perry-stdlib's copy when # `import 'decimal.js'` resolves to perry-ext-decimal instead. diff --git a/crates/perry-transform/Cargo.toml b/crates/perry-transform/Cargo.toml index c4bd9e5f8c..e3a9fc8dcb 100644 --- a/crates/perry-transform/Cargo.toml +++ b/crates/perry-transform/Cargo.toml @@ -10,6 +10,3 @@ workspace = true [dependencies] perry-hir.workspace = true - -thiserror.workspace = true -anyhow.workspace = true diff --git a/crates/perry-ui-android/Cargo.toml b/crates/perry-ui-android/Cargo.toml index 9aff74cc94..420850085e 100644 --- a/crates/perry-ui-android/Cargo.toml +++ b/crates/perry-ui-android/Cargo.toml @@ -27,7 +27,4 @@ perry-ext-sharp = { path = "../perry-ext-sharp" } base64.workspace = true libc.workspace = true jni = "0.22" -serde_json.workspace = true -itoa.workspace = true -ryu.workspace = true tungstenite = { version = "0.24", features = ["rustls-tls-webpki-roots"] } diff --git a/crates/perry-ui-windows-winui/Cargo.toml b/crates/perry-ui-windows-winui/Cargo.toml index 938e07d88a..d9abd197f8 100644 --- a/crates/perry-ui-windows-winui/Cargo.toml +++ b/crates/perry-ui-windows-winui/Cargo.toml @@ -20,8 +20,6 @@ crate-type = ["rlib", "staticlib"] perry-ui-windows = { path = "../perry-ui-windows", default-features = false } perry-ffi.workspace = true perry-runtime = { path = "../perry-runtime", default-features = false, features = ["stdlib"] } -base64.workspace = true -libc.workspace = true windows = { version = "0.62", features = ["Win32_Foundation"] } windows-reactor = { path = "../../third_party/windows-winui/windows-reactor" } diff --git a/crates/perry-updater/Cargo.toml b/crates/perry-updater/Cargo.toml index 258c73abb2..7dc6a323de 100644 --- a/crates/perry-updater/Cargo.toml +++ b/crates/perry-updater/Cargo.toml @@ -15,7 +15,6 @@ crate-type = ["rlib", "staticlib"] anyhow = "1.0" perry-runtime = { workspace = true } serde = { workspace = true, features = ["derive"] } -serde_json.workspace = true semver.workspace = true sha2 = "0.11" hex.workspace = true diff --git a/docs/audits/rust-dependencies-2026-09-14.json b/docs/audits/rust-dependencies-2026-09-14.json new file mode 100644 index 0000000000..16a5f29e4f --- /dev/null +++ b/docs/audits/rust-dependencies-2026-09-14.json @@ -0,0 +1,1245 @@ +{ +"commit": "4945fc1f7498debc76e9f861d7cf1517da5e67c9", +"cargo": "cargo 1.100.0-nightly (514c56dd7 2026-08-19)", +"semantics": "Cross-target lock graph, including optional and dev/build dependencies; not linked size. Lexical references need manual review. Marginal counts freeze third-party edges/features and remove all workspace edges to one package name.", +"summary": {"workspace_members": 83, "direct_external_names": 195, "registry_package_versions": 990, "registry_package_names": 863, "vendored_package_versions": 13, "registry_names_with_multiple_versions": 100}, +"direct": [ +{"name": "aes", "versions": ["0.8.4", "0.9.1"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "aes", "kind": "normal", "target": null, "optional": true, "requirement": "^0.8", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["aes@0.8.4"], "reference_lines": 33, "references": ["crates/perry-stdlib/src/crypto/cipher.rs:70", "crates/perry-stdlib/src/crypto/cipher.rs:72", "crates/perry-stdlib/src/crypto/cipher.rs:74", "crates/perry-stdlib/src/crypto/cipher.rs:76", "crates/perry-stdlib/src/crypto/cipher.rs:78", "crates/perry-stdlib/src/crypto/cipher.rs:80"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "aes_09", "kind": "normal", "target": null, "optional": true, "requirement": "^0.9", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["aes@0.9.1"], "reference_lines": 2, "references": ["crates/perry-stdlib/src/crypto/util.rs:3", "crates/perry-stdlib/src/webcrypto/util.rs:8"]}], "lock_closure_packages": 88, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "aes-gcm", "versions": ["0.10.3"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "aes_gcm", "kind": "normal", "target": null, "optional": true, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["aes-gcm@0.10.3"], "reference_lines": 26, "references": ["crates/perry-stdlib/src/crypto/cipher.rs:70", "crates/perry-stdlib/src/crypto/cipher.rs:72", "crates/perry-stdlib/src/crypto/cipher.rs:74", "crates/perry-stdlib/src/crypto/cipher.rs:76", "crates/perry-stdlib/src/crypto/cipher.rs:78", "crates/perry-stdlib/src/crypto/cipher.rs:80"]}], "lock_closure_packages": 52, "lock_packages_lost_if_all_workspace_edges_removed": ["aes-gcm@0.10.3", "ghash@0.5.1", "polyval@0.6.2"]}, +{"name": "aes-kw", "versions": ["0.3.1"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "aes_kw", "kind": "normal", "target": null, "optional": true, "requirement": "^0.3.0", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["aes-kw@0.3.1"], "reference_lines": 8, "references": ["crates/perry-stdlib/src/crypto/cipher.rs:916", "crates/perry-stdlib/src/crypto/cipher.rs:926", "crates/perry-stdlib/src/crypto/cipher.rs:936", "crates/perry-stdlib/src/crypto/cipher.rs:1048", "crates/perry-stdlib/src/crypto/cipher.rs:1058", "crates/perry-stdlib/src/crypto/cipher.rs:1068"]}], "lock_closure_packages": 79, "lock_packages_lost_if_all_workspace_edges_removed": ["aes-kw@0.3.1"]}, +{"name": "ahash", "versions": ["0.8.12"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "ahash", "kind": "normal", "target": null, "optional": false, "requirement": "^0.8.12", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["ahash@0.8.12"], "reference_lines": 3, "references": ["crates/perry-runtime/src/json/parser.rs:40", "crates/perry-runtime/src/json/parser.rs:48", "crates/perry-runtime/src/json/parser_scan_tests.rs:268"]}], "lock_closure_packages": 38, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "aho-corasick", "versions": ["1.1.4"], "edges": [{"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "aho_corasick", "kind": "normal", "target": null, "optional": false, "requirement": "^1.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["aho-corasick@1.1.4"], "reference_lines": 1, "references": ["crates/perry-codegen/src/codegen/retained_source_pool.rs:5"]}], "lock_closure_packages": 2, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "anyhow", "versions": ["1.0.104"], "edges": [{"owner": "perry-codegen-arkts", "manifest": "crates/perry-codegen-arkts/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 1, "references": ["crates/perry-codegen-arkts/src/lib.rs:49"]}, {"owner": "perry-codegen-glance", "manifest": "crates/perry-codegen-glance/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 1, "references": ["crates/perry-codegen-glance/src/lib.rs:9"]}, {"owner": "perry-codegen-js", "manifest": "crates/perry-codegen-js/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 1, "references": ["crates/perry-codegen-js/src/lib.rs:11"]}, {"owner": "perry-codegen-swiftui", "manifest": "crates/perry-codegen-swiftui/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 1, "references": ["crates/perry-codegen-swiftui/src/lib.rs:9"]}, {"owner": "perry-codegen-wasm", "manifest": "crates/perry-codegen-wasm/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 1, "references": ["crates/perry-codegen-wasm/src/lib.rs:11"]}, {"owner": "perry-codegen-wear-tiles", "manifest": "crates/perry-codegen-wear-tiles/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 1, "references": ["crates/perry-codegen-wear-tiles/src/lib.rs:9"]}, {"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 368, "references": ["crates/perry-codegen/src/codegen/artifacts.rs:8", "crates/perry-codegen/src/codegen/closure.rs:6", "crates/perry-codegen/src/codegen/closure.rs:117", "crates/perry-codegen/src/codegen/closure.rs:285", "crates/perry-codegen/src/codegen/closure.rs:296", "crates/perry-codegen/src/codegen/closure.rs:336"]}, {"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 0, "references": []}, {"owner": "perry-container-e2e", "manifest": "crates/perry-container-e2e/Cargo.toml", "alias": "anyhow", "kind": "dev", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 0, "references": []}, {"owner": "perry-doc-tests", "manifest": "crates/perry-doc-tests/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 10, "references": ["crates/perry-doc-tests/src/image_diff.rs:10", "crates/perry-doc-tests/src/image_diff.rs:49", "crates/perry-doc-tests/src/image_diff.rs:138", "crates/perry-doc-tests/src/lint.rs:9", "crates/perry-doc-tests/src/main.rs:12", "crates/perry-doc-tests/src/main.rs:151"]}, {"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 7, "references": ["crates/perry-ext-typescript/src/bun.rs:14", "crates/perry-ext-typescript/src/bun.rs:941", "crates/perry-ext-typescript/src/bun.rs:957", "crates/perry-ext-typescript/src/bun.rs:970", "crates/perry-ext-typescript/src/bun.rs:989", "crates/perry-ext-typescript/src/bun.rs:1023"]}, {"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 167, "references": ["crates/perry-hir/examples/solid_jsx.rs:6", "crates/perry-hir/examples/solid_jsx.rs:8", "crates/perry-hir/examples/solid_jsx.rs:19", "crates/perry-hir/src/destructuring/assignment_expr.rs:47", "crates/perry-hir/src/destructuring/assignment_expr.rs:98", "crates/perry-hir/src/destructuring/assignment_expr.rs:197"]}, {"owner": "perry-parser", "manifest": "crates/perry-parser/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 4, "references": ["crates/perry-parser/src/defines.rs:5", "crates/perry-parser/src/lib.rs:6", "crates/perry-parser/src/lib.rs:77", "crates/perry-parser/src/lib.rs:118"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 0, "references": []}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 0, "references": []}, {"owner": "perry-transform", "manifest": "crates/perry-transform/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 0, "references": []}, {"owner": "perry-updater", "manifest": "crates/perry-updater/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 3, "references": ["crates/perry-updater/src/cli_manifest.rs:3", "crates/perry-updater/src/cli_manifest.rs:163", "crates/perry-updater/src/cli_manifest.rs:172"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "anyhow", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["anyhow@1.0.104"], "reference_lines": 551, "references": ["crates/perry/src/commands/appstore.rs:3", "crates/perry/src/commands/attest.rs:33", "crates/perry/src/commands/audit.rs:3", "crates/perry/src/commands/audit.rs:485", "crates/perry/src/commands/cache.rs:14", "crates/perry/src/commands/cache.rs:62"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "argon2", "versions": ["0.5.3"], "edges": [{"owner": "perry-ext-argon2", "manifest": "crates/perry-ext-argon2/Cargo.toml", "alias": "argon2", "kind": "normal", "target": null, "optional": false, "requirement": "^0.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["argon2@0.5.3"], "reference_lines": 1, "references": ["crates/perry-ext-argon2/src/lib.rs:6"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "argon2", "kind": "normal", "target": null, "optional": true, "requirement": "^0.5", "default_features": true, "features": [], "direct_feature_activators": ["bundled-argon2"], "resolved": ["argon2@0.5.3"], "reference_lines": 12, "references": ["crates/perry-stdlib/src/argon2.rs:8", "crates/perry-stdlib/src/crypto/kdf.rs:285", "crates/perry-stdlib/src/lib.rs:337", "crates/perry-stdlib/src/lib.rs:339", "crates/perry-stdlib/src/webcrypto/hmac.rs:621", "crates/perry-stdlib/src/webcrypto/hmac.rs:623"]}], "lock_closure_packages": 48, "lock_packages_lost_if_all_workspace_edges_removed": ["argon2@0.5.3", "blake2@0.10.6"]}, +{"name": "async-trait", "versions": ["0.1.92"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "async_trait", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["async-trait@0.1.92"], "reference_lines": 10, "references": ["crates/perry-container-compose/src/backend/cli_backend.rs:7", "crates/perry-container-compose/src/backend.rs:6", "crates/perry-container-compose/src/commands/build.rs:5", "crates/perry-container-compose/src/commands/inspect.rs:6", "crates/perry-container-compose/src/commands/mod.rs:5", "crates/perry-container-compose/src/commands/run.rs:5"]}], "lock_closure_packages": 5, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "atty", "versions": ["0.2.14"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "atty", "kind": "normal", "target": null, "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["atty@0.2.14"], "reference_lines": 0, "references": []}], "lock_closure_packages": 6, "lock_packages_lost_if_all_workspace_edges_removed": ["atty@0.2.14", "hermit-abi@0.1.19"]}, +{"name": "base64", "versions": ["0.22.1", "0.23.1"], "edges": [{"owner": "perry-codegen-wasm", "manifest": "crates/perry-codegen-wasm/Cargo.toml", "alias": "base64", "kind": "normal", "target": null, "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 1, "references": ["crates/perry-codegen-wasm/src/lib.rs:12"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "base64", "kind": "normal", "target": null, "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 6, "references": ["crates/perry-ext-http/src/client_surface.rs:4", "crates/perry-ext-http/src/client_surface.rs:266", "crates/perry-ext-http/src/client_surface.rs:267", "crates/perry-ext-http/src/request_headers.rs:11", "crates/perry-ext-http/src/tls_client.rs:1050", "crates/perry-ext-http/src/tls_client.rs:1055"]}, {"owner": "perry-ext-jsonwebtoken", "manifest": "crates/perry-ext-jsonwebtoken/Cargo.toml", "alias": "base64", "kind": "normal", "target": null, "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 2, "references": ["crates/perry-ext-jsonwebtoken/src/lib.rs:230", "crates/perry-ext-jsonwebtoken/src/lib.rs:231"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "base64", "kind": "normal", "target": null, "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 13, "references": ["crates/perry-runtime/src/object/buffer_dispatch.rs:7", "crates/perry-runtime/src/object/buffer_dispatch.rs:279", "crates/perry-runtime/src/process/node_module/source_map.rs:3", "crates/perry-runtime/src/process/node_module/source_map.rs:749", "crates/perry-runtime/src/process/node_module/source_map.rs:750", "crates/perry-runtime/src/process/node_module/source_map.rs:759"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "base64", "kind": "normal", "target": null, "optional": true, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": ["crypto", "external-tls-server", "tls-runtime"], "resolved": ["base64@0.22.1"], "reference_lines": 61, "references": ["crates/perry-stdlib/src/crypto/certificate.rs:63", "crates/perry-stdlib/src/crypto/certificate.rs:142", "crates/perry-stdlib/src/crypto/hash_handles.rs:185", "crates/perry-stdlib/src/crypto/hash_handles.rs:186", "crates/perry-stdlib/src/crypto/hash_handles.rs:499", "crates/perry-stdlib/src/crypto/hash_handles.rs:500"]}, {"owner": "perry-ui-android", "manifest": "crates/perry-ui-android/Cargo.toml", "alias": "base64", "kind": "normal", "target": "cfg(target_os = \"android\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 2, "references": ["crates/perry-ui-android/src/ffi/issue_553.rs:286", "crates/perry-ui-android/src/ffi/issue_553.rs:294"]}, {"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "base64", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 2, "references": ["crates/perry-ui-gtk4/src/ffi/stubs_webview_attrtext_screenshot.rs:218", "crates/perry-ui-gtk4/src/ffi/stubs_webview_attrtext_screenshot.rs:226"]}, {"owner": "perry-ui-ios", "manifest": "crates/perry-ui-ios/Cargo.toml", "alias": "base64", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 2, "references": ["crates/perry-ui-ios/src/ffi/system.rs:364", "crates/perry-ui-ios/src/ffi/system.rs:372"]}, {"owner": "perry-ui-macos", "manifest": "crates/perry-ui-macos/Cargo.toml", "alias": "base64", "kind": "normal", "target": "cfg(target_os = \"macos\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 2, "references": ["crates/perry-ui-macos/src/lib_ffi/system_aux.rs:46", "crates/perry-ui-macos/src/lib_ffi/system_aux.rs:54"]}, {"owner": "perry-ui-tvos", "manifest": "crates/perry-ui-tvos/Cargo.toml", "alias": "base64", "kind": "normal", "target": "cfg(target_os = \"tvos\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 2, "references": ["crates/perry-ui-tvos/src/ffi/media_extras.rs:298", "crates/perry-ui-tvos/src/ffi/media_extras.rs:306"]}, {"owner": "perry-ui-visionos", "manifest": "crates/perry-ui-visionos/Cargo.toml", "alias": "base64", "kind": "normal", "target": "cfg(target_os = \"visionos\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 2, "references": ["crates/perry-ui-visionos/src/ffi_misc.rs:149", "crates/perry-ui-visionos/src/ffi_misc.rs:157"]}, {"owner": "perry-ui-windows-winui", "manifest": "crates/perry-ui-windows-winui/Cargo.toml", "alias": "base64", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 0, "references": []}, {"owner": "perry-ui-windows", "manifest": "crates/perry-ui-windows/Cargo.toml", "alias": "base64", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 2, "references": ["crates/perry-ui-windows/src/ffi/system.rs:185", "crates/perry-ui-windows/src/ffi/system.rs:193"]}, {"owner": "perry-updater", "manifest": "crates/perry-updater/Cargo.toml", "alias": "base64", "kind": "normal", "target": null, "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 16, "references": ["crates/perry-updater/src/cli_manifest.rs:4", "crates/perry-updater/src/cli_manifest.rs:77", "crates/perry-updater/src/cli_manifest.rs:159", "crates/perry-updater/src/cli_manifest.rs:168", "crates/perry-updater/src/cli_manifest.rs:185", "crates/perry-updater/src/cli_manifest.rs:199"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "base64", "kind": "normal", "target": null, "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["base64@0.22.1"], "reference_lines": 59, "references": ["crates/perry/src/commands/compile/collect_modules/wasm_asset.rs:247", "crates/perry/src/commands/compile/collect_modules/wasm_asset.rs:248", "crates/perry/src/commands/publish/credentials.rs:214", "crates/perry/src/commands/publish/credentials.rs:215", "crates/perry/src/commands/publish/mod.rs:870", "crates/perry/src/commands/publish/mod.rs:873"]}], "lock_closure_packages": 2, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "bcrypt", "versions": ["0.19.3"], "edges": [{"owner": "perry-ext-bcrypt", "manifest": "crates/perry-ext-bcrypt/Cargo.toml", "alias": "bcrypt", "kind": "normal", "target": null, "optional": false, "requirement": "^0.19", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["bcrypt@0.19.3"], "reference_lines": 5, "references": ["crates/perry-ext-bcrypt/src/lib.rs:38", "crates/perry-ext-bcrypt/src/lib.rs:69", "crates/perry-ext-bcrypt/src/lib.rs:88", "crates/perry-ext-bcrypt/src/lib.rs:114", "crates/perry-ext-bcrypt/src/lib.rs:141"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "bcrypt", "kind": "normal", "target": null, "optional": true, "requirement": "^0.19", "default_features": true, "features": [], "direct_feature_activators": ["bundled-bcrypt"], "resolved": ["bcrypt@0.19.3"], "reference_lines": 7, "references": ["crates/perry-stdlib/src/bcrypt.rs:36", "crates/perry-stdlib/src/bcrypt.rs:109", "crates/perry-stdlib/src/bcrypt.rs:155", "crates/perry-stdlib/src/bcrypt.rs:226", "crates/perry-stdlib/src/bcrypt.rs:277", "crates/perry-stdlib/src/lib.rs:332"]}], "lock_closure_packages": 78, "lock_packages_lost_if_all_workspace_edges_removed": ["bcrypt@0.19.3", "blowfish@0.10.0"]}, +{"name": "block2", "versions": ["0.6.2"], "edges": [{"owner": "perry-ext-ads", "manifest": "crates/perry-ext-ads/Cargo.toml", "alias": "block2", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": true, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": ["google-ads"], "resolved": [], "reference_lines": 1, "references": ["crates/perry-ext-ads/src/ios_real.rs:38"]}, {"owner": "perry-ui-ios", "manifest": "crates/perry-ui-ios/Cargo.toml", "alias": "block2", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["block2@0.6.2"], "reference_lines": 24, "references": ["crates/perry-ui-ios/src/app.rs:1109", "crates/perry-ui-ios/src/audio.rs:163", "crates/perry-ui-ios/src/audio.rs:200", "crates/perry-ui-ios/src/audio_playback.rs:605", "crates/perry-ui-ios/src/audio_playback.rs:606", "crates/perry-ui-ios/src/background.rs:46"]}, {"owner": "perry-ui-macos", "manifest": "crates/perry-ui-macos/Cargo.toml", "alias": "block2", "kind": "normal", "target": "cfg(target_os = \"macos\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["block2@0.6.2"], "reference_lines": 19, "references": ["crates/perry-ui-macos/src/app.rs:1093", "crates/perry-ui-macos/src/app.rs:1126", "crates/perry-ui-macos/src/app.rs:1777", "crates/perry-ui-macos/src/audio.rs:196", "crates/perry-ui-macos/src/audio_playback.rs:602", "crates/perry-ui-macos/src/audio_playback.rs:603"]}, {"owner": "perry-ui-tvos", "manifest": "crates/perry-ui-tvos/Cargo.toml", "alias": "block2", "kind": "normal", "target": "cfg(target_os = \"tvos\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["block2@0.6.2"], "reference_lines": 12, "references": ["crates/perry-ui-tvos/src/app.rs:703", "crates/perry-ui-tvos/src/audio.rs:163", "crates/perry-ui-tvos/src/audio.rs:200", "crates/perry-ui-tvos/src/audio_playback.rs:605", "crates/perry-ui-tvos/src/audio_playback.rs:606", "crates/perry-ui-tvos/src/background.rs:37"]}, {"owner": "perry-ui-visionos", "manifest": "crates/perry-ui-visionos/Cargo.toml", "alias": "block2", "kind": "normal", "target": "cfg(target_os = \"visionos\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["block2@0.6.2"], "reference_lines": 20, "references": ["crates/perry-ui-visionos/src/app.rs:513", "crates/perry-ui-visionos/src/audio.rs:163", "crates/perry-ui-visionos/src/audio.rs:200", "crates/perry-ui-visionos/src/audio_playback.rs:605", "crates/perry-ui-visionos/src/audio_playback.rs:606", "crates/perry-ui-visionos/src/background.rs:38"]}, {"owner": "perry-ui-watchos", "manifest": "crates/perry-ui-watchos/Cargo.toml", "alias": "block2", "kind": "normal", "target": "cfg(target_os = \"watchos\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["block2@0.6.2"], "reference_lines": 7, "references": ["crates/perry-ui-watchos/src/audio.rs:77", "crates/perry-ui-watchos/src/audio.rs:84", "crates/perry-ui-watchos/src/audio.rs:118", "crates/perry-ui-watchos/src/audio_playback.rs:605", "crates/perry-ui-watchos/src/audio_playback.rs:606", "crates/perry-ui-watchos/src/background.rs:119"]}], "lock_closure_packages": 3, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "brotli", "versions": ["8.0.4"], "edges": [{"owner": "perry-ext-zlib", "manifest": "crates/perry-ext-zlib/Cargo.toml", "alias": "brotli", "kind": "normal", "target": null, "optional": false, "requirement": "^8.0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["brotli@8.0.4"], "reference_lines": 6, "references": ["crates/perry-ext-zlib/src/stream.rs:110", "crates/perry-ext-zlib/src/stream.rs:117", "crates/perry-ext-zlib/src/stream.rs:366", "crates/perry-ext-zlib/src/stream.rs:367", "crates/perry-ext-zlib/src/stream.rs:463", "crates/perry-ext-zlib/src/stream.rs:466"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "brotli", "kind": "normal", "target": null, "optional": true, "requirement": "^8.0.2", "default_features": true, "features": [], "direct_feature_activators": ["bundled-streams", "compression-brotli"], "resolved": ["brotli@8.0.4"], "reference_lines": 8, "references": ["crates/perry-stdlib/src/streams/transform.rs:995", "crates/perry-stdlib/src/streams/transform.rs:999", "crates/perry-stdlib/src/zlib.rs:509", "crates/perry-stdlib/src/zlib.rs:517", "crates/perry-stdlib/src/zlib.rs:962", "crates/perry-stdlib/src/zlib.rs:964"]}], "lock_closure_packages": 4, "lock_packages_lost_if_all_workspace_edges_removed": ["brotli@8.0.4"]}, +{"name": "bson", "versions": ["3.1.0"], "edges": [{"owner": "perry-ext-mongodb", "manifest": "crates/perry-ext-mongodb/Cargo.toml", "alias": "bson", "kind": "normal", "target": null, "optional": false, "requirement": "^3.1", "default_features": true, "features": ["serde"], "direct_feature_activators": [], "resolved": ["bson@3.1.0"], "reference_lines": 1, "references": ["crates/perry-ext-mongodb/src/lib.rs:36"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "bson", "kind": "normal", "target": null, "optional": true, "requirement": "^3.1", "default_features": true, "features": ["serde"], "direct_feature_activators": ["bundled-mongodb"], "resolved": ["bson@3.1.0"], "reference_lines": 10, "references": ["crates/perry-stdlib/src/mongodb.rs:10", "crates/perry-stdlib/src/mongodb.rs:154", "crates/perry-stdlib/src/mongodb.rs:155", "crates/perry-stdlib/src/mongodb.rs:156", "crates/perry-stdlib/src/mongodb.rs:157", "crates/perry-stdlib/src/mongodb.rs:158"]}], "lock_closure_packages": 108, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "bytes", "versions": ["1.12.1"], "edges": [{"owner": "perry-ext-fastify", "manifest": "crates/perry-ext-fastify/Cargo.toml", "alias": "bytes", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["bytes@1.12.1"], "reference_lines": 9, "references": ["crates/perry-ext-fastify/src/context.rs:667", "crates/perry-ext-fastify/src/context.rs:678", "crates/perry-ext-fastify/src/lib.rs:849", "crates/perry-ext-fastify/src/lib.rs:850", "crates/perry-ext-fastify/src/lib.rs:881", "crates/perry-ext-fastify/src/lib.rs:884"]}, {"owner": "perry-ext-fetch", "manifest": "crates/perry-ext-fetch/Cargo.toml", "alias": "bytes", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["bytes@1.12.1"], "reference_lines": 1, "references": ["crates/perry-ext-fetch/src/lib.rs:11"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "bytes", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["bytes@1.12.1"], "reference_lines": 20, "references": ["crates/perry-ext-http/src/client_dispatch.rs:173", "crates/perry-ext-http/src/continue_client.rs:21", "crates/perry-ext-http/src/lib.rs:108", "crates/perry-ext-http/src/server/http2_server/pump.rs:10", "crates/perry-ext-http/src/server/http2_server/session.rs:11", "crates/perry-ext-http/src/server/http2_server.rs:22"]}, {"owner": "perry-ext-net", "manifest": "crates/perry-ext-net/Cargo.toml", "alias": "bytes", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["bytes@1.12.1"], "reference_lines": 14, "references": ["crates/perry-ext-net/src/buffer_pool.rs:65", "crates/perry-ext-net/src/buffer_pool.rs:142", "crates/perry-ext-net/src/bun_tcp.rs:15", "crates/perry-ext-net/src/jsvalue.rs:391", "crates/perry-ext-net/src/lib.rs:26", "crates/perry-ext-net/src/lib.rs:1247"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "bytes", "kind": "normal", "target": null, "optional": true, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": ["http-server"], "resolved": ["bytes@1.12.1"], "reference_lines": 28, "references": ["crates/perry-stdlib/src/crypto/certificate.rs:69", "crates/perry-stdlib/src/crypto/certificate.rs:74", "crates/perry-stdlib/src/crypto/certificate.rs:78", "crates/perry-stdlib/src/crypto/certificate.rs:82", "crates/perry-stdlib/src/crypto/certificate.rs:85", "crates/perry-stdlib/src/crypto/certificate.rs:90"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "cairo-rs", "versions": ["0.20.12", "0.22.9"], "edges": [{"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "cairo", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["cairo-rs@0.22.9"], "reference_lines": 7, "references": ["crates/perry-ui-gtk4/src/widgets/canvas.rs:207", "crates/perry-ui-gtk4/src/widgets/canvas.rs:208", "crates/perry-ui-gtk4/src/widgets/canvas.rs:249", "crates/perry-ui-gtk4/src/widgets/canvas.rs:252", "crates/perry-ui-gtk4/src/widgets/chart.rs:11", "crates/perry-ui-gtk4/src/widgets/chart.rs:202"]}], "lock_closure_packages": 67, "lock_packages_lost_if_all_workspace_edges_removed": ["cairo-rs@0.22.9", "cairo-sys-rs@0.22.0"]}, +{"name": "cbc", "versions": ["0.1.2", "0.2.1"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "cbc", "kind": "normal", "target": null, "optional": true, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["cbc@0.2.1"], "reference_lines": 2, "references": ["crates/perry-stdlib/src/crypto/util.rs:7", "crates/perry-stdlib/src/webcrypto/util.rs:12"]}], "lock_closure_packages": 85, "lock_packages_lost_if_all_workspace_edges_removed": ["cbc@0.2.1"]}, +{"name": "cc", "versions": ["1.4.4"], "edges": [{"owner": "perry-audio-miniaudio", "manifest": "crates/perry-audio-miniaudio/Cargo.toml", "alias": "cc", "kind": "build", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["cc@1.4.4"], "reference_lines": 1, "references": ["crates/perry-audio-miniaudio/build.rs:18"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "cc", "kind": "build", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["cc@1.4.4"], "reference_lines": 8, "references": ["crates/perry-runtime/build.rs:544", "crates/perry-runtime/build.rs:561", "crates/perry-runtime/src/thread.rs:1093", "crates/perry-runtime/src/thread.rs:1158", "crates/perry-runtime/src/thread.rs:1355", "crates/perry-runtime/src/thread.rs:1405"]}], "lock_closure_packages": 38, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "chacha20poly1305", "versions": ["0.10.1"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "chacha20poly1305", "kind": "normal", "target": null, "optional": true, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["chacha20poly1305@0.10.1"], "reference_lines": 4, "references": ["crates/perry-stdlib/src/webcrypto/aes.rs:155", "crates/perry-stdlib/src/webcrypto/aes.rs:156", "crates/perry-stdlib/src/webcrypto/aes.rs:179", "crates/perry-stdlib/src/webcrypto/aes.rs:180"]}], "lock_closure_packages": 50, "lock_packages_lost_if_all_workspace_edges_removed": ["chacha20@0.9.1", "chacha20poly1305@0.10.1", "poly1305@0.8.0"]}, +{"name": "chrono", "versions": ["0.4.45"], "edges": [{"owner": "perry-ext-cron", "manifest": "crates/perry-ext-cron/Cargo.toml", "alias": "chrono", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["chrono@0.4.45"], "reference_lines": 3, "references": ["crates/perry-ext-cron/src/lib.rs:22", "crates/perry-ext-cron/src/lib.rs:374", "crates/perry-ext-cron/src/lib.rs:386"]}, {"owner": "perry-ext-dayjs", "manifest": "crates/perry-ext-dayjs/Cargo.toml", "alias": "chrono", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["chrono@0.4.45"], "reference_lines": 1, "references": ["crates/perry-ext-dayjs/src/lib.rs:5"]}, {"owner": "perry-ext-moment", "manifest": "crates/perry-ext-moment/Cargo.toml", "alias": "chrono", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["chrono@0.4.45"], "reference_lines": 6, "references": ["crates/perry-ext-moment/src/lib.rs:10", "crates/perry-ext-moment/src/lib.rs:99", "crates/perry-ext-moment/src/lib.rs:201", "crates/perry-ext-moment/src/lib.rs:370", "crates/perry-ext-moment/src/lib.rs:372", "crates/perry-ext-moment/src/lib.rs:376"]}, {"owner": "perry-ext-mysql2", "manifest": "crates/perry-ext-mysql2/Cargo.toml", "alias": "chrono", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["chrono@0.4.45"], "reference_lines": 6, "references": ["crates/perry-ext-mysql2/src/lib.rs:306", "crates/perry-ext-mysql2/src/lib.rs:310", "crates/perry-ext-mysql2/src/lib.rs:314", "crates/perry-ext-mysql2/src/lib.rs:579", "crates/perry-ext-mysql2/src/lib.rs:675", "crates/perry-ext-mysql2/src/lib.rs:1769"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "chrono", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": ["serde"], "direct_feature_activators": [], "resolved": ["chrono@0.4.45"], "reference_lines": 42, "references": ["crates/perry-stdlib/src/cron.rs:96", "crates/perry-stdlib/src/cron.rs:453", "crates/perry-stdlib/src/cron.rs:473", "crates/perry-stdlib/src/crypto/x509.rs:552", "crates/perry-stdlib/src/crypto/x509.rs:557", "crates/perry-stdlib/src/crypto/x509.rs:561"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "chrono", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["chrono@0.4.45"], "reference_lines": 3, "references": ["crates/perry/src/commands/install/scanner/mod.rs:202", "crates/perry/src/commands/native/init.rs:199", "crates/perry/src/commands/native/init.rs:200"]}], "lock_closure_packages": 53, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "clap", "versions": ["4.6.6"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "clap", "kind": "normal", "target": null, "optional": false, "requirement": "^4.5", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["clap@4.6.6"], "reference_lines": 2, "references": ["crates/perry-container-compose/src/cli.rs:5", "crates/perry-container-compose/src/main.rs:3"]}, {"owner": "perry-doc-tests", "manifest": "crates/perry-doc-tests/Cargo.toml", "alias": "clap", "kind": "normal", "target": null, "optional": false, "requirement": "^4.5", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["clap@4.6.6"], "reference_lines": 1, "references": ["crates/perry-doc-tests/src/main.rs:13"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "clap", "kind": "normal", "target": null, "optional": false, "requirement": "^4.4", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["clap@4.6.6"], "reference_lines": 0, "references": []}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "clap", "kind": "normal", "target": null, "optional": false, "requirement": "^4.5", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["clap@4.6.6"], "reference_lines": 37, "references": ["crates/perry/src/commands/appstore.rs:4", "crates/perry/src/commands/audit.rs:4", "crates/perry/src/commands/cache.rs:15", "crates/perry/src/commands/check.rs:4", "crates/perry/src/commands/compile/tiny_program/mod.rs:298", "crates/perry/src/commands/compile/types.rs:9"]}], "lock_closure_packages": 21, "lock_packages_lost_if_all_workspace_edges_removed": ["anstream@1.0.0", "anstyle-parse@1.0.0", "anstyle-query@1.1.5", "anstyle-wincon@3.0.11", "anstyle@1.0.14", "clap@4.6.6", "clap_builder@4.6.6", "clap_derive@4.6.4", "clap_lex@1.1.0", "colorchoice@1.0.5", "is_terminal_polyfill@1.70.2", "once_cell_polyfill@1.70.2", "utf8parse@0.2.2"]}, +{"name": "console", "versions": ["0.15.11", "0.16.4"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "console", "kind": "normal", "target": null, "optional": false, "requirement": "^0.16", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["console@0.16.4"], "reference_lines": 1, "references": ["crates/perry-container-compose/src/installer.rs:5"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "console", "kind": "normal", "target": null, "optional": false, "requirement": "^0.16", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["console@0.16.4"], "reference_lines": 43, "references": ["crates/perry/src/commands/audit.rs:5", "crates/perry/src/commands/audit.rs:247", "crates/perry/src/commands/audit.rs:257", "crates/perry/src/commands/check.rs:404", "crates/perry/src/commands/check.rs:415", "crates/perry/src/commands/check.rs:425"]}], "lock_closure_packages": 20, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "const-oid", "versions": ["0.10.2", "0.9.6"], "edges": [{"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "const_oid", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["const-oid@0.10.2"], "reference_lines": 4, "references": ["crates/perry-ext-node-forge/src/crypto.rs:19", "crates/perry-ext-node-forge/src/crypto.rs:361", "crates/perry-ext-node-forge/src/crypto.rs:375", "crates/perry-ext-node-forge/src/crypto.rs:507"]}], "lock_closure_packages": 2, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "cron", "versions": ["0.17.0"], "edges": [{"owner": "perry-ext-cron", "manifest": "crates/perry-ext-cron/Cargo.toml", "alias": "cron", "kind": "normal", "target": null, "optional": false, "requirement": "^0.17", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["cron@0.17.0"], "reference_lines": 1, "references": ["crates/perry-ext-cron/src/lib.rs:23"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "cron", "kind": "normal", "target": null, "optional": true, "requirement": "^0.17", "default_features": true, "features": [], "direct_feature_activators": ["bundled-cron"], "resolved": ["cron@0.17.0"], "reference_lines": 3, "references": ["crates/perry-stdlib/src/cron.rs:28", "crates/perry-stdlib/src/lib.rs:385", "crates/perry-stdlib/src/lib.rs:387"]}], "lock_closure_packages": 68, "lock_packages_lost_if_all_workspace_edges_removed": ["cron@0.17.0", "winnow@0.7.15"]}, +{"name": "ctr", "versions": ["0.9.2"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "ctr", "kind": "normal", "target": null, "optional": true, "requirement": "^0.9", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["ctr@0.9.2"], "reference_lines": 4, "references": ["crates/perry-stdlib/src/crypto/cipher.rs:96", "crates/perry-stdlib/src/crypto/cipher.rs:97", "crates/perry-stdlib/src/crypto/cipher.rs:98", "crates/perry-stdlib/src/webcrypto/aes.rs:622"]}], "lock_closure_packages": 43, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "dashmap", "versions": ["5.5.3", "6.2.1"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "dashmap", "kind": "normal", "target": null, "optional": false, "requirement": "^6.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dashmap@6.2.1"], "reference_lines": 0, "references": []}, {"owner": "perry-ffi", "manifest": "crates/perry-ffi/Cargo.toml", "alias": "dashmap", "kind": "normal", "target": null, "optional": false, "requirement": "^6.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dashmap@6.2.1"], "reference_lines": 1, "references": ["crates/perry-ffi/src/handle.rs:75"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "dashmap", "kind": "normal", "target": null, "optional": false, "requirement": "^6.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dashmap@6.2.1"], "reference_lines": 3, "references": ["crates/perry-stdlib/src/common/handle.rs:10", "crates/perry-stdlib/src/container/types.rs:4", "crates/perry-stdlib/src/framework/server.rs:349"]}], "lock_closure_packages": 49, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "der", "versions": ["0.7.10", "0.8.1"], "edges": [{"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "der", "kind": "normal", "target": null, "optional": false, "requirement": "^0.8", "default_features": true, "features": ["oid"], "direct_feature_activators": [], "resolved": ["der@0.8.1"], "reference_lines": 11, "references": ["crates/perry-ext-node-forge/src/crypto.rs:20", "crates/perry-ext-node-forge/src/crypto.rs:21", "crates/perry-ext-node-forge/src/crypto.rs:22", "crates/perry-ext-node-forge/src/crypto.rs:236", "crates/perry-ext-node-forge/src/crypto.rs:239", "crates/perry-ext-node-forge/src/crypto.rs:260"]}], "lock_closure_packages": 15, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "dialoguer", "versions": ["0.11.0", "0.12.0"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "dialoguer", "kind": "normal", "target": null, "optional": false, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dialoguer@0.11.0"], "reference_lines": 1, "references": ["crates/perry-container-compose/src/installer.rs:6"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "dialoguer", "kind": "normal", "target": null, "optional": false, "requirement": "^0.12", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dialoguer@0.12.0"], "reference_lines": 16, "references": ["crates/perry/src/commands/publish/mod.rs:6", "crates/perry/src/commands/publish/mod.rs:680", "crates/perry/src/commands/run/devices.rs:293", "crates/perry/src/commands/setup/android.rs:3", "crates/perry/src/commands/setup/common_apple.rs:2", "crates/perry/src/commands/setup/harmonyos.rs:3"]}], "lock_closure_packages": 91, "lock_packages_lost_if_all_workspace_edges_removed": ["console@0.15.11", "dialoguer@0.11.0", "dialoguer@0.12.0", "shell-words@1.1.1"]}, +{"name": "dirs", "versions": ["6.0.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "dirs", "kind": "normal", "target": null, "optional": true, "requirement": "^6", "default_features": true, "features": [], "direct_feature_activators": ["full"], "resolved": ["dirs@6.0.0"], "reference_lines": 2, "references": ["crates/perry-runtime/src/os.rs:169", "crates/perry-runtime/src/update_notify.rs:527"]}, {"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "dirs", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dirs@6.0.0"], "reference_lines": 2, "references": ["crates/perry-ui-gtk4/src/widgets/webview.rs:90", "crates/perry-ui-gtk4/src/widgets/webview.rs:92"]}, {"owner": "perry-ui", "manifest": "crates/perry-ui/Cargo.toml", "alias": "dirs", "kind": "normal", "target": "cfg(any(target_os = \"macos\", target_os = \"windows\", target_os = \"linux\"))", "optional": false, "requirement": "^6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dirs@6.0.0"], "reference_lines": 1, "references": ["crates/perry-ui/src/frame.rs:87"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "dirs", "kind": "normal", "target": null, "optional": false, "requirement": "^6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dirs@6.0.0"], "reference_lines": 22, "references": ["crates/perry/src/commands/compile/compressed_libs.rs:118", "crates/perry/src/commands/compile/library_search/llvm_tool_discovery_tests.rs:19", "crates/perry/src/commands/compile/library_search/llvm_tool_discovery_tests.rs:38", "crates/perry/src/commands/compile/library_search.rs:535", "crates/perry/src/commands/compile/resolve/tests.rs:1969", "crates/perry/src/commands/compile/resolve.rs:397"]}], "lock_closure_packages": 41, "lock_packages_lost_if_all_workspace_edges_removed": ["dirs-sys@0.5.0", "dirs@6.0.0", "libredox@0.1.17", "option-ext@0.2.0", "redox_users@0.5.2"]}, +{"name": "dotenvy", "versions": ["0.15.7"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "dotenvy", "kind": "normal", "target": null, "optional": false, "requirement": "^0.15", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dotenvy@0.15.7"], "reference_lines": 0, "references": []}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "dotenvy", "kind": "normal", "target": null, "optional": false, "requirement": "^0.15", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dotenvy@0.15.7"], "reference_lines": 1, "references": ["crates/perry/src/commands/publish/mod.rs:90"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "dssim-core", "versions": ["3.5.1"], "edges": [{"owner": "perry-doc-tests", "manifest": "crates/perry-doc-tests/Cargo.toml", "alias": "dssim_core", "kind": "normal", "target": null, "optional": false, "requirement": "^3.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["dssim-core@3.5.1"], "reference_lines": 3, "references": ["crates/perry-doc-tests/src/image_diff.rs:61", "crates/perry-doc-tests/src/image_diff.rs:124", "crates/perry-doc-tests/src/image_diff.rs:125"]}], "lock_closure_packages": 18, "lock_packages_lost_if_all_workspace_edges_removed": ["dssim-core@3.5.1"]}, +{"name": "ecb", "versions": ["0.1.2", "0.2.1"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "ecb", "kind": "normal", "target": null, "optional": true, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["ecb@0.2.1"], "reference_lines": 7, "references": ["crates/perry-stdlib/src/crypto/cipher.rs:64", "crates/perry-stdlib/src/crypto/cipher.rs:65", "crates/perry-stdlib/src/crypto/cipher.rs:66", "crates/perry-stdlib/src/crypto/cipher.rs:67", "crates/perry-stdlib/src/crypto/cipher.rs:68", "crates/perry-stdlib/src/crypto/cipher.rs:69"]}], "lock_closure_packages": 85, "lock_packages_lost_if_all_workspace_edges_removed": ["ecb@0.2.1"]}, +{"name": "ed25519-dalek", "versions": ["2.2.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "ed25519_dalek", "kind": "normal", "target": null, "optional": true, "requirement": "^2.1", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["ed25519-dalek@2.2.0"], "reference_lines": 22, "references": ["crates/perry-stdlib/src/crypto/hash.rs:51", "crates/perry-stdlib/src/crypto/sign.rs:76", "crates/perry-stdlib/src/crypto/sign.rs:145", "crates/perry-stdlib/src/crypto/sign.rs:146", "crates/perry-stdlib/src/crypto/sign.rs:528", "crates/perry-stdlib/src/crypto/util.rs:189"]}, {"owner": "perry-updater", "manifest": "crates/perry-updater/Cargo.toml", "alias": "ed25519_dalek", "kind": "normal", "target": null, "optional": false, "requirement": "^2.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["ed25519-dalek@2.2.0"], "reference_lines": 5, "references": ["crates/perry-updater/src/cli_manifest.rs:5", "crates/perry-updater/src/cli_manifest.rs:75", "crates/perry-updater/src/cli_manifest.rs:180", "crates/perry-updater/src/core.rs:24", "crates/perry-updater/src/core.rs:449"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "ed25519_dalek", "kind": "normal", "target": null, "optional": true, "requirement": "^2.1", "default_features": true, "features": ["rand_core"], "direct_feature_activators": ["updater-cli"], "resolved": ["ed25519-dalek@2.2.0"], "reference_lines": 3, "references": ["crates/perry/src/commands/updater.rs:30", "crates/perry/src/commands/updater.rs:326", "crates/perry/src/commands/updater.rs:344"]}], "lock_closure_packages": 69, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "ed448-goldilocks", "versions": ["0.14.0-pre.15"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "ed448_goldilocks", "kind": "normal", "target": null, "optional": true, "requirement": "^0.14.0-pre.13", "default_features": false, "features": ["alloc", "signing"], "direct_feature_activators": ["crypto"], "resolved": ["ed448-goldilocks@0.14.0-pre.15"], "reference_lines": 7, "references": ["crates/perry-stdlib/src/webcrypto/hmac.rs:156", "crates/perry-stdlib/src/webcrypto/hmac.rs:385", "crates/perry-stdlib/src/webcrypto/hmac.rs:389", "crates/perry-stdlib/src/webcrypto/jwk.rs:337", "crates/perry-stdlib/src/webcrypto/jwk.rs:341", "crates/perry-stdlib/src/webcrypto/jwk.rs:929"]}], "lock_closure_packages": 100, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "encoding_rs", "versions": ["0.8.35"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "encoding_rs", "kind": "build", "target": null, "optional": false, "requirement": "^0.8", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["encoding_rs@0.8.35"], "reference_lines": 1, "references": ["crates/perry-runtime/build.rs:494"]}], "lock_closure_packages": 2, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "env_logger", "versions": ["0.10.2"], "edges": [{"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "env_logger", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["env_logger@0.10.2"], "reference_lines": 1, "references": ["crates/perry/src/main.rs:378"]}], "lock_closure_packages": 15, "lock_packages_lost_if_all_workspace_edges_removed": ["env_logger@0.10.2", "humantime@2.3.0", "is-terminal@0.4.17", "termcolor@1.4.1"]}, +{"name": "fast_image_resize", "versions": ["6.1.0"], "edges": [{"owner": "perry-ext-sharp", "manifest": "crates/perry-ext-sharp/Cargo.toml", "alias": "fast_image_resize", "kind": "normal", "target": null, "optional": false, "requirement": "^6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["fast_image_resize@6.1.0"], "reference_lines": 2, "references": ["crates/perry-ext-sharp/src/lib.rs:334", "crates/perry-ext-sharp/src/lib.rs:335"]}], "lock_closure_packages": 13, "lock_packages_lost_if_all_workspace_edges_removed": ["document-features@0.2.12", "fast_image_resize@6.1.0", "litrs@1.0.0"]}, +{"name": "flate2", "versions": ["1.1.10"], "edges": [{"owner": "perry-ext-zlib", "manifest": "crates/perry-ext-zlib/Cargo.toml", "alias": "flate2", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["flate2@1.1.10"], "reference_lines": 12, "references": ["crates/perry-ext-zlib/src/lib.rs:9", "crates/perry-ext-zlib/src/lib.rs:12", "crates/perry-ext-zlib/src/lib.rs:509", "crates/perry-ext-zlib/src/stream.rs:30", "crates/perry-ext-zlib/src/stream.rs:33", "crates/perry-ext-zlib/src/stream.rs:360"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "flate2", "kind": "normal", "target": null, "optional": true, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": ["bundled-streams", "compression-gzip"], "resolved": ["flate2@1.1.10"], "reference_lines": 11, "references": ["crates/perry-stdlib/src/streams/transform.rs:6", "crates/perry-stdlib/src/streams/transform.rs:9", "crates/perry-stdlib/src/zlib.rs:6", "crates/perry-stdlib/src/zlib.rs:9", "crates/perry-stdlib/src/zlib.rs:955", "crates/perry-stdlib/src/zlib.rs:956"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "flate2", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["flate2@1.1.10"], "reference_lines": 6, "references": ["crates/perry/src/commands/publish/mod.rs:7", "crates/perry/src/commands/publish/mod.rs:8", "crates/perry/src/commands/publish/tarball.rs:425", "crates/perry/src/commands/publish/tarball.rs:435", "crates/perry/src/update_checker.rs:991", "crates/perry/src/update_checker.rs:1789"]}], "lock_closure_packages": 7, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "fslock", "versions": ["0.2.1"], "edges": [{"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "fslock", "kind": "normal", "target": null, "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["fslock@0.2.1"], "reference_lines": 3, "references": ["crates/perry/src/commands/compile/optimized_libs/driver.rs:774", "crates/perry/src/update_checker.rs:159", "crates/perry/src/update_checker.rs:164"]}], "lock_closure_packages": 5, "lock_packages_lost_if_all_workspace_edges_removed": ["fslock@0.2.1"]}, +{"name": "futures-util", "versions": ["0.3.34"], "edges": [{"owner": "perry-ext-mongodb", "manifest": "crates/perry-ext-mongodb/Cargo.toml", "alias": "futures_util", "kind": "normal", "target": null, "optional": false, "requirement": "^0.3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["futures-util@0.3.34"], "reference_lines": 1, "references": ["crates/perry-ext-mongodb/src/lib.rs:37"]}, {"owner": "perry-ext-ws", "manifest": "crates/perry-ext-ws/Cargo.toml", "alias": "futures_util", "kind": "normal", "target": null, "optional": false, "requirement": "^0.3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["futures-util@0.3.34"], "reference_lines": 1, "references": ["crates/perry-ext-ws/src/lib.rs:42"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "futures_util", "kind": "normal", "target": null, "optional": true, "requirement": "^0.3", "default_features": true, "features": [], "direct_feature_activators": ["bundled-mongodb", "bundled-ws"], "resolved": ["futures-util@0.3.34"], "reference_lines": 2, "references": ["crates/perry-stdlib/src/mongodb.rs:341", "crates/perry-stdlib/src/ws.rs:7"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "futures_util", "kind": "normal", "target": null, "optional": false, "requirement": "^0.3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["futures-util@0.3.34"], "reference_lines": 3, "references": ["crates/perry/src/commands/publish/mod.rs:1579", "crates/perry/src/commands/publish/mod.rs:1622", "crates/perry/src/commands/run/remote.rs:19"]}], "lock_closure_packages": 13, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "ghash", "versions": ["0.5.1", "0.6.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "ghash", "kind": "normal", "target": null, "optional": true, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["ghash@0.6.0"], "reference_lines": 4, "references": ["crates/perry-stdlib/src/crypto/cipher.rs:116", "crates/perry-stdlib/src/crypto/cipher.rs:121", "crates/perry-stdlib/src/crypto/cipher.rs:122", "crates/perry-stdlib/src/crypto/cipher.rs:129"]}], "lock_closure_packages": 87, "lock_packages_lost_if_all_workspace_edges_removed": ["ghash@0.6.0", "polyval@0.7.3", "universal-hash@0.6.1"]}, +{"name": "gimli", "versions": ["0.34.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "gimli", "kind": "normal", "target": null, "optional": false, "requirement": "^0.34", "default_features": false, "features": ["read"], "direct_feature_activators": [], "resolved": ["gimli@0.34.0"], "reference_lines": 9, "references": ["crates/perry-runtime/src/eh_walker.rs:32", "crates/perry-runtime/src/eh_walker.rs:196", "crates/perry-runtime/src/eh_walker.rs:542", "crates/perry-runtime/src/eh_walker.rs:566", "crates/perry-runtime/src/eh_walker.rs:686", "crates/perry-runtime/src/eh_walker.rs:705"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": ["gimli@0.34.0"]}, +{"name": "governor", "versions": ["0.10.4"], "edges": [{"owner": "perry-ext-ratelimit", "manifest": "crates/perry-ext-ratelimit/Cargo.toml", "alias": "governor", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["governor@0.10.4"], "reference_lines": 1, "references": ["crates/perry-ext-ratelimit/src/lib.rs:20"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "governor", "kind": "normal", "target": null, "optional": true, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": ["bundled-ratelimit"], "resolved": ["governor@0.10.4"], "reference_lines": 1, "references": ["crates/perry-stdlib/src/ratelimit.rs:20"]}], "lock_closure_packages": 68, "lock_packages_lost_if_all_workspace_edges_removed": ["futures-timer@3.0.4", "governor@0.10.4", "nonzero_ext@0.3.0", "quanta@0.12.6", "raw-cpuid@11.6.0", "spinning_top@0.3.0"]}, +{"name": "gstreamer", "versions": ["0.25.3"], "edges": [{"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "gstreamer", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^0.25", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["gstreamer@0.25.3"], "reference_lines": 47, "references": ["crates/perry-ui-gtk4/src/camera.rs:25", "crates/perry-ui-gtk4/src/camera.rs:35", "crates/perry-ui-gtk4/src/camera.rs:428", "crates/perry-ui-gtk4/src/camera.rs:435", "crates/perry-ui-gtk4/src/camera.rs:437", "crates/perry-ui-gtk4/src/camera.rs:441"]}], "lock_closure_packages": 64, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "gstreamer-app", "versions": ["0.25.2"], "edges": [{"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "gstreamer_app", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^0.25", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["gstreamer-app@0.25.2"], "reference_lines": 3, "references": ["crates/perry-ui-gtk4/src/camera.rs:1", "crates/perry-ui-gtk4/src/camera.rs:462", "crates/perry-ui-gtk4/src/camera.rs:466"]}], "lock_closure_packages": 69, "lock_packages_lost_if_all_workspace_edges_removed": ["atomic_refcell@0.1.14", "gstreamer-app-sys@0.25.0", "gstreamer-app@0.25.2", "gstreamer-base-sys@0.25.0", "gstreamer-base@0.25.2"]}, +{"name": "gtk4", "versions": ["0.9.7"], "edges": [{"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "gtk4", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^0.9", "default_features": true, "features": ["v4_6"], "direct_feature_activators": [], "resolved": ["gtk4@0.9.7"], "reference_lines": 375, "references": ["crates/perry-ui-gtk4/src/app.rs:1", "crates/perry-ui-gtk4/src/app.rs:2", "crates/perry-ui-gtk4/src/app.rs:3", "crates/perry-ui-gtk4/src/app.rs:4", "crates/perry-ui-gtk4/src/app.rs:5", "crates/perry-ui-gtk4/src/app.rs:18"]}], "lock_closure_packages": 77, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "h2", "versions": ["0.4.19"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "h2", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["h2@0.4.19"], "reference_lines": 2, "references": ["crates/perry-ext-http/src/server/http2_server/session.rs:322", "crates/perry-ext-http/src/server/http2_server.rs:202"]}], "lock_closure_packages": 55, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "hex", "versions": ["0.4.3"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "hex", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["hex@0.4.3"], "reference_lines": 4, "references": ["crates/perry-container-compose/src/compose.rs:24", "crates/perry-container-compose/src/service.rs:6", "crates/perry-container-compose/src/service.rs:23", "crates/perry-container-compose/src/testing/mock_backend.rs:133"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "hex", "kind": "normal", "target": null, "optional": true, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": ["node-api-host"], "resolved": [], "reference_lines": 4, "references": ["crates/perry-runtime/build.rs:163", "crates/perry-runtime/build.rs:165", "crates/perry-runtime/src/node_api_host/loader.rs:223", "crates/perry-runtime/src/url/search_params.rs:290"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "hex", "kind": "normal", "target": null, "optional": true, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["hex@0.4.3"], "reference_lines": 37, "references": ["crates/perry-stdlib/src/crypto/cipher.rs:1243", "crates/perry-stdlib/src/crypto/cipher.rs:1244", "crates/perry-stdlib/src/crypto/cipher.rs:1245", "crates/perry-stdlib/src/crypto/cipher.rs:1261", "crates/perry-stdlib/src/crypto/ecdh.rs:267", "crates/perry-stdlib/src/crypto/hash.rs:15"]}, {"owner": "perry-updater", "manifest": "crates/perry-updater/Cargo.toml", "alias": "hex", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["hex@0.4.3"], "reference_lines": 4, "references": ["crates/perry-updater/src/cli_manifest.rs:154", "crates/perry-updater/src/cli_manifest.rs:194", "crates/perry-updater/src/core.rs:137", "crates/perry-updater/src/core.rs:517"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "hex", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["hex@0.4.3"], "reference_lines": 20, "references": ["crates/perry/src/commands/attest.rs:80", "crates/perry/src/commands/compile/build_cache.rs:973", "crates/perry/src/commands/compile/build_cache.rs:1038", "crates/perry/src/commands/compile/build_cache.rs:1151", "crates/perry/src/commands/compile/build_cache.rs:1193", "crates/perry/src/commands/compile/collect_modules/eval_worker.rs:34"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "hickory-proto", "versions": ["0.26.1"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "hickory_proto", "kind": "normal", "target": null, "optional": false, "requirement": "^0.26", "default_features": false, "features": ["std"], "direct_feature_activators": [], "resolved": ["hickory-proto@0.26.1"], "reference_lines": 3, "references": ["crates/perry-runtime/src/dns_resolver.rs:17", "crates/perry-runtime/src/dns_resolver.rs:18", "crates/perry-runtime/src/dns_resolver.rs:370"]}], "lock_closure_packages": 156, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "hkdf", "versions": ["0.12.4", "0.13.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "hkdf", "kind": "normal", "target": null, "optional": true, "requirement": "^0.13", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["hkdf@0.13.0"], "reference_lines": 7, "references": ["crates/perry-stdlib/src/crypto/kdf.rs:1107", "crates/perry-stdlib/src/crypto/util.rs:18", "crates/perry-stdlib/src/crypto_e2e.rs:11", "crates/perry-stdlib/src/webcrypto/hmac.rs:591", "crates/perry-stdlib/src/webcrypto/hmac.rs:594", "crates/perry-stdlib/src/webcrypto/hmac.rs:597"]}], "lock_closure_packages": 87, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "hmac", "versions": ["0.12.1", "0.13.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "hmac", "kind": "normal", "target": null, "optional": true, "requirement": "^0.13", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["hmac@0.13.0"], "reference_lines": 23, "references": ["crates/perry-stdlib/src/crypto/hash_handles.rs:156", "crates/perry-stdlib/src/crypto/hash_handles.rs:169", "crates/perry-stdlib/src/crypto/hash_handles.rs:629", "crates/perry-stdlib/src/crypto/hash_handles.rs:630", "crates/perry-stdlib/src/crypto/hash_handles.rs:631", "crates/perry-stdlib/src/crypto/hash_handles.rs:632"]}], "lock_closure_packages": 85, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "hostname", "versions": ["0.4.2"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "hostname", "kind": "normal", "target": null, "optional": true, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": ["full"], "resolved": ["hostname@0.4.2"], "reference_lines": 34, "references": ["crates/perry-runtime/src/dns/ffi.rs:15", "crates/perry-runtime/src/dns/ffi.rs:34", "crates/perry-runtime/src/dns/ffi.rs:66", "crates/perry-runtime/src/dns/ffi.rs:446", "crates/perry-runtime/src/dns/ffi.rs:457", "crates/perry-runtime/src/dns/ffi.rs:478"]}], "lock_closure_packages": 4, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "http-body-util", "versions": ["0.1.5"], "edges": [{"owner": "perry-ext-fastify", "manifest": "crates/perry-ext-fastify/Cargo.toml", "alias": "http_body_util", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["http-body-util@0.1.5"], "reference_lines": 1, "references": ["crates/perry-ext-fastify/src/server.rs:18"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "http_body_util", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["http-body-util@0.1.5"], "reference_lines": 4, "references": ["crates/perry-ext-http/src/server/http2_server/pump.rs:11", "crates/perry-ext-http/src/server/https_server.rs:13", "crates/perry-ext-http/src/server/response.rs:10", "crates/perry-ext-http/src/server/server.rs:16"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "http_body_util", "kind": "normal", "target": null, "optional": true, "requirement": "^0.1", "default_features": true, "features": [], "direct_feature_activators": ["http-server"], "resolved": ["http-body-util@0.1.5"], "reference_lines": 1, "references": ["crates/perry-stdlib/src/framework/server.rs:6"]}], "lock_closure_packages": 7, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "httpdate", "versions": ["1.0.3"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "httpdate", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["httpdate@1.0.3"], "reference_lines": 1, "references": ["crates/perry-ext-http/src/server/response.rs:591"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "hyper", "versions": ["1.11.1"], "edges": [{"owner": "perry-ext-fastify", "manifest": "crates/perry-ext-fastify/Cargo.toml", "alias": "hyper", "kind": "normal", "target": null, "optional": false, "requirement": "^1.4", "default_features": true, "features": ["server", "http1", "http2"], "direct_feature_activators": [], "resolved": ["hyper@1.11.1"], "reference_lines": 7, "references": ["crates/perry-ext-fastify/src/server.rs:19", "crates/perry-ext-fastify/src/server.rs:20", "crates/perry-ext-fastify/src/server.rs:21", "crates/perry-ext-fastify/src/server.rs:724", "crates/perry-ext-fastify/src/server.rs:893", "crates/perry-ext-fastify/src/server.rs:906"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "hyper", "kind": "normal", "target": null, "optional": false, "requirement": "^1.4", "default_features": true, "features": ["server", "http1", "http2"], "direct_feature_activators": [], "resolved": ["hyper@1.11.1"], "reference_lines": 37, "references": ["crates/perry-ext-http/src/server/http2_server/pump.rs:12", "crates/perry-ext-http/src/server/http2_server/pump.rs:34", "crates/perry-ext-http/src/server/http2_server/session.rs:12", "crates/perry-ext-http/src/server/http2_server/session.rs:13", "crates/perry-ext-http/src/server/http2_server.rs:23", "crates/perry-ext-http/src/server/http2_server.rs:24"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "hyper", "kind": "normal", "target": null, "optional": true, "requirement": "^1.4", "default_features": true, "features": ["server", "http1", "http2"], "direct_feature_activators": ["http-server"], "resolved": ["hyper@1.11.1"], "reference_lines": 4, "references": ["crates/perry-stdlib/src/framework/server.rs:7", "crates/perry-stdlib/src/framework/server.rs:8", "crates/perry-stdlib/src/framework/server.rs:9", "crates/perry-stdlib/src/framework/server.rs:137"]}], "lock_closure_packages": 62, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "hyper-util", "versions": ["0.1.20"], "edges": [{"owner": "perry-ext-fastify", "manifest": "crates/perry-ext-fastify/Cargo.toml", "alias": "hyper_util", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1", "default_features": true, "features": ["server", "server-auto", "tokio"], "direct_feature_activators": [], "resolved": ["hyper-util@0.1.20"], "reference_lines": 1, "references": ["crates/perry-ext-fastify/src/server.rs:22"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "hyper_util", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1", "default_features": true, "features": ["server", "server-auto", "tokio"], "direct_feature_activators": [], "resolved": ["hyper-util@0.1.20"], "reference_lines": 4, "references": ["crates/perry-ext-http/src/server/http2_server.rs:25", "crates/perry-ext-http/src/server/http2_server.rs:26", "crates/perry-ext-http/src/server/https_server.rs:17", "crates/perry-ext-http/src/server/server.rs:20"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "hyper_util", "kind": "normal", "target": null, "optional": true, "requirement": "^0.1", "default_features": true, "features": ["server", "server-auto", "tokio"], "direct_feature_activators": ["http-server"], "resolved": ["hyper-util@0.1.20"], "reference_lines": 1, "references": ["crates/perry-stdlib/src/framework/server.rs:10"]}], "lock_closure_packages": 67, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "icu_calendar", "versions": ["2.3.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "icu_calendar", "kind": "normal", "target": null, "optional": true, "requirement": "^2", "default_features": false, "features": ["compiled_data"], "direct_feature_activators": ["intl-datetime"], "resolved": ["icu_calendar@2.3.0"], "reference_lines": 0, "references": []}], "lock_closure_packages": 32, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "icu_datetime", "versions": ["2.3.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "icu_datetime", "kind": "normal", "target": null, "optional": true, "requirement": "^2", "default_features": false, "features": ["compiled_data"], "direct_feature_activators": ["intl-datetime"], "resolved": ["icu_datetime@2.3.0"], "reference_lines": 7, "references": ["crates/perry-runtime/src/intl/icu_dtf.rs:10", "crates/perry-runtime/src/intl/icu_dtf.rs:11", "crates/perry-runtime/src/intl/icu_dtf.rs:12", "crates/perry-runtime/src/intl/icu_dtf.rs:13", "crates/perry-runtime/src/intl/icu_dtf.rs:14", "crates/perry-runtime/src/intl/icu_dtf.rs:15"]}], "lock_closure_packages": 43, "lock_packages_lost_if_all_workspace_edges_removed": ["icu_datetime@2.3.0", "icu_datetime_data@2.3.0", "icu_pattern@0.5.0"]}, +{"name": "icu_decimal", "versions": ["2.3.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "icu_decimal", "kind": "normal", "target": null, "optional": true, "requirement": "^2", "default_features": false, "features": ["compiled_data"], "direct_feature_activators": ["intl-namespace"], "resolved": ["icu_decimal@2.3.0"], "reference_lines": 1, "references": ["crates/perry-runtime/src/intl/number_format.rs:513"]}], "lock_closure_packages": 33, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "icu_locale", "versions": ["2.2.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "icu_locale", "kind": "normal", "target": null, "optional": true, "requirement": "^2", "default_features": true, "features": [], "direct_feature_activators": ["intl-locale"], "resolved": ["icu_locale@2.2.0"], "reference_lines": 4, "references": ["crates/perry-runtime/src/intl/locale/likely_subtags.rs:14", "crates/perry-runtime/src/intl/locale/likely_subtags.rs:17", "crates/perry-runtime/src/intl.rs:504", "crates/perry-runtime/src/intl.rs:513"]}], "lock_closure_packages": 29, "lock_packages_lost_if_all_workspace_edges_removed": ["icu_locale@2.2.0", "icu_locale_data@2.2.0"]}, +{"name": "icu_locale_core", "versions": ["2.3.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "icu_locale_core", "kind": "normal", "target": null, "optional": true, "requirement": "^2", "default_features": true, "features": [], "direct_feature_activators": ["intl-datetime", "intl-locale", "intl-namespace"], "resolved": ["icu_locale_core@2.3.0"], "reference_lines": 2, "references": ["crates/perry-runtime/src/intl/icu_dtf.rs:17", "crates/perry-runtime/src/intl/number_format.rs:516"]}], "lock_closure_packages": 22, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "icu_provider", "versions": ["2.3.1"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "icu_provider", "kind": "normal", "target": null, "optional": true, "requirement": "^2", "default_features": false, "features": [], "direct_feature_activators": ["intl-namespace"], "resolved": ["icu_provider@2.3.1"], "reference_lines": 2, "references": ["crates/perry-runtime/src/intl/number_format.rs:514", "crates/perry-runtime/src/intl/number_format.rs:517"]}], "lock_closure_packages": 24, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "icu_time", "versions": ["2.3.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "icu_time", "kind": "normal", "target": null, "optional": true, "requirement": "^2", "default_features": false, "features": ["compiled_data"], "direct_feature_activators": ["intl-datetime"], "resolved": ["icu_time@2.3.0"], "reference_lines": 0, "references": []}], "lock_closure_packages": 34, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "idna", "versions": ["1.1.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "idna", "kind": "normal", "target": null, "optional": true, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": ["url-engine"], "resolved": ["idna@1.1.0"], "reference_lines": 3, "references": ["crates/perry-runtime/src/tls.rs:1235", "crates/perry-runtime/src/url/node_compat.rs:613", "crates/perry-runtime/src/url/url_class.rs:158"]}, {"owner": "perry-validation", "manifest": "crates/perry-validation/Cargo.toml", "alias": "idna", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["idna@1.1.0"], "reference_lines": 1, "references": ["crates/perry-validation/src/lib.rs:48"]}], "lock_closure_packages": 34, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "image", "versions": ["0.25.10"], "edges": [{"owner": "perry-doc-tests", "manifest": "crates/perry-doc-tests/Cargo.toml", "alias": "image", "kind": "normal", "target": null, "optional": false, "requirement": "^0.25", "default_features": false, "features": ["png"], "direct_feature_activators": [], "resolved": ["image@0.25.10"], "reference_lines": 12, "references": ["crates/perry-doc-tests/src/image_diff.rs:43", "crates/perry-doc-tests/src/image_diff.rs:72", "crates/perry-doc-tests/src/image_diff.rs:75", "crates/perry-doc-tests/src/image_diff.rs:88", "crates/perry-doc-tests/src/image_diff.rs:117", "crates/perry-doc-tests/src/image_diff.rs:118"]}, {"owner": "perry-ext-sharp", "manifest": "crates/perry-ext-sharp/Cargo.toml", "alias": "image", "kind": "normal", "target": null, "optional": false, "requirement": "^0.25", "default_features": true, "features": ["avif"], "direct_feature_activators": [], "resolved": ["image@0.25.10"], "reference_lines": 31, "references": ["crates/perry-ext-sharp/src/lib.rs:7", "crates/perry-ext-sharp/src/lib.rs:63", "crates/perry-ext-sharp/src/lib.rs:66", "crates/perry-ext-sharp/src/lib.rs:80", "crates/perry-ext-sharp/src/lib.rs:94", "crates/perry-ext-sharp/src/lib.rs:100"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "image", "kind": "normal", "target": null, "optional": true, "requirement": "^0.25", "default_features": true, "features": [], "direct_feature_activators": ["bundled-sharp", "full"], "resolved": ["image@0.25.10"], "reference_lines": 10, "references": ["crates/perry-stdlib/src/container/capability.rs:29", "crates/perry-stdlib/src/container/mod.rs:216", "crates/perry-stdlib/src/sharp.rs:10", "crates/perry-stdlib/src/sharp.rs:33", "crates/perry-stdlib/src/sharp.rs:56", "crates/perry-stdlib/src/sharp.rs:58"]}], "lock_closure_packages": 127, "lock_packages_lost_if_all_workspace_edges_removed": ["aligned-vec@0.6.4", "aligned@0.4.3", "arbitrary@1.4.2", "arg_enum_proc_macro@0.3.4", "as-slice@0.2.1", "av-scenechange@0.14.1", "av1-grain@0.2.5", "avif-serialize@0.8.9", "bit_field@0.10.3", "bitstream-io@4.10.0", "built@0.8.1", "byteorder-lite@0.1.0", "color_quant@1.1.0", "equator-macro@0.4.2", "equator@0.4.2", "exr@1.74.0", "fax@0.2.7", "gif@0.14.2", "half@2.7.1", "image-webp@0.2.4", "image@0.25.10", "interpolate_name@0.2.4", "itertools@0.14.0", "lebe@0.5.3", "libfuzzer-sys@0.4.12", "loop9@0.1.5", "maybe-rayon@0.1.1", "moxcms@0.8.1", "no_std_io2@0.9.4", "noop_proc_macro@0.3.0", "paste@1.0.15", "pastey@0.1.1", "profiling-procmacros@1.0.18", "profiling@1.0.18", "pxfm@0.1.29", "qoi@0.4.1", "quick-error@2.0.1", "rav1e@0.8.1", "ravif@0.13.0", "simd_helpers@0.1.0", "tiff@0.11.3", "v_frame@0.3.9", "y4m@0.8.0", "zune-core@0.5.1", "zune-inflate@0.2.54", "zune-jpeg@0.5.15"]}, +{"name": "indexmap", "versions": ["2.14.1"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "indexmap", "kind": "normal", "target": null, "optional": false, "requirement": "^2.2", "default_features": true, "features": ["serde"], "direct_feature_activators": [], "resolved": ["indexmap@2.14.1"], "reference_lines": 13, "references": ["crates/perry-container-compose/src/compose.rs:7", "crates/perry-container-compose/src/lib.rs:39", "crates/perry-container-compose/src/types.rs:7", "crates/perry-container-compose/src/workload.rs:6", "crates/perry-container-compose/tests/compose_tests.rs:1", "crates/perry-container-compose/tests/functional_orchestration.rs:16"]}], "lock_closure_packages": 12, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "indicatif", "versions": ["0.18.6"], "edges": [{"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "indicatif", "kind": "normal", "target": null, "optional": false, "requirement": "^0.18", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["indicatif@0.18.6"], "reference_lines": 3, "references": ["crates/perry/src/commands/publish/mod.rs:9", "crates/perry/src/commands/run/remote.rs:20", "crates/perry/src/update_checker.rs:7"]}], "lock_closure_packages": 38, "lock_packages_lost_if_all_workspace_edges_removed": ["indicatif@0.18.6", "unit-prefix@0.5.2"]}, +{"name": "inkwell", "versions": ["0.9.0"], "edges": [{"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "inkwell", "kind": "normal", "target": "cfg(not(windows))", "optional": true, "requirement": "^0.9.0", "default_features": false, "features": ["llvm22-1", "target-x86", "target-aarch64"], "direct_feature_activators": ["llvm-inprocess"], "resolved": ["inkwell@0.9.0"], "reference_lines": 82, "references": ["crates/perry-codegen/src/dialect/eh.rs:9", "crates/perry-codegen/src/dialect/eh.rs:10", "crates/perry-codegen/src/dialect/eh.rs:60", "crates/perry-codegen/src/dialect/eh.rs:97", "crates/perry-codegen/src/dialect/eh.rs:105", "crates/perry-codegen/src/dialect/eh.rs:180"]}, {"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "inkwell", "kind": "normal", "target": "cfg(windows)", "optional": true, "requirement": "^0.9.0", "default_features": false, "features": ["llvm22-1-no-llvm-linking", "target-x86", "target-aarch64"], "direct_feature_activators": ["llvm-inprocess"], "resolved": ["inkwell@0.9.0"], "reference_lines": 82, "references": ["crates/perry-codegen/src/dialect/eh.rs:9", "crates/perry-codegen/src/dialect/eh.rs:10", "crates/perry-codegen/src/dialect/eh.rs:60", "crates/perry-codegen/src/dialect/eh.rs:97", "crates/perry-codegen/src/dialect/eh.rs:105", "crates/perry-codegen/src/dialect/eh.rs:180"]}], "lock_closure_packages": 51, "lock_packages_lost_if_all_workspace_edges_removed": ["inkwell@0.9.0", "inkwell_internals@0.14.0"]}, +{"name": "itoa", "versions": ["1.0.18"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "itoa", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["itoa@1.0.18"], "reference_lines": 17, "references": ["crates/perry-runtime/src/array/join.rs:498", "crates/perry-runtime/src/json/stringify_api.rs:359", "crates/perry-runtime/src/json/stringify_buffer.rs:54", "crates/perry-runtime/src/json/stringify_buffer.rs:57", "crates/perry-runtime/src/json/stringify_buffer.rs:67", "crates/perry-runtime/src/json/stringify_buffer.rs:93"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "itoa", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["itoa@1.0.18"], "reference_lines": 0, "references": []}, {"owner": "perry-ui-android", "manifest": "crates/perry-ui-android/Cargo.toml", "alias": "itoa", "kind": "normal", "target": "cfg(target_os = \"android\")", "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["itoa@1.0.18"], "reference_lines": 0, "references": []}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "jni", "versions": ["0.22.4"], "edges": [{"owner": "perry-ui-android", "manifest": "crates/perry-ui-android/Cargo.toml", "alias": "jni", "kind": "normal", "target": "cfg(target_os = \"android\")", "optional": false, "requirement": "^0.22", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["jni@0.22.4"], "reference_lines": 1829, "references": ["crates/perry-ui-android/src/app.rs:1", "crates/perry-ui-android/src/app.rs:132", "crates/perry-ui-android/src/app.rs:135", "crates/perry-ui-android/src/app.rs:136", "crates/perry-ui-android/src/app.rs:180", "crates/perry-ui-android/src/app.rs:185"]}], "lock_closure_packages": 59, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "jsonwebtoken", "versions": ["11.0.0"], "edges": [{"owner": "perry-ext-jsonwebtoken", "manifest": "crates/perry-ext-jsonwebtoken/Cargo.toml", "alias": "jsonwebtoken", "kind": "normal", "target": null, "optional": false, "requirement": "^11.0", "default_features": false, "features": ["rust_crypto", "use_pem"], "direct_feature_activators": [], "resolved": ["jsonwebtoken@11.0.0"], "reference_lines": 1, "references": ["crates/perry-ext-jsonwebtoken/src/lib.rs:8"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "jsonwebtoken", "kind": "normal", "target": null, "optional": true, "requirement": "^11.0", "default_features": false, "features": ["rust_crypto", "use_pem"], "direct_feature_activators": ["bundled-jsonwebtoken"], "resolved": ["jsonwebtoken@11.0.0"], "reference_lines": 4, "references": ["crates/perry-stdlib/src/jsonwebtoken.rs:6", "crates/perry-stdlib/src/jsonwebtoken.rs:787", "crates/perry-stdlib/src/lib.rs:346", "crates/perry-stdlib/src/lib.rs:348"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "jsonwebtoken", "kind": "normal", "target": null, "optional": false, "requirement": "^11.0", "default_features": false, "features": ["rust_crypto", "use_pem"], "direct_feature_activators": [], "resolved": ["jsonwebtoken@11.0.0"], "reference_lines": 2, "references": ["crates/perry/src/commands/run/resign.rs:640", "crates/perry/src/commands/setup/common_apple.rs:7"]}], "lock_closure_packages": 119, "lock_packages_lost_if_all_workspace_edges_removed": ["jsonwebtoken@11.0.0", "pem@3.0.6", "simple_asn1@0.6.4"]}, +{"name": "kamadak-exif", "versions": ["0.6.1"], "edges": [{"owner": "perry-ext-sharp", "manifest": "crates/perry-ext-sharp/Cargo.toml", "alias": "exif", "kind": "normal", "target": null, "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["kamadak-exif@0.6.1"], "reference_lines": 2, "references": ["crates/perry-ext-sharp/src/lib.rs:129", "crates/perry-ext-sharp/src/lib.rs:130"]}], "lock_closure_packages": 2, "lock_packages_lost_if_all_workspace_edges_removed": ["kamadak-exif@0.6.1", "mutate_once@0.1.2"]}, +{"name": "ksni", "versions": ["0.3.6"], "edges": [{"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "ksni", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["tokio"], "direct_feature_activators": [], "resolved": ["ksni@0.3.6"], "reference_lines": 6, "references": ["crates/perry-ui-gtk4/src/tray.rs:49", "crates/perry-ui-gtk4/src/tray.rs:50", "crates/perry-ui-gtk4/src/tray.rs:89", "crates/perry-ui-gtk4/src/tray.rs:123", "crates/perry-ui-gtk4/src/tray.rs:190", "crates/perry-ui-gtk4/src/tray.rs:239"]}], "lock_closure_packages": 147, "lock_packages_lost_if_all_workspace_edges_removed": ["ksni@0.3.6"]}, +{"name": "lazy_static", "versions": ["1.5.0"], "edges": [{"owner": "perry-ext-fastify", "manifest": "crates/perry-ext-fastify/Cargo.toml", "alias": "lazy_static", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["lazy_static@1.5.0"], "reference_lines": 0, "references": []}, {"owner": "perry-ext-fetch", "manifest": "crates/perry-ext-fetch/Cargo.toml", "alias": "lazy_static", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["lazy_static@1.5.0"], "reference_lines": 2, "references": ["crates/perry-ext-fetch/src/lib.rs:12", "crates/perry-ext-fetch/src/lib.rs:175"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "lazy_static", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["lazy_static@1.5.0"], "reference_lines": 13, "references": ["crates/perry-ext-http/src/agent/tls_compat.rs:7", "crates/perry-ext-http/src/agent.rs:43", "crates/perry-ext-http/src/agent.rs:212", "crates/perry-ext-http/src/client_request_surface.rs:10", "crates/perry-ext-http/src/lib.rs:109", "crates/perry-ext-http/src/lib.rs:367"]}, {"owner": "perry-ext-ioredis", "manifest": "crates/perry-ext-ioredis/Cargo.toml", "alias": "lazy_static", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["lazy_static@1.5.0"], "reference_lines": 2, "references": ["crates/perry-ext-ioredis/src/lib.rs:11", "crates/perry-ext-ioredis/src/lib.rs:31"]}, {"owner": "perry-ext-streams", "manifest": "crates/perry-ext-streams/Cargo.toml", "alias": "lazy_static", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["lazy_static@1.5.0"], "reference_lines": 2, "references": ["crates/perry-ext-streams/src/lib.rs:51", "crates/perry-ext-streams/src/lib.rs:179"]}, {"owner": "perry-ext-ws", "manifest": "crates/perry-ext-ws/Cargo.toml", "alias": "lazy_static", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["lazy_static@1.5.0"], "reference_lines": 2, "references": ["crates/perry-ext-ws/src/lib.rs:43", "crates/perry-ext-ws/src/lib.rs:134"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "lazy_static", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["lazy_static@1.5.0"], "reference_lines": 5, "references": ["crates/perry-runtime/src/child_process/registry.rs:20", "crates/perry-runtime/src/net.rs:17", "crates/perry-runtime/src/plugin.rs:27", "crates/perry-runtime/src/plugin.rs:273", "crates/perry-runtime/src/text.rs:48"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "lazy_static", "kind": "normal", "target": null, "optional": false, "requirement": "^1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["lazy_static@1.5.0"], "reference_lines": 21, "references": ["crates/perry-stdlib/src/crypto/hash_handles.rs:61", "crates/perry-stdlib/src/dotenv.rs:13", "crates/perry-stdlib/src/fetch/body_metadata.rs:66", "crates/perry-stdlib/src/fetch/dispatch.rs:254", "crates/perry-stdlib/src/fetch/headers_method_value.rs:40", "crates/perry-stdlib/src/fetch/mod.rs:84"]}], "lock_closure_packages": 4, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "lettre", "versions": ["0.11.23"], "edges": [{"owner": "perry-ext-nodemailer", "manifest": "crates/perry-ext-nodemailer/Cargo.toml", "alias": "lettre", "kind": "normal", "target": null, "optional": false, "requirement": "^0.11", "default_features": false, "features": ["tokio1", "tokio1-rustls-tls", "smtp-transport", "builder", "hostname", "pool"], "direct_feature_activators": [], "resolved": ["lettre@0.11.23"], "reference_lines": 3, "references": ["crates/perry-ext-nodemailer/src/lib.rs:13", "crates/perry-ext-nodemailer/src/lib.rs:14", "crates/perry-ext-nodemailer/src/lib.rs:15"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "lettre", "kind": "normal", "target": null, "optional": true, "requirement": "^0.11", "default_features": false, "features": ["tokio1", "tokio1-rustls-tls", "smtp-transport", "builder", "hostname", "pool"], "direct_feature_activators": ["bundled-nodemailer"], "resolved": ["lettre@0.11.23"], "reference_lines": 3, "references": ["crates/perry-stdlib/src/nodemailer.rs:6", "crates/perry-stdlib/src/nodemailer.rs:7", "crates/perry-stdlib/src/nodemailer.rs:8"]}], "lock_closure_packages": 127, "lock_packages_lost_if_all_workspace_edges_removed": ["email-encoding@0.4.1", "email_address@0.2.9", "lettre@0.11.23", "quoted_printable@0.5.2"]}, +{"name": "libc", "versions": ["0.2.189"], "edges": [{"owner": "perry-audio-miniaudio", "manifest": "crates/perry-audio-miniaudio/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(any(target_os = \"linux\", target_os = \"windows\", target_os = \"android\"))", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 1, "references": ["crates/perry-audio-miniaudio/src/lib.rs:20"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "libc", "kind": "normal", "target": null, "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 1138, "references": ["crates/perry-runtime/src/arena/block.rs:231", "crates/perry-runtime/src/arena/quarantine.rs:209", "crates/perry-runtime/src/arena/quarantine.rs:389", "crates/perry-runtime/src/arena/quarantine.rs:392", "crates/perry-runtime/src/arena/quarantine.rs:405", "crates/perry-runtime/src/arena/quarantine.rs:430"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(unix)", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 19, "references": ["crates/perry-stdlib/src/readline/mod.rs:1276", "crates/perry-stdlib/src/readline/mod.rs:1281", "crates/perry-stdlib/src/readline/mod.rs:1282", "crates/perry-stdlib/src/readline/mod.rs:1294", "crates/perry-stdlib/src/readline/mod.rs:1295", "crates/perry-stdlib/src/readline/mod.rs:1296"]}, {"owner": "perry-ui-android", "manifest": "crates/perry-ui-android/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(target_os = \"android\")", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 2, "references": ["crates/perry-ui-android/src/ffi/issue_553.rs:295", "crates/perry-ui-android/src/screenshot.rs:230"]}, {"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 4, "references": ["crates/perry-ui-gtk4/src/app.rs:373", "crates/perry-ui-gtk4/src/audio.rs:398", "crates/perry-ui-gtk4/src/ffi/stubs_webview_attrtext_screenshot.rs:227", "crates/perry-ui-gtk4/src/screenshot.rs:63"]}, {"owner": "perry-ui-ios", "manifest": "crates/perry-ui-ios/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 28, "references": ["crates/perry-ui-ios/src/app.rs:941", "crates/perry-ui-ios/src/audio.rs:443", "crates/perry-ui-ios/src/audio.rs:447", "crates/perry-ui-ios/src/audio.rs:458", "crates/perry-ui-ios/src/crash_log.rs:85", "crates/perry-ui-ios/src/crash_log.rs:86"]}, {"owner": "perry-ui-macos", "manifest": "crates/perry-ui-macos/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(target_os = \"macos\")", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 32, "references": ["crates/perry-ui-macos/src/app.rs:670", "crates/perry-ui-macos/src/audio.rs:515", "crates/perry-ui-macos/src/audio.rs:518", "crates/perry-ui-macos/src/audio.rs:529", "crates/perry-ui-macos/src/crash_log.rs:90", "crates/perry-ui-macos/src/crash_log.rs:91"]}, {"owner": "perry-ui-tvos", "manifest": "crates/perry-ui-tvos/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(target_os = \"tvos\")", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 21, "references": ["crates/perry-ui-tvos/src/app.rs:535", "crates/perry-ui-tvos/src/audio.rs:443", "crates/perry-ui-tvos/src/audio.rs:447", "crates/perry-ui-tvos/src/audio.rs:458", "crates/perry-ui-tvos/src/crash_log.rs:85", "crates/perry-ui-tvos/src/crash_log.rs:86"]}, {"owner": "perry-ui-visionos", "manifest": "crates/perry-ui-visionos/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(target_os = \"visionos\")", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 22, "references": ["crates/perry-ui-visionos/src/audio.rs:443", "crates/perry-ui-visionos/src/audio.rs:447", "crates/perry-ui-visionos/src/audio.rs:458", "crates/perry-ui-visionos/src/crash_log.rs:85", "crates/perry-ui-visionos/src/crash_log.rs:86", "crates/perry-ui-visionos/src/crash_log.rs:87"]}, {"owner": "perry-ui-watchos", "manifest": "crates/perry-ui-watchos/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(target_os = \"watchos\")", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 6, "references": ["crates/perry-ui-watchos/src/audio.rs:181", "crates/perry-ui-watchos/src/audio.rs:184", "crates/perry-ui-watchos/src/audio.rs:195", "crates/perry-ui-watchos/src/notifications.rs:120", "crates/perry-ui-watchos/src/notifications.rs:149", "crates/perry-ui-watchos/src/system.rs:241"]}, {"owner": "perry-ui-windows-winui", "manifest": "crates/perry-ui-windows-winui/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 0, "references": []}, {"owner": "perry-ui-windows", "manifest": "crates/perry-ui-windows/Cargo.toml", "alias": "libc", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 5, "references": ["crates/perry-ui-windows/src/app.rs:1372", "crates/perry-ui-windows/src/ffi/system.rs:194", "crates/perry-ui-windows/src/screenshot.rs:117", "crates/perry-ui-windows/src/widgets/mod.rs:491", "crates/perry-ui-windows/src/widgets/mod.rs:587"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "libc", "kind": "normal", "target": null, "optional": false, "requirement": "^0.2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libc@0.2.189"], "reference_lines": 13, "references": ["crates/perry/src/commands/compile/strip_dedup.rs:118", "crates/perry/src/commands/compile/strip_dedup.rs:125", "crates/perry/src/commands/compile/strip_dedup.rs:131", "crates/perry/src/update_checker.rs:595", "crates/perry/tests/issue_9593_readline_escape_timeout.rs:68", "crates/perry/tests/issue_9593_readline_escape_timeout.rs:104"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "libmimalloc-sys", "versions": ["0.1.49"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "libmimalloc_sys", "kind": "normal", "target": "cfg(target_pointer_width = \"64\")", "optional": true, "requirement": "^0.1", "default_features": true, "features": ["extended"], "direct_feature_activators": ["alloc-mimalloc"], "resolved": ["libmimalloc-sys@0.1.49"], "reference_lines": 4, "references": ["crates/perry-runtime/src/gc/census.rs:650", "crates/perry-runtime/src/gc/cycle_malloc_trim.rs:107", "crates/perry-runtime/src/gc/tests/os_tag.rs:132", "crates/perry-runtime/src/mimalloc_os_tag.rs:66"]}], "lock_closure_packages": 40, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "libshumate", "versions": ["0.6.0"], "edges": [{"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "libshumate", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["libshumate@0.6.0"], "reference_lines": 10, "references": ["crates/perry-ui-gtk4/src/widgets/map_view.rs:18", "crates/perry-ui-gtk4/src/widgets/map_view.rs:25", "crates/perry-ui-gtk4/src/widgets/map_view.rs:31", "crates/perry-ui-gtk4/src/widgets/map_view.rs:32", "crates/perry-ui-gtk4/src/widgets/map_view.rs:35", "crates/perry-ui-gtk4/src/widgets/map_view.rs:40"]}], "lock_closure_packages": 79, "lock_packages_lost_if_all_workspace_edges_removed": ["libshumate-sys@0.6.0", "libshumate@0.6.0"]}, +{"name": "llvm-sys", "versions": ["221.0.1"], "edges": [{"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "llvm_sys", "kind": "normal", "target": "cfg(not(windows))", "optional": true, "requirement": "^221", "default_features": true, "features": [], "direct_feature_activators": ["llvm-inprocess"], "resolved": ["llvm-sys@221.0.1"], "reference_lines": 30, "references": ["crates/perry-codegen/src/dialect/eh.rs:181", "crates/perry-codegen/src/dialect/eh.rs:182", "crates/perry-codegen/src/dialect/eh.rs:192", "crates/perry-codegen/src/dialect/mod.rs:672", "crates/perry-codegen/src/dialect/mod.rs:674", "crates/perry-codegen/src/dialect/mod.rs:675"]}, {"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "llvm_sys", "kind": "normal", "target": "cfg(windows)", "optional": true, "requirement": "^221", "default_features": true, "features": ["no-llvm-linking"], "direct_feature_activators": ["llvm-inprocess"], "resolved": ["llvm-sys@221.0.1"], "reference_lines": 30, "references": ["crates/perry-codegen/src/dialect/eh.rs:181", "crates/perry-codegen/src/dialect/eh.rs:182", "crates/perry-codegen/src/dialect/eh.rs:192", "crates/perry-codegen/src/dialect/mod.rs:672", "crates/perry-codegen/src/dialect/mod.rs:674", "crates/perry-codegen/src/dialect/mod.rs:675"]}], "lock_closure_packages": 46, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "log", "versions": ["0.4.34"], "edges": [{"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "log", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["log@0.4.34"], "reference_lines": 10, "references": ["crates/perry-codegen/src/codegen/mod.rs:3730", "crates/perry-codegen/src/codegen/mod.rs:3767", "crates/perry-codegen/src/gc_map.rs:1345", "crates/perry-codegen/src/linker.rs:1030", "crates/perry-codegen/src/linker.rs:1829", "crates/perry-codegen/src/linker.rs:1847"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "log", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["log@0.4.34"], "reference_lines": 19, "references": ["crates/perry/src/commands/compile/cjs_wrap/tests.rs:811", "crates/perry/src/commands/compile/cjs_wrap/wrap.rs:1488", "crates/perry/src/commands/compile/cjs_wrap/wrap.rs:1490", "crates/perry/src/commands/compile/cjs_wrap/wrap.rs:1496", "crates/perry/src/commands/compile/collect_modules/finish.rs:302", "crates/perry/src/commands/compile/collect_modules/finish.rs:309"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "lru", "versions": ["0.18.3"], "edges": [{"owner": "perry-ext-lru-cache", "manifest": "crates/perry-ext-lru-cache/Cargo.toml", "alias": "lru", "kind": "normal", "target": null, "optional": false, "requirement": "^0.18", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["lru@0.18.3"], "reference_lines": 1, "references": ["crates/perry-ext-lru-cache/src/lib.rs:84"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "lru", "kind": "normal", "target": null, "optional": true, "requirement": "^0.18", "default_features": true, "features": [], "direct_feature_activators": ["bundled-lru-cache"], "resolved": ["lru@0.18.3"], "reference_lines": 1, "references": ["crates/perry-stdlib/src/lru_cache.rs:6"]}], "lock_closure_packages": 5, "lock_packages_lost_if_all_workspace_edges_removed": ["lru@0.18.3"]}, +{"name": "mach2", "versions": ["0.6.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "mach2", "kind": "normal", "target": "cfg(target_vendor = \"apple\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["mach2@0.6.0"], "reference_lines": 4, "references": ["crates/perry-runtime/src/gc/roots/stack_maps_sections.rs:25", "crates/perry-runtime/src/os.rs:355", "crates/perry-runtime/src/os.rs:1139", "crates/perry-runtime/src/os.rs:1181"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": ["mach2@0.6.0"]}, +{"name": "md-5", "versions": ["0.10.6", "0.11.0"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "md5", "kind": "normal", "target": null, "optional": false, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["md-5@0.11.0"], "reference_lines": 3, "references": ["crates/perry-container-compose/src/compose.rs:8", "crates/perry-container-compose/src/service.rs:1", "crates/perry-container-compose/src/testing/mock_backend.rs:128"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "md5", "kind": "normal", "target": null, "optional": true, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["md-5@0.11.0"], "reference_lines": 2, "references": ["crates/perry-stdlib/src/crypto/certificate.rs:198", "crates/perry-stdlib/src/crypto/util.rs:19"]}], "lock_closure_packages": 85, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "mimalloc", "versions": ["0.1.52"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "mimalloc", "kind": "normal", "target": "cfg(target_pointer_width = \"64\")", "optional": true, "requirement": "^0.1", "default_features": false, "features": [], "direct_feature_activators": ["alloc-mimalloc"], "resolved": ["mimalloc@0.1.52"], "reference_lines": 3, "references": ["crates/perry-runtime/src/lib.rs:34", "crates/perry-runtime/src/lib.rs:50", "crates/perry-runtime/src/lib.rs:51"]}], "lock_closure_packages": 41, "lock_packages_lost_if_all_workspace_edges_removed": ["mimalloc@0.1.52"]}, +{"name": "ml-kem", "versions": ["0.3.2"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "ml_kem", "kind": "normal", "target": null, "optional": true, "requirement": "^0.3.2", "default_features": true, "features": ["pkcs8"], "direct_feature_activators": ["crypto"], "resolved": ["ml-kem@0.3.2"], "reference_lines": 33, "references": ["crates/perry-stdlib/src/webcrypto/encapsulation.rs:2", "crates/perry-stdlib/src/webcrypto/encapsulation.rs:47", "crates/perry-stdlib/src/webcrypto/encapsulation.rs:51", "crates/perry-stdlib/src/webcrypto/encapsulation.rs:53", "crates/perry-stdlib/src/webcrypto/encapsulation.rs:59", "crates/perry-stdlib/src/webcrypto/encapsulation.rs:61"]}], "lock_closure_packages": 90, "lock_packages_lost_if_all_workspace_edges_removed": ["kem@0.3.0", "ml-kem@0.3.2", "module-lattice@0.2.3", "sha3@0.11.0"]}, +{"name": "mongodb", "versions": ["3.8.2"], "edges": [{"owner": "perry-ext-mongodb", "manifest": "crates/perry-ext-mongodb/Cargo.toml", "alias": "mongodb", "kind": "normal", "target": null, "optional": false, "requirement": "^3.7", "default_features": false, "features": ["bson-3", "compat-3-3-0", "rustls-tls", "dns-resolver"], "direct_feature_activators": [], "resolved": ["mongodb@3.8.2"], "reference_lines": 4, "references": ["crates/perry-ext-mongodb/src/lib.rs:38", "crates/perry-ext-mongodb/src/lib.rs:169", "crates/perry-ext-mongodb/src/lib.rs:218", "crates/perry-ext-mongodb/src/lib.rs:890"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "mongodb", "kind": "normal", "target": null, "optional": true, "requirement": "^3.7", "default_features": false, "features": ["bson-3", "compat-3-3-0", "rustls-tls", "dns-resolver"], "direct_feature_activators": ["bundled-mongodb"], "resolved": ["mongodb@3.8.2"], "reference_lines": 5, "references": ["crates/perry-stdlib/src/lib.rs:297", "crates/perry-stdlib/src/lib.rs:299", "crates/perry-stdlib/src/mongodb.rs:11", "crates/perry-stdlib/src/mongodb.rs:114", "crates/perry-stdlib/src/mongodb.rs:202"]}], "lock_closure_packages": 270, "lock_packages_lost_if_all_workspace_edges_removed": ["const-random-macro@0.1.16", "const-random@0.1.18", "core-foundation@0.9.4", "darling@0.23.0", "darling_core@0.23.0", "darling_macro@0.23.0", "derive-syn-parse@0.2.0", "derive-where@1.6.1", "hickory-net@0.26.1", "hickory-resolver@0.26.1", "ipconfig@0.3.4", "macro_magic@0.5.1", "macro_magic_core@0.5.1", "macro_magic_core_macros@0.5.1", "macro_magic_macros@0.5.1", "moka@0.12.15", "mongocrypt-sys@0.1.6+1.18.2", "mongocrypt@0.4.0", "mongodb-internal-macros@3.8.2", "mongodb@3.8.2", "ndk-context@0.1.1", "rustc_version_runtime@0.3.0", "serde_with@3.21.0", "serde_with_macros@3.21.0", "system-configuration-sys@0.6.0", "system-configuration@0.7.0", "tagptr@0.2.0", "take_mut@0.2.2", "tiny-keccak@2.0.2", "typed-builder-macro@0.22.0", "typed-builder@0.22.0", "widestring@1.2.1", "windows-registry@0.6.1"]}, +{"name": "mpris-server", "versions": ["0.10.0"], "edges": [{"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "mpris_server", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^0.10", "default_features": true, "features": ["tokio"], "direct_feature_activators": [], "resolved": ["mpris-server@0.10.0"], "reference_lines": 1, "references": ["crates/perry-ui-gtk4/src/media_playback.rs:561"]}], "lock_closure_packages": 148, "lock_packages_lost_if_all_workspace_edges_removed": ["mpris-server@0.10.0", "trait-variant@0.1.2"]}, +{"name": "nanoid", "versions": ["0.5.0"], "edges": [{"owner": "perry-ext-nanoid", "manifest": "crates/perry-ext-nanoid/Cargo.toml", "alias": "nanoid", "kind": "normal", "target": null, "optional": false, "requirement": "^0.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["nanoid@0.5.0"], "reference_lines": 3, "references": ["crates/perry-ext-nanoid/src/lib.rs:8", "crates/perry-ext-nanoid/src/lib.rs:14", "crates/perry-ext-nanoid/src/lib.rs:25"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "nanoid", "kind": "normal", "target": null, "optional": true, "requirement": "^0.5", "default_features": true, "features": [], "direct_feature_activators": ["bundled-nanoid"], "resolved": ["nanoid@0.5.0"], "reference_lines": 5, "references": ["crates/perry-stdlib/src/lib.rs:436", "crates/perry-stdlib/src/lib.rs:438", "crates/perry-stdlib/src/nanoid.rs:6", "crates/perry-stdlib/src/nanoid.rs:15", "crates/perry-stdlib/src/nanoid.rs:27"]}], "lock_closure_packages": 41, "lock_packages_lost_if_all_workspace_edges_removed": ["nanoid@0.5.0"]}, +{"name": "node-semver", "versions": ["2.2.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "node_semver", "kind": "normal", "target": null, "optional": true, "requirement": "^2.2.0", "default_features": true, "features": [], "direct_feature_activators": ["bun-cli-utils"], "resolved": ["node-semver@2.2.0"], "reference_lines": 4, "references": ["crates/perry-runtime/src/bun_compat/cli_utils.rs:195", "crates/perry-runtime/src/bun_compat/cli_utils.rs:202", "crates/perry-runtime/src/bun_compat/cli_utils.rs:223", "crates/perry-runtime/src/bun_compat/cli_utils.rs:230"]}], "lock_closure_packages": 19, "lock_packages_lost_if_all_workspace_edges_removed": ["miette-derive@7.6.0", "miette@7.6.0", "node-semver@2.2.0", "unicode-width@0.1.14"]}, +{"name": "notify", "versions": ["6.1.1"], "edges": [{"owner": "perry-ext-parcel-watcher", "manifest": "crates/perry-ext-parcel-watcher/Cargo.toml", "alias": "notify", "kind": "normal", "target": null, "optional": false, "requirement": "^6.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["notify@6.1.1"], "reference_lines": 3, "references": ["crates/perry-ext-parcel-watcher/src/lib.rs:8", "crates/perry-ext-parcel-watcher/src/lib.rs:9", "crates/perry-ext-parcel-watcher/src/lib.rs:730"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "notify", "kind": "normal", "target": "cfg(not(target_os = \"macos\"))", "optional": false, "requirement": "^6.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["notify@6.1.1"], "reference_lines": 16, "references": ["crates/perry-runtime/src/fs/dir_glob_watch/watch_backend.rs:352", "crates/perry-runtime/src/fs/dir_glob_watch/watch_backend.rs:353", "crates/perry-runtime/src/fs/dir_glob_watch/watch_backend.rs:397", "crates/perry-runtime/src/fs/dir_glob_watch/watch_backend.rs:398", "crates/perry-runtime/src/fs/dir_glob_watch/watch_backend.rs:400", "crates/perry-runtime/src/fs/dir_glob_watch/watch_backend.rs:401"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "notify", "kind": "normal", "target": null, "optional": true, "requirement": "^6.1", "default_features": true, "features": [], "direct_feature_activators": ["watch-cli"], "resolved": ["notify@6.1.1"], "reference_lines": 11, "references": ["crates/perry/src/commands/dev.rs:29", "crates/perry/src/commands/dev.rs:141", "crates/perry/src/commands/dev.rs:143", "crates/perry/src/commands/dev.rs:247", "crates/perry/src/commands/dev.rs:446", "crates/perry/src/commands/dev.rs:449"]}], "lock_closure_packages": 36, "lock_packages_lost_if_all_workspace_edges_removed": ["bitflags@1.3.2", "fsevent-sys@4.1.0", "inotify-sys@0.1.5", "inotify@0.9.6", "kqueue-sys@1.1.2", "kqueue@1.2.0", "mio@0.8.11", "notify@6.1.1", "windows-sys@0.48.0", "windows-targets@0.48.5", "windows_aarch64_gnullvm@0.48.5", "windows_aarch64_msvc@0.48.5", "windows_i686_gnu@0.48.5", "windows_i686_msvc@0.48.5", "windows_x86_64_gnu@0.48.5", "windows_x86_64_gnullvm@0.48.5", "windows_x86_64_msvc@0.48.5"]}, +{"name": "objc2", "versions": ["0.6.4"], "edges": [{"owner": "perry-ext-ads", "manifest": "crates/perry-ext-ads/Cargo.toml", "alias": "objc2", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": true, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": ["google-ads"], "resolved": [], "reference_lines": 4, "references": ["crates/perry-ext-ads/src/ios_real.rs:39", "crates/perry-ext-ads/src/ios_real.rs:40", "crates/perry-ext-ads/src/ios_real.rs:41", "crates/perry-ext-ads/src/ios_real.rs:216"]}, {"owner": "perry-ui-ios", "manifest": "crates/perry-ui-ios/Cargo.toml", "alias": "objc2", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["objc2@0.6.4"], "reference_lines": 608, "references": ["crates/perry-ui-ios/src/adaptive_layout.rs:8", "crates/perry-ui-ios/src/adaptive_layout.rs:9", "crates/perry-ui-ios/src/app.rs:1", "crates/perry-ui-ios/src/app.rs:2", "crates/perry-ui-ios/src/app.rs:3", "crates/perry-ui-ios/src/app.rs:311"]}, {"owner": "perry-ui-macos", "manifest": "crates/perry-ui-macos/Cargo.toml", "alias": "objc2", "kind": "normal", "target": "cfg(target_os = \"macos\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["objc2@0.6.4"], "reference_lines": 557, "references": ["crates/perry-ui-macos/src/app.rs:3", "crates/perry-ui-macos/src/app.rs:4", "crates/perry-ui-macos/src/app.rs:5", "crates/perry-ui-macos/src/app.rs:110", "crates/perry-ui-macos/src/app.rs:111", "crates/perry-ui-macos/src/app.rs:115"]}, {"owner": "perry-ui-tvos", "manifest": "crates/perry-ui-tvos/Cargo.toml", "alias": "objc2", "kind": "normal", "target": "cfg(target_os = \"tvos\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["objc2@0.6.4"], "reference_lines": 458, "references": ["crates/perry-ui-tvos/src/app.rs:1", "crates/perry-ui-tvos/src/app.rs:2", "crates/perry-ui-tvos/src/app.rs:3", "crates/perry-ui-tvos/src/app.rs:197", "crates/perry-ui-tvos/src/app.rs:221", "crates/perry-ui-tvos/src/app.rs:833"]}, {"owner": "perry-ui-visionos", "manifest": "crates/perry-ui-visionos/Cargo.toml", "alias": "objc2", "kind": "normal", "target": "cfg(target_os = \"visionos\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["objc2@0.6.4"], "reference_lines": 528, "references": ["crates/perry-ui-visionos/src/app.rs:1", "crates/perry-ui-visionos/src/app.rs:2", "crates/perry-ui-visionos/src/app.rs:3", "crates/perry-ui-visionos/src/app.rs:89", "crates/perry-ui-visionos/src/app.rs:643", "crates/perry-ui-visionos/src/audio.rs:1"]}, {"owner": "perry-ui-watchos", "manifest": "crates/perry-ui-watchos/Cargo.toml", "alias": "objc2", "kind": "normal", "target": "cfg(target_os = \"watchos\")", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["objc2@0.6.4"], "reference_lines": 90, "references": ["crates/perry-ui-watchos/src/audio.rs:1", "crates/perry-ui-watchos/src/audio.rs:2", "crates/perry-ui-watchos/src/audio.rs:3", "crates/perry-ui-watchos/src/audio.rs:77", "crates/perry-ui-watchos/src/audio.rs:84", "crates/perry-ui-watchos/src/audio_playback.rs:12"]}], "lock_closure_packages": 2, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "objc2-app-kit", "versions": ["0.3.2"], "edges": [{"owner": "perry-ui-macos", "manifest": "crates/perry-ui-macos/Cargo.toml", "alias": "objc2_app_kit", "kind": "normal", "target": "cfg(target_os = \"macos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["NSApplication", "NSWindow", "NSView", "NSButton", "NSTextField", "NSTextFieldCell", "NSActionCell", "NSCell", "NSStackView", "NSControl", "NSText", "NSRunningApplication", "NSResponder", "NSLayoutConstraint", "NSUserInterfaceLayout", "NSGraphics", "NSMenu", "NSMenuItem", "NSEvent", "NSBox", "NSSwitch", "NSSlider", "NSScrollView", "NSClipView", "NSPasteboard", "NSColor", "NSFont", "NSSavePanel", "NSOpenPanel", "NSSecureTextField", "NSProgressIndicator", "NSPopUpButton", "NSImage", "NSImageView", "NSStatusBar", "NSStatusItem", "NSStatusBarButton"], "direct_feature_activators": [], "resolved": ["objc2-app-kit@0.3.2"], "reference_lines": 74, "references": ["crates/perry-ui-macos/src/app.rs:6", "crates/perry-ui-macos/src/app.rs:1888", "crates/perry-ui-macos/src/clipboard.rs:4", "crates/perry-ui-macos/src/drag_drop.rs:31", "crates/perry-ui-macos/src/file_dialog.rs:3", "crates/perry-ui-macos/src/image_picker.rs:7"]}], "lock_closure_packages": 23, "lock_packages_lost_if_all_workspace_edges_removed": ["objc2-app-kit@0.3.2", "objc2-core-video@0.3.2"]}, +{"name": "objc2-core-foundation", "versions": ["0.3.2"], "edges": [{"owner": "perry-ui-ios", "manifest": "crates/perry-ui-ios/Cargo.toml", "alias": "objc2_core_foundation", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["CFCGTypes"], "direct_feature_activators": [], "resolved": ["objc2-core-foundation@0.3.2"], "reference_lines": 144, "references": ["crates/perry-ui-ios/src/adaptive_layout.rs:10", "crates/perry-ui-ios/src/app.rs:1055", "crates/perry-ui-ios/src/app.rs:1071", "crates/perry-ui-ios/src/app.rs:1174", "crates/perry-ui-ios/src/app.rs:1176", "crates/perry-ui-ios/src/app.rs:1183"]}, {"owner": "perry-ui-macos", "manifest": "crates/perry-ui-macos/Cargo.toml", "alias": "objc2_core_foundation", "kind": "normal", "target": "cfg(target_os = \"macos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["CFCGTypes"], "direct_feature_activators": [], "resolved": ["objc2-core-foundation@0.3.2"], "reference_lines": 177, "references": ["crates/perry-ui-macos/src/app.rs:10", "crates/perry-ui-macos/src/drag_drop.rs:32", "crates/perry-ui-macos/src/ffi.rs:68", "crates/perry-ui-macos/src/ffi.rs:69", "crates/perry-ui-macos/src/lib_ffi/system.rs:383", "crates/perry-ui-macos/src/lib_ffi/system.rs:384"]}, {"owner": "perry-ui-tvos", "manifest": "crates/perry-ui-tvos/Cargo.toml", "alias": "objc2_core_foundation", "kind": "normal", "target": "cfg(target_os = \"tvos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["CFCGTypes"], "direct_feature_activators": [], "resolved": ["objc2-core-foundation@0.3.2"], "reference_lines": 91, "references": ["crates/perry-ui-tvos/src/app.rs:649", "crates/perry-ui-tvos/src/app.rs:665", "crates/perry-ui-tvos/src/app.rs:768", "crates/perry-ui-tvos/src/app.rs:770", "crates/perry-ui-tvos/src/app.rs:777", "crates/perry-ui-tvos/src/app.rs:782"]}, {"owner": "perry-ui-visionos", "manifest": "crates/perry-ui-visionos/Cargo.toml", "alias": "objc2_core_foundation", "kind": "normal", "target": "cfg(target_os = \"visionos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["CFCGTypes"], "direct_feature_activators": [], "resolved": ["objc2-core-foundation@0.3.2"], "reference_lines": 137, "references": ["crates/perry-ui-visionos/src/app.rs:459", "crates/perry-ui-visionos/src/app.rs:475", "crates/perry-ui-visionos/src/app.rs:578", "crates/perry-ui-visionos/src/app.rs:580", "crates/perry-ui-visionos/src/app.rs:587", "crates/perry-ui-visionos/src/app.rs:592"]}], "lock_closure_packages": 13, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "objc2-foundation", "versions": ["0.3.2"], "edges": [{"owner": "perry-ext-ads", "manifest": "crates/perry-ext-ads/Cargo.toml", "alias": "objc2_foundation", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": true, "requirement": "^0.3", "default_features": true, "features": [], "direct_feature_activators": ["google-ads"], "resolved": [], "reference_lines": 1, "references": ["crates/perry-ext-ads/src/ios_real.rs:42"]}, {"owner": "perry-ui-ios", "manifest": "crates/perry-ui-ios/Cargo.toml", "alias": "objc2_foundation", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["NSString", "NSThread", "NSRunLoop", "NSURL", "NSArray", "NSError"], "direct_feature_activators": [], "resolved": ["objc2-foundation@0.3.2"], "reference_lines": 105, "references": ["crates/perry-ui-ios/src/app.rs:4", "crates/perry-ui-ios/src/audio.rs:139", "crates/perry-ui-ios/src/audio_playback.rs:202", "crates/perry-ui-ios/src/audio_playback.rs:282", "crates/perry-ui-ios/src/audio_playback.rs:283", "crates/perry-ui-ios/src/audio_playback.rs:287"]}, {"owner": "perry-ui-macos", "manifest": "crates/perry-ui-macos/Cargo.toml", "alias": "objc2_foundation", "kind": "normal", "target": "cfg(target_os = \"macos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["NSString", "NSThread", "NSRunLoop", "NSGeometry"], "direct_feature_activators": [], "resolved": ["objc2-foundation@0.3.2"], "reference_lines": 110, "references": ["crates/perry-ui-macos/src/app.rs:11", "crates/perry-ui-macos/src/audio_playback.rs:199", "crates/perry-ui-macos/src/audio_playback.rs:279", "crates/perry-ui-macos/src/audio_playback.rs:280", "crates/perry-ui-macos/src/audio_playback.rs:284", "crates/perry-ui-macos/src/audio_playback.rs:297"]}, {"owner": "perry-ui-tvos", "manifest": "crates/perry-ui-tvos/Cargo.toml", "alias": "objc2_foundation", "kind": "normal", "target": "cfg(target_os = \"tvos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["NSString", "NSThread", "NSRunLoop", "NSURL", "NSArray", "NSError"], "direct_feature_activators": [], "resolved": ["objc2-foundation@0.3.2"], "reference_lines": 67, "references": ["crates/perry-ui-tvos/src/app.rs:4", "crates/perry-ui-tvos/src/audio.rs:139", "crates/perry-ui-tvos/src/audio_playback.rs:202", "crates/perry-ui-tvos/src/audio_playback.rs:282", "crates/perry-ui-tvos/src/audio_playback.rs:283", "crates/perry-ui-tvos/src/audio_playback.rs:287"]}, {"owner": "perry-ui-visionos", "manifest": "crates/perry-ui-visionos/Cargo.toml", "alias": "objc2_foundation", "kind": "normal", "target": "cfg(target_os = \"visionos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["NSString", "NSThread", "NSRunLoop", "NSURL", "NSArray", "NSError"], "direct_feature_activators": [], "resolved": ["objc2-foundation@0.3.2"], "reference_lines": 92, "references": ["crates/perry-ui-visionos/src/app.rs:4", "crates/perry-ui-visionos/src/audio.rs:139", "crates/perry-ui-visionos/src/audio_playback.rs:202", "crates/perry-ui-visionos/src/audio_playback.rs:282", "crates/perry-ui-visionos/src/audio_playback.rs:283", "crates/perry-ui-visionos/src/audio_playback.rs:287"]}, {"owner": "perry-ui-watchos", "manifest": "crates/perry-ui-watchos/Cargo.toml", "alias": "objc2_foundation", "kind": "normal", "target": "cfg(target_os = \"watchos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["NSString"], "direct_feature_activators": [], "resolved": ["objc2-foundation@0.3.2"], "reference_lines": 26, "references": ["crates/perry-ui-watchos/src/audio.rs:46", "crates/perry-ui-watchos/src/audio.rs:47", "crates/perry-ui-watchos/src/audio_playback.rs:202", "crates/perry-ui-watchos/src/audio_playback.rs:282", "crates/perry-ui-watchos/src/audio_playback.rs:283", "crates/perry-ui-watchos/src/audio_playback.rs:287"]}], "lock_closure_packages": 14, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "objc2-ui-kit", "versions": ["0.3.2"], "edges": [{"owner": "perry-ui-ios", "manifest": "crates/perry-ui-ios/Cargo.toml", "alias": "objc2_ui_kit", "kind": "normal", "target": "cfg(target_os = \"ios\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["UIApplication", "UIWindow", "UIWindowScene", "UIScene", "UISceneSession", "UISceneConfiguration", "UIView", "UIViewController", "UILabel", "UIButton", "UIButtonConfiguration", "UIStackView", "UISwitch", "UISlider", "UIScrollView", "UITextField", "UITextView", "UIColor", "UIFont", "UIControl", "UIGeometry", "UIPasteboard", "UIResponder", "UIScreen"], "direct_feature_activators": [], "resolved": ["objc2-ui-kit@0.3.2"], "reference_lines": 45, "references": ["crates/perry-ui-ios/src/adaptive_layout.rs:11", "crates/perry-ui-ios/src/app.rs:5", "crates/perry-ui-ios/src/camera.rs:10", "crates/perry-ui-ios/src/ffi/widgets_basic.rs:27", "crates/perry-ui-ios/src/widgets/adbanner.rs:20", "crates/perry-ui-ios/src/widgets/attributed_text.rs:9"]}, {"owner": "perry-ui-tvos", "manifest": "crates/perry-ui-tvos/Cargo.toml", "alias": "objc2_ui_kit", "kind": "normal", "target": "cfg(target_os = \"tvos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["UIApplication", "UIWindow", "UIWindowScene", "UIScene", "UISceneSession", "UISceneConfiguration", "UIView", "UIViewController", "UILabel", "UIButton", "UIButtonConfiguration", "UIStackView", "UISwitch", "UISlider", "UIScrollView", "UITextField", "UITextView", "UIColor", "UIFont", "UIControl", "UIResponder", "UIScreen"], "direct_feature_activators": [], "resolved": ["objc2-ui-kit@0.3.2"], "reference_lines": 29, "references": ["crates/perry-ui-tvos/src/app.rs:5", "crates/perry-ui-tvos/src/lib.rs:89", "crates/perry-ui-tvos/src/widgets/attributed_text.rs:9", "crates/perry-ui-tvos/src/widgets/bloomview.rs:12", "crates/perry-ui-tvos/src/widgets/bottom_nav.rs:12", "crates/perry-ui-tvos/src/widgets/button.rs:5"]}, {"owner": "perry-ui-visionos", "manifest": "crates/perry-ui-visionos/Cargo.toml", "alias": "objc2_ui_kit", "kind": "normal", "target": "cfg(target_os = \"visionos\")", "optional": false, "requirement": "^0.3", "default_features": true, "features": ["UIApplication", "UIWindow", "UIWindowScene", "UIScene", "UISceneSession", "UISceneConfiguration", "UIView", "UIViewController", "UILabel", "UIButton", "UIButtonConfiguration", "UIStackView", "UISwitch", "UISlider", "UIScrollView", "UITextField", "UITextView", "UIColor", "UIFont", "UIControl", "UIPasteboard", "UIResponder", "UIScreen"], "direct_feature_activators": [], "resolved": ["objc2-ui-kit@0.3.2"], "reference_lines": 41, "references": ["crates/perry-ui-visionos/src/app.rs:5", "crates/perry-ui-visionos/src/camera.rs:10", "crates/perry-ui-visionos/src/ffi_core.rs:33", "crates/perry-ui-visionos/src/widgets/attributed_text.rs:9", "crates/perry-ui-visionos/src/widgets/bloomview.rs:13", "crates/perry-ui-visionos/src/widgets/bottom_nav.rs:12"]}], "lock_closure_packages": 24, "lock_packages_lost_if_all_workspace_edges_removed": ["objc2-core-location@0.3.2", "objc2-ui-kit@0.3.2", "objc2-user-notifications@0.3.2"]}, +{"name": "object", "versions": ["0.37.3"], "edges": [{"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "object", "kind": "normal", "target": null, "optional": false, "requirement": "^0.37", "default_features": false, "features": ["read", "std"], "direct_feature_activators": [], "resolved": ["object@0.37.3"], "reference_lines": 16, "references": ["crates/perry/src/commands/compile/collect_modules/crypto_ns.rs:14", "crates/perry/src/commands/compile/collect_modules/native_addon.rs:13", "crates/perry/src/commands/compile/collect_modules/native_addon.rs:133", "crates/perry/src/commands/compile/resolve/subpath_imports.rs:330", "crates/perry/src/commands/compile/size_report.rs:33", "crates/perry/src/commands/compile/size_report.rs:212"]}], "lock_closure_packages": 2, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "once_cell", "versions": ["1.21.4"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "once_cell", "kind": "normal", "target": null, "optional": false, "requirement": "^1.19", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["once_cell@1.21.4"], "reference_lines": 3, "references": ["crates/perry-container-compose/src/compose.rs:27", "crates/perry-container-compose/src/compose.rs:28", "crates/perry-container-compose/src/workload.rs:7"]}, {"owner": "perry-ffi", "manifest": "crates/perry-ffi/Cargo.toml", "alias": "once_cell", "kind": "normal", "target": null, "optional": false, "requirement": "^1.19", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["once_cell@1.21.4"], "reference_lines": 1, "references": ["crates/perry-ffi/src/handle.rs:76"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "once_cell", "kind": "normal", "target": null, "optional": false, "requirement": "^1.19", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["once_cell@1.21.4"], "reference_lines": 5, "references": ["crates/perry-stdlib/src/common/async_bridge.rs:20", "crates/perry-stdlib/src/common/handle.rs:11", "crates/perry-stdlib/src/fetch/abort_bridge.rs:24", "crates/perry-stdlib/src/framework/server.rs:350", "crates/perry-stdlib/src/webcrypto/util.rs:17"]}], "lock_closure_packages": 3, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "p12", "versions": ["0.6.3"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "p12", "kind": "normal", "target": null, "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["p12@0.6.3"], "reference_lines": 5, "references": ["crates/perry-ext-http/src/tls_client.rs:901", "crates/perry-ext-http/src/tls_client.rs:906", "crates/perry-ext-http/src/tls_client.rs:923", "crates/perry-ext-http/src/tls_client.rs:926", "crates/perry-ext-http/src/tls_client.rs:968"]}], "lock_closure_packages": 58, "lock_packages_lost_if_all_workspace_edges_removed": ["des@0.8.1", "p12@0.6.3", "rc2@0.8.1", "yasna@0.5.2"]}, +{"name": "p256", "versions": ["0.13.2"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "p256", "kind": "normal", "target": null, "optional": true, "requirement": "^0.13", "default_features": false, "features": ["pkcs8", "pem", "ecdsa", "ecdh"], "direct_feature_activators": ["bundled-jsonwebtoken", "crypto"], "resolved": ["p256@0.13.2"], "reference_lines": 23, "references": ["crates/perry-stdlib/src/crypto/kdf.rs:1182", "crates/perry-stdlib/src/crypto/kdf.rs:1183", "crates/perry-stdlib/src/crypto/sign.rs:321", "crates/perry-stdlib/src/crypto/sign.rs:472", "crates/perry-stdlib/src/crypto/util.rs:20", "crates/perry-stdlib/src/crypto/util.rs:21"]}], "lock_closure_packages": 73, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "p384", "versions": ["0.13.1"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "p384", "kind": "normal", "target": null, "optional": true, "requirement": "^0.13", "default_features": false, "features": ["pkcs8", "pem", "ecdsa", "ecdh"], "direct_feature_activators": ["crypto"], "resolved": ["p384@0.13.1"], "reference_lines": 3, "references": ["crates/perry-stdlib/src/webcrypto/util.rs:28", "crates/perry-stdlib/src/webcrypto/util.rs:29", "crates/perry-stdlib/src/webcrypto/util.rs:33"]}], "lock_closure_packages": 73, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "p521", "versions": ["0.13.3"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "p521", "kind": "normal", "target": null, "optional": true, "requirement": "^0.13", "default_features": false, "features": ["pkcs8", "pem", "ecdsa", "ecdh"], "direct_feature_activators": ["crypto"], "resolved": ["p521@0.13.3"], "reference_lines": 3, "references": ["crates/perry-stdlib/src/webcrypto/util.rs:34", "crates/perry-stdlib/src/webcrypto/util.rs:35", "crates/perry-stdlib/src/webcrypto/util.rs:39"]}], "lock_closure_packages": 73, "lock_packages_lost_if_all_workspace_edges_removed": ["p521@0.13.3"]}, +{"name": "pbkdf2", "versions": ["0.12.2", "0.13.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "pbkdf2", "kind": "normal", "target": null, "optional": true, "requirement": "^0.13", "default_features": true, "features": ["hmac"], "direct_feature_activators": ["crypto"], "resolved": ["pbkdf2@0.13.0"], "reference_lines": 6, "references": ["crates/perry-stdlib/src/crypto/kdf.rs:20", "crates/perry-stdlib/src/crypto/kdf.rs:792", "crates/perry-stdlib/src/webcrypto/hmac.rs:614", "crates/perry-stdlib/src/webcrypto/hmac.rs:615", "crates/perry-stdlib/src/webcrypto/hmac.rs:616", "crates/perry-stdlib/src/webcrypto/hmac.rs:617"]}], "lock_closure_packages": 87, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "pem", "versions": ["3.0.6", "4.0.0"], "edges": [{"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "pem", "kind": "normal", "target": null, "optional": false, "requirement": "^4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["pem@4.0.0"], "reference_lines": 2, "references": ["crates/perry-ext-node-forge/src/crypto.rs:476", "crates/perry-ext-node-forge/src/lib.rs:616"]}], "lock_closure_packages": 10, "lock_packages_lost_if_all_workspace_edges_removed": ["pem@4.0.0"]}, +{"name": "perex", "versions": ["0.1.4"], "edges": [{"owner": "perry-perex", "manifest": "crates/perry-perex/Cargo.toml", "alias": "perex", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["perex@0.1.4"], "reference_lines": 7, "references": ["crates/perry-perex/src/lib.rs:14", "crates/perry-perex/src/lib.rs:18", "crates/perry-perex/src/lib.rs:19", "crates/perry-perex/src/lib.rs:23", "crates/perry-perex/src/lib.rs:24", "crates/perry-perex/src/lib.rs:25"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "perex", "kind": "normal", "target": null, "optional": true, "requirement": "^0.1.4", "default_features": true, "features": [], "direct_feature_activators": ["regex-engine"], "resolved": ["perex@0.1.4"], "reference_lines": 94, "references": ["crates/perry-runtime/src/fs/dir_glob_watch/glob.rs:629", "crates/perry-runtime/src/gc/tests/runtime_roots/perex_cross_call.rs:11", "crates/perry-runtime/src/gc/tests/runtime_roots/perex_cross_call.rs:42", "crates/perry-runtime/src/gc/tests/runtime_roots/perex_cross_call.rs:46", "crates/perry-runtime/src/gc/tests/runtime_roots/perex_dispatch.rs:10", "crates/perry-runtime/src/gc/tests/runtime_roots/perex_dispatch.rs:370"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": ["perex@0.1.4"]}, +{"name": "pkcs5", "versions": ["0.7.1"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "pkcs5", "kind": "normal", "target": null, "optional": false, "requirement": "^0.7", "default_features": true, "features": ["alloc", "pbes2"], "direct_feature_activators": [], "resolved": ["pkcs5@0.7.1"], "reference_lines": 2, "references": ["crates/perry-ext-http/src/tls_client.rs:918", "crates/perry-ext-http/src/tls_client.rs:935"]}], "lock_closure_packages": 60, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "png", "versions": ["0.18.1"], "edges": [{"owner": "perry-ui-windows", "manifest": "crates/perry-ui-windows/Cargo.toml", "alias": "png", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^0.18", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["png@0.18.1"], "reference_lines": 5, "references": ["crates/perry-ui-windows/src/screenshot.rs:137", "crates/perry-ui-windows/src/screenshot.rs:138", "crates/perry-ui-windows/src/screenshot.rs:139", "crates/perry-ui-windows/src/screenshot.rs:142", "crates/perry-ui-windows/src/widgets/pdf_view.rs:625"]}], "lock_closure_packages": 17, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "printpdf", "versions": ["0.10.1"], "edges": [{"owner": "perry-ext-pdf", "manifest": "crates/perry-ext-pdf/Cargo.toml", "alias": "printpdf", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": false, "features": [], "direct_feature_activators": [], "resolved": ["printpdf@0.10.1"], "reference_lines": 1, "references": ["crates/perry-ext-pdf/src/lib.rs:46"]}], "lock_closure_packages": 124, "lock_packages_lost_if_all_workspace_edges_removed": ["aliasable@0.1.3", "allsorts-azul@0.16.5", "ecb@0.1.2", "glyph-names@0.2.0", "heck@0.4.1", "lopdf@0.39.0", "nom_locate@5.0.0", "ouroboros@0.17.2", "ouroboros_macro@0.17.2", "pathfinder_geometry@0.5.1", "pathfinder_simd@0.5.6", "printpdf@0.10.1", "proc-macro-error-attr@1.0.4", "proc-macro-error@1.0.4", "rangemap@1.7.1", "rustc-hash@1.1.0", "syn@1.0.109", "ttf-parser@0.25.1", "ucd-trie@0.1.7", "unicode-canonical-combining-class@1.0.0", "unicode-general-category@1.1.0", "unicode-joining-type@1.0.0"]}, +{"name": "proptest", "versions": ["1.11.0"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "proptest", "kind": "dev", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["proptest@1.11.0"], "reference_lines": 31, "references": ["crates/perry-container-compose/src/yaml.rs:505", "crates/perry-container-compose/src/yaml.rs:508", "crates/perry-container-compose/tests/compose_tests.rs:4", "crates/perry-container-compose/tests/compose_tests.rs:139", "crates/perry-container-compose/tests/fixtures_tests.rs:83", "crates/perry-container-compose/tests/fixtures_tests.rs:85"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "proptest", "kind": "dev", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["proptest@1.11.0"], "reference_lines": 13, "references": ["crates/perry-stdlib/tests/container_props.rs:9", "crates/perry-stdlib/tests/container_props.rs:20", "crates/perry-stdlib/tests/container_props.rs:21", "crates/perry-stdlib/tests/container_props.rs:22", "crates/perry-stdlib/tests/container_props.rs:23", "crates/perry-stdlib/tests/container_props.rs:28"]}], "lock_closure_packages": 91, "lock_packages_lost_if_all_workspace_edges_removed": ["bit-set@0.8.0", "bit-vec@0.8.0", "proptest@1.11.0", "quick-error@1.2.3", "rand_xorshift@0.4.0", "rusty-fork@0.3.1", "unarray@0.1.4", "wait-timeout@0.2.1"]}, +{"name": "qrcodegen", "versions": ["1.8.0"], "edges": [{"owner": "perry-ui-windows", "manifest": "crates/perry-ui-windows/Cargo.toml", "alias": "qrcodegen", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^1.8", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["qrcodegen@1.8.0"], "reference_lines": 1, "references": ["crates/perry-ui-windows/src/widgets/qrcode.rs:62"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": ["qrcodegen@1.8.0"]}, +{"name": "rand", "versions": ["0.10.2", "0.8.7", "0.9.4"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "rand", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rand@0.10.2"], "reference_lines": 2, "references": ["crates/perry-container-compose/src/service.rs:8", "crates/perry-container-compose/src/service.rs:26"]}, {"owner": "perry-ext-ethers", "manifest": "crates/perry-ext-ethers/Cargo.toml", "alias": "rand", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rand@0.10.2"], "reference_lines": 1, "references": ["crates/perry-ext-ethers/src/lib.rs:41"]}, {"owner": "perry-ext-nanoid", "manifest": "crates/perry-ext-nanoid/Cargo.toml", "alias": "rand", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rand@0.10.2"], "reference_lines": 2, "references": ["crates/perry-ext-nanoid/src/lib.rs:55", "crates/perry-ext-nanoid/src/lib.rs:56"]}, {"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "rand", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rand@0.10.2"], "reference_lines": 1, "references": ["crates/perry-ext-node-forge/src/crypto.rs:144"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "rand", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rand@0.10.2"], "reference_lines": 7, "references": ["crates/perry-runtime/src/buffer/mutate.rs:32", "crates/perry-runtime/src/buffer/mutate.rs:41", "crates/perry-runtime/src/math.rs:3", "crates/perry-runtime/src/math.rs:288", "crates/perry-runtime/src/object/native_module_crypto_random.rs:75", "crates/perry-runtime/src/object/native_module_crypto_random.rs:93"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "rand", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rand@0.10.2"], "reference_lines": 19, "references": ["crates/perry-stdlib/src/container/capability.rs:30", "crates/perry-stdlib/src/crypto/prime.rs:201", "crates/perry-stdlib/src/crypto/random.rs:66", "crates/perry-stdlib/src/crypto/random.rs:118", "crates/perry-stdlib/src/crypto/random.rs:255", "crates/perry-stdlib/src/crypto/random.rs:525"]}, {"owner": "perry-ui-geisterhand", "manifest": "crates/perry-ui-geisterhand/Cargo.toml", "alias": "rand", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rand@0.10.2"], "reference_lines": 6, "references": ["crates/perry-ui-geisterhand/src/chaos.rs:67", "crates/perry-ui-geisterhand/src/chaos.rs:83", "crates/perry-ui-geisterhand/src/chaos.rs:86", "crates/perry-ui-geisterhand/src/chaos.rs:109", "crates/perry-ui-geisterhand/src/chaos.rs:116", "crates/perry-ui-geisterhand/src/chaos.rs:127"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "rand", "kind": "normal", "target": null, "optional": true, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": ["updater-cli"], "resolved": ["rand@0.10.2"], "reference_lines": 2, "references": ["crates/perry/src/commands/updater.rs:160", "crates/perry/src/commands/updater.rs:162"]}], "lock_closure_packages": 79, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "rand_core", "versions": ["0.10.1", "0.6.4", "0.9.5"], "edges": [{"owner": "perry-ext-argon2", "manifest": "crates/perry-ext-argon2/Cargo.toml", "alias": "rand_core", "kind": "normal", "target": null, "optional": false, "requirement": "^0.6", "default_features": true, "features": ["getrandom"], "direct_feature_activators": [], "resolved": ["rand_core@0.6.4"], "reference_lines": 1, "references": ["crates/perry-ext-argon2/src/lib.rs:13"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "rand_core_06", "kind": "normal", "target": null, "optional": false, "requirement": "^0.6", "default_features": true, "features": ["getrandom"], "direct_feature_activators": [], "resolved": ["rand_core@0.6.4"], "reference_lines": 36, "references": ["crates/perry-stdlib/src/crypto/kdf.rs:1170", "crates/perry-stdlib/src/crypto/kdf.rs:1183", "crates/perry-stdlib/src/crypto/keys.rs:84", "crates/perry-stdlib/src/crypto/sign.rs:224", "crates/perry-stdlib/src/crypto/sign.rs:249", "crates/perry-stdlib/src/crypto/sign.rs:414"]}], "lock_closure_packages": 39, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "rayon", "versions": ["1.12.0"], "edges": [{"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "rayon", "kind": "normal", "target": null, "optional": false, "requirement": "^1.10", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rayon@1.12.0"], "reference_lines": 3, "references": ["crates/perry/src/commands/compile/bootstrap.rs:1016", "crates/perry/src/commands/compile/run_pipeline.rs:3129", "crates/perry/src/commands/compile.rs:4"]}], "lock_closure_packages": 13, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "redis", "versions": ["1.6.0"], "edges": [{"owner": "perry-ext-ioredis", "manifest": "crates/perry-ext-ioredis/Cargo.toml", "alias": "redis", "kind": "normal", "target": null, "optional": false, "requirement": "^1.2", "default_features": true, "features": ["tokio-comp", "connection-manager"], "direct_feature_activators": [], "resolved": ["redis@1.6.0"], "reference_lines": 9, "references": ["crates/perry-ext-ioredis/src/lib.rs:17", "crates/perry-ext-ioredis/src/lib.rs:32", "crates/perry-ext-ioredis/src/lib.rs:78", "crates/perry-ext-ioredis/src/lib.rs:91", "crates/perry-ext-ioredis/src/lib.rs:151", "crates/perry-ext-ioredis/src/lib.rs:152"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "redis", "kind": "normal", "target": null, "optional": true, "requirement": "^1.2", "default_features": true, "features": ["tokio-comp", "connection-manager"], "direct_feature_activators": ["bundled-ioredis"], "resolved": ["redis@1.6.0"], "reference_lines": 33, "references": ["crates/perry-stdlib/src/ioredis.rs:7", "crates/perry-stdlib/src/ioredis.rs:28", "crates/perry-stdlib/src/ioredis.rs:59", "crates/perry-stdlib/src/ioredis.rs:78", "crates/perry-stdlib/src/ioredis.rs:133", "crates/perry-stdlib/src/ioredis.rs:138"]}], "lock_closure_packages": 96, "lock_packages_lost_if_all_workspace_edges_removed": ["arc-swap@1.9.1", "arcstr@1.2.0", "backon@1.6.0", "num-bigint@0.5.1", "redis@1.6.0"]}, +{"name": "regex", "versions": ["1.13.1"], "edges": [{"owner": "perry-perex", "manifest": "crates/perry-perex/Cargo.toml", "alias": "regex", "kind": "dev", "target": null, "optional": false, "requirement": "^1.12", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["regex@1.13.1"], "reference_lines": 10, "references": ["crates/perry-perex/tests/dialect_parity.rs:177", "crates/perry-perex/tests/dialect_parity.rs:178", "crates/perry-perex/tests/dialect_parity.rs:179", "crates/perry-perex/tests/dialect_parity.rs:180", "crates/perry-perex/tests/dialect_parity.rs:181", "crates/perry-perex/tests/dialect_parity.rs:233"]}, {"owner": "perry-validation", "manifest": "crates/perry-validation/Cargo.toml", "alias": "regex", "kind": "dev", "target": null, "optional": false, "requirement": "^1.12", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["regex@1.13.1"], "reference_lines": 1, "references": ["crates/perry-validation/src/tests.rs:6"]}], "lock_closure_packages": 5, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "reqwest", "versions": ["0.12.28"], "edges": [{"owner": "perry-ext-axios", "manifest": "crates/perry-ext-axios/Cargo.toml", "alias": "reqwest", "kind": "normal", "target": null, "optional": false, "requirement": "^0.12", "default_features": false, "features": ["rustls-tls", "json", "multipart", "blocking"], "direct_feature_activators": [], "resolved": ["reqwest@0.12.28"], "reference_lines": 4, "references": ["crates/perry-ext-axios/src/lib.rs:81", "crates/perry-ext-axios/src/lib.rs:96", "crates/perry-ext-axios/src/lib.rs:114", "crates/perry-ext-axios/src/lib.rs:172"]}, {"owner": "perry-ext-fetch", "manifest": "crates/perry-ext-fetch/Cargo.toml", "alias": "reqwest", "kind": "normal", "target": null, "optional": false, "requirement": "^0.12", "default_features": false, "features": ["json", "rustls-tls", "http2"], "direct_feature_activators": [], "resolved": ["reqwest@0.12.28"], "reference_lines": 14, "references": ["crates/perry-ext-fetch/src/lib.rs:203", "crates/perry-ext-fetch/src/lib.rs:205", "crates/perry-ext-fetch/src/lib.rs:213", "crates/perry-ext-fetch/src/lib.rs:218", "crates/perry-ext-fetch/src/lib.rs:219", "crates/perry-ext-fetch/src/lib.rs:230"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "reqwest", "kind": "normal", "target": null, "optional": false, "requirement": "^0.12", "default_features": false, "features": ["json", "rustls-tls", "http2"], "direct_feature_activators": [], "resolved": ["reqwest@0.12.28"], "reference_lines": 39, "references": ["crates/perry-ext-http/src/agent/tls_compat.rs:8", "crates/perry-ext-http/src/agent/tls_compat.rs:39", "crates/perry-ext-http/src/agent.rs:213", "crates/perry-ext-http/src/agent.rs:221", "crates/perry-ext-http/src/agent.rs:258", "crates/perry-ext-http/src/agent.rs:637"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "reqwest", "kind": "normal", "target": null, "optional": true, "requirement": "^0.12", "default_features": false, "features": ["json", "rustls-tls", "http2"], "direct_feature_activators": ["web-fetch"], "resolved": ["reqwest@0.12.28"], "reference_lines": 26, "references": ["crates/perry-stdlib/src/axios.rs:50", "crates/perry-stdlib/src/axios.rs:64", "crates/perry-stdlib/src/axios.rs:104", "crates/perry-stdlib/src/axios.rs:110", "crates/perry-stdlib/src/axios.rs:116", "crates/perry-stdlib/src/axios.rs:141"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "reqwest", "kind": "normal", "target": null, "optional": false, "requirement": "^0.12", "default_features": false, "features": ["rustls-tls", "json", "multipart", "blocking"], "direct_feature_activators": [], "resolved": ["reqwest@0.12.28"], "reference_lines": 18, "references": ["crates/perry/src/commands/audit.rs:6", "crates/perry/src/commands/audit.rs:204", "crates/perry/src/commands/login.rs:79", "crates/perry/src/commands/publish/mod.rs:10", "crates/perry/src/commands/publish/mod.rs:1476", "crates/perry/src/commands/publish/mod.rs:1985"]}], "lock_closure_packages": 178, "lock_packages_lost_if_all_workspace_edges_removed": ["hyper-rustls@0.27.9", "lru-slab@0.1.2", "mime_guess@2.0.5", "quinn-proto@0.11.15", "quinn-udp@0.5.14", "quinn@0.11.9", "reqwest@0.12.28", "serde_urlencoded@0.7.1", "sync_wrapper@1.0.2", "tower-http@0.6.11", "tower-layer@0.3.3", "tower@0.5.3", "unicase@2.9.0", "windows-sys@0.60.2", "windows-targets@0.53.5", "windows_aarch64_gnullvm@0.53.1", "windows_aarch64_msvc@0.53.1", "windows_i686_gnu@0.53.1", "windows_i686_gnullvm@0.53.1", "windows_i686_msvc@0.53.1", "windows_x86_64_gnu@0.53.1", "windows_x86_64_gnullvm@0.53.1", "windows_x86_64_msvc@0.53.1"]}, +{"name": "resolv-conf", "versions": ["0.7.6"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "resolv_conf", "kind": "normal", "target": null, "optional": false, "requirement": "^0.7", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["resolv-conf@0.7.6"], "reference_lines": 1, "references": ["crates/perry-runtime/src/dns_resolver.rs:167"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "rgb", "versions": ["0.8.53"], "edges": [{"owner": "perry-doc-tests", "manifest": "crates/perry-doc-tests/Cargo.toml", "alias": "rgb", "kind": "normal", "target": null, "optional": false, "requirement": "^0.8", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rgb@0.8.53"], "reference_lines": 2, "references": ["crates/perry-doc-tests/src/image_diff.rs:128", "crates/perry-doc-tests/src/image_diff.rs:130"]}], "lock_closure_packages": 2, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "ring", "versions": ["0.17.14"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "ring", "kind": "normal", "target": null, "optional": false, "requirement": "^0.17", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["ring@0.17.14"], "reference_lines": 21, "references": ["crates/perry-ext-http/src/server/tls.rs:10", "crates/perry-ext-http/src/server/tls.rs:11", "crates/perry-ext-http/src/server/tls.rs:12", "crates/perry-ext-http/src/server/tls.rs:328", "crates/perry-ext-http/src/tls_client.rs:52", "crates/perry-ext-http/src/tls_client.rs:443"]}], "lock_closure_packages": 52, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "rsa", "versions": ["0.10.0-rc.18", "0.9.10"], "edges": [{"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "rsa", "kind": "normal", "target": null, "optional": false, "requirement": "^0.10.0-rc.18", "default_features": true, "features": ["sha2"], "direct_feature_activators": [], "resolved": ["rsa@0.10.0-rc.18"], "reference_lines": 11, "references": ["crates/perry-ext-node-forge/src/crypto.rs:23", "crates/perry-ext-node-forge/src/crypto.rs:24", "crates/perry-ext-node-forge/src/crypto.rs:25", "crates/perry-ext-node-forge/src/crypto.rs:26", "crates/perry-ext-node-forge/src/crypto.rs:148", "crates/perry-ext-node-forge/src/crypto.rs:152"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "rsa", "kind": "normal", "target": null, "optional": true, "requirement": "^0.9", "default_features": false, "features": ["pem", "pkcs5", "sha2"], "direct_feature_activators": ["bundled-jsonwebtoken"], "resolved": ["rsa@0.9.10"], "reference_lines": 32, "references": ["crates/perry-stdlib/src/crypto/certificate.rs:161", "crates/perry-stdlib/src/crypto/kdf.rs:1169", "crates/perry-stdlib/src/crypto/kdf.rs:1173", "crates/perry-stdlib/src/crypto/sign.rs:412", "crates/perry-stdlib/src/crypto/util.rs:33", "crates/perry-stdlib/src/crypto/util.rs:36"]}], "lock_closure_packages": 136, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "rusqlite", "versions": ["0.39.0"], "edges": [{"owner": "perry-ext-better-sqlite3", "manifest": "crates/perry-ext-better-sqlite3/Cargo.toml", "alias": "rusqlite", "kind": "normal", "target": null, "optional": false, "requirement": "^0.39", "default_features": true, "features": ["bundled"], "direct_feature_activators": [], "resolved": ["rusqlite@0.39.0"], "reference_lines": 8, "references": ["crates/perry-ext-better-sqlite3/src/lib.rs:21", "crates/perry-ext-better-sqlite3/src/lib.rs:80", "crates/perry-ext-better-sqlite3/src/lib.rs:89", "crates/perry-ext-better-sqlite3/src/lib.rs:96", "crates/perry-ext-better-sqlite3/src/lib.rs:104", "crates/perry-ext-better-sqlite3/src/lib.rs:251"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "rusqlite", "kind": "normal", "target": null, "optional": true, "requirement": "^0.39", "default_features": true, "features": ["bundled", "column_decltype", "limits", "session"], "direct_feature_activators": ["database-sqlite"], "resolved": ["rusqlite@0.39.0"], "reference_lines": 21, "references": ["crates/perry-stdlib/src/sqlite/backup.rs:9", "crates/perry-stdlib/src/sqlite/backup.rs:77", "crates/perry-stdlib/src/sqlite/backup.rs:79", "crates/perry-stdlib/src/sqlite/better.rs:7", "crates/perry-stdlib/src/sqlite/better.rs:141", "crates/perry-stdlib/src/sqlite/better.rs:158"]}], "lock_closure_packages": 70, "lock_packages_lost_if_all_workspace_edges_removed": ["fallible-iterator@0.3.0", "fallible-streaming-iterator@0.1.9", "rsqlite-vfs@0.1.1", "rusqlite@0.39.0", "sqlite-wasm-rs@0.5.5"]}, +{"name": "rust_decimal", "versions": ["1.43.0"], "edges": [{"owner": "perry-ext-decimal", "manifest": "crates/perry-ext-decimal/Cargo.toml", "alias": "rust_decimal", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rust_decimal@1.43.0"], "reference_lines": 2, "references": ["crates/perry-ext-decimal/src/lib.rs:8", "crates/perry-ext-decimal/src/lib.rs:9"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "rust_decimal", "kind": "normal", "target": null, "optional": true, "requirement": "^1.33", "default_features": true, "features": ["maths"], "direct_feature_activators": ["bundled-decimal"], "resolved": ["rust_decimal@1.43.0"], "reference_lines": 2, "references": ["crates/perry-stdlib/src/decimal.rs:7", "crates/perry-stdlib/src/decimal.rs:8"]}], "lock_closure_packages": 66, "lock_packages_lost_if_all_workspace_edges_removed": ["borsh-derive@1.6.1", "borsh@1.6.1", "rust_decimal@1.43.0"]}, +{"name": "rustc-demangle", "versions": ["0.1.28"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "rustc_demangle", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rustc-demangle@0.1.28"], "reference_lines": 1, "references": ["crates/perry-runtime/src/error_stack_frames.rs:459"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "rustc_demangle", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rustc-demangle@0.1.28"], "reference_lines": 1, "references": ["crates/perry/src/commands/compile/size_report.rs:730"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": ["rustc-demangle@0.1.28"]}, +{"name": "rustls", "versions": ["0.23.43"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "rustls", "kind": "normal", "target": null, "optional": false, "requirement": "^0.23", "default_features": true, "features": ["std", "ring", "tls12"], "direct_feature_activators": [], "resolved": ["rustls@0.23.43"], "reference_lines": 90, "references": ["crates/perry-ext-http/src/server/http2_server.rs:176", "crates/perry-ext-http/src/server/https_server.rs:236", "crates/perry-ext-http/src/server/tls.rs:13", "crates/perry-ext-http/src/server/tls.rs:14", "crates/perry-ext-http/src/server/tls.rs:15", "crates/perry-ext-http/src/server/tls.rs:294"]}, {"owner": "perry-ext-net", "manifest": "crates/perry-ext-net/Cargo.toml", "alias": "rustls", "kind": "normal", "target": null, "optional": false, "requirement": "^0.23", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rustls@0.23.43"], "reference_lines": 44, "references": ["crates/perry-ext-net/src/tls.rs:9", "crates/perry-ext-net/src/tls.rs:12", "crates/perry-ext-net/src/tls.rs:202", "crates/perry-ext-net/src/tls.rs:206", "crates/perry-ext-net/src/tls.rs:209", "crates/perry-ext-net/src/tls.rs:247"]}, {"owner": "perry-ext-ws", "manifest": "crates/perry-ext-ws/Cargo.toml", "alias": "rustls", "kind": "normal", "target": null, "optional": false, "requirement": "^0.23", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rustls@0.23.43"], "reference_lines": 1, "references": ["crates/perry-ext-ws/src/lib.rs:67"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "rustls", "kind": "normal", "target": null, "optional": true, "requirement": "^0.23", "default_features": true, "features": [], "direct_feature_activators": ["bundled-ws", "external-tls-server", "tls-runtime"], "resolved": ["rustls@0.23.43"], "reference_lines": 86, "references": ["crates/perry-stdlib/src/net/mod.rs:48", "crates/perry-stdlib/src/net/mod.rs:52", "crates/perry-stdlib/src/net/mod.rs:427", "crates/perry-stdlib/src/net/mod.rs:431", "crates/perry-stdlib/src/net/mod.rs:434", "crates/perry-stdlib/src/net/mod.rs:665"]}], "lock_closure_packages": 65, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "rustls-native-certs", "versions": ["0.8.4"], "edges": [{"owner": "perry-ext-net", "manifest": "crates/perry-ext-net/Cargo.toml", "alias": "rustls_native_certs", "kind": "normal", "target": null, "optional": false, "requirement": "^0.8", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rustls-native-certs@0.8.4"], "reference_lines": 1, "references": ["crates/perry-ext-net/src/tls.rs:386"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "rustls_native_certs", "kind": "normal", "target": null, "optional": true, "requirement": "^0.8", "default_features": true, "features": [], "direct_feature_activators": ["external-tls-server", "tls-runtime"], "resolved": ["rustls-native-certs@0.8.4"], "reference_lines": 1, "references": ["crates/perry-stdlib/src/net/mod.rs:678"]}], "lock_closure_packages": 44, "lock_packages_lost_if_all_workspace_edges_removed": ["core-foundation@0.10.1", "openssl-probe@0.2.1", "rustls-native-certs@0.8.4", "schannel@0.1.29", "security-framework-sys@2.17.0", "security-framework@3.7.0"]}, +{"name": "rustls-pemfile", "versions": ["2.2.0"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "rustls_pemfile", "kind": "normal", "target": null, "optional": false, "requirement": "^2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rustls-pemfile@2.2.0"], "reference_lines": 8, "references": ["crates/perry-ext-http/src/server/tls.rs:259", "crates/perry-ext-http/src/server/tls.rs:268", "crates/perry-ext-http/src/server/tls.rs:272", "crates/perry-ext-http/src/server/tls.rs:276", "crates/perry-ext-http/src/tls_client.rs:548", "crates/perry-ext-http/src/tls_client.rs:1176"]}, {"owner": "perry-ext-net", "manifest": "crates/perry-ext-net/Cargo.toml", "alias": "rustls_pemfile", "kind": "normal", "target": null, "optional": false, "requirement": "^2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rustls-pemfile@2.2.0"], "reference_lines": 6, "references": ["crates/perry-ext-net/src/tls.rs:250", "crates/perry-ext-net/src/tls.rs:262", "crates/perry-ext-net/src/tls.rs:437", "crates/perry-ext-net/src/tls.rs:442", "crates/perry-ext-net/src/tls.rs:563", "crates/perry-ext-net/src/tls.rs:583"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "rustls_pemfile", "kind": "normal", "target": null, "optional": true, "requirement": "^2", "default_features": true, "features": [], "direct_feature_activators": ["external-tls-server", "tls-runtime"], "resolved": ["rustls-pemfile@2.2.0"], "reference_lines": 11, "references": ["crates/perry-stdlib/src/net/mod.rs:726", "crates/perry-stdlib/src/net/mod.rs:739", "crates/perry-stdlib/src/net/mod.rs:755", "crates/perry-stdlib/src/net/mod.rs:760", "crates/perry-stdlib/src/net/mod.rs:1365", "crates/perry-stdlib/src/net/mod.rs:1380"]}], "lock_closure_packages": 34, "lock_packages_lost_if_all_workspace_edges_removed": ["rustls-pemfile@2.2.0"]}, +{"name": "rustls-webpki", "versions": ["0.103.13"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "rustls_webpki", "kind": "normal", "target": null, "optional": false, "requirement": "^0.103", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["rustls-webpki@0.103.13"], "reference_lines": 6, "references": ["crates/perry-ext-http/src/tls_client.rs:277", "crates/perry-ext-http/src/tls_client.rs:281", "crates/perry-ext-http/src/tls_client.rs:369", "crates/perry-ext-http/src/tls_client.rs:374", "crates/perry-ext-http/src/tls_client.rs:403", "crates/perry-ext-http/src/tls_client.rs:422"]}], "lock_closure_packages": 62, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "ryu", "versions": ["1.0.23"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "ryu", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["ryu@1.0.23"], "reference_lines": 2, "references": ["crates/perry-runtime/src/bun_compat/cli_utils.rs:1045", "crates/perry-runtime/src/node_stream_json.rs:21"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "ryu", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["ryu@1.0.23"], "reference_lines": 0, "references": []}, {"owner": "perry-ui-android", "manifest": "crates/perry-ui-android/Cargo.toml", "alias": "ryu", "kind": "normal", "target": "cfg(target_os = \"android\")", "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["ryu@1.0.23"], "reference_lines": 0, "references": []}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "ryu-js", "versions": ["1.0.3"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "ryu_js", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0.3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["ryu-js@1.0.3"], "reference_lines": 8, "references": ["crates/perry-runtime/src/json/stringify_api.rs:365", "crates/perry-runtime/src/json/stringify_flat.rs:198", "crates/perry-runtime/src/json/stringify_flat_tests.rs:308", "crates/perry-runtime/src/json/stringify_scalars.rs:53", "crates/perry-runtime/src/json/stringify_scalars_tests.rs:12", "crates/perry-runtime/src/json/stringify_scalars_tests.rs:40"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "scraper", "versions": ["0.27.0"], "edges": [{"owner": "perry-ext-cheerio", "manifest": "crates/perry-ext-cheerio/Cargo.toml", "alias": "scraper", "kind": "normal", "target": null, "optional": false, "requirement": "^0.27", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["scraper@0.27.0"], "reference_lines": 1, "references": ["crates/perry-ext-cheerio/src/lib.rs:9"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "scraper", "kind": "normal", "target": null, "optional": true, "requirement": "^0.27", "default_features": true, "features": [], "direct_feature_activators": ["bundled-cheerio"], "resolved": ["scraper@0.27.0"], "reference_lines": 1, "references": ["crates/perry-stdlib/src/cheerio.rs:10"]}], "lock_closure_packages": 55, "lock_packages_lost_if_all_workspace_edges_removed": ["cssparser-macros@0.7.0", "cssparser@0.37.0", "dtoa-short@0.3.5", "dtoa@1.0.11", "ego-tree@0.11.0", "getopts@0.2.24", "html5ever@0.39.0", "markup5ever@0.39.0", "phf@0.13.1", "phf_codegen@0.13.1", "phf_generator@0.13.1", "phf_macros@0.13.1", "phf_shared@0.13.1", "precomputed-hash@0.1.1", "scraper@0.27.0", "selectors@0.38.0", "servo_arc@0.4.3", "string_cache@0.9.0", "string_cache_codegen@0.6.1", "tendril@0.5.0", "web_atoms@0.2.4"]}, +{"name": "scrypt", "versions": ["0.11.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "scrypt", "kind": "normal", "target": null, "optional": true, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["scrypt@0.11.0"], "reference_lines": 9, "references": ["crates/perry-stdlib/src/crypto/kdf.rs:826", "crates/perry-stdlib/src/crypto/kdf.rs:827", "crates/perry-stdlib/src/crypto/kdf.rs:830", "crates/perry-stdlib/src/crypto/kdf.rs:871", "crates/perry-stdlib/src/crypto/kdf.rs:877", "crates/perry-stdlib/src/crypto/kdf.rs:1027"]}], "lock_closure_packages": 54, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "semver", "versions": ["1.0.28"], "edges": [{"owner": "perry-updater", "manifest": "crates/perry-updater/Cargo.toml", "alias": "semver", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["semver@1.0.28"], "reference_lines": 3, "references": ["crates/perry-updater/src/cli_manifest.rs:6", "crates/perry-updater/src/core.rs:80", "crates/perry-updater/src/core.rs:84"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "semver", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["semver@1.0.28"], "reference_lines": 3, "references": ["crates/perry/src/commands/compile/resolve/native_library.rs:1810", "crates/perry/src/update_checker.rs:8", "crates/perry/tests/issue_9600_bun_cli_utilities.rs:49"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "serde", "versions": ["1.0.229"], "edges": [{"owner": "perry-api-manifest", "manifest": "crates/perry-api-manifest/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": true, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": ["serde"], "resolved": ["serde@1.0.229"], "reference_lines": 5, "references": ["crates/perry-api-manifest/src/lib.rs:36", "crates/perry-api-manifest/src/lib.rs:128", "crates/perry-api-manifest/src/lib.rs:160", "crates/perry-api-manifest/src/lib.rs:192", "crates/perry-api-manifest/src/lib.rs:214"]}, {"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 21, "references": ["crates/perry-codegen/src/native_value/artifact.rs:6", "crates/perry-codegen/src/native_value/buffer.rs:1", "crates/perry-codegen/src/native_value/materialize.rs:1", "crates/perry-codegen/src/native_value/rep.rs:1", "crates/perry-codegen/src/opt_report/mod.rs:181", "crates/perry-codegen/src/opt_report/mod.rs:204"]}, {"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 9, "references": ["crates/perry-container-compose/src/backend/apple.rs:6", "crates/perry-container-compose/src/backend/docker.rs:6", "crates/perry-container-compose/src/backend.rs:7", "crates/perry-container-compose/src/compose.rs:1076", "crates/perry-container-compose/src/error.rs:6", "crates/perry-container-compose/src/error.rs:69"]}, {"owner": "perry-diagnostics", "manifest": "crates/perry-diagnostics/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive", "derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 3, "references": ["crates/perry-diagnostics/src/compat_report.rs:26", "crates/perry-diagnostics/src/diagnostic.rs:4", "crates/perry-diagnostics/src/span.rs:3"]}, {"owner": "perry-doc-tests", "manifest": "crates/perry-doc-tests/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 1, "references": ["crates/perry-doc-tests/src/main.rs:14"]}, {"owner": "perry-ext-jsonwebtoken", "manifest": "crates/perry-ext-jsonwebtoken/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 1, "references": ["crates/perry-ext-jsonwebtoken/src/lib.rs:10"]}, {"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 1, "references": ["crates/perry-ext-node-forge/src/lib.rs:36"]}, {"owner": "perry-ext-parcel-watcher", "manifest": "crates/perry-ext-parcel-watcher/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive", "derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 1, "references": ["crates/perry-ext-parcel-watcher/src/lib.rs:19"]}, {"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 2, "references": ["crates/perry-ext-typescript/src/bun.rs:23", "crates/perry-ext-typescript/src/lib.rs:12"]}, {"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 2, "references": ["crates/perry-hir/src/audit.rs:26", "crates/perry-hir/src/audit.rs:43"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 1, "references": ["crates/perry-runtime/src/node_api_host/loader.rs:3"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive", "derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 4, "references": ["crates/perry-stdlib/src/container/types.rs:6", "crates/perry-stdlib/src/fetch/bun_server_bridge.rs:10", "crates/perry-stdlib/src/fetch/bun_server_bridge.rs:18", "crates/perry-stdlib/src/jsonwebtoken.rs:10"]}, {"owner": "perry-ui-geisterhand", "manifest": "crates/perry-ui-geisterhand/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive", "derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 1, "references": ["crates/perry-ui-geisterhand/src/chaos.rs:20"]}, {"owner": "perry-updater", "manifest": "crates/perry-updater/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive", "derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 1, "references": ["crates/perry-updater/src/cli_manifest.rs:7"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "serde", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": ["derive"], "direct_feature_activators": [], "resolved": ["serde@1.0.229"], "reference_lines": 31, "references": ["crates/perry/src/commands/attest.rs:34", "crates/perry/src/commands/audit.rs:7", "crates/perry/src/commands/compile/asset_manifest.rs:7", "crates/perry/src/commands/compile/build_cache.rs:2", "crates/perry/src/commands/compile/collect_modules/static_require_transform.rs:6", "crates/perry/src/commands/compile/collect_modules/static_require_transform.rs:7"]}], "lock_closure_packages": 7, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "serde_json", "versions": ["1.0.151"], "edges": [{"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 46, "references": ["crates/perry-codegen/src/native_value/artifact.rs:620", "crates/perry-codegen/src/opt_report/mod.rs:1394", "crates/perry-codegen/src/opt_report/mod.rs:1410", "crates/perry-codegen/src/opt_report/render.rs:585", "crates/perry-codegen/src/opt_report/render.rs:733", "crates/perry-codegen/src/opt_report/render.rs:757"]}, {"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 33, "references": ["crates/perry-container-compose/src/backend/apple.rs:394", "crates/perry-container-compose/src/backend/apple.rs:413", "crates/perry-container-compose/src/backend/apple.rs:433", "crates/perry-container-compose/src/backend/detect.rs:199", "crates/perry-container-compose/src/backend/detect.rs:200", "crates/perry-container-compose/src/backend/detect.rs:239"]}, {"owner": "perry-diagnostics", "manifest": "crates/perry-diagnostics/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 9, "references": ["crates/perry-diagnostics/src/emitter.rs:275", "crates/perry-diagnostics/src/emitter.rs:279", "crates/perry-diagnostics/src/emitter.rs:285", "crates/perry-diagnostics/src/emitter.rs:287", "crates/perry-diagnostics/src/emitter.rs:294", "crates/perry-diagnostics/src/emitter.rs:301"]}, {"owner": "perry-diagnostics", "manifest": "crates/perry-diagnostics/Cargo.toml", "alias": "serde_json", "kind": "dev", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 9, "references": ["crates/perry-diagnostics/src/emitter.rs:275", "crates/perry-diagnostics/src/emitter.rs:279", "crates/perry-diagnostics/src/emitter.rs:285", "crates/perry-diagnostics/src/emitter.rs:287", "crates/perry-diagnostics/src/emitter.rs:294", "crates/perry-diagnostics/src/emitter.rs:301"]}, {"owner": "perry-doc-tests", "manifest": "crates/perry-doc-tests/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 4, "references": ["crates/perry-doc-tests/src/image_diff.rs:108", "crates/perry-doc-tests/src/main.rs:282", "crates/perry-doc-tests/tests/compiler_environment.rs:6", "crates/perry-doc-tests/tests/compiler_environment.rs:72"]}, {"owner": "perry-ext-dotenv", "manifest": "crates/perry-ext-dotenv/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 1, "references": ["crates/perry-ext-dotenv/src/lib.rs:124"]}, {"owner": "perry-ext-fastify", "manifest": "crates/perry-ext-fastify/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 8, "references": ["crates/perry-ext-fastify/src/app.rs:284", "crates/perry-ext-fastify/src/app.rs:294", "crates/perry-ext-fastify/src/app.rs:304", "crates/perry-ext-fastify/src/context.rs:274", "crates/perry-ext-fastify/src/context.rs:331", "crates/perry-ext-fastify/src/context.rs:724"]}, {"owner": "perry-ext-fetch", "manifest": "crates/perry-ext-fetch/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 2, "references": ["crates/perry-ext-fetch/src/lib.rs:694", "crates/perry-ext-fetch/src/lib.rs:888"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 116, "references": ["crates/perry-ext-http/src/agent/tls_compat.rs:222", "crates/perry-ext-http/src/agent/tls_compat.rs:233", "crates/perry-ext-http/src/agent/tls_compat.rs:238", "crates/perry-ext-http/src/agent.rs:1205", "crates/perry-ext-http/src/agent.rs:1253", "crates/perry-ext-http/src/agent.rs:1316"]}, {"owner": "perry-ext-jsonwebtoken", "manifest": "crates/perry-ext-jsonwebtoken/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 4, "references": ["crates/perry-ext-jsonwebtoken/src/lib.rs:19", "crates/perry-ext-jsonwebtoken/src/lib.rs:53", "crates/perry-ext-jsonwebtoken/src/lib.rs:206", "crates/perry-ext-jsonwebtoken/src/lib.rs:238"]}, {"owner": "perry-ext-mongodb", "manifest": "crates/perry-ext-mongodb/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 17, "references": ["crates/perry-ext-mongodb/src/lib.rs:327", "crates/perry-ext-mongodb/src/lib.rs:332", "crates/perry-ext-mongodb/src/lib.rs:370", "crates/perry-ext-mongodb/src/lib.rs:378", "crates/perry-ext-mongodb/src/lib.rs:421", "crates/perry-ext-mongodb/src/lib.rs:465"]}, {"owner": "perry-ext-mysql2", "manifest": "crates/perry-ext-mysql2/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["preserve_order"], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 9, "references": ["crates/perry-ext-mysql2/src/lib.rs:234", "crates/perry-ext-mysql2/src/lib.rs:318", "crates/perry-ext-mysql2/src/lib.rs:396", "crates/perry-ext-mysql2/src/lib.rs:398", "crates/perry-ext-mysql2/src/lib.rs:399", "crates/perry-ext-mysql2/src/lib.rs:401"]}, {"owner": "perry-ext-net", "manifest": "crates/perry-ext-net/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 3, "references": ["crates/perry-ext-net/src/lib.rs:880", "crates/perry-ext-net/src/socket_facade.rs:121", "crates/perry-ext-net/src/socket_facade.rs:122"]}, {"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 16, "references": ["crates/perry-ext-node-forge/src/lib.rs:103", "crates/perry-ext-node-forge/src/lib.rs:140", "crates/perry-ext-node-forge/src/lib.rs:142", "crates/perry-ext-node-forge/src/lib.rs:171", "crates/perry-ext-node-forge/src/lib.rs:185", "crates/perry-ext-node-forge/src/lib.rs:187"]}, {"owner": "perry-ext-parcel-watcher", "manifest": "crates/perry-ext-parcel-watcher/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 4, "references": ["crates/perry-ext-parcel-watcher/src/lib.rs:860", "crates/perry-ext-parcel-watcher/src/lib.rs:903", "crates/perry-ext-parcel-watcher/src/lib.rs:1049", "crates/perry-ext-parcel-watcher/src/lib.rs:1050"]}, {"owner": "perry-ext-qs", "manifest": "crates/perry-ext-qs/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 14, "references": ["crates/perry-ext-qs/src/lib.rs:44", "crates/perry-ext-qs/src/parse.rs:4", "crates/perry-ext-qs/src/parse.rs:337", "crates/perry-ext-qs/src/parse.rs:349", "crates/perry-ext-qs/src/parse.rs:355", "crates/perry-ext-qs/src/parse.rs:367"]}, {"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 11, "references": ["crates/perry-ext-typescript/src/bun.rs:556", "crates/perry-ext-typescript/src/bun.rs:655", "crates/perry-ext-typescript/src/bun.rs:668", "crates/perry-ext-typescript/src/lib.rs:13", "crates/perry-ext-typescript/src/lib.rs:42", "crates/perry-ext-typescript/src/lib.rs:54"]}, {"owner": "perry-ext-undici", "manifest": "crates/perry-ext-undici/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 1, "references": ["crates/perry-ext-undici/src/lib.rs:90"]}, {"owner": "perry-ext-validator", "manifest": "crates/perry-ext-validator/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 1, "references": ["crates/perry-ext-validator/src/lib.rs:199"]}, {"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 5, "references": ["crates/perry-hir/src/audit.rs:439", "crates/perry-hir/src/lower/lower_expr/json_literal/tests.rs:29", "crates/perry-hir/src/lower/lower_expr/json_literal/tests.rs:113", "crates/perry-hir/src/lower/lower_expr/json_literal.rs:125", "crates/perry-hir/src/lower/lower_expr/json_literal.rs:135"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 189, "references": ["crates/perry-runtime/src/bun_compat/cli_utils.rs:165", "crates/perry-runtime/src/bun_compat/cli_utils.rs:663", "crates/perry-runtime/src/child_process/fork.rs:198", "crates/perry-runtime/src/child_process/registry.rs:95", "crates/perry-runtime/src/gc/census.rs:644", "crates/perry-runtime/src/gc/census.rs:661"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 125, "references": ["crates/perry-stdlib/src/container/backend_ctl.rs:87", "crates/perry-stdlib/src/container/backend_ctl.rs:99", "crates/perry-stdlib/src/container/backend_ctl.rs:101", "crates/perry-stdlib/src/container/backend_ctl.rs:158", "crates/perry-stdlib/src/container/backend_ctl.rs:165", "crates/perry-stdlib/src/container/backend_ctl.rs:207"]}, {"owner": "perry-ui-android", "manifest": "crates/perry-ui-android/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": "cfg(target_os = \"android\")", "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 0, "references": []}, {"owner": "perry-ui-geisterhand", "manifest": "crates/perry-ui-geisterhand/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 17, "references": ["crates/perry-ui-geisterhand/src/chaos.rs:53", "crates/perry-ui-geisterhand/src/server.rs:295", "crates/perry-ui-geisterhand/src/server.rs:297", "crates/perry-ui-geisterhand/src/server.rs:323", "crates/perry-ui-geisterhand/src/server.rs:351", "crates/perry-ui-geisterhand/src/server.rs:422"]}, {"owner": "perry-updater", "manifest": "crates/perry-updater/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 0, "references": []}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "serde_json", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_json@1.0.151"], "reference_lines": 577, "references": ["crates/perry/src/commands/attest.rs:134", "crates/perry/src/commands/attest.rs:158", "crates/perry/src/commands/attest.rs:282", "crates/perry/src/commands/audit.rs:188", "crates/perry/src/commands/audit.rs:191", "crates/perry/src/commands/audit.rs:201"]}], "lock_closure_packages": 16, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "serde_yaml", "versions": ["0.9.34+deprecated"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "serde_yaml", "kind": "normal", "target": null, "optional": false, "requirement": "^0.9", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_yaml@0.9.34+deprecated"], "reference_lines": 102, "references": ["crates/perry-container-compose/src/cli.rs:195", "crates/perry-container-compose/src/compose.rs:429", "crates/perry-container-compose/src/compose.rs:430", "crates/perry-container-compose/src/compose.rs:438", "crates/perry-container-compose/src/compose.rs:439", "crates/perry-container-compose/src/compose.rs:444"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "serde_yaml", "kind": "dev", "target": null, "optional": false, "requirement": "^0.9", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["serde_yaml@0.9.34+deprecated"], "reference_lines": 1, "references": ["crates/perry-stdlib/tests/container_props.rs:164"]}], "lock_closure_packages": 16, "lock_packages_lost_if_all_workspace_edges_removed": ["serde_yaml@0.9.34+deprecated"]}, +{"name": "sha1", "versions": ["0.10.6", "0.11.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "rsa_sha1", "kind": "normal", "target": null, "optional": true, "requirement": "^0.10", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["sha1@0.10.6"], "reference_lines": 4, "references": ["crates/perry-stdlib/src/crypto/sign.rs:225", "crates/perry-stdlib/src/crypto/sign.rs:250", "crates/perry-stdlib/src/webcrypto/util.rs:1154", "crates/perry-stdlib/src/webcrypto/util.rs:1170"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "sha1", "kind": "normal", "target": null, "optional": true, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["sha1@0.11.0"], "reference_lines": 4, "references": ["crates/perry-stdlib/src/crypto/util.rs:45", "crates/perry-stdlib/src/crypto/x509.rs:682", "crates/perry-stdlib/src/crypto/x509.rs:1022", "crates/perry-stdlib/src/webcrypto/util.rs:53"]}], "lock_closure_packages": 87, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "sha2", "versions": ["0.10.9", "0.11.0"], "edges": [{"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "sha2", "kind": "normal", "target": null, "optional": false, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["sha2@0.11.0"], "reference_lines": 2, "references": ["crates/perry-ext-node-forge/src/crypto.rs:27", "crates/perry-ext-node-forge/src/crypto.rs:490"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "sha2", "kind": "normal", "target": null, "optional": true, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": ["node-api-host"], "resolved": ["sha2@0.11.0"], "reference_lines": 2, "references": ["crates/perry-runtime/build.rs:51", "crates/perry-runtime/src/node_api_host/loader.rs:4"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "sha2", "kind": "build", "target": null, "optional": false, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": ["node-api-host"], "resolved": ["sha2@0.11.0"], "reference_lines": 2, "references": ["crates/perry-runtime/build.rs:51", "crates/perry-runtime/src/node_api_host/loader.rs:4"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "sha2", "kind": "normal", "target": null, "optional": true, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["sha2@0.11.0"], "reference_lines": 9, "references": ["crates/perry-stdlib/src/crypto/kdf.rs:21", "crates/perry-stdlib/src/crypto/sign.rs:11", "crates/perry-stdlib/src/crypto/util.rs:40", "crates/perry-stdlib/src/crypto/util.rs:46", "crates/perry-stdlib/src/crypto/x509.rs:683", "crates/perry-stdlib/src/crypto/x509.rs:1023"]}, {"owner": "perry-updater", "manifest": "crates/perry-updater/Cargo.toml", "alias": "sha2", "kind": "normal", "target": null, "optional": false, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["sha2@0.11.0"], "reference_lines": 2, "references": ["crates/perry-updater/src/cli_manifest.rs:8", "crates/perry-updater/src/core.rs:11"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "sha2", "kind": "normal", "target": null, "optional": false, "requirement": "^0.11", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["sha2@0.11.0"], "reference_lines": 15, "references": ["crates/perry/src/commands/attest.rs:35", "crates/perry/src/commands/compile/asset_manifest.rs:8", "crates/perry/src/commands/compile/asset_modules.rs:13", "crates/perry/src/commands/compile/build_cache.rs:3", "crates/perry/src/commands/compile/collect_modules/eval_worker.rs:27", "crates/perry/src/commands/compile/link/archive_cache.rs:2"]}], "lock_closure_packages": 87, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "sha3", "versions": ["0.10.9", "0.11.0", "0.12.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "sha3", "kind": "normal", "target": null, "optional": true, "requirement": "^0.12", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["sha3@0.12.0"], "reference_lines": 0, "references": []}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "sha3_010", "kind": "normal", "target": null, "optional": true, "requirement": "^0.10", "default_features": false, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["sha3@0.10.9"], "reference_lines": 6, "references": ["crates/perry-stdlib/src/webcrypto/util.rs:1021", "crates/perry-stdlib/src/webcrypto/util.rs:1022", "crates/perry-stdlib/src/webcrypto/util.rs:1026", "crates/perry-stdlib/src/webcrypto/util.rs:1039", "crates/perry-stdlib/src/webcrypto/util.rs:1040", "crates/perry-stdlib/src/webcrypto/util.rs:1044"]}], "lock_closure_packages": 91, "lock_packages_lost_if_all_workspace_edges_removed": ["keccak@0.1.6", "sha3@0.10.9", "sha3@0.12.0"]}, +{"name": "sha3-utils", "versions": ["0.5.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "sha3_utils", "kind": "normal", "target": null, "optional": true, "requirement": "^0.5", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["sha3-utils@0.5.0"], "reference_lines": 4, "references": ["crates/perry-stdlib/src/webcrypto/util.rs:1027", "crates/perry-stdlib/src/webcrypto/util.rs:1033", "crates/perry-stdlib/src/webcrypto/util.rs:1045", "crates/perry-stdlib/src/webcrypto/util.rs:1051"]}], "lock_closure_packages": 7, "lock_packages_lost_if_all_workspace_edges_removed": ["sha3-utils@0.5.0"]}, +{"name": "shake", "versions": ["0.1.0"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "shake", "kind": "normal", "target": null, "optional": true, "requirement": "^0.1", "default_features": true, "features": [], "direct_feature_activators": ["crypto"], "resolved": ["shake@0.1.0"], "reference_lines": 3, "references": ["crates/perry-stdlib/src/crypto/hash_handles.rs:121", "crates/perry-stdlib/src/crypto/hash_handles.rs:122", "crates/perry-stdlib/src/crypto/util.rs:49"]}], "lock_closure_packages": 78, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "simdutf8", "versions": ["0.1.5"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "simdutf8", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1.5", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["simdutf8@0.1.5"], "reference_lines": 1, "references": ["crates/perry-runtime/src/string/utf16_count.rs:22"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "socket2", "versions": ["0.6.5"], "edges": [{"owner": "perry-ext-fastify", "manifest": "crates/perry-ext-fastify/Cargo.toml", "alias": "socket2", "kind": "normal", "target": "cfg(unix)", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["socket2@0.6.5"], "reference_lines": 1, "references": ["crates/perry-ext-fastify/src/cluster_bind.rs:29"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "socket2", "kind": "normal", "target": "cfg(unix)", "optional": false, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["socket2@0.6.5"], "reference_lines": 1, "references": ["crates/perry-ext-http/src/server/cluster_bind.rs:22"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "socket2", "kind": "normal", "target": null, "optional": false, "requirement": "^0.6", "default_features": true, "features": ["all"], "direct_feature_activators": [], "resolved": ["socket2@0.6.5"], "reference_lines": 8, "references": ["crates/perry-runtime/src/cluster.rs:107", "crates/perry-runtime/src/cluster.rs:108", "crates/perry-runtime/src/cluster.rs:109", "crates/perry-runtime/src/cluster.rs:110", "crates/perry-runtime/src/cluster_sched.rs:693", "crates/perry-runtime/src/dgram/net.rs:13"]}], "lock_closure_packages": 4, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "spki", "versions": ["0.7.3", "0.8.0"], "edges": [{"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "spki", "kind": "normal", "target": null, "optional": false, "requirement": "^0.8", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["spki@0.8.0"], "reference_lines": 1, "references": ["crates/perry-ext-node-forge/src/crypto.rs:40"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "spki", "kind": "normal", "target": null, "optional": true, "requirement": "^0.8", "default_features": false, "features": ["pem", "alloc"], "direct_feature_activators": ["bundled-jsonwebtoken"], "resolved": ["spki@0.8.0"], "reference_lines": 0, "references": []}], "lock_closure_packages": 17, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "sqlx", "versions": ["0.9.0"], "edges": [{"owner": "perry-ext-mysql2", "manifest": "crates/perry-ext-mysql2/Cargo.toml", "alias": "sqlx", "kind": "normal", "target": null, "optional": false, "requirement": "^0.9.0", "default_features": false, "features": ["runtime-tokio", "mysql", "mysql-rsa", "chrono", "json"], "direct_feature_activators": [], "resolved": ["sqlx@0.9.0"], "reference_lines": 8, "references": ["crates/perry-ext-mysql2/src/lib.rs:23", "crates/perry-ext-mysql2/src/lib.rs:24", "crates/perry-ext-mysql2/src/lib.rs:25", "crates/perry-ext-mysql2/src/lib.rs:733", "crates/perry-ext-mysql2/src/lib.rs:824", "crates/perry-ext-mysql2/src/lib.rs:856"]}, {"owner": "perry-ext-pg", "manifest": "crates/perry-ext-pg/Cargo.toml", "alias": "sqlx", "kind": "normal", "target": null, "optional": false, "requirement": "^0.9.0", "default_features": false, "features": ["runtime-tokio", "postgres", "chrono"], "direct_feature_activators": [], "resolved": ["sqlx@0.9.0"], "reference_lines": 5, "references": ["crates/perry-ext-pg/src/lib.rs:22", "crates/perry-ext-pg/src/lib.rs:23", "crates/perry-ext-pg/src/lib.rs:459", "crates/perry-ext-pg/src/lib.rs:511", "crates/perry-ext-pg/src/lib.rs:656"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "sqlx", "kind": "normal", "target": null, "optional": true, "requirement": "^0.9.0", "default_features": false, "features": ["runtime-tokio", "mysql", "postgres", "chrono"], "direct_feature_activators": ["bundled-mysql2", "bundled-pg"], "resolved": ["sqlx@0.9.0"], "reference_lines": 27, "references": ["crates/perry-stdlib/src/mysql2/connection.rs:7", "crates/perry-stdlib/src/mysql2/connection.rs:8", "crates/perry-stdlib/src/mysql2/connection.rs:36", "crates/perry-stdlib/src/mysql2/connection.rs:125", "crates/perry-stdlib/src/mysql2/connection.rs:135", "crates/perry-stdlib/src/mysql2/pool.rs:10"]}], "lock_closure_packages": 228, "lock_packages_lost_if_all_workspace_edges_removed": ["atoi@2.0.0", "crc-catalog@2.5.0", "crc@3.4.0", "crossbeam-queue@0.3.12", "etcetera@0.11.0", "flume@0.12.0", "futures-intrusive@0.5.0", "sqlx-core@0.9.0", "sqlx-macros-core@0.9.0", "sqlx-macros@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "sqlx@0.9.0", "tokio-stream@0.1.18", "whoami@2.1.2"]}, +{"name": "stacker", "versions": ["0.1.25"], "edges": [{"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "stacker", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1.24", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["stacker@0.1.25"], "reference_lines": 3, "references": ["crates/perry-hir/src/lower/lower_expr.rs:95", "crates/perry-hir/src/lower_decl/body_stmt.rs:85", "crates/perry-hir/src/lower_types.rs:341"]}], "lock_closure_packages": 44, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "swc_bundler", "versions": ["37.0.0"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_bundler", "kind": "normal", "target": null, "optional": false, "requirement": "^37.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_bundler@37.0.0"], "reference_lines": 1, "references": ["crates/perry-ext-typescript/src/bun.rs:24"]}], "lock_closure_packages": 206, "lock_packages_lost_if_all_workspace_edges_removed": ["auto_impl@1.3.0", "crc-catalog@1.1.1", "crc@2.1.0", "dashmap@5.5.3", "fixedbitset@0.5.7", "petgraph@0.7.1", "radix_fmt@1.0.0", "relative-path@1.9.3", "swc_bundler@37.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_graph_analyzer@14.0.2"]}, +{"name": "swc_common", "versions": ["18.0.1"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_common", "kind": "normal", "target": null, "optional": false, "requirement": "^18.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_common@18.0.1"], "reference_lines": 3, "references": ["crates/perry-ext-typescript/src/bun.rs:28", "crates/perry-ext-typescript/src/bun.rs:205", "crates/perry-ext-typescript/src/lib.rs:14"]}, {"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "swc_common", "kind": "normal", "target": null, "optional": false, "requirement": "^18.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_common@18.0.1"], "reference_lines": 44, "references": ["crates/perry-hir/src/destructuring/var_decl.rs:4", "crates/perry-hir/src/error.rs:8", "crates/perry-hir/src/eval_classifier.rs:704", "crates/perry-hir/src/eval_classifier.rs:744", "crates/perry-hir/src/lower/builder_fold.rs:401", "crates/perry-hir/src/lower/const_fold_fn.rs:51"]}, {"owner": "perry-parser", "manifest": "crates/perry-parser/Cargo.toml", "alias": "swc_common", "kind": "normal", "target": null, "optional": false, "requirement": "^18.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_common@18.0.1"], "reference_lines": 11, "references": ["crates/perry-parser/src/defines.rs:6", "crates/perry-parser/src/defines.rs:229", "crates/perry-parser/src/lib.rs:9", "crates/perry-parser/src/lib.rs:20", "crates/perry-parser/src/lib.rs:129", "crates/perry-parser/src/lib.rs:142"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "swc_common", "kind": "normal", "target": null, "optional": false, "requirement": "^18.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_common@18.0.1"], "reference_lines": 2, "references": ["crates/perry/src/commands/compile/collect_modules/import_meta_require.rs:13", "crates/perry/src/commands/lower_diagnostic.rs:96"]}], "lock_closure_packages": 96, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "swc_ecma_ast", "versions": ["19.0.0"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_ecma_ast", "kind": "normal", "target": null, "optional": false, "requirement": "^19.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_ast@19.0.0"], "reference_lines": 8, "references": ["crates/perry-ext-typescript/src/bun.rs:32", "crates/perry-ext-typescript/src/bun.rs:345", "crates/perry-ext-typescript/src/bun.rs:358", "crates/perry-ext-typescript/src/bun.rs:404", "crates/perry-ext-typescript/src/bun.rs:407", "crates/perry-ext-typescript/src/bun.rs:410"]}, {"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "swc_ecma_ast", "kind": "normal", "target": null, "optional": false, "requirement": "^19.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_ast@19.0.0"], "reference_lines": 5, "references": ["crates/perry-hir/src/lower/context.rs:411", "crates/perry-hir/src/lower/context.rs:413", "crates/perry-hir/src/lower/lowering_context.rs:67", "crates/perry-hir/src/lower/typed_parse.rs:16", "crates/perry-hir/src/lower_types/extract.rs:284"]}, {"owner": "perry-parser", "manifest": "crates/perry-parser/Cargo.toml", "alias": "swc_ecma_ast", "kind": "normal", "target": null, "optional": false, "requirement": "^19.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_ast@19.0.0"], "reference_lines": 12, "references": ["crates/perry-parser/src/lib.rs:10", "crates/perry-parser/src/lib.rs:17", "crates/perry-parser/src/lib.rs:134", "crates/perry-parser/src/lib.rs:1487", "crates/perry-parser/src/lib.rs:1492", "crates/perry-parser/src/lib.rs:1519"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "swc_ecma_ast", "kind": "normal", "target": null, "optional": false, "requirement": "^19.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_ast@19.0.0"], "reference_lines": 26, "references": ["crates/perry/src/commands/check.rs:573", "crates/perry/src/commands/check.rs:580", "crates/perry/src/commands/check.rs:636", "crates/perry/src/commands/check.rs:657", "crates/perry/src/commands/check.rs:661", "crates/perry/src/commands/compile/collect_modules/import_meta_require.rs:15"]}], "lock_closure_packages": 113, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "swc_ecma_codegen", "versions": ["21.0.0"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_ecma_codegen", "kind": "normal", "target": null, "optional": false, "requirement": "^21.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_codegen@21.0.0"], "reference_lines": 2, "references": ["crates/perry-ext-typescript/src/bun.rs:36", "crates/perry-ext-typescript/src/lib.rs:19"]}, {"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "swc_ecma_codegen", "kind": "dev", "target": null, "optional": false, "requirement": "^21.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_codegen@21.0.0"], "reference_lines": 1, "references": ["crates/perry-hir/examples/solid_jsx.rs:26"]}], "lock_closure_packages": 179, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "swc_ecma_loader", "versions": ["18.0.0"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_ecma_loader", "kind": "normal", "target": null, "optional": false, "requirement": "^18.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_loader@18.0.0"], "reference_lines": 1, "references": ["crates/perry-ext-typescript/src/bun.rs:37"]}], "lock_closure_packages": 98, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "swc_ecma_parser", "versions": ["29.0.2", "32.0.0"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_ecma_parser", "kind": "normal", "target": null, "optional": false, "requirement": "^32.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_parser@32.0.0"], "reference_lines": 2, "references": ["crates/perry-ext-typescript/src/bun.rs:38", "crates/perry-ext-typescript/src/lib.rs:20"]}, {"owner": "perry-parser", "manifest": "crates/perry-parser/Cargo.toml", "alias": "swc_ecma_parser", "kind": "normal", "target": null, "optional": false, "requirement": "^32.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_parser@32.0.0"], "reference_lines": 3, "references": ["crates/perry-parser/src/lib.rs:11", "crates/perry-parser/src/lib.rs:145", "crates/perry-parser/src/lib.rs:322"]}], "lock_closure_packages": 128, "lock_packages_lost_if_all_workspace_edges_removed": ["swc_ecma_parser@32.0.0"]}, +{"name": "swc_ecma_transforms_base", "versions": ["32.0.0"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_ecma_transforms_base", "kind": "normal", "target": null, "optional": false, "requirement": "^32.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_transforms_base@32.0.0"], "reference_lines": 2, "references": ["crates/perry-ext-typescript/src/bun.rs:39", "crates/perry-ext-typescript/src/lib.rs:21"]}, {"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "swc_ecma_transforms_base", "kind": "normal", "target": null, "optional": false, "requirement": "^32.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_transforms_base@32.0.0"], "reference_lines": 2, "references": ["crates/perry-hir/examples/solid_jsx.rs:25", "crates/perry-hir/src/solid_jsx.rs:51"]}, {"owner": "perry-parser", "manifest": "crates/perry-parser/Cargo.toml", "alias": "swc_ecma_transforms_base", "kind": "normal", "target": null, "optional": false, "requirement": "^32.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_transforms_base@32.0.0"], "reference_lines": 1, "references": ["crates/perry-parser/src/defines.rs:41"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "swc_ecma_transforms_base", "kind": "normal", "target": null, "optional": false, "requirement": "^32.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_transforms_base@32.0.0"], "reference_lines": 1, "references": ["crates/perry/src/commands/compile/collect_modules/import_meta_require.rs:16"]}], "lock_closure_packages": 128, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "swc_ecma_transforms_react", "versions": ["35.0.0"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_ecma_transforms_react", "kind": "normal", "target": null, "optional": false, "requirement": "^35.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_transforms_react@35.0.0"], "reference_lines": 2, "references": ["crates/perry-ext-typescript/src/bun.rs:40", "crates/perry-ext-typescript/src/lib.rs:22"]}], "lock_closure_packages": 146, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "swc_ecma_transforms_typescript", "versions": ["35.0.0"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_ecma_transforms_typescript", "kind": "normal", "target": null, "optional": false, "requirement": "^35.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_transforms_typescript@35.0.0"], "reference_lines": 2, "references": ["crates/perry-ext-typescript/src/bun.rs:41", "crates/perry-ext-typescript/src/lib.rs:23"]}], "lock_closure_packages": 147, "lock_packages_lost_if_all_workspace_edges_removed": ["swc_ecma_transforms_typescript@35.0.0"]}, +{"name": "swc_ecma_visit", "versions": ["19.0.0"], "edges": [{"owner": "perry-ext-typescript", "manifest": "crates/perry-ext-typescript/Cargo.toml", "alias": "swc_ecma_visit", "kind": "normal", "target": null, "optional": false, "requirement": "^19.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_visit@19.0.0"], "reference_lines": 1, "references": ["crates/perry-ext-typescript/src/bun.rs:42"]}, {"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "swc_ecma_visit", "kind": "normal", "target": null, "optional": false, "requirement": "^19.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_visit@19.0.0"], "reference_lines": 6, "references": ["crates/perry-hir/examples/solid_jsx.rs:4", "crates/perry-hir/src/lower/builder_fold.rs:44", "crates/perry-hir/src/lower/expr_object.rs:720", "crates/perry-hir/src/lower/pre_scan/class_decl_names.rs:26", "crates/perry-hir/src/lower_decl/helpers.rs:819", "crates/perry-hir/src/solid_jsx.rs:10"]}, {"owner": "perry-parser", "manifest": "crates/perry-parser/Cargo.toml", "alias": "swc_ecma_visit", "kind": "normal", "target": null, "optional": false, "requirement": "^19.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_visit@19.0.0"], "reference_lines": 2, "references": ["crates/perry-parser/src/defines.rs:8", "crates/perry-parser/src/lib.rs:12"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "swc_ecma_visit", "kind": "normal", "target": null, "optional": false, "requirement": "^19.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["swc_ecma_visit@19.0.0"], "reference_lines": 4, "references": ["crates/perry/src/commands/compile/collect_modules/import_meta_require.rs:17", "crates/perry/src/commands/compile/collect_modules/import_meta_resolve.rs:7", "crates/perry/src/commands/compile/collect_modules/reexport_prune/scan.rs:10", "crates/perry/src/commands/compile/collect_modules_helpers.rs:73"]}], "lock_closure_packages": 114, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "taffy", "versions": ["0.13.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "taffy", "kind": "normal", "target": null, "optional": false, "requirement": "^0.13", "default_features": false, "features": ["std", "flexbox", "taffy_tree"], "direct_feature_activators": [], "resolved": ["taffy@0.13.0"], "reference_lines": 24, "references": ["crates/perry-runtime/src/tui/layout.rs:18", "crates/perry-runtime/src/tui/layout.rs:19", "crates/perry-runtime/src/tui/layout.rs:41", "crates/perry-runtime/src/tui/layout.rs:55", "crates/perry-runtime/src/tui/layout.rs:90", "crates/perry-runtime/src/tui/layout.rs:134"]}], "lock_closure_packages": 11, "lock_packages_lost_if_all_workspace_edges_removed": ["slotmap@1.1.1", "taffy@0.13.0"]}, +{"name": "tar", "versions": ["0.4.46"], "edges": [{"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "tar", "kind": "normal", "target": null, "optional": false, "requirement": "^0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tar@0.4.46"], "reference_lines": 9, "references": ["crates/perry/src/commands/publish/tarball.rs:143", "crates/perry/src/commands/publish/tarball.rs:156", "crates/perry/src/commands/publish/tarball.rs:276", "crates/perry/src/commands/publish/tarball.rs:403", "crates/perry/src/commands/publish/tarball.rs:426", "crates/perry/src/commands/publish/tarball.rs:436"]}], "lock_closure_packages": 17, "lock_packages_lost_if_all_workspace_edges_removed": ["tar@0.4.46", "xattr@1.6.1"]}, +{"name": "tempfile", "versions": ["3.27.0"], "edges": [{"owner": "perry-doc-tests", "manifest": "crates/perry-doc-tests/Cargo.toml", "alias": "tempfile", "kind": "dev", "target": null, "optional": false, "requirement": "^3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tempfile@3.27.0"], "reference_lines": 5, "references": ["crates/perry-doc-tests/src/image_diff.rs:171", "crates/perry-doc-tests/src/image_diff.rs:183", "crates/perry-doc-tests/src/image_diff.rs:197", "crates/perry-doc-tests/src/tests.rs:31", "crates/perry-doc-tests/tests/compiler_environment.rs:7"]}, {"owner": "perry-ext-parcel-watcher", "manifest": "crates/perry-ext-parcel-watcher/Cargo.toml", "alias": "tempfile", "kind": "dev", "target": null, "optional": false, "requirement": "^3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tempfile@3.27.0"], "reference_lines": 5, "references": ["crates/perry-ext-parcel-watcher/src/lib.rs:938", "crates/perry-ext-parcel-watcher/src/lib.rs:971", "crates/perry-ext-parcel-watcher/src/lib.rs:993", "crates/perry-ext-parcel-watcher/src/lib.rs:1039", "crates/perry-ext-parcel-watcher/src/lib.rs:1113"]}, {"owner": "perry-ui", "manifest": "crates/perry-ui/Cargo.toml", "alias": "tempfile", "kind": "normal", "target": "cfg(any(target_os = \"macos\", target_os = \"windows\", target_os = \"linux\"))", "optional": false, "requirement": "^3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tempfile@3.27.0"], "reference_lines": 3, "references": ["crates/perry-ui/src/frame.rs:124", "crates/perry-ui/src/frame.rs:161", "crates/perry-ui/src/frame.rs:197"]}, {"owner": "perry-updater", "manifest": "crates/perry-updater/Cargo.toml", "alias": "tempfile", "kind": "dev", "target": null, "optional": false, "requirement": "^3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tempfile@3.27.0"], "reference_lines": 1, "references": ["crates/perry-updater/src/cli_manifest.rs:261"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "tempfile", "kind": "normal", "target": null, "optional": false, "requirement": "^3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tempfile@3.27.0"], "reference_lines": 1006, "references": ["crates/perry/src/commands/attest.rs:188", "crates/perry/src/commands/attest.rs:189", "crates/perry/src/commands/attest.rs:237", "crates/perry/src/commands/check.rs:774", "crates/perry/src/commands/compile/app_metadata.rs:232", "crates/perry/src/commands/compile/app_metadata.rs:257"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "tempfile", "kind": "dev", "target": null, "optional": false, "requirement": "^3", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tempfile@3.27.0"], "reference_lines": 1006, "references": ["crates/perry/src/commands/attest.rs:188", "crates/perry/src/commands/attest.rs:189", "crates/perry/src/commands/attest.rs:237", "crates/perry/src/commands/check.rs:774", "crates/perry/src/commands/compile/app_metadata.rs:232", "crates/perry/src/commands/compile/app_metadata.rs:257"]}], "lock_closure_packages": 70, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "temporal_rs", "versions": ["0.2.6"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "temporal_rs", "kind": "normal", "target": null, "optional": true, "requirement": "^0.2.3", "default_features": false, "features": ["std", "compiled_data"], "direct_feature_activators": ["temporal"], "resolved": ["temporal_rs@0.2.6"], "reference_lines": 69, "references": ["crates/perry-runtime/src/temporal/dispatch.rs:207", "crates/perry-runtime/src/temporal/dispatch.rs:221", "crates/perry-runtime/src/temporal/duration.rs:14", "crates/perry-runtime/src/temporal/instant.rs:10", "crates/perry-runtime/src/temporal/instant.rs:11", "crates/perry-runtime/src/temporal/mod.rs:59"]}], "lock_closure_packages": 77, "lock_packages_lost_if_all_workspace_edges_removed": ["ixdtf@0.6.5", "temporal_rs@0.2.6"]}, +{"name": "thiserror", "versions": ["1.0.69", "2.0.18"], "edges": [{"owner": "perry-codegen", "manifest": "crates/perry-codegen/Cargo.toml", "alias": "thiserror", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["thiserror@1.0.69"], "reference_lines": 0, "references": []}, {"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "thiserror", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["thiserror@1.0.69"], "reference_lines": 1, "references": ["crates/perry-container-compose/src/error.rs:7"]}, {"owner": "perry-hir", "manifest": "crates/perry-hir/Cargo.toml", "alias": "thiserror", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["thiserror@1.0.69"], "reference_lines": 0, "references": []}, {"owner": "perry-parser", "manifest": "crates/perry-parser/Cargo.toml", "alias": "thiserror", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["thiserror@1.0.69"], "reference_lines": 0, "references": []}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "thiserror", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["thiserror@1.0.69"], "reference_lines": 0, "references": []}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "thiserror", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["thiserror@1.0.69"], "reference_lines": 0, "references": []}, {"owner": "perry-transform", "manifest": "crates/perry-transform/Cargo.toml", "alias": "thiserror", "kind": "normal", "target": null, "optional": false, "requirement": "^1.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["thiserror@1.0.69"], "reference_lines": 0, "references": []}], "lock_closure_packages": 8, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "time", "versions": ["0.3.55"], "edges": [{"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "time", "kind": "normal", "target": null, "optional": false, "requirement": "^0.3", "default_features": true, "features": ["parsing"], "direct_feature_activators": [], "resolved": ["time@0.3.55"], "reference_lines": 6, "references": ["crates/perry-ext-node-forge/src/crypto.rs:41", "crates/perry-ext-node-forge/src/crypto.rs:308", "crates/perry-ext-node-forge/src/crypto.rs:309", "crates/perry-ext-node-forge/src/lib.rs:211", "crates/perry-ext-node-forge/tests/openssl_e2e.rs:47", "crates/perry-ext-node-forge/tests/openssl_e2e.rs:48"]}], "lock_closure_packages": 35, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "timezone_provider", "versions": ["0.2.6"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "timezone_provider", "kind": "normal", "target": null, "optional": true, "requirement": "^0.2.6", "default_features": false, "features": ["tzif"], "direct_feature_activators": ["intl-datetime"], "resolved": ["timezone_provider@0.2.6"], "reference_lines": 4, "references": ["crates/perry-runtime/src/date.rs:324", "crates/perry-runtime/src/date.rs:326", "crates/perry-runtime/src/date.rs:336", "crates/perry-runtime/src/date.rs:349"]}], "lock_closure_packages": 60, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "tiny_http", "versions": ["0.12.0"], "edges": [{"owner": "perry-ui-geisterhand", "manifest": "crates/perry-ui-geisterhand/Cargo.toml", "alias": "tiny_http", "kind": "normal", "target": null, "optional": false, "requirement": "^0.12", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tiny_http@0.12.0"], "reference_lines": 2, "references": ["crates/perry-ui-geisterhand/src/server.rs:6", "crates/perry-ui-geisterhand/src/server.rs:213"]}], "lock_closure_packages": 5, "lock_packages_lost_if_all_workspace_edges_removed": ["chunked_transfer@1.5.0", "tiny_http@0.12.0"]}, +{"name": "tokio", "versions": ["1.53.1"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 52, "references": ["crates/perry-container-compose/src/backend/cli_backend.rs:11", "crates/perry-container-compose/src/backend/cli_backend.rs:37", "crates/perry-container-compose/src/backend/detect.rs:5", "crates/perry-container-compose/src/backend/detect.rs:31", "crates/perry-container-compose/src/backend/detect.rs:54", "crates/perry-container-compose/src/backend/detect.rs:91"]}, {"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "tokio", "kind": "dev", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 52, "references": ["crates/perry-container-compose/src/backend/cli_backend.rs:11", "crates/perry-container-compose/src/backend/cli_backend.rs:37", "crates/perry-container-compose/src/backend/detect.rs:5", "crates/perry-container-compose/src/backend/detect.rs:31", "crates/perry-container-compose/src/backend/detect.rs:54", "crates/perry-container-compose/src/backend/detect.rs:91"]}, {"owner": "perry-ext-axios", "manifest": "crates/perry-ext-axios/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 1, "references": ["crates/perry-ext-axios/src/lib.rs:94"]}, {"owner": "perry-ext-fastify", "manifest": "crates/perry-ext-fastify/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 8, "references": ["crates/perry-ext-fastify/src/lib.rs:582", "crates/perry-ext-fastify/src/lib.rs:799", "crates/perry-ext-fastify/src/server.rs:23", "crates/perry-ext-fastify/src/server.rs:24", "crates/perry-ext-fastify/src/server.rs:342", "crates/perry-ext-fastify/src/server.rs:357"]}, {"owner": "perry-ext-fetch", "manifest": "crates/perry-ext-fetch/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 5, "references": ["crates/perry-ext-fetch/src/lib.rs:375", "crates/perry-ext-fetch/src/lib.rs:539", "crates/perry-ext-fetch/src/lib.rs:850", "crates/perry-ext-fetch/src/lib.rs:890", "crates/perry-ext-fetch/src/lib.rs:902"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 86, "references": ["crates/perry-ext-http/src/agent.rs:838", "crates/perry-ext-http/src/client_dispatch.rs:62", "crates/perry-ext-http/src/client_dispatch.rs:71", "crates/perry-ext-http/src/client_outgoing.rs:182", "crates/perry-ext-http/src/client_outgoing.rs:187", "crates/perry-ext-http/src/client_outgoing.rs:189"]}, {"owner": "perry-ext-ioredis", "manifest": "crates/perry-ext-ioredis/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 7, "references": ["crates/perry-ext-ioredis/src/lib.rs:92", "crates/perry-ext-ioredis/src/lib.rs:158", "crates/perry-ext-ioredis/src/lib.rs:160", "crates/perry-ext-ioredis/src/lib.rs:180", "crates/perry-ext-ioredis/src/lib.rs:408", "crates/perry-ext-ioredis/src/lib.rs:411"]}, {"owner": "perry-ext-mongodb", "manifest": "crates/perry-ext-mongodb/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 14, "references": ["crates/perry-ext-mongodb/src/lib.rs:168", "crates/perry-ext-mongodb/src/lib.rs:217", "crates/perry-ext-mongodb/src/lib.rs:324", "crates/perry-ext-mongodb/src/lib.rs:367", "crates/perry-ext-mongodb/src/lib.rs:419", "crates/perry-ext-mongodb/src/lib.rs:462"]}, {"owner": "perry-ext-mysql2", "manifest": "crates/perry-ext-mysql2/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 20, "references": ["crates/perry-ext-mysql2/src/lib.rs:28", "crates/perry-ext-mysql2/src/lib.rs:826", "crates/perry-ext-mysql2/src/lib.rs:836", "crates/perry-ext-mysql2/src/lib.rs:870", "crates/perry-ext-mysql2/src/lib.rs:879", "crates/perry-ext-mysql2/src/lib.rs:927"]}, {"owner": "perry-ext-net", "manifest": "crates/perry-ext-net/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 47, "references": ["crates/perry-ext-net/src/adopt.rs:11", "crates/perry-ext-net/src/adopt.rs:29", "crates/perry-ext-net/src/adopt.rs:79", "crates/perry-ext-net/src/buffer_pool.rs:333", "crates/perry-ext-net/src/buffer_pool.rs:334", "crates/perry-ext-net/src/buffer_pool.rs:353"]}, {"owner": "perry-ext-nodemailer", "manifest": "crates/perry-ext-nodemailer/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 2, "references": ["crates/perry-ext-nodemailer/src/lib.rs:233", "crates/perry-ext-nodemailer/src/lib.rs:283"]}, {"owner": "perry-ext-pg", "manifest": "crates/perry-ext-pg/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 8, "references": ["crates/perry-ext-pg/src/lib.rs:368", "crates/perry-ext-pg/src/lib.rs:396", "crates/perry-ext-pg/src/lib.rs:417", "crates/perry-ext-pg/src/lib.rs:452", "crates/perry-ext-pg/src/lib.rs:504", "crates/perry-ext-pg/src/lib.rs:623"]}, {"owner": "perry-ext-ws", "manifest": "crates/perry-ext-ws/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 13, "references": ["crates/perry-ext-ws/src/lib.rs:53", "crates/perry-ext-ws/src/lib.rs:286", "crates/perry-ext-ws/src/lib.rs:341", "crates/perry-ext-ws/src/lib.rs:369", "crates/perry-ext-ws/src/lib.rs:399", "crates/perry-ext-ws/src/lib.rs:406"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": true, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": ["async-runtime"], "resolved": ["tokio@1.53.1"], "reference_lines": 110, "references": ["crates/perry-stdlib/src/bcrypt.rs:36", "crates/perry-stdlib/src/bcrypt.rs:109", "crates/perry-stdlib/src/bcrypt.rs:151", "crates/perry-stdlib/src/common/async_bridge.rs:21", "crates/perry-stdlib/src/common/async_bridge.rs:136", "crates/perry-stdlib/src/common/async_bridge.rs:146"]}, {"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "tokio", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "^1", "default_features": true, "features": ["rt", "sync", "time", "net", "io-util"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 3, "references": ["crates/perry-ui-gtk4/src/media_playback.rs:568", "crates/perry-ui-gtk4/src/media_playback.rs:618", "crates/perry-ui-gtk4/src/tray.rs:52"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "tokio", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": ["full"], "direct_feature_activators": [], "resolved": ["tokio@1.53.1"], "reference_lines": 13, "references": ["crates/perry/src/commands/audit.rs:453", "crates/perry/src/commands/compile/optimized_libs/no_auto.rs:295", "crates/perry/src/commands/compile/shared_tokio.rs:325", "crates/perry/src/commands/compile/shared_tokio.rs:327", "crates/perry/src/commands/login.rs:36", "crates/perry/src/commands/login.rs:137"]}], "lock_closure_packages": 36, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "tokio-cron-scheduler", "versions": ["0.15.1"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "tokio_cron_scheduler", "kind": "normal", "target": null, "optional": true, "requirement": "^0.15", "default_features": true, "features": [], "direct_feature_activators": ["bundled-cron"], "resolved": ["tokio-cron-scheduler@0.15.1"], "reference_lines": 0, "references": []}], "lock_closure_packages": 137, "lock_packages_lost_if_all_workspace_edges_removed": ["chrono-tz@0.10.4", "croner@3.0.1", "darling@0.20.11", "darling_core@0.20.11", "darling_macro@0.20.11", "derive_builder@0.20.2", "derive_builder_core@0.20.2", "derive_builder_macro@0.20.2", "phf@0.12.1", "phf_shared@0.12.1", "strum@0.27.2", "strum_macros@0.27.2", "tokio-cron-scheduler@0.15.1"]}, +{"name": "tokio-rustls", "versions": ["0.26.4"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "tokio_rustls", "kind": "normal", "target": null, "optional": false, "requirement": "^0.26", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tokio-rustls@0.26.4"], "reference_lines": 2, "references": ["crates/perry-ext-http/src/server/http2_server.rs:34", "crates/perry-ext-http/src/server/https_server.rs:24"]}, {"owner": "perry-ext-net", "manifest": "crates/perry-ext-net/Cargo.toml", "alias": "tokio_rustls", "kind": "normal", "target": null, "optional": false, "requirement": "^0.26", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tokio-rustls@0.26.4"], "reference_lines": 3, "references": ["crates/perry-ext-net/src/tls.rs:9", "crates/perry-ext-net/src/tls.rs:12", "crates/perry-ext-net/src/transport.rs:15"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "tokio_rustls", "kind": "normal", "target": null, "optional": true, "requirement": "^0.26", "default_features": true, "features": [], "direct_feature_activators": ["external-tls-server", "tls-runtime"], "resolved": ["tokio-rustls@0.26.4"], "reference_lines": 3, "references": ["crates/perry-stdlib/src/net/mod.rs:48", "crates/perry-stdlib/src/net/mod.rs:52", "crates/perry-stdlib/src/tls.rs:25"]}], "lock_closure_packages": 86, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "tokio-tungstenite", "versions": ["0.29.0"], "edges": [{"owner": "perry-ext-fastify", "manifest": "crates/perry-ext-fastify/Cargo.toml", "alias": "tokio_tungstenite", "kind": "normal", "target": null, "optional": false, "requirement": "^0.29", "default_features": true, "features": ["rustls-tls-webpki-roots"], "direct_feature_activators": [], "resolved": ["tokio-tungstenite@0.29.0"], "reference_lines": 3, "references": ["crates/perry-ext-fastify/src/server.rs:899", "crates/perry-ext-fastify/src/server.rs:911", "crates/perry-ext-fastify/src/server.rs:913"]}, {"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "tokio_tungstenite", "kind": "normal", "target": null, "optional": false, "requirement": "^0.29", "default_features": true, "features": ["rustls-tls-webpki-roots"], "direct_feature_activators": [], "resolved": ["tokio-tungstenite@0.29.0"], "reference_lines": 3, "references": ["crates/perry-ext-http/src/server/server.rs:1369", "crates/perry-ext-http/src/server/server.rs:1395", "crates/perry-ext-http/src/server/server.rs:1397"]}, {"owner": "perry-ext-ws", "manifest": "crates/perry-ext-ws/Cargo.toml", "alias": "tokio_tungstenite", "kind": "normal", "target": null, "optional": false, "requirement": "^0.29", "default_features": true, "features": ["rustls-tls-webpki-roots"], "direct_feature_activators": [], "resolved": ["tokio-tungstenite@0.29.0"], "reference_lines": 7, "references": ["crates/perry-ext-ws/src/lib.rs:54", "crates/perry-ext-ws/src/lib.rs:368", "crates/perry-ext-ws/src/lib.rs:369", "crates/perry-ext-ws/src/lib.rs:396", "crates/perry-ext-ws/src/lib.rs:776", "crates/perry-ext-ws/src/lib.rs:913"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "tokio_tungstenite", "kind": "normal", "target": null, "optional": true, "requirement": "^0.29", "default_features": true, "features": ["rustls-tls-webpki-roots"], "direct_feature_activators": ["bundled-ws"], "resolved": ["tokio-tungstenite@0.29.0"], "reference_lines": 2, "references": ["crates/perry-stdlib/src/ws.rs:19", "crates/perry-stdlib/src/ws.rs:1109"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "tokio_tungstenite", "kind": "normal", "target": null, "optional": false, "requirement": "^0.29", "default_features": true, "features": ["rustls-tls-webpki-roots"], "direct_feature_activators": [], "resolved": ["tokio-tungstenite@0.29.0"], "reference_lines": 5, "references": ["crates/perry/src/commands/publish/mod.rs:15", "crates/perry/src/commands/publish/mod.rs:1572", "crates/perry/src/commands/publish/mod.rs:1650", "crates/perry/src/commands/run/remote.rs:24", "crates/perry/src/commands/run/remote.rs:219"]}], "lock_closure_packages": 112, "lock_packages_lost_if_all_workspace_edges_removed": ["tokio-tungstenite@0.29.0", "tungstenite@0.29.0"]}, +{"name": "toml", "versions": ["1.1.4+spec-1.1.0"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "toml", "kind": "normal", "target": null, "optional": true, "requirement": "^1.1", "default_features": true, "features": [], "direct_feature_activators": ["bun-cli-utils"], "resolved": ["toml@1.1.4+spec-1.1.0"], "reference_lines": 1, "references": ["crates/perry-runtime/src/bun_compat/cli_utils.rs:157"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "toml", "kind": "normal", "target": null, "optional": false, "requirement": "^1.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["toml@1.1.4+spec-1.1.0"], "reference_lines": 151, "references": ["crates/perry/src/commands/appstore.rs:62", "crates/perry/src/commands/appstore.rs:130", "crates/perry/src/commands/compile/app_metadata.rs:39", "crates/perry/src/commands/compile/app_metadata.rs:48", "crates/perry/src/commands/compile/app_metadata.rs:86", "crates/perry/src/commands/compile/app_metadata.rs:199"]}], "lock_closure_packages": 19, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "tracing", "versions": ["0.1.44"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "tracing", "kind": "normal", "target": null, "optional": false, "requirement": "^0.1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["tracing@0.1.44"], "reference_lines": 9, "references": ["crates/perry-container-compose/src/backend/cli_backend.rs:107", "crates/perry-container-compose/src/compose.rs:273", "crates/perry-container-compose/src/compose.rs:630", "crates/perry-container-compose/src/compose.rs:644", "crates/perry-container-compose/src/compose.rs:875", "crates/perry-container-compose/src/orchestrate.rs:32"]}], "lock_closure_packages": 13, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "tracing-subscriber", "versions": ["0.3.23"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "tracing_subscriber", "kind": "normal", "target": null, "optional": false, "requirement": "^0.3", "default_features": true, "features": ["env-filter"], "direct_feature_activators": [], "resolved": ["tracing-subscriber@0.3.23"], "reference_lines": 1, "references": ["crates/perry-container-compose/src/main.rs:5"]}], "lock_closure_packages": 35, "lock_packages_lost_if_all_workspace_edges_removed": ["matchers@0.2.0", "nu-ansi-term@0.50.3", "sharded-slab@0.1.7", "thread_local@1.1.9", "tracing-log@0.2.0", "tracing-subscriber@0.3.23"]}, +{"name": "tungstenite", "versions": ["0.24.0", "0.29.0"], "edges": [{"owner": "perry-ui-android", "manifest": "crates/perry-ui-android/Cargo.toml", "alias": "tungstenite", "kind": "normal", "target": "cfg(target_os = \"android\")", "optional": false, "requirement": "^0.24", "default_features": true, "features": ["rustls-tls-webpki-roots"], "direct_feature_activators": [], "resolved": ["tungstenite@0.24.0"], "reference_lines": 3, "references": ["crates/perry-ui-android/src/ws.rs:16", "crates/perry-ui-android/src/ws.rs:17", "crates/perry-ui-android/src/ws.rs:130"]}], "lock_closure_packages": 98, "lock_packages_lost_if_all_workspace_edges_removed": ["tungstenite@0.24.0"]}, +{"name": "unicode-normalization", "versions": ["0.1.25"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "unicode_normalization", "kind": "normal", "target": null, "optional": true, "requirement": "^0.1", "default_features": true, "features": [], "direct_feature_activators": ["string-normalize"], "resolved": ["unicode-normalization@0.1.25"], "reference_lines": 5, "references": ["crates/perry-runtime/src/intl/date_collator.rs:1512", "crates/perry-runtime/src/intl/date_collator.rs:1603", "crates/perry-runtime/src/string/compare.rs:688", "crates/perry-runtime/src/string/compare.rs:730", "crates/perry-runtime/src/string/locale.rs:154"]}], "lock_closure_packages": 3, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "unicode-segmentation", "versions": ["1.13.3"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "unicode_segmentation", "kind": "normal", "target": null, "optional": true, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": ["intl-segmenter"], "resolved": ["unicode-segmentation@1.13.3"], "reference_lines": 3, "references": ["crates/perry-runtime/src/intl/segmenter.rs:8", "crates/perry-runtime/src/intl/segments_view.rs:206", "crates/perry-runtime/src/intl/segments_view.rs:628"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "unsafe-libyaml", "versions": ["0.2.11"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "unsafe_libyaml", "kind": "normal", "target": null, "optional": true, "requirement": "^0.2.11", "default_features": true, "features": [], "direct_feature_activators": ["bun-cli-utils"], "resolved": ["unsafe-libyaml@0.2.11"], "reference_lines": 55, "references": ["crates/perry-runtime/src/bun_compat/cli_utils.rs:729", "crates/perry-runtime/src/bun_compat/cli_utils.rs:734", "crates/perry-runtime/src/bun_compat/cli_utils.rs:768", "crates/perry-runtime/src/bun_compat/cli_utils.rs:778", "crates/perry-runtime/src/bun_compat/cli_utils.rs:796", "crates/perry-runtime/src/bun_compat/cli_utils.rs:801"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "url", "versions": ["2.5.8"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "url", "kind": "normal", "target": null, "optional": true, "requirement": "^2", "default_features": true, "features": [], "direct_feature_activators": ["url-engine"], "resolved": ["url@2.5.8"], "reference_lines": 238, "references": ["crates/perry-runtime/src/array/flat_clone.rs:532", "crates/perry-runtime/src/array/flat_clone.rs:533", "crates/perry-runtime/src/array/iter_object.rs:434", "crates/perry-runtime/src/array/iter_object.rs:436", "crates/perry-runtime/src/array/iter_object.rs:437", "crates/perry-runtime/src/array/iter_object.rs:438"]}, {"owner": "perry-validation", "manifest": "crates/perry-validation/Cargo.toml", "alias": "url", "kind": "normal", "target": null, "optional": false, "requirement": "^2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["url@2.5.8"], "reference_lines": 1, "references": ["crates/perry-validation/src/lib.rs:73"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "url", "kind": "normal", "target": null, "optional": false, "requirement": "^2", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["url@2.5.8"], "reference_lines": 46, "references": ["crates/perry/src/commands/compile/collect_modules/import_meta_resolve.rs:77", "crates/perry/src/commands/compile/collect_modules/import_meta_resolve.rs:103", "crates/perry/src/commands/compile/collect_modules/import_meta_resolve.rs:115", "crates/perry/src/commands/compile/collect_modules/worker.rs:20", "crates/perry/src/commands/compile/run_pipeline.rs:2970", "crates/perry/src/commands/compile/run_pipeline.rs:2972"]}], "lock_closure_packages": 37, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "uuid", "versions": ["1.26.0"], "edges": [{"owner": "perry-ext-nodemailer", "manifest": "crates/perry-ext-nodemailer/Cargo.toml", "alias": "uuid", "kind": "normal", "target": null, "optional": false, "requirement": "^1.23", "default_features": true, "features": ["v4"], "direct_feature_activators": [], "resolved": ["uuid@1.26.0"], "reference_lines": 1, "references": ["crates/perry-ext-nodemailer/src/lib.rs:237"]}, {"owner": "perry-ext-uuid", "manifest": "crates/perry-ext-uuid/Cargo.toml", "alias": "uuid", "kind": "normal", "target": null, "optional": false, "requirement": "^1.23", "default_features": true, "features": ["v1", "v3", "v4", "v5", "v7"], "direct_feature_activators": [], "resolved": ["uuid@1.26.0"], "reference_lines": 2, "references": ["crates/perry-ext-uuid/src/lib.rs:7", "crates/perry-ext-uuid/src/lib.rs:20"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "uuid", "kind": "normal", "target": null, "optional": true, "requirement": "^1.23", "default_features": true, "features": ["v4", "v1", "v3", "v5", "v7"], "direct_feature_activators": ["bundled-uuid"], "resolved": ["uuid@1.26.0"], "reference_lines": 7, "references": ["crates/perry-stdlib/src/crypto/random.rs:129", "crates/perry-stdlib/src/crypto/random.rs:142", "crates/perry-stdlib/src/lib.rs:431", "crates/perry-stdlib/src/lib.rs:433", "crates/perry-stdlib/src/nodemailer.rs:272", "crates/perry-stdlib/src/uuid.rs:7"]}], "lock_closure_packages": 81, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "validator", "versions": ["0.21.0"], "edges": [{"owner": "perry-validation", "manifest": "crates/perry-validation/Cargo.toml", "alias": "validator", "kind": "dev", "target": null, "optional": false, "requirement": "=0.21.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["validator@0.21.0"], "reference_lines": 1, "references": ["crates/perry-validation/src/tests.rs:2"]}], "lock_closure_packages": 51, "lock_packages_lost_if_all_workspace_edges_removed": ["validator@0.21.0"]}, +{"name": "walkdir", "versions": ["2.5.0"], "edges": [{"owner": "perry-doc-tests", "manifest": "crates/perry-doc-tests/Cargo.toml", "alias": "walkdir", "kind": "normal", "target": null, "optional": false, "requirement": "^2.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["walkdir@2.5.0"], "reference_lines": 2, "references": ["crates/perry-doc-tests/src/lint.rs:20", "crates/perry-doc-tests/src/main.rs:368"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "walkdir", "kind": "normal", "target": null, "optional": false, "requirement": "^2.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["walkdir@2.5.0"], "reference_lines": 13, "references": ["crates/perry/src/commands/audit.rs:11", "crates/perry/src/commands/check.rs:12", "crates/perry/src/commands/compile/asset_modules.rs:68", "crates/perry/src/commands/compile/build_cache.rs:782", "crates/perry/src/commands/compile/embed.rs:294", "crates/perry/src/commands/compile/link/harmonyos_objects.rs:55"]}], "lock_closure_packages": 5, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "wasm-encoder", "versions": ["0.244.0", "0.258.0"], "edges": [{"owner": "perry-codegen-wasm", "manifest": "crates/perry-codegen-wasm/Cargo.toml", "alias": "wasm_encoder", "kind": "normal", "target": null, "optional": false, "requirement": "^0.258", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["wasm-encoder@0.258.0"], "reference_lines": 203, "references": ["crates/perry-codegen-wasm/src/emit/compile.rs:1235", "crates/perry-codegen-wasm/src/emit/compile.rs:1245", "crates/perry-codegen-wasm/src/emit/compile.rs:1288", "crates/perry-codegen-wasm/src/emit/compile.rs:1296", "crates/perry-codegen-wasm/src/emit/compile.rs:1454", "crates/perry-codegen-wasm/src/emit/compile.rs:1461"]}], "lock_closure_packages": 21, "lock_packages_lost_if_all_workspace_edges_removed": ["wasm-encoder@0.258.0", "wasmparser@0.258.0"]}, +{"name": "wasmi", "versions": ["1.1.0"], "edges": [{"owner": "perry-wasm-host", "manifest": "crates/perry-wasm-host/Cargo.toml", "alias": "wasmi", "kind": "normal", "target": null, "optional": false, "requirement": "^1.1", "default_features": false, "features": ["simd"], "direct_feature_activators": [], "resolved": ["wasmi@1.1.0"], "reference_lines": 8, "references": ["crates/perry-wasm-host/src/host_runtime.rs:12", "crates/perry-wasm-host/src/lib.rs:21", "crates/perry-wasm-host/src/lib.rs:104", "crates/perry-wasm-host/src/lib.rs:120", "crates/perry-wasm-host/src/lib.rs:567", "crates/perry-wasm-host/src/lib.rs:568"]}], "lock_closure_packages": 16, "lock_packages_lost_if_all_workspace_edges_removed": ["wasmi@1.1.0", "wasmi_collections@1.1.0", "wasmi_core@1.1.0", "wasmi_ir@1.1.0", "wasmparser@0.239.0"]}, +{"name": "webkit6", "versions": ["0.4.0"], "edges": [{"owner": "perry-ui-gtk4", "manifest": "crates/perry-ui-gtk4/Cargo.toml", "alias": "webkit6", "kind": "normal", "target": "cfg(target_os = \"linux\")", "optional": false, "requirement": "=0.4", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["webkit6@0.4.0"], "reference_lines": 11, "references": ["crates/perry-ui-gtk4/src/widgets/webview.rs:14", "crates/perry-ui-gtk4/src/widgets/webview.rs:25", "crates/perry-ui-gtk4/src/widgets/webview.rs:86", "crates/perry-ui-gtk4/src/widgets/webview.rs:96", "crates/perry-ui-gtk4/src/widgets/webview.rs:101", "crates/perry-ui-gtk4/src/widgets/webview.rs:137"]}], "lock_closure_packages": 83, "lock_packages_lost_if_all_workspace_edges_removed": ["javascriptcore6-sys@0.4.0", "javascriptcore6@0.4.0", "soup3-sys@0.7.0", "soup3@0.7.0", "webkit6-sys@0.4.0", "webkit6@0.4.0"]}, +{"name": "webpki-roots", "versions": ["0.26.11", "1.0.9"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "webpki_roots", "kind": "normal", "target": null, "optional": false, "requirement": "^1", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["webpki-roots@1.0.9"], "reference_lines": 1, "references": ["crates/perry-ext-http/src/tls_client.rs:543"]}], "lock_closure_packages": 35, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "webview2-com", "versions": ["0.39.1"], "edges": [{"owner": "perry-ui-windows", "manifest": "crates/perry-ui-windows/Cargo.toml", "alias": "webview2_com", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "=0.39", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["webview2-com@0.39.1"], "reference_lines": 3, "references": ["crates/perry-ui-windows/src/widgets/webview.rs:35", "crates/perry-ui-windows/src/widgets/webview.rs:37", "crates/perry-ui-windows/src/widgets/webview.rs:447"]}], "lock_closure_packages": 20, "lock_packages_lost_if_all_workspace_edges_removed": ["webview2-com-macros@0.8.1", "webview2-com-sys@0.39.1", "webview2-com@0.39.1"]}, +{"name": "which", "versions": ["8.0.6"], "edges": [{"owner": "perry-container-compose", "manifest": "crates/perry-container-compose/Cargo.toml", "alias": "which", "kind": "normal", "target": null, "optional": false, "requirement": "^8.0", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["which@8.0.6"], "reference_lines": 1, "references": ["crates/perry-container-compose/src/backend/detect.rs:149"]}], "lock_closure_packages": 2, "lock_packages_lost_if_all_workspace_edges_removed": ["which@8.0.6"]}, +{"name": "windows", "versions": ["0.35.0", "0.62.2"], "edges": [{"owner": "perry-ui-windows-winui", "manifest": "crates/perry-ui-windows-winui/Cargo.toml", "alias": "windows", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^0.62", "default_features": true, "features": ["Win32_Foundation"], "direct_feature_activators": [], "resolved": ["windows@0.62.2"], "reference_lines": 3, "references": ["crates/perry-ui-windows-winui/src/app.rs:7", "crates/perry-ui-windows-winui/src/app.rs:200", "crates/perry-ui-windows-winui/src/widgets.rs:5"]}, {"owner": "perry-ui-windows", "manifest": "crates/perry-ui-windows/Cargo.toml", "alias": "windows", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^0.62", "default_features": true, "features": ["Win32_Foundation", "Win32_UI_WindowsAndMessaging", "Win32_UI_Controls", "Win32_UI_Input_KeyboardAndMouse", "Win32_Graphics_Gdi", "Win32_System_LibraryLoader", "Win32_System_DataExchange", "Win32_System_Ole", "Win32_System_Com", "Win32_System_Com_StructuredStorage", "Win32_System_Memory", "Win32_System_SystemServices", "Win32_UI_HiDpi", "Win32_UI_Shell", "Win32_UI_Shell_Common", "Win32_UI_HiDpi", "Win32_System_Registry", "Win32_Storage_Xps", "Win32_Media_Audio", "Win32_System_Threading", "Win32_System_SystemInformation", "Win32_Graphics_GdiPlus", "Media_Playback", "Media_Core", "Foundation", "Media", "Data_Pdf", "Storage", "Storage_Streams", "Win32_Networking_WinHttp"], "direct_feature_activators": [], "resolved": ["windows@0.62.2"], "reference_lines": 547, "references": ["crates/perry-ui-windows/src/app.rs:13", "crates/perry-ui-windows/src/app.rs:15", "crates/perry-ui-windows/src/app.rs:17", "crates/perry-ui-windows/src/app.rs:19", "crates/perry-ui-windows/src/app.rs:21", "crates/perry-ui-windows/src/app.rs:23"]}, {"owner": "perry-ui-windows", "manifest": "crates/perry-ui-windows/Cargo.toml", "alias": "windows_xaml", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^0.35", "default_features": true, "features": ["Foundation", "Foundation_Collections", "Devices_Geolocation", "UI_Xaml", "UI_Xaml_Controls", "UI_Xaml_Controls_Maps", "UI_Xaml_Hosting", "Win32_Foundation", "Win32_System_WinRT_Xaml", "Win32_UI_WindowsAndMessaging"], "direct_feature_activators": [], "resolved": ["windows@0.35.0"], "reference_lines": 9, "references": ["crates/perry-ui-windows/src/widgets/map_view.rs:28", "crates/perry-ui-windows/src/widgets/map_view.rs:30", "crates/perry-ui-windows/src/widgets/map_view.rs:32", "crates/perry-ui-windows/src/widgets/map_view.rs:34", "crates/perry-ui-windows/src/widgets/map_view.rs:36", "crates/perry-ui-windows/src/widgets/map_view.rs:111"]}], "lock_closure_packages": 21, "lock_packages_lost_if_all_workspace_edges_removed": ["windows@0.35.0", "windows_aarch64_msvc@0.35.0", "windows_i686_gnu@0.35.0", "windows_i686_msvc@0.35.0", "windows_x86_64_gnu@0.35.0", "windows_x86_64_msvc@0.35.0"]}, +{"name": "windows-core", "versions": ["0.62.2"], "edges": [{"owner": "perry-ui-windows", "manifest": "crates/perry-ui-windows/Cargo.toml", "alias": "windows_core", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "^0.62", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["windows-core@0.62.2"], "reference_lines": 0, "references": []}], "lock_closure_packages": 16, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "windows-reactor", "versions": ["0.0.0"], "edges": [{"owner": "perry-ui-windows-winui", "manifest": "crates/perry-ui-windows-winui/Cargo.toml", "alias": "windows_reactor", "kind": "normal", "target": "cfg(target_os = \"windows\")", "optional": false, "requirement": "*", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["windows-reactor@0.0.0 [vendored]"], "reference_lines": 3, "references": ["crates/perry-ui-windows-winui/src/app.rs:8", "crates/perry-ui-windows-winui/src/app.rs:9", "crates/perry-ui-windows-winui/src/widgets.rs:6"]}], "lock_closure_packages": 18, "lock_packages_lost_if_all_workspace_edges_removed": ["windows-collections@0.3.2 [vendored]", "windows-core@0.62.2 [vendored]", "windows-future@0.3.2 [vendored]", "windows-implement@0.60.2 [vendored]", "windows-interface@0.59.3 [vendored]", "windows-link@0.2.1 [vendored]", "windows-numerics@0.3.1 [vendored]", "windows-reactor@0.0.0 [vendored]", "windows-reference@0.1.0 [vendored]", "windows-result@0.4.1 [vendored]", "windows-strings@0.5.1 [vendored]", "windows-threading@0.2.1 [vendored]", "windows-time@0.1.0 [vendored]"]}, +{"name": "windows-sys", "versions": ["0.48.0", "0.52.0", "0.59.0", "0.60.2", "0.61.2"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "windows_sys", "kind": "normal", "target": "cfg(windows)", "optional": false, "requirement": "^0.61", "default_features": true, "features": ["Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_Foundation", "Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_Ndis", "Win32_Networking_WinSock", "Win32_System_LibraryLoader", "Win32_System_IO", "Win32_System_Pipes", "Win32_System_Threading"], "direct_feature_activators": [], "resolved": ["windows-sys@0.61.2"], "reference_lines": 60, "references": ["crates/perry-runtime/src/child_process/ipc_transport.rs:14", "crates/perry-runtime/src/child_process/ipc_transport.rs:18", "crates/perry-runtime/src/child_process/ipc_transport.rs:19", "crates/perry-runtime/src/child_process/ipc_transport.rs:20", "crates/perry-runtime/src/child_process/ipc_transport.rs:21", "crates/perry-runtime/src/child_process/reactor/kill.rs:20"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "windows_sys", "kind": "normal", "target": "cfg(windows)", "optional": false, "requirement": "^0.61", "default_features": true, "features": ["Win32_System_Console", "Win32_Foundation"], "direct_feature_activators": [], "resolved": ["windows-sys@0.61.2"], "reference_lines": 3, "references": ["crates/perry-stdlib/src/readline/mod.rs:1329", "crates/perry-stdlib/src/readline/mod.rs:1354", "crates/perry-stdlib/src/readline/mod.rs:1400"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "windows_sys", "kind": "normal", "target": "cfg(windows)", "optional": false, "requirement": "^0.61", "default_features": true, "features": ["Win32_Foundation", "Win32_Storage_FileSystem", "Win32_System_Threading"], "direct_feature_activators": [], "resolved": ["windows-sys@0.61.2"], "reference_lines": 4, "references": ["crates/perry/src/update_checker.rs:1165", "crates/perry/src/update_checker.rs:1214", "crates/perry/src/update_checker.rs:1215", "crates/perry/src/update_checker.rs:1216"]}], "lock_closure_packages": 32, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "winresource", "versions": ["0.1.31"], "edges": [{"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "winresource", "kind": "build", "target": null, "optional": false, "requirement": "^0.1.31", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["winresource@0.1.31"], "reference_lines": 1, "references": ["crates/perry/build.rs:11"]}], "lock_closure_packages": 21, "lock_packages_lost_if_all_workspace_edges_removed": ["winresource@0.1.31"]}, +{"name": "writeable", "versions": ["0.6.4"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "writeable", "kind": "normal", "target": null, "optional": true, "requirement": "^0.6", "default_features": true, "features": [], "direct_feature_activators": ["intl-datetime"], "resolved": ["writeable@0.6.4"], "reference_lines": 1, "references": ["crates/perry-runtime/src/intl/icu_dtf.rs:18"]}], "lock_closure_packages": 9, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "x25519-dalek", "versions": ["2.0.1"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "x25519_dalek", "kind": "normal", "target": null, "optional": true, "requirement": "^2.0", "default_features": true, "features": ["static_secrets"], "direct_feature_activators": ["crypto"], "resolved": ["x25519-dalek@2.0.1"], "reference_lines": 18, "references": ["crates/perry-stdlib/src/crypto/sign.rs:552", "crates/perry-stdlib/src/crypto/sign.rs:553", "crates/perry-stdlib/src/crypto/sign.rs:598", "crates/perry-stdlib/src/crypto/sign.rs:599", "crates/perry-stdlib/src/crypto/sign.rs:630", "crates/perry-stdlib/src/crypto/sign.rs:631"]}], "lock_closure_packages": 50, "lock_packages_lost_if_all_workspace_edges_removed": ["x25519-dalek@2.0.1"]}, +{"name": "x448", "versions": ["0.14.0-pre.12"], "edges": [{"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "x448", "kind": "normal", "target": null, "optional": true, "requirement": "^0.14.0-pre.9", "default_features": true, "features": ["static_secrets"], "direct_feature_activators": ["crypto"], "resolved": ["x448@0.14.0-pre.12"], "reference_lines": 6, "references": ["crates/perry-stdlib/src/webcrypto/hmac.rs:523", "crates/perry-stdlib/src/webcrypto/hmac.rs:524", "crates/perry-stdlib/src/webcrypto/jwk.rs:939", "crates/perry-stdlib/src/webcrypto/jwk.rs:940", "crates/perry-stdlib/src/webcrypto/keys.rs:370", "crates/perry-stdlib/src/webcrypto/keys.rs:371"]}], "lock_closure_packages": 101, "lock_packages_lost_if_all_workspace_edges_removed": ["x448@0.14.0-pre.12"]}, +{"name": "x509-cert", "versions": ["0.3.0"], "edges": [{"owner": "perry-ext-http", "manifest": "crates/perry-ext-http/Cargo.toml", "alias": "x509_cert", "kind": "normal", "target": null, "optional": false, "requirement": "^0.3", "default_features": false, "features": [], "direct_feature_activators": [], "resolved": ["x509-cert@0.3.0"], "reference_lines": 12, "references": ["crates/perry-ext-http/src/tls_client.rs:441", "crates/perry-ext-http/src/tls_client.rs:455", "crates/perry-ext-http/src/tls_client.rs:481", "crates/perry-ext-http/src/tls_client.rs:483", "crates/perry-ext-http/src/tls_client.rs:486", "crates/perry-ext-http/src/tls_client.rs:489"]}, {"owner": "perry-ext-node-forge", "manifest": "crates/perry-ext-node-forge/Cargo.toml", "alias": "x509_cert", "kind": "normal", "target": null, "optional": false, "requirement": "^0.3", "default_features": true, "features": ["builder", "hazmat"], "direct_feature_activators": [], "resolved": ["x509-cert@0.3.0"], "reference_lines": 18, "references": ["crates/perry-ext-node-forge/src/crypto.rs:28", "crates/perry-ext-node-forge/src/crypto.rs:29", "crates/perry-ext-node-forge/src/crypto.rs:30", "crates/perry-ext-node-forge/src/crypto.rs:31", "crates/perry-ext-node-forge/src/crypto.rs:32", "crates/perry-ext-node-forge/src/crypto.rs:33"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "x509_cert", "kind": "normal", "target": null, "optional": false, "requirement": "^0.3", "default_features": false, "features": [], "direct_feature_activators": [], "resolved": ["x509-cert@0.3.0"], "reference_lines": 12, "references": ["crates/perry-runtime/src/tls.rs:472", "crates/perry-runtime/src/tls.rs:473", "crates/perry-runtime/src/tls.rs:475", "crates/perry-runtime/src/tls.rs:479", "crates/perry-runtime/src/tls.rs:484", "crates/perry-runtime/src/tls.rs:493"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "x509_cert", "kind": "normal", "target": null, "optional": true, "requirement": "^0.3", "default_features": false, "features": ["pem"], "direct_feature_activators": ["crypto", "external-tls-server", "tls-runtime"], "resolved": ["x509-cert@0.3.0"], "reference_lines": 62, "references": ["crates/perry-stdlib/src/crypto/x509.rs:5", "crates/perry-stdlib/src/crypto/x509.rs:32", "crates/perry-stdlib/src/crypto/x509.rs:44", "crates/perry-stdlib/src/crypto/x509.rs:45", "crates/perry-stdlib/src/crypto/x509.rs:50", "crates/perry-stdlib/src/crypto/x509.rs:54"]}], "lock_closure_packages": 86, "lock_packages_lost_if_all_workspace_edges_removed": ["tls_codec@0.4.2", "tls_codec_derive@0.4.2", "x509-cert@0.3.0"]}, +{"name": "xxhash-rust", "versions": ["0.8.18"], "edges": [{"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "xxhash_rust", "kind": "normal", "target": null, "optional": true, "requirement": "^0.8.15", "default_features": true, "features": ["xxh64"], "direct_feature_activators": ["bun-cli-utils"], "resolved": ["xxhash-rust@0.8.18"], "reference_lines": 1, "references": ["crates/perry-runtime/src/bun_compat/cli_utils.rs:565"]}], "lock_closure_packages": 1, "lock_packages_lost_if_all_workspace_edges_removed": []}, +{"name": "zip", "versions": ["8.6.0"], "edges": [{"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "zip", "kind": "normal", "target": null, "optional": false, "requirement": "^8", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["zip@8.6.0"], "reference_lines": 12, "references": ["crates/perry/src/commands/harmonyos_hap.rs:53", "crates/perry/src/commands/harmonyos_hap.rs:54", "crates/perry/src/commands/harmonyos_hap.rs:635", "crates/perry/src/commands/harmonyos_hap.rs:795", "crates/perry/src/commands/run/remote.rs:622", "crates/perry/src/update_checker.rs:961"]}], "lock_closure_packages": 115, "lock_packages_lost_if_all_workspace_edges_removed": ["bzip2@0.6.1", "constant_time_eq@0.4.2", "deflate64@0.1.12", "libbz2-rs-sys@0.2.5", "lzma-rust2@0.16.4", "ppmd-rust@1.4.0", "typed-path@0.12.3", "zip@8.6.0", "zopfli@0.8.3"]}, +{"name": "zstd", "versions": ["0.13.3"], "edges": [{"owner": "perry-ext-zlib", "manifest": "crates/perry-ext-zlib/Cargo.toml", "alias": "zstd", "kind": "normal", "target": null, "optional": false, "requirement": "^0.13", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["zstd@0.13.3"], "reference_lines": 11, "references": ["crates/perry-ext-zlib/src/stream.rs:243", "crates/perry-ext-zlib/src/stream.rs:262", "crates/perry-ext-zlib/src/stream.rs:276", "crates/perry-ext-zlib/src/stream.rs:287", "crates/perry-ext-zlib/src/stream.rs:344", "crates/perry-ext-zlib/src/stream.rs:345"]}, {"owner": "perry-runtime", "manifest": "crates/perry-runtime/Cargo.toml", "alias": "zstd", "kind": "normal", "target": null, "optional": true, "requirement": "^0.13", "default_features": true, "features": [], "direct_feature_activators": ["bun-cli-utils"], "resolved": ["zstd@0.13.3"], "reference_lines": 10, "references": ["crates/perry-runtime/src/bun_compat/cli_utils.rs:539", "crates/perry-runtime/src/embedded/compressed.rs:8", "crates/perry-runtime/src/embedded/compressed.rs:9", "crates/perry-runtime/src/embedded/compressed.rs:17", "crates/perry-runtime/src/embedded/compressed.rs:94", "crates/perry-runtime/src/embedded/compressed.rs:105"]}, {"owner": "perry-stdlib", "manifest": "crates/perry-stdlib/Cargo.toml", "alias": "zstd", "kind": "normal", "target": null, "optional": true, "requirement": "^0.13.3", "default_features": true, "features": [], "direct_feature_activators": ["compression-zstd"], "resolved": ["zstd@0.13.3"], "reference_lines": 2, "references": ["crates/perry-stdlib/src/zlib.rs:563", "crates/perry-stdlib/src/zlib.rs:568"]}, {"owner": "perry", "manifest": "crates/perry/Cargo.toml", "alias": "zstd", "kind": "normal", "target": null, "optional": false, "requirement": "^0.13", "default_features": true, "features": [], "direct_feature_activators": [], "resolved": ["zstd@0.13.3"], "reference_lines": 5, "references": ["crates/perry/src/commands/compile/compressed_libs.rs:77", "crates/perry/src/commands/compile/embed/compression.rs:31", "crates/perry/src/commands/compile/embed/compression.rs:79", "crates/perry/src/commands/compile/embed/compression.rs:82", "crates/perry/src/commands/run/entry.rs:336"]}], "lock_closure_packages": 42, "lock_packages_lost_if_all_workspace_edges_removed": []} +], +"external_lock_packages": [ +{"package": "adler2@2.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["miniz_oxide@0.8.9", "miniz_oxide@0.9.1"], "dependencies": []}, +{"package": "aead@0.5.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "getrandom", "rand_core"], "parents": ["aes-gcm@0.10.3", "chacha20poly1305@0.10.1"], "dependencies": ["crypto-common@0.1.7", "generic-array@0.14.7"]}, +{"package": "aes-gcm@0.10.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["aes", "alloc", "default", "getrandom", "rand_core"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["aead@0.5.2", "aes@0.8.4", "cipher@0.4.4", "ctr@0.9.2", "ghash@0.5.1", "subtle@2.6.1"]}, +{"package": "aes-kw@0.3.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "oid"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["aes@0.9.1", "const-oid@0.10.2"]}, +{"package": "aes@0.8.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["aes-gcm@0.10.3", "lopdf@0.39.0", "perry-stdlib@0.5.1565", "pkcs5@0.7.1"], "dependencies": ["cfg-if@1.0.4", "cipher@0.4.4", "cpufeatures@0.2.17"]}, +{"package": "aes@0.9.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["aes-kw@0.3.1", "perry-stdlib@0.5.1565", "zip@8.6.0"], "dependencies": ["cipher@0.5.2", "cpubits@0.1.1", "cpufeatures@0.3.0"]}, +{"package": "ahash@0.8.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "getrandom", "runtime-rng", "std"], "parents": ["bson@3.1.0", "hashbrown@0.14.5", "perry-runtime@0.5.1565"], "dependencies": ["cfg-if@1.0.4", "getrandom@0.3.4", "once_cell@1.21.4", "version_check@0.9.5", "zerocopy@0.8.50"]}, +{"package": "aho-corasick@1.1.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "perf-literal", "std"], "parents": ["perry-codegen@0.5.1565", "regex-automata@0.4.18", "regex@1.13.1"], "dependencies": ["memchr@2.8.1"]}, +{"package": "aliasable@0.1.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default"], "parents": ["ouroboros@0.17.2"], "dependencies": []}, +{"package": "aligned-vec@0.6.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["rav1e@0.8.1", "v_frame@0.3.9"], "dependencies": ["equator@0.4.2"]}, +{"package": "aligned@0.4.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["av-scenechange@0.14.1"], "dependencies": ["as-slice@0.2.1"]}, +{"package": "alloc-no-stdlib@2.0.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["alloc-stdlib@0.2.2", "brotli-decompressor@5.0.1", "brotli@8.0.4"], "dependencies": []}, +{"package": "alloc-stdlib@0.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["brotli-decompressor@5.0.1", "brotli@8.0.4"], "dependencies": ["alloc-no-stdlib@2.0.4"]}, +{"package": "allocator-api2@0.2.21", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["bumpalo@3.20.3", "hashbrown@0.14.5", "hashbrown@0.16.1", "hashbrown@0.17.1", "swc_allocator@4.0.1"], "dependencies": []}, +{"package": "allsorts-azul@0.16.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["flate2", "flate2_rust"], "parents": ["printpdf@0.10.1"], "dependencies": ["bitflags@2.12.1", "brotli-decompressor@5.0.1", "encoding_rs@0.8.35", "flate2@1.1.10", "glyph-names@0.2.0", "log@0.4.34", "ouroboros@0.17.2", "pathfinder_geometry@0.5.1", "rustc-hash@1.1.0", "tinyvec@1.11.0", "ucd-trie@0.1.7", "unicode-canonical-combining-class@1.0.0", "unicode-general-category@1.1.0", "unicode-joining-type@1.0.0"]}, +{"package": "android_system_properties@0.1.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["iana-time-zone@0.1.65"], "dependencies": ["libc@0.2.189"]}, +{"package": "anstream@1.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["auto", "default", "wincon"], "parents": ["clap_builder@4.6.6"], "dependencies": ["anstyle-parse@1.0.0", "anstyle-query@1.1.5", "anstyle-wincon@3.0.11", "anstyle@1.0.14", "colorchoice@1.0.5", "is_terminal_polyfill@1.70.2", "utf8parse@0.2.2"]}, +{"package": "anstyle-parse@1.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "utf8"], "parents": ["anstream@1.0.0"], "dependencies": ["utf8parse@0.2.2"]}, +{"package": "anstyle-query@1.1.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["anstream@1.0.0"], "dependencies": ["windows-sys@0.61.2"]}, +{"package": "anstyle-wincon@3.0.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["anstream@1.0.0"], "dependencies": ["anstyle@1.0.14", "once_cell_polyfill@1.70.2", "windows-sys@0.61.2"]}, +{"package": "anstyle@1.0.14", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["anstream@1.0.0", "anstyle-wincon@3.0.11", "clap_builder@4.6.6"], "dependencies": []}, +{"package": "anyhow@1.0.104", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["av-scenechange@0.14.1", "av1-grain@0.2.5", "llvm-sys@221.0.1", "perry-codegen-arkts@0.5.1565", "perry-codegen-glance@0.5.1565", "perry-codegen-js@0.5.1565", "perry-codegen-swiftui@0.5.1565", "perry-codegen-wasm@0.5.1565", "perry-codegen-wear-tiles@0.5.1565", "perry-codegen@0.5.1565", "perry-container-compose@0.5.1565", "perry-container-e2e@0.5.1565", "perry-doc-tests@0.5.1565", "perry-ext-typescript@0.5.1565", "perry-hir@0.5.1565", "perry-parser@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-transform@0.5.1565", "perry-updater@0.5.1565", "perry@0.5.1565", "swc_bundler@37.0.0", "swc_common@18.0.1", "swc_config@3.1.2", "swc_ecma_loader@18.0.0", "wasm-metadata@0.244.0", "wit-bindgen-core@0.51.0", "wit-bindgen-rust-macro@0.51.0", "wit-bindgen-rust@0.51.0", "wit-component@0.244.0", "wit-parser@0.244.0"], "dependencies": []}, +{"package": "ar_archive_writer@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["psm@0.1.32"], "dependencies": ["object@0.37.3"]}, +{"package": "arbitrary@1.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["libfuzzer-sys@0.4.12", "rav1e@0.8.1"], "dependencies": []}, +{"package": "arc-swap@1.9.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["redis@1.6.0"], "dependencies": ["rustversion@1.0.22"]}, +{"package": "arcstr@1.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "substr"], "parents": ["redis@1.6.0"], "dependencies": []}, +{"package": "arg_enum_proc_macro@0.3.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["av-scenechange@0.14.1", "rav1e@0.8.1"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "argon2@0.5.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "password-hash", "rand"], "parents": ["perry-ext-argon2@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["base64ct@1.8.3", "blake2@0.10.6", "cpufeatures@0.2.17", "password-hash@0.5.0"]}, +{"package": "arrayvec@0.7.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["av-scenechange@0.14.1", "av1-grain@0.2.5", "avif-serialize@0.8.9", "rav1e@0.8.1", "rust_decimal@1.43.0", "taffy@0.13.0"], "dependencies": []}, +{"package": "as-slice@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["aligned@0.4.3"], "dependencies": ["stable_deref_trait@1.2.1"]}, +{"package": "ascii@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["swc_ecma_codegen@21.0.0", "tiny_http@0.12.0"], "dependencies": []}, +{"package": "ast_node@5.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_common@18.0.1"], "dependencies": ["quote@1.0.45", "swc_macros_common@1.0.1", "syn@2.0.117"]}, +{"package": "async-broadcast@0.7.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zbus@5.16.0"], "dependencies": ["event-listener-strategy@0.5.4", "event-listener@5.4.1", "futures-core@0.3.34", "pin-project-lite@0.2.17"]}, +{"package": "async-channel@2.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["async-process@2.5.0", "blocking@1.6.2", "mpris-server@0.10.0"], "dependencies": ["concurrent-queue@2.5.0", "event-listener-strategy@0.5.4", "futures-core@0.3.34", "pin-project-lite@0.2.17"]}, +{"package": "async-executor@1.14.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zbus@5.16.0"], "dependencies": ["async-task@4.7.1", "concurrent-queue@2.5.0", "fastrand@2.4.1", "futures-lite@2.6.1", "pin-project-lite@0.2.17", "slab@0.4.12"]}, +{"package": "async-io@2.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["async-process@2.5.0", "async-signal@0.2.14", "zbus@5.16.0"], "dependencies": ["autocfg@1.5.1", "cfg-if@1.0.4", "concurrent-queue@2.5.0", "futures-io@0.3.34", "futures-lite@2.6.1", "parking@2.2.1", "polling@3.11.0", "rustix@1.1.4", "slab@0.4.12", "windows-sys@0.61.2"]}, +{"package": "async-lock@3.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["async-process@2.5.0", "async-signal@0.2.14", "redis@1.6.0", "zbus@5.16.0"], "dependencies": ["event-listener-strategy@0.5.4", "event-listener@5.4.1", "pin-project-lite@0.2.17"]}, +{"package": "async-process@2.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zbus@5.16.0"], "dependencies": ["async-channel@2.5.0", "async-io@2.6.0", "async-lock@3.4.2", "async-signal@0.2.14", "async-task@4.7.1", "blocking@1.6.2", "cfg-if@1.0.4", "event-listener@5.4.1", "futures-lite@2.6.1", "rustix@1.1.4"]}, +{"package": "async-recursion@1.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zbus@5.16.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "async-signal@0.2.14", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["async-process@2.5.0"], "dependencies": ["async-io@2.6.0", "async-lock@3.4.2", "atomic-waker@1.1.2", "cfg-if@1.0.4", "futures-core@0.3.34", "futures-io@0.3.34", "rustix@1.1.4", "signal-hook-registry@1.4.8", "slab@0.4.12", "windows-sys@0.61.2"]}, +{"package": "async-task@4.7.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["async-executor@1.14.0", "async-process@2.5.0", "blocking@1.6.2", "zbus@5.16.0"], "dependencies": []}, +{"package": "async-trait@0.1.92", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["hickory-net@0.26.1", "lettre@0.11.23", "perry-container-compose@0.5.1565", "zbus@5.16.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@3.0.3"]}, +{"package": "atoi@2.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0"], "dependencies": ["num-traits@0.2.19"]}, +{"package": "atomic-waker@1.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["async-signal@0.2.14", "h2@0.4.19", "hyper@1.11.1", "piper@0.2.5"], "dependencies": []}, +{"package": "atomic@0.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["uuid@1.26.0"], "dependencies": ["bytemuck@1.25.0"]}, +{"package": "atomic_refcell@0.1.14", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["gstreamer-base@0.25.2"], "dependencies": []}, +{"package": "atty@0.2.14", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-container-compose@0.5.1565"], "dependencies": ["hermit-abi@0.1.19", "libc@0.2.189", "winapi@0.3.9"]}, +{"package": "auto_impl@1.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_graph_analyzer@14.0.2"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "autocfg@1.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["async-io@2.6.0", "memoffset@0.9.1", "num-iter@0.1.45", "num-traits@0.2.19", "smartstring@1.0.1"], "dependencies": []}, +{"package": "av-scenechange@0.14.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rav1e@0.8.1"], "dependencies": ["aligned@0.4.3", "anyhow@1.0.104", "arg_enum_proc_macro@0.3.4", "arrayvec@0.7.6", "log@0.4.34", "num-rational@0.4.2", "num-traits@0.2.19", "pastey@0.1.1", "rayon@1.12.0", "thiserror@2.0.18", "v_frame@0.3.9", "y4m@0.8.0"]}, +{"package": "av1-grain@0.2.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["create", "default", "diff", "estimate", "nom", "num-rational", "parse", "v_frame"], "parents": ["rav1e@0.8.1"], "dependencies": ["anyhow@1.0.104", "arrayvec@0.7.6", "log@0.4.34", "nom@8.0.0", "num-rational@0.4.2", "v_frame@0.3.9"]}, +{"package": "avif-serialize@0.8.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ravif@0.13.0"], "dependencies": ["arrayvec@0.7.6"]}, +{"package": "aws-lc-rs@1.17.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["aws-lc-sys", "prebuilt-nasm"], "parents": ["rustls-webpki@0.103.13", "rustls@0.23.43"], "dependencies": ["aws-lc-sys@0.41.0", "zeroize@1.8.2"]}, +{"package": "aws-lc-sys@0.41.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["prebuilt-nasm"], "parents": ["aws-lc-rs@1.17.0"], "dependencies": ["cc@1.4.4", "cmake@0.1.58", "dunce@1.0.5", "fs_extra@1.3.0"]}, +{"package": "backon@1.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["redis@1.6.0"], "dependencies": ["fastrand@2.4.1"]}, +{"package": "base16ct@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["elliptic-curve@0.13.8", "p521@0.13.3", "sec1@0.7.3"], "dependencies": []}, +{"package": "base16ct@1.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["elliptic-curve@0.14.0", "sec1@0.8.1", "serdect@0.4.3"], "dependencies": []}, +{"package": "base64-simd@0.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "detect", "std"], "parents": ["swc_sourcemap@9.3.4"], "dependencies": ["outref@0.5.2", "vsimd@0.8.0"]}, +{"package": "base64@0.22.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "std"], "parents": ["bson@3.1.0", "email-encoding@0.4.1", "hyper-util@0.1.20", "jsonwebtoken@11.0.0", "mongodb@3.8.2", "pem@3.0.6", "perry-codegen-wasm@0.5.1565", "perry-ext-http@0.5.1565", "perry-ext-jsonwebtoken@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-ui-android@0.5.1565", "perry-ui-gtk4@0.5.1565", "perry-ui-ios@0.5.1565", "perry-ui-macos@0.5.1565", "perry-ui-tvos@0.5.1565", "perry-ui-visionos@0.5.1565", "perry-ui-windows-winui@0.5.1565", "perry-ui-windows@0.5.1565", "perry-updater@0.5.1565", "perry@0.5.1565", "printpdf@0.10.1", "reqwest@0.12.28", "sqlx-core@0.9.0", "sqlx-postgres@0.9.0", "swc_ecma_transforms_react@35.0.0"], "dependencies": []}, +{"package": "base64@0.23.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "simd-unsafe", "std"], "parents": ["bcrypt@0.19.3", "lettre@0.11.23", "pem@4.0.0"], "dependencies": []}, +{"package": "base64ct@1.8.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "std"], "parents": ["argon2@0.5.3", "password-hash@0.5.0", "pem-rfc7468@0.7.0", "pem-rfc7468@1.0.0", "spki@0.7.3", "spki@0.8.0"], "dependencies": []}, +{"package": "bcrypt@0.19.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "getrandom", "std", "zeroize"], "parents": ["perry-ext-bcrypt@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["base64@0.23.1", "blowfish@0.10.0", "getrandom@0.4.2", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "better_scoped_tls@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_common@18.0.1", "swc_ecma_transforms_base@32.0.0"], "dependencies": ["scoped-tls@1.0.1"]}, +{"package": "bindgen@0.72.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["runtime"], "parents": ["libsqlite3-sys@0.37.0"], "dependencies": ["bitflags@2.12.1", "cexpr@0.6.0", "clang-sys@1.8.1", "itertools@0.12.1", "proc-macro2@1.0.106", "quote@1.0.45", "regex@1.13.1", "rustc-hash@2.1.2", "shlex@1.3.0", "syn@2.0.117"]}, +{"package": "bit-set@0.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["proptest@1.11.0"], "dependencies": ["bit-vec@0.8.0"]}, +{"package": "bit-vec@0.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["bit-set@0.8.0", "proptest@1.11.0"], "dependencies": []}, +{"package": "bit_field@0.10.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["exr@1.74.0"], "dependencies": []}, +{"package": "bitflags@1.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["inotify@0.9.6"], "dependencies": []}, +{"package": "bitflags@2.12.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["serde", "serde_core", "std"], "parents": ["allsorts-azul@0.16.5", "bindgen@0.72.1", "cairo-rs@0.20.12", "cairo-rs@0.22.9", "dispatch2@0.3.1", "glib@0.20.12", "glib@0.22.7", "inkwell@0.9.0", "kqueue-sys@1.1.2", "lopdf@0.39.0", "mongodb@3.8.2", "notify@6.1.1", "objc2-app-kit@0.3.2", "objc2-cloud-kit@0.3.2", "objc2-core-data@0.3.2", "objc2-core-foundation@0.3.2", "objc2-core-graphics@0.3.2", "objc2-core-text@0.3.2", "objc2-core-video@0.3.2", "objc2-foundation@0.3.2", "objc2-io-surface@0.3.2", "objc2-quartz-core@0.3.2", "objc2-ui-kit@0.3.2", "png@0.18.1", "proptest@1.11.0", "raw-cpuid@11.6.0", "redox_syscall@0.5.18", "rusqlite@0.39.0", "rustix@1.1.4", "security-framework@3.7.0", "selectors@0.38.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "swc_ecma_ast@19.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "system-configuration@0.7.0", "tower-http@0.6.11", "wasmparser@0.239.0", "wasmparser@0.244.0", "wasmparser@0.258.0", "wit-component@0.244.0"], "dependencies": ["serde_core@1.0.229"]}, +{"package": "bitstream-io@4.10.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["rav1e@0.8.1"], "dependencies": ["no_std_io2@0.9.4"]}, +{"package": "bitvec@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "atomic", "default", "std"], "parents": ["bson@3.1.0", "swc_sourcemap@9.3.4"], "dependencies": ["funty@2.0.0", "radium@0.7.0", "tap@1.0.1", "wyz@0.5.1"]}, +{"package": "blake2@0.10.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["argon2@0.5.3"], "dependencies": ["digest@0.10.7"]}, +{"package": "block-buffer@0.10.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["digest@0.10.7"], "dependencies": ["generic-array@0.14.7"]}, +{"package": "block-buffer@0.12.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["zeroize"], "parents": ["digest@0.11.3"], "dependencies": ["hybrid-array@0.4.12", "zeroize@1.8.2"]}, +{"package": "block-padding@0.3.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["inout@0.1.4"], "dependencies": ["generic-array@0.14.7"]}, +{"package": "block-padding@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["inout@0.2.2"], "dependencies": ["hybrid-array@0.4.12"]}, +{"package": "block2@0.6.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "std"], "parents": ["objc2-app-kit@0.3.2", "objc2-core-foundation@0.3.2", "objc2-foundation@0.3.2", "objc2-ui-kit@0.3.2", "perry-ui-ios@0.5.1565", "perry-ui-macos@0.5.1565", "perry-ui-tvos@0.5.1565", "perry-ui-visionos@0.5.1565", "perry-ui-watchos@0.5.1565"], "dependencies": ["objc2@0.6.4"]}, +{"package": "blocking@1.6.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["async-process@2.5.0", "zbus@5.16.0"], "dependencies": ["async-channel@2.5.0", "async-task@4.7.1", "futures-io@0.3.34", "futures-lite@2.6.1", "piper@0.2.5"]}, +{"package": "blowfish@0.10.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["bcrypt"], "parents": ["bcrypt@0.19.3"], "dependencies": ["byteorder@1.5.0", "cipher@0.5.2"]}, +{"package": "borsh-derive@1.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "schema"], "parents": ["borsh@1.6.1"], "dependencies": ["once_cell@1.21.4", "proc-macro-crate@3.5.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "borsh@1.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["borsh-derive", "derive", "std", "unstable__schema"], "parents": ["rust_decimal@1.43.0"], "dependencies": ["borsh-derive@1.6.1", "bytes@1.12.1", "cfg_aliases@0.2.1"]}, +{"package": "brotli-decompressor@5.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc-stdlib", "default", "std"], "parents": ["allsorts-azul@0.16.5", "brotli@8.0.4"], "dependencies": ["alloc-no-stdlib@2.0.4", "alloc-stdlib@0.2.2"]}, +{"package": "brotli@8.0.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc-stdlib", "default", "std"], "parents": ["perry-ext-zlib@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["alloc-no-stdlib@2.0.4", "alloc-stdlib@0.2.2", "brotli-decompressor@5.0.1"]}, +{"package": "bson@3.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["compat-3-0-0", "default", "serde"], "parents": ["mongocrypt@0.4.0", "mongodb@3.8.2", "perry-ext-mongodb@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["ahash@0.8.12", "base64@0.22.1", "bitvec@1.0.1", "getrandom@0.3.4", "hex@0.4.3", "indexmap@2.14.1", "js-sys@0.3.99", "rand@0.9.4", "serde@1.0.229", "serde_bytes@0.11.19", "simdutf8@0.1.5", "thiserror@2.0.18", "time@0.3.55", "uuid@1.26.0"]}, +{"package": "built@0.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rav1e@0.8.1"], "dependencies": []}, +{"package": "bumpalo@3.20.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["allocator-api2", "default"], "parents": ["swc_allocator@4.0.1", "wasm-bindgen-macro-support@0.2.122", "zopfli@0.8.3"], "dependencies": ["allocator-api2@0.2.21"]}, +{"package": "bytecount@0.6.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["node-semver@2.2.0", "nom_locate@5.0.0"], "dependencies": []}, +{"package": "bytemuck@1.25.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["extern_crate_alloc"], "parents": ["atomic@0.6.1", "image@0.25.10", "qoi@0.4.1", "rgb@0.8.53"], "dependencies": []}, +{"package": "byteorder-lite@0.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["image-webp@0.2.4", "image@0.25.10"], "dependencies": []}, +{"package": "byteorder@1.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["blowfish@0.10.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "tungstenite@0.24.0"], "dependencies": []}, +{"package": "bytes-str@0.2.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["serde"], "parents": ["swc_common@18.0.1", "swc_config@3.1.2", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_transforms_typescript@35.0.0", "swc_sourcemap@9.3.4"], "dependencies": ["bytes@1.12.1", "serde@1.0.229"]}, +{"package": "bytes@1.12.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["borsh@1.6.1", "bytes-str@0.2.7", "combine@4.6.7", "h2@0.4.19", "http-body-util@0.1.5", "http-body@1.0.1", "http@1.4.1", "hyper-util@0.1.20", "hyper@1.11.1", "perry-ext-fastify@0.5.1565", "perry-ext-fetch@0.5.1565", "perry-ext-http@0.5.1565", "perry-ext-net@0.5.1565", "perry-stdlib@0.5.1565", "quinn-proto@0.11.15", "quinn@0.11.9", "redis@1.6.0", "reqwest@0.12.28", "rust_decimal@1.43.0", "sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "tokio-util@0.7.18", "tokio@1.53.1", "tower-http@0.6.11", "tungstenite@0.24.0", "tungstenite@0.29.0"], "dependencies": []}, +{"package": "bzip2@0.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["zip@8.6.0"], "dependencies": ["libbz2-rs-sys@0.2.5"]}, +{"package": "cairo-rs@0.20.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "glib", "use_glib"], "parents": ["gdk4@0.9.6", "gsk4@0.9.6", "gtk4@0.9.7"], "dependencies": ["bitflags@2.12.1", "cairo-sys-rs@0.20.10", "glib@0.20.12", "libc@0.2.189"]}, +{"package": "cairo-rs@0.22.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "glib", "use_glib"], "parents": ["perry-ui-gtk4@0.5.1565"], "dependencies": ["bitflags@2.12.1", "cairo-sys-rs@0.22.0", "glib@0.22.7", "libc@0.2.189"]}, +{"package": "cairo-sys-rs@0.20.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["glib-sys", "use_glib"], "parents": ["cairo-rs@0.20.12", "gdk4-sys@0.9.6", "gsk4-sys@0.9.6", "gtk4-sys@0.9.6"], "dependencies": ["glib-sys@0.20.10", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "cairo-sys-rs@0.22.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["glib-sys", "use_glib"], "parents": ["cairo-rs@0.22.9"], "dependencies": ["glib-sys@0.22.6", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "calendrical_calculations@0.2.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_calendar@2.3.0", "icu_time@2.3.0", "temporal_rs@0.2.6"], "dependencies": ["core_maths@0.1.1", "displaydoc@0.2.6"]}, +{"package": "castaway@0.2.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["compact_str@0.7.1"], "dependencies": ["rustversion@1.0.22"]}, +{"package": "cbc@0.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["block-padding", "default"], "parents": ["lopdf@0.39.0", "p12@0.6.3", "pkcs5@0.7.1"], "dependencies": ["cipher@0.4.4"]}, +{"package": "cbc@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["block-padding", "default"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["cipher@0.5.2"]}, +{"package": "cc@1.4.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["parallel"], "parents": ["aws-lc-sys@0.41.0", "cmake@0.1.58", "iana-time-zone-haiku@0.1.2", "libfuzzer-sys@0.4.12", "libmimalloc-sys@0.1.49", "libsqlite3-sys@0.37.0", "llvm-sys@221.0.1", "perry-audio-miniaudio@0.5.1565", "perry-runtime@0.5.1565", "psm@0.1.32", "ring@0.17.14", "sqlite-wasm-rs@0.5.5", "stacker@0.1.25", "zstd-sys@2.0.16+zstd.1.5.7"], "dependencies": ["find-msvc-tools@0.1.11", "jobserver@0.1.34", "libc@0.2.189", "shlex@2.0.1"]}, +{"package": "cexpr@0.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["bindgen@0.72.1"], "dependencies": ["nom@7.1.3"]}, +{"package": "cfg-expr@0.20.8", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "target-lexicon", "targets"], "parents": ["system-deps@7.0.8"], "dependencies": ["smallvec@1.15.1", "target-lexicon@0.13.5"]}, +{"package": "cfg-if@1.0.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["aes@0.8.4", "ahash@0.8.12", "async-io@2.6.0", "async-process@2.5.0", "async-signal@0.2.14", "chacha20@0.10.0", "chacha20@0.9.1", "compact_str@0.7.1", "crc32fast@1.5.0", "curve25519-dalek@4.1.3", "dashmap@5.5.3", "dashmap@6.2.1", "encoding_rs@0.8.35", "etcetera@0.11.0", "fast_image_resize@6.1.0", "filetime@0.2.29", "getrandom@0.2.17", "getrandom@0.3.4", "getrandom@0.4.2", "governor@0.10.4", "gstreamer-base@0.25.2", "gstreamer-sys@0.25.2", "gstreamer@0.25.3", "half@2.7.1", "hickory-net@0.26.1", "hickory-resolver@0.26.1", "hostname@0.4.2", "jni@0.22.4", "js-sys@0.3.99", "keccak@0.2.0", "libloading@0.8.9", "maybe-rayon@0.1.1", "md-5@0.10.6", "md-5@0.11.0", "miette@7.6.0", "parking_lot_core@0.9.12", "polling@3.11.0", "polyval@0.6.2", "rav1e@0.8.1", "redis@1.6.0", "ring@0.17.14", "sha1@0.10.6", "sha1@0.11.0", "sha2@0.10.9", "sha2@0.11.0", "sqlx-core@0.9.0", "sqlx-macros-core@0.9.0", "stacker@0.1.25", "thread_local@1.1.9", "wasm-bindgen@0.2.122"], "dependencies": []}, +{"package": "cfg_aliases@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["borsh@1.6.1", "quinn-udp@0.5.14", "quinn@0.11.9"], "dependencies": []}, +{"package": "chacha20@0.10.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["rng"], "parents": ["rand@0.10.2"], "dependencies": ["cfg-if@1.0.4", "cpufeatures@0.3.0", "rand_core@0.10.1"]}, +{"package": "chacha20@0.9.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["zeroize"], "parents": ["chacha20poly1305@0.10.1"], "dependencies": ["cfg-if@1.0.4", "cipher@0.4.4", "cpufeatures@0.2.17"]}, +{"package": "chacha20poly1305@0.10.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "getrandom", "rand_core"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["aead@0.5.2", "chacha20@0.9.1", "cipher@0.4.4", "poly1305@0.8.0", "zeroize@1.8.2"]}, +{"package": "chrono-tz@0.10.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["tokio-cron-scheduler@0.15.1"], "dependencies": ["chrono@0.4.45", "phf@0.12.1"]}, +{"package": "chrono@0.4.45", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "clock", "default", "iana-time-zone", "js-sys", "now", "oldtime", "serde", "std", "wasm-bindgen", "wasmbind", "winapi", "windows-link"], "parents": ["chrono-tz@0.10.4", "cron@0.17.0", "croner@3.0.1", "perry-ext-cron@0.5.1565", "perry-ext-dayjs@0.5.1565", "perry-ext-moment@0.5.1565", "perry-ext-mysql2@0.5.1565", "perry-stdlib@0.5.1565", "perry@0.5.1565", "sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "tokio-cron-scheduler@0.15.1"], "dependencies": ["iana-time-zone@0.1.65", "js-sys@0.3.99", "num-traits@0.2.19", "serde@1.0.229", "wasm-bindgen@0.2.122", "windows-link@0.2.1"]}, +{"package": "chunked_transfer@1.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tiny_http@0.12.0"], "dependencies": []}, +{"package": "cipher@0.4.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "block-padding", "zeroize"], "parents": ["aes-gcm@0.10.3", "aes@0.8.4", "cbc@0.1.2", "chacha20@0.9.1", "chacha20poly1305@0.10.1", "ctr@0.9.2", "des@0.8.1", "ecb@0.1.2", "p12@0.6.3", "rc2@0.8.1", "salsa20@0.10.2"], "dependencies": ["crypto-common@0.1.7", "inout@0.1.4", "zeroize@1.8.2"]}, +{"package": "cipher@0.5.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["block-padding"], "parents": ["aes@0.9.1", "blowfish@0.10.0", "cbc@0.2.1", "ecb@0.2.1"], "dependencies": ["crypto-common@0.2.2", "inout@0.2.2"]}, +{"package": "clang-sys@1.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["clang_10_0", "clang_11_0", "clang_3_5", "clang_3_6", "clang_3_7", "clang_3_8", "clang_3_9", "clang_4_0", "clang_5_0", "clang_6_0", "clang_7_0", "clang_8_0", "clang_9_0", "libloading", "runtime"], "parents": ["bindgen@0.72.1"], "dependencies": ["glob@0.3.3", "libc@0.2.189", "libloading@0.8.9"]}, +{"package": "clap@4.6.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["color", "default", "derive", "error-context", "help", "std", "suggestions", "usage"], "parents": ["perry-container-compose@0.5.1565", "perry-doc-tests@0.5.1565", "perry-stdlib@0.5.1565", "perry@0.5.1565"], "dependencies": ["clap_builder@4.6.6", "clap_derive@4.6.4"]}, +{"package": "clap_builder@4.6.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["color", "error-context", "help", "std", "suggestions", "usage"], "parents": ["clap@4.6.6"], "dependencies": ["anstream@1.0.0", "anstyle@1.0.14", "clap_lex@1.1.0", "strsim@0.11.1"]}, +{"package": "clap_derive@4.6.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["clap@4.6.6"], "dependencies": ["heck@0.5.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@3.0.3"]}, +{"package": "clap_lex@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["clap_builder@4.6.6"], "dependencies": []}, +{"package": "cmake@0.1.58", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["aws-lc-sys@0.41.0"], "dependencies": ["cc@1.4.4"]}, +{"package": "cmov@0.5.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ctutils@0.4.2"], "dependencies": []}, +{"package": "color_quant@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gif@0.14.2", "image@0.25.10"], "dependencies": []}, +{"package": "colorchoice@1.0.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["anstream@1.0.0"], "dependencies": []}, +{"package": "combine@4.6.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "bytes", "default", "futures-core-03", "pin-project-lite", "std", "tokio", "tokio-dep", "tokio-util"], "parents": ["jni@0.22.4", "redis@1.6.0", "timezone_provider@0.2.6", "tzif@0.4.1"], "dependencies": ["bytes@1.12.1", "futures-core@0.3.34", "memchr@2.8.1", "pin-project-lite@0.2.17", "tokio-util@0.7.18", "tokio@1.53.1"]}, +{"package": "compact_str@0.7.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_codegen@21.0.0"], "dependencies": ["castaway@0.2.4", "cfg-if@1.0.4", "itoa@1.0.18", "ryu@1.0.23", "static_assertions@1.1.0"]}, +{"package": "concurrent-queue@2.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["async-channel@2.5.0", "async-executor@1.14.0", "async-io@2.6.0", "event-listener@5.4.1", "polling@3.11.0"], "dependencies": ["crossbeam-utils@0.8.21"]}, +{"package": "console@0.15.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["ansi-parsing", "default", "unicode-width"], "parents": ["dialoguer@0.11.0"], "dependencies": ["encode_unicode@1.0.0", "libc@0.2.189", "once_cell@1.21.4", "unicode-width@0.2.2", "windows-sys@0.59.0"]}, +{"package": "console@0.16.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "ansi-parsing", "default", "std", "unicode-width"], "parents": ["dialoguer@0.12.0", "indicatif@0.18.6", "perry-container-compose@0.5.1565", "perry@0.5.1565"], "dependencies": ["encode_unicode@1.0.0", "libc@0.2.189", "unicode-width@0.2.2", "windows-sys@0.61.2"]}, +{"package": "const-oid@0.10.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["db"], "parents": ["aes-kw@0.3.1", "der@0.8.1", "digest@0.11.3", "ml-kem@0.3.2", "perry-ext-node-forge@0.5.1565", "rsa@0.10.0-rc.18", "x509-cert@0.3.0"], "dependencies": []}, +{"package": "const-oid@0.9.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["der@0.7.10", "digest@0.10.7", "rsa@0.9.10"], "dependencies": []}, +{"package": "const-random-macro@0.1.16", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["const-random@0.1.18"], "dependencies": ["getrandom@0.2.17", "once_cell@1.21.4", "tiny-keccak@2.0.2"]}, +{"package": "const-random@0.1.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["macro_magic_core@0.5.1"], "dependencies": ["const-random-macro@0.1.16"]}, +{"package": "constant_time_eq@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["zip@8.6.0"], "dependencies": []}, +{"package": "convert_case@0.10.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["derive_more-impl@2.1.1"], "dependencies": ["unicode-segmentation@1.13.3"]}, +{"package": "core-foundation-sys@0.8.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "link"], "parents": ["core-foundation@0.10.1", "core-foundation@0.9.4", "iana-time-zone@0.1.65", "security-framework-sys@2.17.0", "security-framework@3.7.0", "system-configuration-sys@0.6.0"], "dependencies": []}, +{"package": "core-foundation@0.10.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "link"], "parents": ["security-framework@3.7.0"], "dependencies": ["core-foundation-sys@0.8.7", "libc@0.2.189"]}, +{"package": "core-foundation@0.9.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "link"], "parents": ["system-configuration@0.7.0"], "dependencies": ["core-foundation-sys@0.8.7", "libc@0.2.189"]}, +{"package": "core_maths@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["calendrical_calculations@0.2.4", "temporal_rs@0.2.6"], "dependencies": ["libm@0.2.16"]}, +{"package": "cpubits@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["aes@0.9.1", "crypto-bigint@0.7.5", "polyval@0.7.3"], "dependencies": []}, +{"package": "cpufeatures@0.2.17", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["aes@0.8.4", "argon2@0.5.3", "chacha20@0.9.1", "curve25519-dalek@4.1.3", "keccak@0.1.6", "poly1305@0.8.0", "polyval@0.6.2", "sha1@0.10.6", "sha2@0.10.9"], "dependencies": ["libc@0.2.189"]}, +{"package": "cpufeatures@0.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["aes@0.9.1", "chacha20@0.10.0", "keccak@0.2.0", "polyval@0.7.3", "sha1@0.11.0", "sha2@0.11.0"], "dependencies": ["libc@0.2.189"]}, +{"package": "crc-catalog@1.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["crc@2.1.0"], "dependencies": []}, +{"package": "crc-catalog@2.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["crc@3.4.0"], "dependencies": []}, +{"package": "crc32fast@1.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["flate2@1.1.10", "png@0.18.1", "zip@8.6.0", "zopfli@0.8.3"], "dependencies": ["cfg-if@1.0.4"]}, +{"package": "crc@2.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_bundler@37.0.0"], "dependencies": ["crc-catalog@1.1.1"]}, +{"package": "crc@3.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0"], "dependencies": ["crc-catalog@2.5.0"]}, +{"package": "critical-section@1.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["once_cell@1.21.4"], "dependencies": []}, +{"package": "cron@0.17.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ext-cron@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["chrono@0.4.45", "once_cell@1.21.4", "phf@0.11.3", "winnow@0.7.15"]}, +{"package": "croner@3.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tokio-cron-scheduler@0.15.1"], "dependencies": ["chrono@0.4.45", "derive_builder@0.20.2", "strum@0.27.2"]}, +{"package": "crossbeam-channel@0.5.15", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["moka@0.12.15", "notify@6.1.1"], "dependencies": ["crossbeam-utils@0.8.21"]}, +{"package": "crossbeam-deque@0.8.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["rayon-core@1.13.0"], "dependencies": ["crossbeam-epoch@0.9.20", "crossbeam-utils@0.8.21"]}, +{"package": "crossbeam-epoch@0.9.20", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["crossbeam-deque@0.8.6", "moka@0.12.15"], "dependencies": ["crossbeam-utils@0.8.21"]}, +{"package": "crossbeam-queue@0.3.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["sqlx-core@0.9.0"], "dependencies": ["crossbeam-utils@0.8.21"]}, +{"package": "crossbeam-utils@0.8.21", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["concurrent-queue@2.5.0", "crossbeam-channel@0.5.15", "crossbeam-deque@0.8.6", "crossbeam-epoch@0.9.20", "crossbeam-queue@0.3.12", "dashmap@6.2.1", "moka@0.12.15", "quanta@0.12.6", "rayon-core@1.13.0"], "dependencies": []}, +{"package": "crunchy@0.2.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "limit_128"], "parents": ["half@2.7.1", "tiny-keccak@2.0.2"], "dependencies": []}, +{"package": "crypto-bigint@0.5.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["generic-array", "rand_core", "zeroize"], "parents": ["elliptic-curve@0.13.8"], "dependencies": ["generic-array@0.14.7", "rand_core@0.6.4", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "crypto-bigint@0.7.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "getrandom", "hybrid-array", "rand_core", "subtle", "zeroize"], "parents": ["crypto-primes@0.7.2", "elliptic-curve@0.14.0", "rsa@0.10.0-rc.18"], "dependencies": ["cpubits@0.1.1", "ctutils@0.4.2", "getrandom@0.4.2", "hybrid-array@0.4.12", "num-traits@0.2.19", "rand_core@0.10.1", "serdect@0.4.3", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "crypto-common@0.1.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["getrandom", "rand_core", "std"], "parents": ["aead@0.5.2", "cipher@0.4.4", "digest@0.10.7", "universal-hash@0.5.1"], "dependencies": ["generic-array@0.14.7", "rand_core@0.6.4", "typenum@1.20.1"]}, +{"package": "crypto-common@0.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["getrandom", "rand_core"], "parents": ["cipher@0.5.2", "digest@0.11.3", "elliptic-curve@0.14.0", "kem@0.3.0", "universal-hash@0.6.1"], "dependencies": ["getrandom@0.4.2", "hybrid-array@0.4.12", "rand_core@0.10.1"]}, +{"package": "crypto-primes@0.7.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rsa@0.10.0-rc.18"], "dependencies": ["crypto-bigint@0.7.5", "rand_core@0.10.1"]}, +{"package": "cssparser-macros@0.7.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["cssparser@0.37.0"], "dependencies": ["quote@1.0.45", "syn@2.0.117"]}, +{"package": "cssparser@0.37.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "fast_match_byte", "fast_match_color"], "parents": ["scraper@0.27.0", "selectors@0.38.0"], "dependencies": ["cssparser-macros@0.7.0", "dtoa-short@0.3.5", "itoa@1.0.18", "phf@0.13.1", "smallvec@1.15.1"]}, +{"package": "ctr@0.9.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["aes-gcm@0.10.3", "perry-stdlib@0.5.1565"], "dependencies": ["cipher@0.4.4"]}, +{"package": "ctutils@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["subtle"], "parents": ["crypto-bigint@0.7.5", "digest@0.11.3", "hybrid-array@0.4.12", "module-lattice@0.2.3", "sec1@0.8.1", "universal-hash@0.6.1"], "dependencies": ["cmov@0.5.4", "subtle@2.6.1"]}, +{"package": "cty@0.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["libmimalloc-sys@0.1.49"], "dependencies": []}, +{"package": "curve25519-dalek-derive@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["curve25519-dalek@4.1.3"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "curve25519-dalek@4.1.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "digest", "precomputed-tables", "zeroize"], "parents": ["ed25519-dalek@2.2.0", "x25519-dalek@2.0.1"], "dependencies": ["cfg-if@1.0.4", "cpufeatures@0.2.17", "curve25519-dalek-derive@0.1.1", "digest@0.10.7", "fiat-crypto@0.2.9", "rustc_version@0.4.1", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "darling@0.20.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "suggestions"], "parents": ["derive_builder_core@0.20.2"], "dependencies": ["darling_core@0.20.11", "darling_macro@0.20.11"]}, +{"package": "darling@0.23.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "suggestions"], "parents": ["serde_with_macros@3.21.0"], "dependencies": ["darling_core@0.23.0", "darling_macro@0.23.0"]}, +{"package": "darling_core@0.20.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["strsim", "suggestions"], "parents": ["darling@0.20.11", "darling_macro@0.20.11"], "dependencies": ["fnv@1.0.7", "ident_case@1.0.1", "proc-macro2@1.0.106", "quote@1.0.45", "strsim@0.11.1", "syn@2.0.117"]}, +{"package": "darling_core@0.23.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["strsim", "suggestions"], "parents": ["darling@0.23.0", "darling_macro@0.23.0"], "dependencies": ["ident_case@1.0.1", "proc-macro2@1.0.106", "quote@1.0.45", "strsim@0.11.1", "syn@2.0.117"]}, +{"package": "darling_macro@0.20.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["darling@0.20.11"], "dependencies": ["darling_core@0.20.11", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "darling_macro@0.23.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["darling@0.23.0"], "dependencies": ["darling_core@0.23.0", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "dashmap@5.5.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["swc_ecma_transforms_optimization@34.0.0"], "dependencies": ["cfg-if@1.0.4", "hashbrown@0.14.5", "lock_api@0.4.14", "once_cell@1.21.4", "parking_lot_core@0.9.12"]}, +{"package": "dashmap@6.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["governor@0.10.4", "perry-container-compose@0.5.1565", "perry-ffi@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["cfg-if@1.0.4", "crossbeam-utils@0.8.21", "hashbrown@0.14.5", "lock_api@0.4.14", "once_cell@1.21.4", "parking_lot_core@0.9.12"]}, +{"package": "data-encoding@2.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["hickory-net@0.26.1", "hickory-proto@0.26.1", "swc_sourcemap@9.3.4", "tungstenite@0.24.0", "tungstenite@0.29.0"], "dependencies": []}, +{"package": "debugid@0.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["serde"], "parents": ["swc_sourcemap@9.3.4"], "dependencies": ["serde@1.0.229", "uuid@1.26.0"]}, +{"package": "deflate64@0.1.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["zip@8.6.0"], "dependencies": []}, +{"package": "der@0.7.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "oid", "pem", "std", "zeroize"], "parents": ["ecdsa@0.16.9", "pkcs1@0.7.5", "pkcs5@0.7.1", "pkcs8@0.10.2", "sec1@0.7.3", "spki@0.7.3"], "dependencies": ["const-oid@0.9.6", "pem-rfc7468@0.7.0", "zeroize@1.8.2"]}, +{"package": "der@0.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "derive", "flagset", "oid", "pem", "std", "zeroize"], "parents": ["perry-ext-node-forge@0.5.1565", "pkcs1@0.8.0-rc.4", "pkcs8@0.11.0", "sec1@0.8.1", "spki@0.8.0", "x509-cert@0.3.0"], "dependencies": ["const-oid@0.10.2", "der_derive@0.8.0", "flagset@0.4.7", "pem-rfc7468@1.0.0", "zeroize@1.8.2"]}, +{"package": "der_derive@0.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["der@0.8.1"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "deranged@0.5.8", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "serde"], "parents": ["time@0.3.55"], "dependencies": ["serde_core@1.0.229"]}, +{"package": "derive-syn-parse@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["macro_magic_core@0.5.1"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "derive-where@1.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["mongodb@3.8.2"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "derive_builder@0.20.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["croner@3.0.1"], "dependencies": ["derive_builder_macro@0.20.2"]}, +{"package": "derive_builder_core@0.20.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["lib_has_std"], "parents": ["derive_builder_macro@0.20.2"], "dependencies": ["darling@0.20.11", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "derive_builder_macro@0.20.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["lib_has_std"], "parents": ["derive_builder@0.20.2"], "dependencies": ["derive_builder_core@0.20.2", "syn@2.0.117"]}, +{"package": "derive_more-impl@2.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["add", "add_assign", "default", "display", "from"], "parents": ["derive_more@2.1.1"], "dependencies": ["convert_case@0.10.0", "proc-macro2@1.0.106", "quote@1.0.45", "rustc_version@0.4.1", "syn@2.0.117", "unicode-xid@0.2.6"]}, +{"package": "derive_more@2.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["add", "add_assign", "default", "display", "from", "std"], "parents": ["mongodb@3.8.2", "selectors@0.38.0"], "dependencies": ["derive_more-impl@2.1.1"]}, +{"package": "des@0.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["p12@0.6.3"], "dependencies": ["cipher@0.4.4"]}, +{"package": "dialoguer@0.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "editor", "password", "tempfile", "zeroize"], "parents": ["perry-container-compose@0.5.1565"], "dependencies": ["console@0.15.11", "shell-words@1.1.1", "tempfile@3.27.0", "thiserror@1.0.69", "zeroize@1.8.2"]}, +{"package": "dialoguer@0.12.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "editor", "password", "tempfile", "zeroize"], "parents": ["perry@0.5.1565"], "dependencies": ["console@0.16.4", "shell-words@1.1.1", "tempfile@3.27.0", "zeroize@1.8.2"]}, +{"package": "digest@0.10.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "block-buffer", "const-oid", "core-api", "default", "mac", "oid", "std", "subtle"], "parents": ["blake2@0.10.6", "curve25519-dalek@4.1.3", "ecdsa@0.16.9", "elliptic-curve@0.13.8", "hmac@0.12.1", "md-5@0.10.6", "pbkdf2@0.12.2", "rsa@0.9.10", "sha1@0.10.6", "sha2@0.10.9", "sha3@0.10.9", "signature@2.2.0"], "dependencies": ["block-buffer@0.10.4", "const-oid@0.9.6", "crypto-common@0.1.7", "subtle@2.6.1"]}, +{"package": "digest@0.11.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "block-api", "default", "mac", "oid", "zeroize"], "parents": ["hash2curve@0.14.0", "hmac@0.13.0", "md-5@0.11.0", "pbkdf2@0.13.0", "rsa@0.10.0-rc.18", "sha1@0.11.0", "sha2@0.11.0", "sha3@0.11.0", "sha3@0.12.0", "shake@0.1.0", "signature@3.0.0", "sqlx-mysql@0.9.0"], "dependencies": ["block-buffer@0.12.0", "const-oid@0.10.2", "crypto-common@0.2.2", "ctutils@0.4.2", "zeroize@1.8.2"]}, +{"package": "dirs-sys@0.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["dirs@6.0.0"], "dependencies": ["libc@0.2.189", "option-ext@0.2.0", "redox_users@0.5.2", "windows-sys@0.61.2"]}, +{"package": "dirs@6.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-runtime@0.5.1565", "perry-ui-gtk4@0.5.1565", "perry-ui@0.5.1565", "perry@0.5.1565"], "dependencies": ["dirs-sys@0.5.0"]}, +{"package": "dispatch2@0.3.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "objc2"], "parents": ["objc2-core-foundation@0.3.2", "objc2-core-graphics@0.3.2"], "dependencies": ["bitflags@2.12.1", "objc2@0.6.4"]}, +{"package": "displaydoc@0.2.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["calendrical_calculations@0.2.4", "fixed_decimal@0.7.2", "icu_calendar@2.3.0", "icu_collections@2.2.0", "icu_datetime@2.3.0", "icu_decimal@2.3.0", "icu_locale_core@2.3.0", "icu_pattern@0.5.0", "icu_provider@2.3.1", "icu_time@2.3.0", "tinystr@0.8.4", "zerotrie@0.2.5"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "document-features@0.2.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["fast_image_resize@6.1.0"], "dependencies": ["litrs@1.0.0"]}, +{"package": "dotenvy@0.15.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-container-compose@0.5.1565", "perry@0.5.1565", "sqlx-macros-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0"], "dependencies": []}, +{"package": "dssim-core@3.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "threads"], "parents": ["perry-doc-tests@0.5.1565"], "dependencies": ["imgref@1.12.3", "itertools@0.15.0", "rayon@1.12.0", "rgb@0.8.53"]}, +{"package": "dtoa-short@0.3.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["cssparser@0.37.0"], "dependencies": ["dtoa@1.0.11"]}, +{"package": "dtoa@1.0.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["dtoa-short@0.3.5"], "dependencies": []}, +{"package": "dunce@1.0.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["aws-lc-sys@0.41.0"], "dependencies": []}, +{"package": "ecb@0.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["block-padding", "default"], "parents": ["lopdf@0.39.0"], "dependencies": ["cipher@0.4.4"]}, +{"package": "ecb@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["block-padding", "default"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["cipher@0.5.2"]}, +{"package": "ecdsa@0.16.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "arithmetic", "der", "digest", "hazmat", "pem", "pkcs8", "rfc6979", "signing", "spki", "std", "verifying"], "parents": ["p256@0.13.2", "p384@0.13.1", "p521@0.13.3"], "dependencies": ["der@0.7.10", "digest@0.10.7", "elliptic-curve@0.13.8", "rfc6979@0.4.0", "signature@2.2.0", "spki@0.7.3"]}, +{"package": "ed25519-dalek@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "fast", "pkcs8", "rand_core", "std", "zeroize"], "parents": ["jsonwebtoken@11.0.0", "perry-stdlib@0.5.1565", "perry-updater@0.5.1565", "perry@0.5.1565"], "dependencies": ["curve25519-dalek@4.1.3", "ed25519@2.2.3", "rand_core@0.6.4", "serde@1.0.229", "sha2@0.10.9", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "ed25519@2.2.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "pkcs8", "std"], "parents": ["ed25519-dalek@2.2.0"], "dependencies": ["pkcs8@0.10.2", "signature@2.2.0"]}, +{"package": "ed448-goldilocks@0.14.0-pre.15", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "getrandom", "signing"], "parents": ["perry-stdlib@0.5.1565", "x448@0.14.0-pre.12"], "dependencies": ["ed448@0.5.0", "elliptic-curve@0.14.0", "hash2curve@0.14.0", "rand_core@0.10.1", "serdect@0.4.3", "shake@0.1.0", "signature@3.0.0", "subtle@2.6.1"]}, +{"package": "ed448@0.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["ed448-goldilocks@0.14.0-pre.15"], "dependencies": ["pkcs8@0.11.0", "signature@3.0.0"]}, +{"package": "ego-tree@0.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["scraper@0.27.0"], "dependencies": []}, +{"package": "either@1.16.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "serde", "std", "use_std"], "parents": ["icu_pattern@0.5.0", "itertools@0.12.1", "itertools@0.14.0", "itertools@0.15.0", "prefix-trie@0.8.4", "rayon@1.12.0", "sqlx-core@0.9.0", "sqlx-macros-core@0.9.0", "sqlx-mysql@0.9.0", "swc_common@18.0.1", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "swc_visit@2.0.1", "writeable@0.6.4"], "dependencies": ["serde@1.0.229"]}, +{"package": "elliptic-curve@0.13.8", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "arithmetic", "digest", "ecdh", "ff", "group", "hazmat", "pem", "pkcs8", "sec1", "std"], "parents": ["ecdsa@0.16.9", "p256@0.13.2", "p384@0.13.1", "p521@0.13.3", "primeorder@0.13.6"], "dependencies": ["base16ct@0.2.0", "crypto-bigint@0.5.5", "digest@0.10.7", "ff@0.13.1", "generic-array@0.14.7", "group@0.13.0", "hkdf@0.12.4", "pem-rfc7468@0.7.0", "pkcs8@0.10.2", "rand_core@0.6.4", "sec1@0.7.3", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "elliptic-curve@0.14.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "arithmetic", "default", "ff", "getrandom", "group", "pkcs8", "sec1"], "parents": ["ed448-goldilocks@0.14.0-pre.15", "hash2curve@0.14.0"], "dependencies": ["base16ct@1.0.0", "crypto-bigint@0.7.5", "crypto-common@0.2.2", "ff@0.14.0", "group@0.14.0", "hybrid-array@0.4.12", "pkcs8@0.11.0", "rand_core@0.10.1", "sec1@0.8.1", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "email-encoding@0.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["lettre@0.11.23"], "dependencies": ["base64@0.22.1", "memchr@2.8.1"]}, +{"package": "email_address@0.2.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["lettre@0.11.23"], "dependencies": []}, +{"package": "encode_unicode@1.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["console@0.15.11", "console@0.16.4"], "dependencies": []}, +{"package": "encoding_rs@0.8.35", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default"], "parents": ["allsorts-azul@0.16.5", "lopdf@0.39.0", "perry-runtime@0.5.1565"], "dependencies": ["cfg-if@1.0.4"]}, +{"package": "endi@1.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["zvariant@5.12.0"], "dependencies": []}, +{"package": "enumflags2@0.7.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["serde"], "parents": ["zbus@5.16.0", "zvariant@5.12.0"], "dependencies": ["enumflags2_derive@0.7.12", "serde@1.0.229"]}, +{"package": "enumflags2_derive@0.7.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["enumflags2@0.7.12"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "env_logger@0.10.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["auto-color", "color", "default", "humantime", "regex"], "parents": ["perry@0.5.1565"], "dependencies": ["humantime@2.3.0", "is-terminal@0.4.17", "log@0.4.34", "regex@1.13.1", "termcolor@1.4.1"]}, +{"package": "equator-macro@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["equator@0.4.2"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "equator@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["aligned-vec@0.6.4"], "dependencies": ["equator-macro@0.4.2"]}, +{"package": "equivalent@1.0.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["hashbrown@0.16.1", "hashbrown@0.17.1", "indexmap@2.14.1", "moka@0.12.15"], "dependencies": []}, +{"package": "errno@0.3.14", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["rustix@1.1.4", "signal-hook-registry@1.4.8"], "dependencies": ["libc@0.2.189", "windows-sys@0.61.2"]}, +{"package": "etcetera@0.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["sqlx-postgres@0.9.0"], "dependencies": ["cfg-if@1.0.4", "windows-sys@0.61.2"]}, +{"package": "event-listener-strategy@0.5.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["async-broadcast@0.7.2", "async-channel@2.5.0", "async-lock@3.4.2"], "dependencies": ["event-listener@5.4.1", "pin-project-lite@0.2.17"]}, +{"package": "event-listener@5.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "parking", "std"], "parents": ["async-broadcast@0.7.2", "async-lock@3.4.2", "async-process@2.5.0", "event-listener-strategy@0.5.4", "sqlx-core@0.9.0", "zbus@5.16.0"], "dependencies": ["concurrent-queue@2.5.0", "parking@2.2.1", "pin-project-lite@0.2.17"]}, +{"package": "exr@1.74.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["rayon"], "parents": ["image@0.25.10"], "dependencies": ["bit_field@0.10.3", "half@2.7.1", "lebe@0.5.3", "miniz_oxide@0.8.9", "rayon-core@1.13.0", "smallvec@1.15.1", "zune-inflate@0.2.54"]}, +{"package": "fallible-iterator@0.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default"], "parents": ["rusqlite@0.39.0"], "dependencies": []}, +{"package": "fallible-streaming-iterator@0.1.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rusqlite@0.39.0"], "dependencies": []}, +{"package": "fast_image_resize@6.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["perry-ext-sharp@0.5.1565"], "dependencies": ["cfg-if@1.0.4", "document-features@0.2.12", "num-traits@0.2.19", "thiserror@2.0.18"]}, +{"package": "fastrand@2.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["async-executor@1.14.0", "backon@1.6.0", "futures-lite@2.6.1", "lettre@0.11.23", "phf_generator@0.13.1", "piper@0.2.5", "tempfile@3.27.0"], "dependencies": []}, +{"package": "fax@0.2.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tiff@0.11.3"], "dependencies": []}, +{"package": "fdeflate@0.3.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["png@0.18.1"], "dependencies": ["simd-adler32@0.3.9"]}, +{"package": "ff@0.13.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["elliptic-curve@0.13.8", "group@0.13.0"], "dependencies": ["rand_core@0.6.4", "subtle@2.6.1"]}, +{"package": "ff@0.14.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["elliptic-curve@0.14.0", "group@0.14.0"], "dependencies": ["rand_core@0.10.1", "subtle@2.6.1"]}, +{"package": "fiat-crypto@0.2.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["curve25519-dalek@4.1.3"], "dependencies": []}, +{"package": "field-offset@0.3.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gtk4@0.9.7"], "dependencies": ["memoffset@0.9.1", "rustc_version@0.4.1"]}, +{"package": "filetime@0.2.29", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["notify@6.1.1", "tar@0.4.46"], "dependencies": ["cfg-if@1.0.4", "libc@0.2.189"]}, +{"package": "find-msvc-tools@0.1.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["cc@1.4.4"], "dependencies": []}, +{"package": "fixed_decimal@0.7.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_datetime@2.3.0", "icu_decimal@2.3.0", "icu_plurals@2.3.0"], "dependencies": ["displaydoc@0.2.6", "smallvec@1.15.1", "writeable@0.6.4"]}, +{"package": "fixedbitset@0.5.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["petgraph@0.7.1"], "dependencies": []}, +{"package": "flagset@0.4.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["der@0.8.1"], "dependencies": []}, +{"package": "flate2@1.1.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["any_impl", "any_zlib", "default", "miniz_oxide", "runtime_detection", "rust_backend", "zlib-rs"], "parents": ["allsorts-azul@0.16.5", "lopdf@0.39.0", "perry-ext-zlib@0.5.1565", "perry-stdlib@0.5.1565", "perry@0.5.1565", "png@0.18.1", "printpdf@0.10.1", "tiff@0.11.3", "zip@8.6.0"], "dependencies": ["crc32fast@1.5.0", "miniz_oxide@0.9.1", "zlib-rs@0.6.4"]}, +{"package": "flume@0.12.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["async", "futures-core", "futures-sink"], "parents": ["sqlx-sqlite@0.9.0"], "dependencies": ["futures-core@0.3.34", "futures-sink@0.3.34", "spin@0.9.8"]}, +{"package": "fnv@1.0.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["darling_core@0.20.11", "h2@0.4.19", "rusty-fork@0.3.1"], "dependencies": []}, +{"package": "foldhash@0.1.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["hashbrown@0.15.5"], "dependencies": []}, +{"package": "foldhash@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["hashbrown@0.16.1", "hashbrown@0.17.1"], "dependencies": []}, +{"package": "form_urlencoded@1.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["serde_urlencoded@0.7.1", "sqlx-sqlite@0.9.0", "url@2.5.8"], "dependencies": ["percent-encoding@2.3.2"]}, +{"package": "from_variant@3.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_common@18.0.1"], "dependencies": ["swc_macros_common@1.0.1", "syn@2.0.117"]}, +{"package": "fs_extra@1.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["aws-lc-sys@0.41.0"], "dependencies": []}, +{"package": "fsevent-sys@4.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["notify@6.1.1"], "dependencies": ["libc@0.2.189"]}, +{"package": "fslock@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["perry@0.5.1565"], "dependencies": ["libc@0.2.189", "winapi@0.3.9"]}, +{"package": "funty@2.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["bitvec@1.0.1"], "dependencies": []}, +{"package": "futures-channel@0.3.32", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "futures-sink", "sink", "std"], "parents": ["gio@0.20.12", "glib@0.20.12", "glib@0.22.7", "gstreamer@0.25.3", "gtk4@0.9.7", "hickory-net@0.26.1", "hyper-util@0.1.20", "hyper@1.11.1", "mpris-server@0.10.0", "redis@1.6.0", "reqwest@0.12.28", "soup3@0.7.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0"], "dependencies": ["futures-core@0.3.34", "futures-sink@0.3.34"]}, +{"package": "futures-core@0.3.34", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["async-broadcast@0.7.2", "async-channel@2.5.0", "async-signal@0.2.14", "combine@4.6.7", "flume@0.12.0", "futures-channel@0.3.32", "futures-executor@0.3.32", "futures-intrusive@0.5.0", "futures-lite@2.6.1", "futures-util@0.3.34", "gio@0.20.12", "glib@0.20.12", "glib@0.22.7", "gstreamer-app@0.25.2", "gstreamer@0.25.3", "h2@0.4.19", "http-body-util@0.1.5", "hyper@1.11.1", "mongodb@3.8.2", "ordered-stream@0.2.0", "reqwest@0.12.28", "sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "sync_wrapper@1.0.2", "tokio-stream@0.1.18", "tokio-util@0.7.18", "tower@0.5.3", "zbus@5.16.0"], "dependencies": []}, +{"package": "futures-executor@0.3.32", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["glib@0.20.12", "glib@0.22.7", "sqlx-sqlite@0.9.0"], "dependencies": ["futures-core@0.3.34", "futures-task@0.3.34", "futures-util@0.3.34"]}, +{"package": "futures-intrusive@0.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "parking_lot", "std"], "parents": ["sqlx-core@0.9.0", "sqlx-sqlite@0.9.0"], "dependencies": ["futures-core@0.3.34", "lock_api@0.4.14", "parking_lot@0.12.5"]}, +{"package": "futures-io@0.3.34", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["async-io@2.6.0", "async-signal@0.2.14", "blocking@1.6.2", "futures-lite@2.6.1", "futures-util@0.3.34", "gio@0.20.12", "hickory-net@0.26.1", "lettre@0.11.23", "mongodb@3.8.2", "piper@0.2.5", "sqlx-core@0.9.0", "tokio-util@0.7.18"], "dependencies": []}, +{"package": "futures-lite@2.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "fastrand", "futures-io", "parking", "race", "std"], "parents": ["async-executor@1.14.0", "async-io@2.6.0", "async-process@2.5.0", "blocking@1.6.2", "zbus@5.16.0"], "dependencies": ["fastrand@2.4.1", "futures-core@0.3.34", "futures-io@0.3.34", "parking@2.2.1", "pin-project-lite@0.2.17"]}, +{"package": "futures-macro@0.3.34", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["futures-util@0.3.34"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@3.0.3"]}, +{"package": "futures-sink@0.3.34", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["flume@0.12.0", "futures-channel@0.3.32", "futures-util@0.3.34", "governor@0.10.4", "gstreamer-app@0.25.2", "h2@0.4.19", "tokio-util@0.7.18"], "dependencies": []}, +{"package": "futures-task@0.3.34", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "std"], "parents": ["futures-executor@0.3.32", "futures-util@0.3.34", "glib@0.20.12", "glib@0.22.7"], "dependencies": []}, +{"package": "futures-timer@3.0.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["governor@0.10.4"], "dependencies": []}, +{"package": "futures-util@0.3.34", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "async-await", "async-await-macro", "default", "futures-io", "futures-macro", "futures-sink", "io", "memchr", "sink", "slab", "std"], "parents": ["futures-executor@0.3.32", "gio@0.20.12", "glib@0.20.12", "glib@0.22.7", "governor@0.10.4", "gstreamer@0.25.3", "hickory-net@0.26.1", "hickory-resolver@0.26.1", "hyper-util@0.1.20", "js-sys@0.3.99", "ksni@0.3.6", "lettre@0.11.23", "mongodb@3.8.2", "perry-ext-mongodb@0.5.1565", "perry-ext-ws@0.5.1565", "perry-stdlib@0.5.1565", "perry@0.5.1565", "redis@1.6.0", "reqwest@0.12.28", "sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "tokio-tungstenite@0.29.0", "tokio-util@0.7.18", "tower-http@0.6.11", "tower@0.5.3"], "dependencies": ["futures-core@0.3.34", "futures-io@0.3.34", "futures-macro@0.3.34", "futures-sink@0.3.34", "futures-task@0.3.34", "memchr@2.8.1", "pin-project-lite@0.2.17", "slab@0.4.12"]}, +{"package": "gdk-pixbuf-sys@0.20.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gdk-pixbuf@0.20.10", "gdk4-sys@0.9.6", "gtk4-sys@0.9.6", "libshumate-sys@0.6.0"], "dependencies": ["gio-sys@0.20.10", "glib-sys@0.20.10", "gobject-sys@0.20.10", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "gdk-pixbuf@0.20.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gdk4@0.9.6", "gtk4@0.9.7", "libshumate@0.6.0"], "dependencies": ["gdk-pixbuf-sys@0.20.10", "gio@0.20.12", "glib@0.20.12", "libc@0.2.189"]}, +{"package": "gdk4-sys@0.9.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v4_2", "v4_4", "v4_6"], "parents": ["gdk4@0.9.6", "gsk4-sys@0.9.6", "gtk4-sys@0.9.6", "libshumate-sys@0.6.0", "webkit6-sys@0.4.0"], "dependencies": ["cairo-sys-rs@0.20.10", "gdk-pixbuf-sys@0.20.10", "gio-sys@0.20.10", "glib-sys@0.20.10", "gobject-sys@0.20.10", "libc@0.2.189", "pango-sys@0.20.10", "pkg-config@0.3.33", "system-deps@7.0.8"]}, +{"package": "gdk4@0.9.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v4_2", "v4_4", "v4_6"], "parents": ["gsk4@0.9.6", "gtk4@0.9.7", "libshumate@0.6.0", "webkit6@0.4.0"], "dependencies": ["cairo-rs@0.20.12", "gdk-pixbuf@0.20.10", "gdk4-sys@0.9.6", "gio@0.20.12", "glib@0.20.12", "libc@0.2.189", "pango@0.20.12"]}, +{"package": "generic-array@0.14.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["more_lengths", "zeroize"], "parents": ["aead@0.5.2", "block-buffer@0.10.4", "block-padding@0.3.3", "crypto-bigint@0.5.5", "crypto-common@0.1.7", "elliptic-curve@0.13.8", "inout@0.1.4", "sec1@0.7.3", "sqlx-mysql@0.9.0"], "dependencies": ["typenum@1.20.1", "version_check@0.9.5", "zeroize@1.8.2"]}, +{"package": "getopts@0.2.24", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "unicode"], "parents": ["scraper@0.27.0"], "dependencies": ["unicode-width@0.2.2"]}, +{"package": "getrandom@0.2.17", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["js", "js-sys", "std", "wasm-bindgen"], "parents": ["const-random-macro@0.1.16", "jsonwebtoken@11.0.0", "p12@0.6.3", "rand_core@0.6.4", "redox_users@0.5.2", "ring@0.17.14"], "dependencies": ["cfg-if@1.0.4", "js-sys@0.3.99", "libc@0.2.189", "wasi@0.11.1+wasi-snapshot-preview1", "wasm-bindgen@0.2.122"]}, +{"package": "getrandom@0.3.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std", "wasm_js"], "parents": ["ahash@0.8.12", "bson@3.1.0", "governor@0.10.4", "jobserver@0.1.34", "lopdf@0.39.0", "printpdf@0.10.1", "quinn-proto@0.11.15", "rand_core@0.9.5"], "dependencies": ["cfg-if@1.0.4", "js-sys@0.3.99", "libc@0.2.189", "r-efi@5.3.0", "wasip2@1.0.3+wasi-0.2.9", "wasm-bindgen@0.2.122"]}, +{"package": "getrandom@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std", "sys_rng", "wasm_js"], "parents": ["bcrypt@0.19.3", "crypto-bigint@0.7.5", "crypto-common@0.2.2", "rand@0.10.2", "tempfile@3.27.0", "uuid@1.26.0", "zip@8.6.0"], "dependencies": ["cfg-if@1.0.4", "js-sys@0.3.99", "libc@0.2.189", "r-efi@6.0.0", "rand_core@0.10.1", "wasip2@1.0.3+wasi-0.2.9", "wasip3@0.4.0+wasi-0.3.0-rc-2026-01-06", "wasm-bindgen@0.2.122"]}, +{"package": "ghash@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["aes-gcm@0.10.3"], "dependencies": ["opaque-debug@0.3.1", "polyval@0.6.2"]}, +{"package": "ghash@0.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["polyval@0.7.3"]}, +{"package": "gif@0.14.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["color_quant", "default", "raii_no_panic", "std"], "parents": ["image@0.25.10"], "dependencies": ["color_quant@1.1.0", "weezl@0.1.12"]}, +{"package": "gimli@0.34.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["read", "read-core"], "parents": ["perry-runtime@0.5.1565"], "dependencies": []}, +{"package": "gio-sys@0.20.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v2_58", "v2_60", "v2_62", "v2_64", "v2_66", "v2_68", "v2_70"], "parents": ["gdk-pixbuf-sys@0.20.10", "gdk4-sys@0.9.6", "gio@0.20.12", "glib@0.20.12", "gtk4-sys@0.9.6", "libshumate-sys@0.6.0", "soup3-sys@0.7.0", "webkit6-sys@0.4.0"], "dependencies": ["glib-sys@0.20.10", "gobject-sys@0.20.10", "libc@0.2.189", "system-deps@7.0.8", "windows-sys@0.59.0"]}, +{"package": "gio-sys@0.22.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["glib@0.22.7"], "dependencies": ["glib-sys@0.22.6", "gobject-sys@0.22.6", "libc@0.2.189", "system-deps@7.0.8", "windows-sys@0.61.2"]}, +{"package": "gio@0.20.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v2_58", "v2_60", "v2_62", "v2_64", "v2_66", "v2_68", "v2_70"], "parents": ["gdk-pixbuf@0.20.10", "gdk4@0.9.6", "gtk4@0.9.7", "libshumate@0.6.0", "pango@0.20.12", "soup3@0.7.0", "webkit6@0.4.0"], "dependencies": ["futures-channel@0.3.32", "futures-core@0.3.34", "futures-io@0.3.34", "futures-util@0.3.34", "gio-sys@0.20.10", "glib@0.20.12", "libc@0.2.189", "pin-project-lite@0.2.17", "smallvec@1.15.1"]}, +{"package": "glib-macros@0.20.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["glib@0.20.12"], "dependencies": ["heck@0.5.0", "proc-macro-crate@3.5.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "glib-macros@0.22.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["glib@0.22.7"], "dependencies": ["heck@0.5.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "glib-sys@0.20.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v2_58", "v2_60", "v2_62", "v2_64", "v2_66", "v2_68", "v2_70"], "parents": ["cairo-sys-rs@0.20.10", "gdk-pixbuf-sys@0.20.10", "gdk4-sys@0.9.6", "gio-sys@0.20.10", "glib@0.20.12", "gobject-sys@0.20.10", "graphene-sys@0.20.10", "gsk4-sys@0.9.6", "gtk4-sys@0.9.6", "javascriptcore6-sys@0.4.0", "libshumate-sys@0.6.0", "pango-sys@0.20.10", "soup3-sys@0.7.0", "webkit6-sys@0.4.0"], "dependencies": ["libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "glib-sys@0.22.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["cairo-sys-rs@0.22.0", "gio-sys@0.22.0", "glib@0.22.7", "gobject-sys@0.22.6", "gstreamer-app-sys@0.25.0", "gstreamer-base-sys@0.25.0", "gstreamer-sys@0.25.2"], "dependencies": ["libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "glib@0.20.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "gio", "gio-sys", "v2_58", "v2_60", "v2_62", "v2_64", "v2_66", "v2_68", "v2_70"], "parents": ["cairo-rs@0.20.12", "gdk-pixbuf@0.20.10", "gdk4@0.9.6", "gio@0.20.12", "graphene-rs@0.20.10", "gsk4@0.9.6", "gtk4@0.9.7", "javascriptcore6@0.4.0", "libshumate@0.6.0", "pango@0.20.12", "soup3@0.7.0", "webkit6@0.4.0"], "dependencies": ["bitflags@2.12.1", "futures-channel@0.3.32", "futures-core@0.3.34", "futures-executor@0.3.32", "futures-task@0.3.34", "futures-util@0.3.34", "gio-sys@0.20.10", "glib-macros@0.20.12", "glib-sys@0.20.10", "gobject-sys@0.20.10", "libc@0.2.189", "memchr@2.8.1", "smallvec@1.15.1"]}, +{"package": "glib@0.22.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "futures", "futures-channel", "futures-core", "futures-executor", "futures-task", "futures-util", "gio", "gio-sys"], "parents": ["cairo-rs@0.22.9", "gstreamer-app@0.25.2", "gstreamer-base@0.25.2", "gstreamer@0.25.3"], "dependencies": ["bitflags@2.12.1", "futures-channel@0.3.32", "futures-core@0.3.34", "futures-executor@0.3.32", "futures-task@0.3.34", "futures-util@0.3.34", "gio-sys@0.22.0", "glib-macros@0.22.6", "glib-sys@0.22.6", "gobject-sys@0.22.6", "libc@0.2.189", "memchr@2.8.1", "smallvec@1.15.1"]}, +{"package": "glob@0.3.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["clang-sys@1.8.1"], "dependencies": []}, +{"package": "glyph-names@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["allsorts-azul@0.16.5"], "dependencies": []}, +{"package": "gobject-sys@0.20.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v2_58", "v2_62", "v2_66", "v2_68", "v2_70"], "parents": ["gdk-pixbuf-sys@0.20.10", "gdk4-sys@0.9.6", "gio-sys@0.20.10", "glib@0.20.12", "gsk4-sys@0.9.6", "gtk4-sys@0.9.6", "javascriptcore6-sys@0.4.0", "libshumate-sys@0.6.0", "pango-sys@0.20.10", "soup3-sys@0.7.0", "webkit6-sys@0.4.0"], "dependencies": ["glib-sys@0.20.10", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "gobject-sys@0.22.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gio-sys@0.22.0", "glib@0.22.7", "gstreamer-base-sys@0.25.0", "gstreamer-sys@0.25.2"], "dependencies": ["glib-sys@0.22.6", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "governor@0.10.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["dashmap", "default", "jitter", "quanta", "std"], "parents": ["perry-ext-ratelimit@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["cfg-if@1.0.4", "dashmap@6.2.1", "futures-sink@0.3.34", "futures-timer@3.0.4", "futures-util@0.3.34", "getrandom@0.3.4", "hashbrown@0.16.1", "nonzero_ext@0.3.0", "parking_lot@0.12.5", "portable-atomic@1.13.1", "quanta@0.12.6", "rand@0.9.4", "smallvec@1.15.1", "spinning_top@0.3.0", "web-time@1.1.0"]}, +{"package": "graphene-rs@0.20.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gsk4@0.9.6", "gtk4@0.9.7"], "dependencies": ["glib@0.20.12", "graphene-sys@0.20.10", "libc@0.2.189"]}, +{"package": "graphene-sys@0.20.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["graphene-rs@0.20.10", "gsk4-sys@0.9.6", "gtk4-sys@0.9.6"], "dependencies": ["glib-sys@0.20.10", "libc@0.2.189", "pkg-config@0.3.33", "system-deps@7.0.8"]}, +{"package": "group@0.13.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["elliptic-curve@0.13.8"], "dependencies": ["ff@0.13.1", "rand_core@0.6.4", "subtle@2.6.1"]}, +{"package": "group@0.14.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["elliptic-curve@0.14.0"], "dependencies": ["ff@0.14.0", "rand_core@0.10.1", "subtle@2.6.1"]}, +{"package": "gsk4-sys@0.9.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v4_2", "v4_4", "v4_6"], "parents": ["gsk4@0.9.6", "gtk4-sys@0.9.6"], "dependencies": ["cairo-sys-rs@0.20.10", "gdk4-sys@0.9.6", "glib-sys@0.20.10", "gobject-sys@0.20.10", "graphene-sys@0.20.10", "libc@0.2.189", "pango-sys@0.20.10", "system-deps@7.0.8"]}, +{"package": "gsk4@0.9.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v4_2", "v4_4", "v4_6"], "parents": ["gtk4@0.9.7"], "dependencies": ["cairo-rs@0.20.12", "gdk4@0.9.6", "glib@0.20.12", "graphene-rs@0.20.10", "gsk4-sys@0.9.6", "libc@0.2.189", "pango@0.20.12"]}, +{"package": "gstreamer-app-sys@0.25.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gstreamer-app@0.25.2"], "dependencies": ["glib-sys@0.22.6", "gstreamer-base-sys@0.25.0", "gstreamer-sys@0.25.2", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "gstreamer-app@0.25.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-ui-gtk4@0.5.1565"], "dependencies": ["futures-core@0.3.34", "futures-sink@0.3.34", "glib@0.22.7", "gstreamer-app-sys@0.25.0", "gstreamer-base@0.25.2", "gstreamer@0.25.3", "libc@0.2.189"]}, +{"package": "gstreamer-base-sys@0.25.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gstreamer-app-sys@0.25.0", "gstreamer-base@0.25.2"], "dependencies": ["glib-sys@0.22.6", "gobject-sys@0.22.6", "gstreamer-sys@0.25.2", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "gstreamer-base@0.25.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["gstreamer-app@0.25.2"], "dependencies": ["atomic_refcell@0.1.14", "cfg-if@1.0.4", "glib@0.22.7", "gstreamer-base-sys@0.25.0", "gstreamer@0.25.3", "libc@0.2.189"]}, +{"package": "gstreamer-sys@0.25.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gstreamer-app-sys@0.25.0", "gstreamer-base-sys@0.25.0", "gstreamer@0.25.3"], "dependencies": ["cfg-if@1.0.4", "glib-sys@0.22.6", "gobject-sys@0.22.6", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "gstreamer@0.25.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["gstreamer-app@0.25.2", "gstreamer-base@0.25.2", "perry-ui-gtk4@0.5.1565"], "dependencies": ["cfg-if@1.0.4", "futures-channel@0.3.32", "futures-core@0.3.34", "futures-util@0.3.34", "glib@0.22.7", "gstreamer-sys@0.25.2", "itertools@0.15.0", "kstring@2.0.2", "libc@0.2.189", "muldiv@1.0.1", "num-integer@0.1.46", "num-rational@0.4.2", "option-operations@0.6.1", "pastey@0.2.3", "pin-project-lite@0.2.17", "smallvec@1.15.1", "thiserror@2.0.18"]}, +{"package": "gtk4-macros@0.9.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["gtk4@0.9.7"], "dependencies": ["proc-macro-crate@3.5.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "gtk4-sys@0.9.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v4_2", "v4_4", "v4_6"], "parents": ["gtk4@0.9.7", "libshumate-sys@0.6.0", "webkit6-sys@0.4.0"], "dependencies": ["cairo-sys-rs@0.20.10", "gdk-pixbuf-sys@0.20.10", "gdk4-sys@0.9.6", "gio-sys@0.20.10", "glib-sys@0.20.10", "gobject-sys@0.20.10", "graphene-sys@0.20.10", "gsk4-sys@0.9.6", "libc@0.2.189", "pango-sys@0.20.10", "system-deps@7.0.8"]}, +{"package": "gtk4@0.9.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["v4_2", "v4_4", "v4_6"], "parents": ["libshumate@0.6.0", "perry-ui-gtk4@0.5.1565", "webkit6@0.4.0"], "dependencies": ["cairo-rs@0.20.12", "field-offset@0.3.6", "futures-channel@0.3.32", "gdk-pixbuf@0.20.10", "gdk4@0.9.6", "gio@0.20.12", "glib@0.20.12", "graphene-rs@0.20.10", "gsk4@0.9.6", "gtk4-macros@0.9.5", "gtk4-sys@0.9.6", "libc@0.2.189", "pango@0.20.12"]}, +{"package": "h2@0.4.19", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["hyper@1.11.1", "perry-ext-http@0.5.1565", "reqwest@0.12.28"], "dependencies": ["atomic-waker@1.1.2", "bytes@1.12.1", "fnv@1.0.7", "futures-core@0.3.34", "futures-sink@0.3.34", "http@1.4.1", "indexmap@2.14.1", "slab@0.4.12", "tokio-util@0.7.18", "tokio@1.53.1", "tracing@0.1.44"]}, +{"package": "half@2.7.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["exr@1.74.0", "tiff@0.11.3"], "dependencies": ["cfg-if@1.0.4", "crunchy@0.2.4", "zerocopy@0.8.50"]}, +{"package": "hash2curve@0.14.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ed448-goldilocks@0.14.0-pre.15"], "dependencies": ["digest@0.11.3", "elliptic-curve@0.14.0"]}, +{"package": "hashbrown@0.14.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["ahash", "allocator-api2", "default", "inline-more", "raw"], "parents": ["dashmap@5.5.3", "dashmap@6.2.1", "hstr@3.0.6", "swc_allocator@4.0.1"], "dependencies": ["ahash@0.8.12", "allocator-api2@0.2.21"]}, +{"package": "hashbrown@0.15.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default-hasher"], "parents": ["wasmparser@0.244.0"], "dependencies": ["foldhash@0.1.5"]}, +{"package": "hashbrown@0.16.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["allocator-api2", "default", "default-hasher", "equivalent", "inline-more", "raw-entry"], "parents": ["governor@0.10.4", "hashlink@0.11.1", "rsqlite-vfs@0.1.1", "sqlx-core@0.9.0"], "dependencies": ["allocator-api2@0.2.21", "equivalent@1.0.2", "foldhash@0.2.0"]}, +{"package": "hashbrown@0.17.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["allocator-api2", "default", "default-hasher", "equivalent", "inline-more", "raw-entry"], "parents": ["indexmap@2.14.1", "lru@0.18.3"], "dependencies": ["allocator-api2@0.2.21", "equivalent@1.0.2", "foldhash@0.2.0"]}, +{"package": "hashlink@0.11.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rusqlite@0.39.0", "sqlx-core@0.9.0"], "dependencies": ["hashbrown@0.16.1"]}, +{"package": "heck@0.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["ouroboros_macro@0.17.2"], "dependencies": []}, +{"package": "heck@0.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["clap_derive@4.6.4", "glib-macros@0.20.12", "glib-macros@0.22.6", "is-macro@0.3.7", "sqlx-macros-core@0.9.0", "strum_macros@0.27.2", "system-deps@7.0.8", "wit-bindgen-core@0.51.0", "wit-bindgen-rust@0.51.0"], "dependencies": []}, +{"package": "hermit-abi@0.1.19", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["atty@0.2.14"], "dependencies": ["libc@0.2.189"]}, +{"package": "hermit-abi@0.5.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["is-terminal@0.4.17", "num_cpus@1.17.0", "polling@3.11.0"], "dependencies": []}, +{"package": "hex@0.4.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "std"], "parents": ["bson@3.1.0", "mongodb@3.8.2", "perry-container-compose@0.5.1565", "perry-stdlib@0.5.1565", "perry-updater@0.5.1565", "perry@0.5.1565", "sqlx-macros-core@0.9.0", "sqlx-postgres@0.9.0", "zbus@5.16.0"], "dependencies": []}, +{"package": "hickory-net@0.26.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "tokio"], "parents": ["hickory-resolver@0.26.1", "mongodb@3.8.2"], "dependencies": ["async-trait@0.1.92", "cfg-if@1.0.4", "data-encoding@2.11.0", "futures-channel@0.3.32", "futures-io@0.3.34", "futures-util@0.3.34", "hickory-proto@0.26.1", "idna@1.1.0", "ipnet@2.12.0", "jni@0.22.4", "rand@0.10.2", "thiserror@2.0.18", "tinyvec@1.11.0", "tokio@1.53.1", "tracing@0.1.44", "url@2.5.8"]}, +{"package": "hickory-proto@0.26.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["access-control", "default", "std"], "parents": ["hickory-net@0.26.1", "hickory-resolver@0.26.1", "mongodb@3.8.2", "perry-runtime@0.5.1565"], "dependencies": ["data-encoding@2.11.0", "idna@1.1.0", "ipnet@2.12.0", "jni@0.22.4", "once_cell@1.21.4", "prefix-trie@0.8.4", "rand@0.10.2", "ring@0.17.14", "thiserror@2.0.18", "tinyvec@1.11.0", "tracing@0.1.44", "url@2.5.8"]}, +{"package": "hickory-resolver@0.26.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "system-config", "tokio"], "parents": ["mongodb@3.8.2"], "dependencies": ["cfg-if@1.0.4", "futures-util@0.3.34", "hickory-net@0.26.1", "hickory-proto@0.26.1", "ipconfig@0.3.4", "ipnet@2.12.0", "jni@0.22.4", "moka@0.12.15", "ndk-context@0.1.1", "once_cell@1.21.4", "parking_lot@0.12.5", "rand@0.10.2", "resolv-conf@0.7.6", "smallvec@1.15.1", "system-configuration@0.7.0", "thiserror@2.0.18", "tokio@1.53.1", "tracing@0.1.44"]}, +{"package": "hkdf@0.12.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["elliptic-curve@0.13.8"], "dependencies": ["hmac@0.12.1"]}, +{"package": "hkdf@0.13.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-stdlib@0.5.1565", "sqlx-postgres@0.9.0"], "dependencies": ["hmac@0.13.0"]}, +{"package": "hmac@0.12.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["reset"], "parents": ["hkdf@0.12.4", "jsonwebtoken@11.0.0", "p12@0.6.3", "pbkdf2@0.12.2", "rfc6979@0.4.0"], "dependencies": ["digest@0.10.7"]}, +{"package": "hmac@0.13.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["zeroize"], "parents": ["hkdf@0.13.0", "mongodb@3.8.2", "pbkdf2@0.13.0", "perry-stdlib@0.5.1565", "sqlx-postgres@0.9.0", "zip@8.6.0"], "dependencies": ["digest@0.11.3"]}, +{"package": "hostname@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["lettre@0.11.23", "perry-runtime@0.5.1565"], "dependencies": ["cfg-if@1.0.4", "libc@0.2.189", "windows-link@0.2.1"]}, +{"package": "hstr@3.0.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["serde"], "parents": ["swc_atoms@9.0.3"], "dependencies": ["hashbrown@0.14.5", "new_debug_unreachable@1.0.6", "once_cell@1.21.4", "rustc-hash@2.1.2", "serde@1.0.229", "triomphe@0.1.15"]}, +{"package": "html5ever@0.39.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["scraper@0.27.0"], "dependencies": ["log@0.4.34", "markup5ever@0.39.0"]}, +{"package": "http-body-util@0.1.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-ext-fastify@0.5.1565", "perry-ext-http@0.5.1565", "perry-stdlib@0.5.1565", "reqwest@0.12.28"], "dependencies": ["bytes@1.12.1", "futures-core@0.3.34", "http-body@1.0.1", "http@1.4.1", "pin-project-lite@0.2.17"]}, +{"package": "http-body@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["http-body-util@0.1.5", "hyper-util@0.1.20", "hyper@1.11.1", "reqwest@0.12.28", "tower-http@0.6.11"], "dependencies": ["bytes@1.12.1", "http@1.4.1"]}, +{"package": "http@1.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["h2@0.4.19", "http-body-util@0.1.5", "http-body@1.0.1", "hyper-rustls@0.27.9", "hyper-util@0.1.20", "hyper@1.11.1", "reqwest@0.12.28", "tower-http@0.6.11", "tungstenite@0.24.0", "tungstenite@0.29.0"], "dependencies": ["bytes@1.12.1", "itoa@1.0.18"]}, +{"package": "httparse@1.10.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["hyper@1.11.1", "tungstenite@0.24.0", "tungstenite@0.29.0"], "dependencies": []}, +{"package": "httpdate@1.0.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["hyper@1.11.1", "lettre@0.11.23", "perry-ext-http@0.5.1565", "tiny_http@0.12.0"], "dependencies": []}, +{"package": "humantime@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["env_logger@0.10.2"], "dependencies": []}, +{"package": "hybrid-array@0.4.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "ctutils", "extra-sizes", "subtle", "zeroize"], "parents": ["block-buffer@0.12.0", "block-padding@0.4.2", "crypto-bigint@0.7.5", "crypto-common@0.2.2", "elliptic-curve@0.14.0", "inout@0.2.2", "ml-kem@0.3.2", "module-lattice@0.2.3", "sec1@0.8.1"], "dependencies": ["ctutils@0.4.2", "subtle@2.6.1", "typenum@1.20.1", "zeroize@1.8.2"]}, +{"package": "hyper-rustls@0.27.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["http1", "http2", "ring", "tls12", "webpki-roots", "webpki-tokio"], "parents": ["reqwest@0.12.28"], "dependencies": ["http@1.4.1", "hyper-util@0.1.20", "hyper@1.11.1", "rustls@0.23.43", "tokio-rustls@0.26.4", "tokio@1.53.1", "tower-service@0.3.3", "webpki-roots@1.0.9"]}, +{"package": "hyper-util@0.1.20", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["client", "client-legacy", "client-proxy", "default", "http1", "http2", "server", "server-auto", "tokio"], "parents": ["hyper-rustls@0.27.9", "perry-ext-fastify@0.5.1565", "perry-ext-http@0.5.1565", "perry-stdlib@0.5.1565", "reqwest@0.12.28"], "dependencies": ["base64@0.22.1", "bytes@1.12.1", "futures-channel@0.3.32", "futures-util@0.3.34", "http-body@1.0.1", "http@1.4.1", "hyper@1.11.1", "ipnet@2.12.0", "libc@0.2.189", "percent-encoding@2.3.2", "pin-project-lite@0.2.17", "socket2@0.6.5", "tokio@1.53.1", "tower-service@0.3.3", "tracing@0.1.44"]}, +{"package": "hyper@1.11.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["client", "default", "http1", "http2", "server"], "parents": ["hyper-rustls@0.27.9", "hyper-util@0.1.20", "perry-ext-fastify@0.5.1565", "perry-ext-http@0.5.1565", "perry-stdlib@0.5.1565", "reqwest@0.12.28"], "dependencies": ["atomic-waker@1.1.2", "bytes@1.12.1", "futures-channel@0.3.32", "futures-core@0.3.34", "h2@0.4.19", "http-body@1.0.1", "http@1.4.1", "httparse@1.10.1", "httpdate@1.0.3", "itoa@1.0.18", "pin-project-lite@0.2.17", "smallvec@1.15.1", "tokio@1.53.1", "want@0.3.1"]}, +{"package": "iana-time-zone-haiku@0.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["iana-time-zone@0.1.65"], "dependencies": ["cc@1.4.4"]}, +{"package": "iana-time-zone@0.1.65", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["fallback"], "parents": ["chrono@0.4.45"], "dependencies": ["android_system_properties@0.1.5", "core-foundation-sys@0.8.7", "iana-time-zone-haiku@0.1.2", "js-sys@0.3.99", "log@0.4.34", "wasm-bindgen@0.2.122", "windows-core@0.62.2"]}, +{"package": "icu_calendar@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["compiled_data"], "parents": ["icu_datetime@2.3.0", "icu_time@2.3.0", "perry-runtime@0.5.1565", "temporal_rs@0.2.6"], "dependencies": ["calendrical_calculations@0.2.4", "displaydoc@0.2.6", "icu_calendar_data@2.3.0", "icu_locale_core@2.3.0", "icu_locale_fallback@2.3.0", "icu_provider@2.3.1", "tinystr@0.8.4", "zerovec@0.11.8"]}, +{"package": "icu_calendar_data@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_calendar@2.3.0"], "dependencies": []}, +{"package": "icu_collections@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_locale@2.2.0", "icu_normalizer@2.2.0", "icu_properties@2.2.0"], "dependencies": ["displaydoc@0.2.6", "potential_utf@0.1.5", "utf8_iter@1.0.4", "yoke@0.8.3", "zerofrom@0.1.8", "zerovec@0.11.8"]}, +{"package": "icu_datetime@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["compiled_data"], "parents": ["perry-runtime@0.5.1565"], "dependencies": ["displaydoc@0.2.6", "fixed_decimal@0.7.2", "icu_calendar@2.3.0", "icu_datetime_data@2.3.0", "icu_decimal@2.3.0", "icu_locale_core@2.3.0", "icu_locale_fallback@2.3.0", "icu_pattern@0.5.0", "icu_plurals@2.3.0", "icu_provider@2.3.1", "icu_time@2.3.0", "potential_utf@0.1.5", "tinystr@0.8.4", "writeable@0.6.4", "zerovec@0.11.8"]}, +{"package": "icu_datetime_data@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_datetime@2.3.0"], "dependencies": []}, +{"package": "icu_decimal@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["compiled_data"], "parents": ["icu_datetime@2.3.0", "perry-runtime@0.5.1565"], "dependencies": ["displaydoc@0.2.6", "fixed_decimal@0.7.2", "icu_decimal_data@2.3.0", "icu_locale_core@2.3.0", "icu_locale_fallback@2.3.0", "icu_plurals@2.3.0", "icu_provider@2.3.1", "writeable@0.6.4", "zerovec@0.11.8"]}, +{"package": "icu_decimal_data@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_decimal@2.3.0"], "dependencies": []}, +{"package": "icu_locale@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["compiled_data", "default"], "parents": ["perry-runtime@0.5.1565"], "dependencies": ["icu_collections@2.2.0", "icu_locale_core@2.3.0", "icu_locale_data@2.2.0", "icu_provider@2.3.1", "potential_utf@0.1.5", "tinystr@0.8.4", "zerovec@0.11.8"]}, +{"package": "icu_locale_core@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "zerovec"], "parents": ["icu_calendar@2.3.0", "icu_datetime@2.3.0", "icu_decimal@2.3.0", "icu_locale@2.2.0", "icu_locale_fallback@2.3.0", "icu_properties@2.2.0", "icu_provider@2.3.1", "icu_time@2.3.0", "perry-runtime@0.5.1565", "temporal_rs@0.2.6"], "dependencies": ["displaydoc@0.2.6", "litemap@0.8.2", "serde@1.0.229", "tinystr@0.8.4", "writeable@0.6.4", "zerovec@0.11.8"]}, +{"package": "icu_locale_data@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_locale@2.2.0"], "dependencies": []}, +{"package": "icu_locale_fallback@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["compiled_data"], "parents": ["icu_calendar@2.3.0", "icu_datetime@2.3.0", "icu_decimal@2.3.0", "icu_plurals@2.3.0"], "dependencies": ["icu_locale_core@2.3.0", "icu_locale_fallback_data@2.3.0", "icu_provider@2.3.1", "potential_utf@0.1.5", "tinystr@0.8.4", "zerovec@0.11.8"]}, +{"package": "icu_locale_fallback_data@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_locale_fallback@2.3.0"], "dependencies": []}, +{"package": "icu_normalizer@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["compiled_data"], "parents": ["idna_adapter@1.2.2"], "dependencies": ["icu_collections@2.2.0", "icu_normalizer_data@2.2.0", "icu_properties@2.2.0", "icu_provider@2.3.1", "smallvec@1.15.1", "zerovec@0.11.8"]}, +{"package": "icu_normalizer_data@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_normalizer@2.2.0"], "dependencies": []}, +{"package": "icu_pattern@0.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "zerovec"], "parents": ["icu_datetime@2.3.0"], "dependencies": ["displaydoc@0.2.6", "either@1.16.0", "serde@1.0.229", "writeable@0.6.4", "zerovec@0.11.8"]}, +{"package": "icu_plurals@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["compiled_data"], "parents": ["icu_datetime@2.3.0", "icu_decimal@2.3.0"], "dependencies": ["fixed_decimal@0.7.2", "icu_locale_fallback@2.3.0", "icu_plurals_data@2.3.0", "icu_provider@2.3.1", "zerovec@0.11.8"]}, +{"package": "icu_plurals_data@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_plurals@2.3.0"], "dependencies": []}, +{"package": "icu_properties@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["compiled_data"], "parents": ["icu_normalizer@2.2.0", "idna_adapter@1.2.2"], "dependencies": ["icu_collections@2.2.0", "icu_locale_core@2.3.0", "icu_properties_data@2.2.0", "icu_provider@2.3.1", "zerotrie@0.2.5", "zerovec@0.11.8"]}, +{"package": "icu_properties_data@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_properties@2.2.0"], "dependencies": []}, +{"package": "icu_provider@2.3.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "baked"], "parents": ["icu_calendar@2.3.0", "icu_datetime@2.3.0", "icu_decimal@2.3.0", "icu_locale@2.2.0", "icu_locale_fallback@2.3.0", "icu_normalizer@2.2.0", "icu_plurals@2.3.0", "icu_properties@2.2.0", "icu_time@2.3.0", "perry-runtime@0.5.1565"], "dependencies": ["displaydoc@0.2.6", "icu_locale_core@2.3.0", "serde@1.0.229", "stable_deref_trait@1.2.1", "writeable@0.6.4", "yoke@0.8.3", "zerofrom@0.1.8", "zerotrie@0.2.5", "zerovec@0.11.8"]}, +{"package": "icu_time@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "compiled_data"], "parents": ["icu_datetime@2.3.0", "perry-runtime@0.5.1565"], "dependencies": ["calendrical_calculations@0.2.4", "displaydoc@0.2.6", "icu_calendar@2.3.0", "icu_locale_core@2.3.0", "icu_provider@2.3.1", "icu_time_data@2.3.0", "serde@1.0.229", "zerotrie@0.2.5", "zerovec@0.11.8"]}, +{"package": "icu_time_data@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_time@2.3.0"], "dependencies": []}, +{"package": "id-arena@2.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["wit-parser@0.244.0"], "dependencies": []}, +{"package": "ident_case@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["darling_core@0.20.11", "darling_core@0.23.0"], "dependencies": []}, +{"package": "idna@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "compiled_data", "default", "std"], "parents": ["hickory-net@0.26.1", "hickory-proto@0.26.1", "lettre@0.11.23", "perry-runtime@0.5.1565", "perry-validation@0.5.1565", "url@2.5.8", "validator@0.21.0"], "dependencies": ["idna_adapter@1.2.2", "smallvec@1.15.1", "utf8_iter@1.0.4"]}, +{"package": "idna_adapter@1.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["compiled_data"], "parents": ["idna@1.1.0"], "dependencies": ["icu_normalizer@2.2.0", "icu_properties@2.2.0"]}, +{"package": "if_chain@1.0.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_sourcemap@9.3.4"], "dependencies": []}, +{"package": "image-webp@0.2.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["image@0.25.10"], "dependencies": ["byteorder-lite@0.1.0", "quick-error@2.0.1"]}, +{"package": "image@0.25.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["avif", "bmp", "dds", "default", "default-formats", "exr", "ff", "gif", "hdr", "ico", "jpeg", "png", "pnm", "qoi", "rayon", "tga", "tiff", "webp"], "parents": ["perry-doc-tests@0.5.1565", "perry-ext-sharp@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["bytemuck@1.25.0", "byteorder-lite@0.1.0", "color_quant@1.1.0", "exr@1.74.0", "gif@0.14.2", "image-webp@0.2.4", "moxcms@0.8.1", "num-traits@0.2.19", "png@0.18.1", "qoi@0.4.1", "ravif@0.13.0", "rayon@1.12.0", "rgb@0.8.53", "tiff@0.11.3", "zune-core@0.5.1", "zune-jpeg@0.5.15"]}, +{"package": "imgref@1.12.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "deprecated"], "parents": ["dssim-core@3.5.1", "loop9@0.1.5", "ravif@0.13.0"], "dependencies": []}, +{"package": "indexmap@2.14.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "serde", "std"], "parents": ["bson@3.1.0", "h2@0.4.19", "lopdf@0.39.0", "perry-container-compose@0.5.1565", "petgraph@0.7.1", "serde_json@1.0.151", "serde_yaml@0.9.34+deprecated", "sqlx-core@0.9.0", "swc_bundler@37.0.0", "swc_config@3.1.2", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_utils@25.0.0", "toml@1.1.4+spec-1.1.0", "toml_edit@0.25.12+spec-1.1.0", "wasm-metadata@0.244.0", "wasmparser@0.244.0", "wasmparser@0.258.0", "wit-bindgen-rust@0.51.0", "wit-component@0.244.0", "wit-parser@0.244.0", "zip@8.6.0"], "dependencies": ["equivalent@1.0.2", "hashbrown@0.17.1", "serde@1.0.229", "serde_core@1.0.229"]}, +{"package": "indicatif@0.18.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "unicode-width", "wasmbind"], "parents": ["perry@0.5.1565"], "dependencies": ["console@0.16.4", "portable-atomic@1.13.1", "unicode-width@0.2.2", "unit-prefix@0.5.2", "web-time@1.1.0"]}, +{"package": "inkwell@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["llvm-sys-221", "llvm22-1", "llvm22-1-no-llvm-linking", "target-aarch64", "target-x86"], "parents": ["perry-codegen@0.5.1565"], "dependencies": ["bitflags@2.12.1", "inkwell_internals@0.14.0", "libc@0.2.189", "llvm-sys@221.0.1", "thiserror@2.0.18"]}, +{"package": "inkwell_internals@0.14.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["inkwell@0.9.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "inotify-sys@0.1.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["inotify@0.9.6"], "dependencies": ["libc@0.2.189"]}, +{"package": "inotify@0.9.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["notify@6.1.1"], "dependencies": ["bitflags@1.3.2", "inotify-sys@0.1.5", "libc@0.2.189"]}, +{"package": "inout@0.1.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["block-padding"], "parents": ["cipher@0.4.4"], "dependencies": ["block-padding@0.3.3", "generic-array@0.14.7"]}, +{"package": "inout@0.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["block-padding"], "parents": ["cipher@0.5.2"], "dependencies": ["block-padding@0.4.2", "hybrid-array@0.4.12"]}, +{"package": "interpolate_name@0.2.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rav1e@0.8.1"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "ipconfig@0.3.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["computer", "default"], "parents": ["hickory-resolver@0.26.1"], "dependencies": ["socket2@0.6.5", "widestring@1.2.1", "windows-registry@0.6.1", "windows-result@0.4.1", "windows-sys@0.61.2"]}, +{"package": "ipnet@2.12.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "serde", "std"], "parents": ["hickory-net@0.26.1", "hickory-proto@0.26.1", "hickory-resolver@0.26.1", "hyper-util@0.1.20", "prefix-trie@0.8.4"], "dependencies": ["serde@1.0.229"]}, +{"package": "is-macro@0.3.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_bundler@37.0.0", "swc_ecma_ast@19.0.0"], "dependencies": ["heck@0.5.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "is-terminal@0.4.17", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["env_logger@0.10.2"], "dependencies": ["hermit-abi@0.5.2", "libc@0.2.189", "windows-sys@0.61.2"]}, +{"package": "is_terminal_polyfill@1.70.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["anstream@1.0.0"], "dependencies": []}, +{"package": "itertools@0.12.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["bindgen@0.72.1"], "dependencies": ["either@1.16.0"]}, +{"package": "itertools@0.14.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "use_alloc", "use_std"], "parents": ["rav1e@0.8.1"], "dependencies": ["either@1.16.0"]}, +{"package": "itertools@0.15.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "use_alloc", "use_std"], "parents": ["dssim-core@3.5.1", "gstreamer@0.25.3"], "dependencies": ["either@1.16.0"]}, +{"package": "itoa@1.0.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["compact_str@0.7.1", "cssparser@0.37.0", "http@1.4.1", "hyper@1.11.1", "lopdf@0.39.0", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-ui-android@0.5.1565", "redis@1.6.0", "serde_json@1.0.151", "serde_urlencoded@0.7.1", "serde_yaml@0.9.34+deprecated", "sqlx-postgres@0.9.0"], "dependencies": []}, +{"package": "ixdtf@0.6.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "duration"], "parents": ["temporal_rs@0.2.6"], "dependencies": []}, +{"package": "javascriptcore6-sys@0.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["javascriptcore6@0.4.0", "webkit6-sys@0.4.0"], "dependencies": ["glib-sys@0.20.10", "gobject-sys@0.20.10", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "javascriptcore6@0.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["webkit6@0.4.0"], "dependencies": ["glib@0.20.12", "javascriptcore6-sys@0.4.0", "libc@0.2.189"]}, +{"package": "jiff-tzdb@0.1.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["timezone_provider@0.2.6"], "dependencies": []}, +{"package": "jni-macros@0.22.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["jni@0.22.4"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "rustc_version@0.4.1", "simd_cesu8@1.1.1", "syn@2.0.117"]}, +{"package": "jni-sys-macros@0.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["jni-sys@0.4.1"], "dependencies": ["quote@1.0.45", "syn@2.0.117"]}, +{"package": "jni-sys@0.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["jni@0.22.4"], "dependencies": ["jni-sys-macros@0.4.1"]}, +{"package": "jni@0.22.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["hickory-net@0.26.1", "hickory-proto@0.26.1", "hickory-resolver@0.26.1", "perry-ui-android@0.5.1565"], "dependencies": ["cfg-if@1.0.4", "combine@4.6.7", "jni-macros@0.22.4", "jni-sys@0.4.1", "log@0.4.34", "simd_cesu8@1.1.1", "thiserror@2.0.18", "walkdir@2.5.0", "windows-link@0.2.1"]}, +{"package": "jobserver@0.1.34", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["cc@1.4.4"], "dependencies": ["getrandom@0.3.4", "libc@0.2.189"]}, +{"package": "js-sys@0.3.99", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std", "unsafe-eval"], "parents": ["bson@3.1.0", "chrono@0.4.45", "getrandom@0.2.17", "getrandom@0.3.4", "getrandom@0.4.2", "iana-time-zone@0.1.65", "jsonwebtoken@11.0.0", "reqwest@0.12.28", "sqlite-wasm-rs@0.5.5", "time@0.3.55", "uuid@1.26.0", "wasm-bindgen-futures@0.4.72", "web-sys@0.3.99", "web-time@1.1.0"], "dependencies": ["cfg-if@1.0.4", "futures-util@0.3.34", "once_cell@1.21.4", "wasm-bindgen@0.2.122"]}, +{"package": "jsonwebtoken@11.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["rust_crypto", "use_pem"], "parents": ["perry-ext-jsonwebtoken@0.5.1565", "perry-stdlib@0.5.1565", "perry@0.5.1565"], "dependencies": ["base64@0.22.1", "ed25519-dalek@2.2.0", "getrandom@0.2.17", "hmac@0.12.1", "js-sys@0.3.99", "p256@0.13.2", "p384@0.13.1", "pem@3.0.6", "rand@0.8.7", "rsa@0.9.10", "serde@1.0.229", "serde_json@1.0.151", "sha2@0.10.9", "signature@2.2.0", "simple_asn1@0.6.4", "zeroize@1.8.2"]}, +{"package": "kamadak-exif@0.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ext-sharp@0.5.1565"], "dependencies": ["mutate_once@0.1.2"]}, +{"package": "keccak@0.1.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["sha3@0.10.9"], "dependencies": ["cpufeatures@0.2.17"]}, +{"package": "keccak@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["sha3@0.11.0", "sha3@0.12.0", "shake@0.1.0"], "dependencies": ["cfg-if@1.0.4", "cpufeatures@0.3.0"]}, +{"package": "kem@0.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ml-kem@0.3.2"], "dependencies": ["crypto-common@0.2.2", "rand_core@0.10.1"]}, +{"package": "kqueue-sys@1.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["kqueue@1.2.0"], "dependencies": ["bitflags@2.12.1", "libc@0.2.189"]}, +{"package": "kqueue@1.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["notify@6.1.1"], "dependencies": ["kqueue-sys@1.1.2", "libc@0.2.189"]}, +{"package": "ksni@0.3.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "tokio"], "parents": ["perry-ui-gtk4@0.5.1565"], "dependencies": ["futures-util@0.3.34", "pastey@0.2.3", "serde@1.0.229", "tokio@1.53.1", "zbus@5.16.0"]}, +{"package": "kstring@2.0.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std", "unsafe"], "parents": ["gstreamer@0.25.3"], "dependencies": ["static_assertions@1.1.0"]}, +{"package": "lazy_static@1.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["spin", "spin_no_std"], "parents": ["llvm-sys@221.0.1", "num-bigint-dig@0.8.6", "p12@0.6.3", "perry-ext-fastify@0.5.1565", "perry-ext-fetch@0.5.1565", "perry-ext-http@0.5.1565", "perry-ext-ioredis@0.5.1565", "perry-ext-streams@0.5.1565", "perry-ext-ws@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "sharded-slab@0.1.7"], "dependencies": ["spin@0.9.8"]}, +{"package": "leb128fmt@0.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wasm-encoder@0.244.0", "wasm-encoder@0.258.0"], "dependencies": []}, +{"package": "lebe@0.5.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["exr@1.74.0"], "dependencies": []}, +{"package": "lettre@0.11.23", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["builder", "hostname", "pool", "ring", "rustls", "rustls-tls", "smtp-transport", "tokio1", "tokio1-rustls", "tokio1-rustls-tls", "webpki-roots"], "parents": ["perry-ext-nodemailer@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["async-trait@0.1.92", "base64@0.23.1", "email-encoding@0.4.1", "email_address@0.2.9", "fastrand@2.4.1", "futures-io@0.3.34", "futures-util@0.3.34", "hostname@0.4.2", "httpdate@1.0.3", "idna@1.1.0", "mime@0.3.17", "nom@8.0.0", "percent-encoding@2.3.2", "quoted_printable@0.5.2", "rustls@0.23.43", "socket2@0.6.5", "tokio-rustls@0.26.4", "tokio@1.53.1", "url@2.5.8", "webpki-roots@1.0.9"]}, +{"package": "libbz2-rs-sys@0.2.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["rust-allocator"], "parents": ["bzip2@0.6.1"], "dependencies": []}, +{"package": "libc@0.2.189", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["android_system_properties@0.1.5", "atty@0.2.14", "cairo-rs@0.20.12", "cairo-rs@0.22.9", "cairo-sys-rs@0.20.10", "cairo-sys-rs@0.22.0", "cc@1.4.4", "clang-sys@1.8.1", "console@0.15.11", "console@0.16.4", "core-foundation@0.10.1", "core-foundation@0.9.4", "cpufeatures@0.2.17", "cpufeatures@0.3.0", "dirs-sys@0.5.0", "errno@0.3.14", "filetime@0.2.29", "fsevent-sys@4.1.0", "fslock@0.2.1", "gdk-pixbuf-sys@0.20.10", "gdk-pixbuf@0.20.10", "gdk4-sys@0.9.6", "gdk4@0.9.6", "getrandom@0.2.17", "getrandom@0.3.4", "getrandom@0.4.2", "gio-sys@0.20.10", "gio-sys@0.22.0", "gio@0.20.12", "glib-sys@0.20.10", "glib-sys@0.22.6", "glib@0.20.12", "glib@0.22.7", "gobject-sys@0.20.10", "gobject-sys@0.22.6", "graphene-rs@0.20.10", "graphene-sys@0.20.10", "gsk4-sys@0.9.6", "gsk4@0.9.6", "gstreamer-app-sys@0.25.0", "gstreamer-app@0.25.2", "gstreamer-base-sys@0.25.0", "gstreamer-base@0.25.2", "gstreamer-sys@0.25.2", "gstreamer@0.25.3", "gtk4-sys@0.9.6", "gtk4@0.9.7", "hermit-abi@0.1.19", "hostname@0.4.2", "hyper-util@0.1.20", "inkwell@0.9.0", "inotify-sys@0.1.5", "inotify@0.9.6", "is-terminal@0.4.17", "javascriptcore6-sys@0.4.0", "javascriptcore6@0.4.0", "jobserver@0.1.34", "kqueue-sys@1.1.2", "kqueue@1.2.0", "libredox@0.1.17", "libshumate-sys@0.6.0", "libshumate@0.6.0", "llvm-sys@221.0.1", "mio@0.8.11", "mio@1.2.1", "notify@6.1.1", "num_cpus@1.17.0", "objc2-app-kit@0.3.2", "objc2-core-foundation@0.3.2", "objc2-foundation@0.3.2", "pango-sys@0.20.10", "pango@0.20.12", "parking_lot_core@0.9.12", "perry-audio-miniaudio@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-ui-android@0.5.1565", "perry-ui-gtk4@0.5.1565", "perry-ui-ios@0.5.1565", "perry-ui-macos@0.5.1565", "perry-ui-tvos@0.5.1565", "perry-ui-visionos@0.5.1565", "perry-ui-watchos@0.5.1565", "perry-ui-windows-winui@0.5.1565", "perry-ui-windows@0.5.1565", "perry@0.5.1565", "quanta@0.12.6", "quinn-udp@0.5.14", "rand@0.8.7", "rav1e@0.8.1", "ring@0.17.14", "rustix@1.1.4", "security-framework-sys@2.17.0", "security-framework@3.7.0", "signal-hook-registry@1.4.8", "socket2@0.6.5", "soup3-sys@0.7.0", "soup3@0.7.0", "stacker@0.1.25", "system-configuration-sys@0.6.0", "tar@0.4.46", "tokio@1.53.1", "wait-timeout@0.2.1", "webkit6-sys@0.4.0", "webkit6@0.4.0", "which@8.0.6", "xattr@1.6.1", "zbus@5.16.0"], "dependencies": []}, +{"package": "libfuzzer-sys@0.4.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "link_libfuzzer"], "parents": ["rav1e@0.8.1"], "dependencies": ["arbitrary@1.4.2", "cc@1.4.4"]}, +{"package": "libloading@0.8.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["clang-sys@1.8.1"], "dependencies": ["cfg-if@1.0.4", "windows-link@0.2.1"]}, +{"package": "libm@0.2.16", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["arch", "default"], "parents": ["core_maths@0.1.1", "num-bigint-dig@0.8.6", "num-traits@0.2.19", "wasmi_core@1.1.0"], "dependencies": []}, +{"package": "libmimalloc-sys@0.1.49", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["cty", "extended"], "parents": ["mimalloc@0.1.52", "perry-runtime@0.5.1565"], "dependencies": ["cc@1.4.4", "cty@0.2.2"]}, +{"package": "libredox@0.1.17", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["base", "call", "libc", "std"], "parents": ["redox_users@0.5.2"], "dependencies": ["libc@0.2.189"]}, +{"package": "libshumate-sys@0.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["libshumate@0.6.0"], "dependencies": ["gdk-pixbuf-sys@0.20.10", "gdk4-sys@0.9.6", "gio-sys@0.20.10", "glib-sys@0.20.10", "gobject-sys@0.20.10", "gtk4-sys@0.9.6", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "libshumate@0.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ui-gtk4@0.5.1565"], "dependencies": ["gdk-pixbuf@0.20.10", "gdk4@0.9.6", "gio@0.20.12", "glib@0.20.12", "gtk4@0.9.7", "libc@0.2.189", "libshumate-sys@0.6.0"]}, +{"package": "libsqlite3-sys@0.37.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["bindgen", "buildtime_bindgen", "bundled", "bundled_bindings", "cc", "default", "min_sqlite_version_3_34_1", "pkg-config", "preupdate_hook", "session", "vcpkg"], "parents": ["rusqlite@0.39.0", "sqlx-sqlite@0.9.0"], "dependencies": ["bindgen@0.72.1", "cc@1.4.4", "pkg-config@0.3.33", "vcpkg@0.2.15"]}, +{"package": "linux-raw-sys@0.12.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["auxvec", "elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "xdp"], "parents": ["rustix@1.1.4"], "dependencies": []}, +{"package": "litemap@0.8.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["icu_locale_core@2.3.0"], "dependencies": []}, +{"package": "litrs@1.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["document-features@0.2.12"], "dependencies": []}, +{"package": "llvm-sys@221.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["no-llvm-linking"], "parents": ["inkwell@0.9.0", "perry-codegen@0.5.1565"], "dependencies": ["anyhow@1.0.104", "cc@1.4.4", "lazy_static@1.5.0", "libc@0.2.189", "regex-lite@0.1.9", "semver@1.0.28"]}, +{"package": "lock_api@0.4.14", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["atomic_usize", "default"], "parents": ["dashmap@5.5.3", "dashmap@6.2.1", "futures-intrusive@0.5.0", "parking_lot@0.12.5", "spin@0.9.8", "spinning_top@0.3.0"], "dependencies": ["scopeguard@1.2.0"]}, +{"package": "log@0.4.34", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "std"], "parents": ["allsorts-azul@0.16.5", "av-scenechange@0.14.1", "av1-grain@0.2.5", "env_logger@0.10.2", "html5ever@0.39.0", "iana-time-zone@0.1.65", "jni@0.22.4", "lopdf@0.39.0", "markup5ever@0.39.0", "mio@0.8.11", "notify@6.1.1", "pathfinder_geometry@0.5.1", "perry-codegen@0.5.1565", "perry@0.5.1565", "rav1e@0.8.1", "reqwest@0.12.28", "rustls@0.23.43", "selectors@0.38.0", "sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "tiny_http@0.12.0", "tokio-tungstenite@0.29.0", "tracing-log@0.2.0", "tracing@0.1.44", "tungstenite@0.24.0", "tungstenite@0.29.0", "wit-component@0.244.0", "wit-parser@0.244.0", "zopfli@0.8.3"], "dependencies": []}, +{"package": "loop9@0.1.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ravif@0.13.0"], "dependencies": ["imgref@1.12.3"]}, +{"package": "lopdf@0.39.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["time"], "parents": ["printpdf@0.10.1"], "dependencies": ["aes@0.8.4", "bitflags@2.12.1", "cbc@0.1.2", "ecb@0.1.2", "encoding_rs@0.8.35", "flate2@1.1.10", "getrandom@0.3.4", "indexmap@2.14.1", "itoa@1.0.18", "log@0.4.34", "md-5@0.10.6", "nom@8.0.0", "nom_locate@5.0.0", "rand@0.9.4", "rangemap@1.7.1", "sha2@0.10.9", "stringprep@0.1.5", "thiserror@2.0.18", "time@0.3.55", "ttf-parser@0.25.1", "weezl@0.1.12"]}, +{"package": "lru-slab@0.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["quinn-proto@0.11.15"], "dependencies": []}, +{"package": "lru@0.18.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "hashbrown"], "parents": ["perry-ext-lru-cache@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["hashbrown@0.17.1"]}, +{"package": "lzma-rust2@0.16.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["encoder", "optimization", "sha2", "std", "xz"], "parents": ["zip@8.6.0"], "dependencies": ["sha2@0.11.0"]}, +{"package": "mach2@0.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-runtime@0.5.1565"], "dependencies": []}, +{"package": "macro_magic@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "proc_support"], "parents": ["mongodb-internal-macros@3.8.2", "mongodb@3.8.2"], "dependencies": ["macro_magic_core@0.5.1", "macro_magic_macros@0.5.1", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "macro_magic_core@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["macro_magic@0.5.1", "macro_magic_macros@0.5.1"], "dependencies": ["const-random@0.1.18", "derive-syn-parse@0.2.0", "macro_magic_core_macros@0.5.1", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "macro_magic_core_macros@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["macro_magic_core@0.5.1"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "macro_magic_macros@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["macro_magic@0.5.1"], "dependencies": ["macro_magic_core@0.5.1", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "markup5ever@0.39.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["html5ever@0.39.0"], "dependencies": ["log@0.4.34", "tendril@0.5.0", "web_atoms@0.2.4"]}, +{"package": "matchers@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tracing-subscriber@0.3.23"], "dependencies": ["regex-automata@0.4.18"]}, +{"package": "maybe-rayon@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["rayon", "threads"], "parents": ["rav1e@0.8.1"], "dependencies": ["cfg-if@1.0.4", "rayon@1.12.0"]}, +{"package": "md-5@0.10.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["lopdf@0.39.0", "uuid@1.26.0"], "dependencies": ["cfg-if@1.0.4", "digest@0.10.7"]}, +{"package": "md-5@0.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "oid"], "parents": ["mongodb@3.8.2", "perry-container-compose@0.5.1565", "perry-stdlib@0.5.1565", "sqlx-postgres@0.9.0"], "dependencies": ["cfg-if@1.0.4", "digest@0.11.3"]}, +{"package": "memchr@2.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std", "use_std"], "parents": ["aho-corasick@1.1.4", "combine@4.6.7", "email-encoding@0.4.1", "futures-util@0.3.34", "glib@0.20.12", "glib@0.22.7", "no_std_io2@0.9.4", "nom@7.1.3", "nom@8.0.0", "nom_locate@5.0.0", "object@0.37.3", "regex-automata@0.4.18", "regex@1.13.1", "serde_json@1.0.151", "sqlx-core@0.9.0", "sqlx-postgres@0.9.0", "swc_ecma_codegen@21.0.0", "winnow@0.7.15", "winnow@1.0.3", "zip@8.6.0"], "dependencies": []}, +{"package": "memoffset@0.9.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["field-offset@0.3.6", "uds_windows@1.2.1"], "dependencies": ["autocfg@1.5.1"]}, +{"package": "miette-derive@7.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["miette@7.6.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "miette@7.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "derive"], "parents": ["node-semver@2.2.0"], "dependencies": ["cfg-if@1.0.4", "miette-derive@7.6.0", "unicode-width@0.1.14"]}, +{"package": "mimalloc@0.1.52", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-runtime@0.5.1565"], "dependencies": ["libmimalloc-sys@0.1.49"]}, +{"package": "mime@0.3.17", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["lettre@0.11.23", "mime_guess@2.0.5"], "dependencies": []}, +{"package": "mime_guess@2.0.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["reqwest@0.12.28"], "dependencies": ["mime@0.3.17", "unicase@2.9.0"]}, +{"package": "minimal-lexical@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["nom@7.1.3"], "dependencies": []}, +{"package": "miniz_oxide@0.8.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "simd", "simd-adler32", "with-alloc"], "parents": ["exr@1.74.0", "png@0.18.1"], "dependencies": ["adler2@2.0.1", "simd-adler32@0.3.9"]}, +{"package": "miniz_oxide@0.9.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "simd", "simd-adler32", "with-alloc"], "parents": ["flate2@1.1.10"], "dependencies": ["adler2@2.0.1", "simd-adler32@0.3.9"]}, +{"package": "mio@0.8.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "log", "os-ext", "os-poll"], "parents": ["notify@6.1.1"], "dependencies": ["libc@0.2.189", "log@0.4.34", "wasi@0.11.1+wasi-snapshot-preview1", "windows-sys@0.48.0"]}, +{"package": "mio@1.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["net", "os-ext", "os-poll"], "parents": ["tokio@1.53.1"], "dependencies": ["libc@0.2.189", "wasi@0.11.1+wasi-snapshot-preview1", "windows-sys@0.61.2"]}, +{"package": "ml-kem@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "pkcs8"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["const-oid@0.10.2", "hybrid-array@0.4.12", "kem@0.3.0", "module-lattice@0.2.3", "pkcs8@0.11.0", "rand_core@0.10.1", "sha3@0.11.0"]}, +{"package": "module-lattice@0.2.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "ctutils"], "parents": ["ml-kem@0.3.2"], "dependencies": ["ctutils@0.4.2", "hybrid-array@0.4.12", "num-traits@0.2.19"]}, +{"package": "moka@0.12.15", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "sync"], "parents": ["hickory-resolver@0.26.1"], "dependencies": ["crossbeam-channel@0.5.15", "crossbeam-epoch@0.9.20", "crossbeam-utils@0.8.21", "equivalent@1.0.2", "parking_lot@0.12.5", "portable-atomic@1.13.1", "smallvec@1.15.1", "tagptr@0.2.0", "uuid@1.26.0"]}, +{"package": "mongocrypt-sys@0.1.6+1.18.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["mongocrypt@0.4.0"], "dependencies": []}, +{"package": "mongocrypt@0.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["bson-3"], "parents": ["mongodb@3.8.2"], "dependencies": ["bson@3.1.0", "mongocrypt-sys@0.1.6+1.18.2", "once_cell@1.21.4", "serde@1.0.229"]}, +{"package": "mongodb-internal-macros@3.8.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["mongodb@3.8.2"], "dependencies": ["macro_magic@0.5.1", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "mongodb@3.8.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["bson-3", "compat-3-3-0", "dns-resolver", "rustls-tls"], "parents": ["perry-ext-mongodb@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["base64@0.22.1", "bitflags@2.12.1", "bson@3.1.0", "derive-where@1.6.1", "derive_more@2.1.1", "futures-core@0.3.34", "futures-io@0.3.34", "futures-util@0.3.34", "hex@0.4.3", "hickory-net@0.26.1", "hickory-proto@0.26.1", "hickory-resolver@0.26.1", "hmac@0.13.0", "macro_magic@0.5.1", "md-5@0.11.0", "mongocrypt@0.4.0", "mongodb-internal-macros@3.8.2", "pbkdf2@0.13.0", "percent-encoding@2.3.2", "rand@0.9.4", "rustc_version_runtime@0.3.0", "rustls@0.23.43", "serde@1.0.229", "serde_bytes@0.11.19", "serde_with@3.21.0", "sha1@0.11.0", "sha2@0.11.0", "socket2@0.6.5", "stringprep@0.1.5", "strsim@0.11.1", "take_mut@0.2.2", "thiserror@2.0.18", "tokio-rustls@0.26.4", "tokio-util@0.7.18", "tokio@1.53.1", "typed-builder@0.22.0", "uuid@1.26.0", "webpki-roots@1.0.9"]}, +{"package": "moxcms@0.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["avx", "avx_luts", "avx_shaper_fixed_point_paths", "avx_shaper_paths", "default", "lut", "neon", "neon_luts", "neon_shaper_fixed_point_paths", "neon_shaper_paths", "sse", "sse_luts", "sse_shaper_fixed_point_paths", "sse_shaper_paths"], "parents": ["image@0.25.10"], "dependencies": ["num-traits@0.2.19", "pxfm@0.1.29"]}, +{"package": "mpris-server@0.10.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["tokio"], "parents": ["perry-ui-gtk4@0.5.1565"], "dependencies": ["async-channel@2.5.0", "futures-channel@0.3.32", "serde@1.0.229", "trait-variant@0.1.2", "zbus@5.16.0"]}, +{"package": "muldiv@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gstreamer@0.25.3"], "dependencies": []}, +{"package": "mutate_once@0.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["kamadak-exif@0.6.1"], "dependencies": []}, +{"package": "nanoid@0.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-ext-nanoid@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["rand@0.9.4"]}, +{"package": "ndk-context@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["hickory-resolver@0.26.1"], "dependencies": []}, +{"package": "new_debug_unreachable@1.0.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["hstr@3.0.6", "rav1e@0.8.1", "selectors@0.38.0", "string_cache@0.9.0", "swc_ecma_visit@19.0.0", "swc_visit@2.0.1", "tendril@0.5.0"], "dependencies": []}, +{"package": "no_std_io2@0.9.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["bitstream-io@4.10.0"], "dependencies": ["memchr@2.8.1"]}, +{"package": "node-semver@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-runtime@0.5.1565"], "dependencies": ["bytecount@0.6.9", "miette@7.6.0", "nom@7.1.3", "serde@1.0.229", "thiserror@1.0.69"]}, +{"package": "nom@7.1.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["cexpr@0.6.0", "node-semver@2.2.0"], "dependencies": ["memchr@2.8.1", "minimal-lexical@0.2.1"]}, +{"package": "nom@8.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["av1-grain@0.2.5", "lettre@0.11.23", "lopdf@0.39.0", "nom_locate@5.0.0"], "dependencies": ["memchr@2.8.1"]}, +{"package": "nom_locate@5.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["lopdf@0.39.0"], "dependencies": ["bytecount@0.6.9", "memchr@2.8.1", "nom@8.0.0"]}, +{"package": "nonzero_ext@0.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["governor@0.10.4"], "dependencies": []}, +{"package": "noop_proc_macro@0.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rav1e@0.8.1"], "dependencies": []}, +{"package": "notify@6.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["crossbeam-channel", "default", "fsevent-sys", "macos_fsevent"], "parents": ["perry-ext-parcel-watcher@0.5.1565", "perry-runtime@0.5.1565", "perry@0.5.1565"], "dependencies": ["bitflags@2.12.1", "crossbeam-channel@0.5.15", "filetime@0.2.29", "fsevent-sys@4.1.0", "inotify@0.9.6", "kqueue@1.2.0", "libc@0.2.189", "log@0.4.34", "mio@0.8.11", "walkdir@2.5.0", "windows-sys@0.48.0"]}, +{"package": "nu-ansi-term@0.50.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["tracing-subscriber@0.3.23"], "dependencies": ["windows-sys@0.61.2"]}, +{"package": "num-bigint-dig@0.8.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["i128", "prime", "rand", "u64_digit", "zeroize"], "parents": ["rsa@0.9.10"], "dependencies": ["lazy_static@1.5.0", "libm@0.2.16", "num-integer@0.1.46", "num-iter@0.1.45", "num-traits@0.2.19", "rand@0.8.7", "smallvec@1.15.1", "zeroize@1.8.2"]}, +{"package": "num-bigint@0.4.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "serde", "std"], "parents": ["num-rational@0.4.2", "simple_asn1@0.6.4", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_codegen@21.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "swc_ecma_visit@19.0.0"], "dependencies": ["num-integer@0.1.46", "num-traits@0.2.19", "serde@1.0.229"]}, +{"package": "num-bigint@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["redis@1.6.0"], "dependencies": ["num-integer@0.1.46", "num-traits@0.2.19"]}, +{"package": "num-conv@0.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["time-macros@0.2.32", "time@0.3.55"], "dependencies": []}, +{"package": "num-derive@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rav1e@0.8.1", "tokio-cron-scheduler@0.15.1"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "num-integer@0.1.46", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["i128", "std"], "parents": ["gstreamer@0.25.3", "num-bigint-dig@0.8.6", "num-bigint@0.4.6", "num-bigint@0.5.1", "num-iter@0.1.45", "num-rational@0.4.2", "rsa@0.9.10"], "dependencies": ["num-traits@0.2.19"]}, +{"package": "num-iter@0.1.45", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["num-bigint-dig@0.8.6"], "dependencies": ["autocfg@1.5.1", "num-integer@0.1.46", "num-traits@0.2.19"]}, +{"package": "num-rational@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "num-bigint", "std"], "parents": ["av-scenechange@0.14.1", "av1-grain@0.2.5", "gstreamer@0.25.3"], "dependencies": ["num-bigint@0.4.6", "num-integer@0.1.46", "num-traits@0.2.19"]}, +{"package": "num-traits@0.2.19", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "i128", "libm", "std"], "parents": ["atoi@2.0.0", "av-scenechange@0.14.1", "chrono@0.4.45", "crypto-bigint@0.7.5", "fast_image_resize@6.1.0", "image@0.25.10", "module-lattice@0.2.3", "moxcms@0.8.1", "num-bigint-dig@0.8.6", "num-bigint@0.4.6", "num-bigint@0.5.1", "num-integer@0.1.46", "num-iter@0.1.45", "num-rational@0.4.2", "prefix-trie@0.8.4", "proptest@1.11.0", "rav1e@0.8.1", "rsa@0.9.10", "rust_decimal@1.43.0", "simple_asn1@0.6.4", "temporal_rs@0.2.6", "tokio-cron-scheduler@0.15.1", "v_frame@0.3.9"], "dependencies": ["autocfg@1.5.1", "libm@0.2.16"]}, +{"package": "num_cpus@1.17.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_utils@25.0.0"], "dependencies": ["hermit-abi@0.5.2", "libc@0.2.189"]}, +{"package": "objc2-app-kit@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["AppKitDefines", "AppKitErrors", "NSATSTypesetter", "NSAccessibility", "NSAccessibilityColor", "NSAccessibilityConstants", "NSAccessibilityCustomAction", "NSAccessibilityCustomRotor", "NSAccessibilityElement", "NSAccessibilityProtocols", "NSActionCell", "NSAdaptiveImageGlyph", "NSAffineTransform", "NSAlert", "NSAlignmentFeedbackFilter", "NSAnimation", "NSAnimationContext", "NSAppearance", "NSAppleScriptExtensions", "NSApplication", "NSApplicationScripting", "NSArrayController", "NSAttributedString", "NSBackgroundExtensionView", "NSBezierPath", "NSBitmapImageRep", "NSBox", "NSBrowser", "NSBrowserCell", "NSButton", "NSButtonCell", "NSButtonTouchBarItem", "NSCIImageRep", "NSCachedImageRep", "NSCandidateListTouchBarItem", "NSCell", "NSClickGestureRecognizer", "NSClipView", "NSCollectionView", "NSCollectionViewCompositionalLayout", "NSCollectionViewFlowLayout", "NSCollectionViewGridLayout", "NSCollectionViewLayout", "NSCollectionViewTransitionLayout", "NSColor", "NSColorList", "NSColorPanel", "NSColorPicker", "NSColorPickerTouchBarItem", "NSColorPicking", "NSColorSampler", "NSColorSpace", "NSColorWell", "NSComboBox", "NSComboBoxCell", "NSComboButton", "NSControl", "NSController", "NSCursor", "NSCustomImageRep", "NSCustomTouchBarItem", "NSDataAsset", "NSDatePicker", "NSDatePickerCell", "NSDictionaryController", "NSDiffableDataSource", "NSDirection", "NSDockTile", "NSDocument", "NSDocumentController", "NSDocumentScripting", "NSDragging", "NSDraggingItem", "NSDraggingSession", "NSDrawer", "NSEPSImageRep", "NSErrors", "NSEvent", "NSFilePromiseProvider", "NSFilePromiseReceiver", "NSFileWrapperExtensions", "NSFont", "NSFontAssetRequest", "NSFontCollection", "NSFontDescriptor", "NSFontManager", "NSFontPanel", "NSForm", "NSFormCell", "NSGestureRecognizer", "NSGlassEffectView", "NSGlyphGenerator", "NSGlyphInfo", "NSGradient", "NSGraphics", "NSGraphicsContext", "NSGridView", "NSGroupTouchBarItem", "NSHapticFeedback", "NSHelpManager", "NSImage", "NSImageCell", "NSImageRep", "NSImageView", "NSInputManager", "NSInputServer", "NSInterfaceStyle", "NSItemBadge", "NSItemProvider", "NSKeyValueBinding", "NSLayoutAnchor", "NSLayoutConstraint", "NSLayoutGuide", "NSLayoutManager", "NSLevelIndicator", "NSLevelIndicatorCell", "NSMagnificationGestureRecognizer", "NSMatrix", "NSMediaLibraryBrowserController", "NSMenu", "NSMenuItem", "NSMenuItemBadge", "NSMenuItemCell", "NSMenuToolbarItem", "NSMovie", "NSNib", "NSNibConnector", "NSNibControlConnector", "NSNibDeclarations", "NSNibLoading", "NSNibOutletConnector", "NSObjectController", "NSOpenGL", "NSOpenGLLayer", "NSOpenGLView", "NSOpenPanel", "NSOutlineView", "NSPDFImageRep", "NSPDFInfo", "NSPDFPanel", "NSPICTImageRep", "NSPageController", "NSPageLayout", "NSPanGestureRecognizer", "NSPanel", "NSParagraphStyle", "NSPasteboard", "NSPasteboardItem", "NSPathCell", "NSPathComponentCell", "NSPathControl", "NSPathControlItem", "NSPersistentDocument", "NSPickerTouchBarItem", "NSPopUpButton", "NSPopUpButtonCell", "NSPopover", "NSPopoverTouchBarItem", "NSPredicateEditor", "NSPredicateEditorRowTemplate", "NSPressGestureRecognizer", "NSPressureConfiguration", "NSPreviewRepresentingActivityItem", "NSPrintInfo", "NSPrintOperation", "NSPrintPanel", "NSPrinter", "NSProgressIndicator", "NSResponder", "NSRotationGestureRecognizer", "NSRuleEditor", "NSRulerMarker", "NSRulerView", "NSRunningApplication", "NSSavePanel", "NSScreen", "NSScrollView", "NSScroller", "NSScrubber", "NSScrubberItemView", "NSScrubberLayout", "NSSearchField", "NSSearchFieldCell", "NSSearchToolbarItem", "NSSecureTextField", "NSSegmentedCell", "NSSegmentedControl", "NSShadow", "NSSharingCollaborationModeRestriction", "NSSharingService", "NSSharingServicePickerToolbarItem", "NSSharingServicePickerTouchBarItem", "NSSlider", "NSSliderAccessory", "NSSliderCell", "NSSliderTouchBarItem", "NSSound", "NSSpeechRecognizer", "NSSpeechSynthesizer", "NSSpellChecker", "NSSpellProtocol", "NSSplitView", "NSSplitViewController", "NSSplitViewItem", "NSSplitViewItemAccessoryViewController", "NSStackView", "NSStatusBar", "NSStatusBarButton", "NSStatusItem", "NSStepper", "NSStepperCell", "NSStepperTouchBarItem", "NSStoryboard", "NSStoryboardSegue", "NSStringDrawing", "NSSwitch", "NSTabView", "NSTabViewController", "NSTabViewItem", "NSTableCellView", "NSTableColumn", "NSTableHeaderCell", "NSTableHeaderView", "NSTableRowView", "NSTableView", "NSTableViewDiffableDataSource", "NSTableViewRowAction", "NSText", "NSTextAlternatives", "NSTextAttachment", "NSTextAttachmentCell", "NSTextCheckingClient", "NSTextCheckingController", "NSTextContainer", "NSTextContent", "NSTextContentManager", "NSTextElement", "NSTextField", "NSTextFieldCell", "NSTextFinder", "NSTextInputClient", "NSTextInputContext", "NSTextInsertionIndicator", "NSTextLayoutFragment", "NSTextLayoutManager", "NSTextLineFragment", "NSTextList", "NSTextListElement", "NSTextRange", "NSTextSelection", "NSTextSelectionNavigation", "NSTextStorage", "NSTextStorageScripting", "NSTextTable", "NSTextView", "NSTextViewportLayoutController", "NSTintConfiguration", "NSTintProminence", "NSTitlebarAccessoryViewController", "NSTokenField", "NSTokenFieldCell", "NSToolbar", "NSToolbarItem", "NSToolbarItemGroup", "NSTouch", "NSTouchBar", "NSTouchBarItem", "NSTrackingArea", "NSTrackingSeparatorToolbarItem", "NSTreeController", "NSTreeNode", "NSTypesetter", "NSUserActivity", "NSUserDefaultsController", "NSUserInterfaceCompression", "NSUserInterfaceItemIdentification", "NSUserInterfaceItemSearching", "NSUserInterfaceLayout", "NSUserInterfaceValidation", "NSView", "NSViewController", "NSViewLayoutRegion", "NSVisualEffectView", "NSWindow", "NSWindowController", "NSWindowRestoration", "NSWindowScripting", "NSWindowTab", "NSWindowTabGroup", "NSWorkspace", "NSWritingToolsCoordinator", "NSWritingToolsCoordinatorAnimationParameters", "NSWritingToolsCoordinatorContext", "alloc", "bitflags", "block2", "default", "libc", "objc2-cloud-kit", "objc2-core-data", "objc2-core-foundation", "objc2-core-graphics", "objc2-core-image", "objc2-core-text", "objc2-core-video", "objc2-quartz-core", "std"], "parents": ["perry-ui-macos@0.5.1565"], "dependencies": ["bitflags@2.12.1", "block2@0.6.2", "libc@0.2.189", "objc2-cloud-kit@0.3.2", "objc2-core-data@0.3.2", "objc2-core-foundation@0.3.2", "objc2-core-graphics@0.3.2", "objc2-core-image@0.3.2", "objc2-core-text@0.3.2", "objc2-core-video@0.3.2", "objc2-foundation@0.3.2", "objc2-quartz-core@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-cloud-kit@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["CKContainer", "CKRecord", "CKShare", "CKShareMetadata", "bitflags"], "parents": ["objc2-app-kit@0.3.2", "objc2-ui-kit@0.3.2"], "dependencies": ["bitflags@2.12.1", "objc2-foundation@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-core-data@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["NSAttributeDescription", "NSEntityDescription", "NSFetchRequest", "NSManagedObjectContext", "NSManagedObjectModel", "NSPersistentStoreRequest", "NSPropertyDescription", "bitflags"], "parents": ["objc2-app-kit@0.3.2", "objc2-ui-kit@0.3.2"], "dependencies": ["bitflags@2.12.1", "objc2-foundation@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-core-foundation@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["CFArray", "CFAttributedString", "CFAvailability", "CFBag", "CFBinaryHeap", "CFBitVector", "CFBundle", "CFByteOrder", "CFCGTypes", "CFCalendar", "CFCharacterSet", "CFData", "CFDate", "CFDateFormatter", "CFDictionary", "CFError", "CFFileDescriptor", "CFFileSecurity", "CFLocale", "CFMachPort", "CFMessagePort", "CFNotificationCenter", "CFNumber", "CFNumberFormatter", "CFPlugIn", "CFPlugInCOM", "CFPreferences", "CFPropertyList", "CFRunLoop", "CFSet", "CFSocket", "CFStream", "CFString", "CFStringEncodingExt", "CFStringTokenizer", "CFTimeZone", "CFTree", "CFURL", "CFURLAccess", "CFURLEnumerator", "CFUUID", "CFUserNotification", "CFUtilities", "CFXMLNode", "CFXMLParser", "alloc", "bitflags", "block2", "default", "dispatch2", "libc", "objc2", "std"], "parents": ["objc2-app-kit@0.3.2", "objc2-core-graphics@0.3.2", "objc2-core-text@0.3.2", "objc2-core-video@0.3.2", "objc2-foundation@0.3.2", "objc2-io-surface@0.3.2", "objc2-quartz-core@0.3.2", "objc2-ui-kit@0.3.2", "perry-ui-ios@0.5.1565", "perry-ui-macos@0.5.1565", "perry-ui-tvos@0.5.1565", "perry-ui-visionos@0.5.1565"], "dependencies": ["bitflags@2.12.1", "block2@0.6.2", "dispatch2@0.3.1", "libc@0.2.189", "objc2@0.6.4"]}, +{"package": "objc2-core-graphics@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["CGColor", "CGColorSpace", "CGContext", "CGDirectDisplay", "CGEventTypes", "CGFont", "CGImage", "CGPath", "bitflags", "objc2"], "parents": ["objc2-app-kit@0.3.2", "objc2-core-text@0.3.2", "objc2-core-video@0.3.2", "objc2-ui-kit@0.3.2"], "dependencies": ["bitflags@2.12.1", "dispatch2@0.3.1", "objc2-core-foundation@0.3.2", "objc2-io-surface@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-core-image@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["CIColor", "CIContext", "CIFilter", "CIImage"], "parents": ["objc2-app-kit@0.3.2", "objc2-ui-kit@0.3.2"], "dependencies": ["objc2-foundation@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-core-location@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["CLRegion"], "parents": ["objc2-ui-kit@0.3.2"], "dependencies": ["objc2-foundation@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-core-text@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["CTFont", "CTFontCollection", "CTFontDescriptor", "CTGlyphInfo", "bitflags", "objc2"], "parents": ["objc2-app-kit@0.3.2", "objc2-ui-kit@0.3.2"], "dependencies": ["bitflags@2.12.1", "objc2-core-foundation@0.3.2", "objc2-core-graphics@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-core-video@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["CVBase", "bitflags", "objc2"], "parents": ["objc2-app-kit@0.3.2"], "dependencies": ["bitflags@2.12.1", "objc2-core-foundation@0.3.2", "objc2-core-graphics@0.3.2", "objc2-io-surface@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-encode@4.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "std"], "parents": ["objc2@0.6.4"], "dependencies": []}, +{"package": "objc2-foundation@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["FoundationErrors", "FoundationLegacySwiftCompatibility", "NSAffineTransform", "NSAppleEventDescriptor", "NSAppleEventManager", "NSAppleScript", "NSArchiver", "NSArray", "NSAttributedString", "NSAutoreleasePool", "NSBackgroundActivityScheduler", "NSBundle", "NSByteCountFormatter", "NSByteOrder", "NSCache", "NSCalendar", "NSCalendarDate", "NSCharacterSet", "NSClassDescription", "NSCoder", "NSComparisonPredicate", "NSCompoundPredicate", "NSConnection", "NSData", "NSDate", "NSDateComponentsFormatter", "NSDateFormatter", "NSDateInterval", "NSDateIntervalFormatter", "NSDebug", "NSDecimal", "NSDecimalNumber", "NSDictionary", "NSDistantObject", "NSDistributedLock", "NSDistributedNotificationCenter", "NSEnergyFormatter", "NSEnumerator", "NSError", "NSException", "NSExpression", "NSExtensionContext", "NSExtensionItem", "NSExtensionRequestHandling", "NSFileCoordinator", "NSFileHandle", "NSFileManager", "NSFilePresenter", "NSFileVersion", "NSFileWrapper", "NSFormatter", "NSGarbageCollector", "NSGeometry", "NSHFSFileTypes", "NSHTTPCookie", "NSHTTPCookieStorage", "NSHashTable", "NSHost", "NSISO8601DateFormatter", "NSIndexPath", "NSIndexSet", "NSInflectionRule", "NSInvocation", "NSItemProvider", "NSJSONSerialization", "NSKeyValueCoding", "NSKeyValueObserving", "NSKeyValueSharedObservers", "NSKeyedArchiver", "NSLengthFormatter", "NSLinguisticTagger", "NSListFormatter", "NSLocale", "NSLocalizedNumberFormatRule", "NSLock", "NSMapTable", "NSMassFormatter", "NSMeasurement", "NSMeasurementFormatter", "NSMetadata", "NSMetadataAttributes", "NSMethodSignature", "NSMorphology", "NSNetServices", "NSNotification", "NSNotificationQueue", "NSNull", "NSNumberFormatter", "NSObjCRuntime", "NSObject", "NSObjectScripting", "NSOperation", "NSOrderedCollectionChange", "NSOrderedCollectionDifference", "NSOrderedSet", "NSOrthography", "NSPathUtilities", "NSPersonNameComponents", "NSPersonNameComponentsFormatter", "NSPointerArray", "NSPointerFunctions", "NSPort", "NSPortCoder", "NSPortMessage", "NSPortNameServer", "NSPredicate", "NSProcessInfo", "NSProgress", "NSPropertyList", "NSProtocolChecker", "NSProxy", "NSRange", "NSRegularExpression", "NSRelativeDateTimeFormatter", "NSRunLoop", "NSScanner", "NSScriptClassDescription", "NSScriptCoercionHandler", "NSScriptCommand", "NSScriptCommandDescription", "NSScriptExecutionContext", "NSScriptKeyValueCoding", "NSScriptObjectSpecifiers", "NSScriptStandardSuiteCommands", "NSScriptSuiteRegistry", "NSScriptWhoseTests", "NSSet", "NSSortDescriptor", "NSSpellServer", "NSStream", "NSString", "NSTask", "NSTermOfAddress", "NSTextCheckingResult", "NSThread", "NSTimeZone", "NSTimer", "NSURL", "NSURLAuthenticationChallenge", "NSURLCache", "NSURLConnection", "NSURLCredential", "NSURLCredentialStorage", "NSURLDownload", "NSURLError", "NSURLHandle", "NSURLProtectionSpace", "NSURLProtocol", "NSURLRequest", "NSURLResponse", "NSURLSession", "NSUUID", "NSUbiquitousKeyValueStore", "NSUndoManager", "NSUnit", "NSUserActivity", "NSUserDefaults", "NSUserNotification", "NSUserScriptTask", "NSValue", "NSValueTransformer", "NSXMLDTD", "NSXMLDTDNode", "NSXMLDocument", "NSXMLElement", "NSXMLNode", "NSXMLNodeOptions", "NSXMLParser", "NSXPCConnection", "NSZone", "alloc", "bitflags", "block2", "default", "libc", "objc2-core-foundation", "std"], "parents": ["objc2-app-kit@0.3.2", "objc2-cloud-kit@0.3.2", "objc2-core-data@0.3.2", "objc2-core-image@0.3.2", "objc2-core-location@0.3.2", "objc2-quartz-core@0.3.2", "objc2-ui-kit@0.3.2", "objc2-user-notifications@0.3.2", "perry-ui-ios@0.5.1565", "perry-ui-macos@0.5.1565", "perry-ui-tvos@0.5.1565", "perry-ui-visionos@0.5.1565", "perry-ui-watchos@0.5.1565"], "dependencies": ["bitflags@2.12.1", "block2@0.6.2", "libc@0.2.189", "objc2-core-foundation@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-io-surface@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["IOSurfaceRef", "bitflags", "objc2"], "parents": ["objc2-core-graphics@0.3.2", "objc2-core-video@0.3.2"], "dependencies": ["bitflags@2.12.1", "objc2-core-foundation@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-quartz-core@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["CADisplayLink", "CAFrameRateRange", "CALayer", "CAMediaTiming", "CAMediaTimingFunction", "CAOpenGLLayer", "CATransform3D", "bitflags", "objc2-core-foundation"], "parents": ["objc2-app-kit@0.3.2", "objc2-ui-kit@0.3.2"], "dependencies": ["bitflags@2.12.1", "objc2-core-foundation@0.3.2", "objc2-foundation@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-ui-kit@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["DocumentManager", "NSAdaptiveImageGlyph", "NSAttributedString", "NSDataAsset", "NSDiffableDataSourceSectionSnapshot", "NSFileProviderExtension", "NSIndexPath_UIKitAdditions", "NSItemProvider_UIKitAdditions", "NSLayoutAnchor", "NSLayoutConstraint", "NSLayoutManager", "NSParagraphStyle", "NSShadow", "NSStringDrawing", "NSText", "NSTextAttachment", "NSTextContainer", "NSTextContentManager", "NSTextElement", "NSTextLayoutFragment", "NSTextLayoutManager", "NSTextLineFragment", "NSTextList", "NSTextListElement", "NSTextRange", "NSTextSelection", "NSTextSelectionNavigation", "NSTextStorage", "NSTextViewportLayoutController", "NSToolbar_UIKitAdditions", "NSTouchBar_UIKitAdditions", "NSUserActivity_NSItemProvider", "PrintKitUI", "ShareSheet", "UIAccelerometer", "UIAccessibility", "UIAccessibilityAdditions", "UIAccessibilityConstants", "UIAccessibilityContainer", "UIAccessibilityContentSizeCategoryImageAdjusting", "UIAccessibilityCustomAction", "UIAccessibilityCustomRotor", "UIAccessibilityElement", "UIAccessibilityIdentification", "UIAccessibilityLocationDescriptor", "UIAccessibilityZoom", "UIAction", "UIActionSheet", "UIActivity", "UIActivityCollaborationModeRestriction", "UIActivityIndicatorView", "UIActivityItemProvider", "UIActivityItemsConfiguration", "UIActivityItemsConfigurationReading", "UIActivityItemsConfigurationReading_ShareSheet", "UIActivityViewController", "UIAlert", "UIAlertController", "UIAlertView", "UIAppearance", "UIApplication", "UIApplicationShortcutItem", "UIAttachmentBehavior", "UIBackgroundConfiguration", "UIBackgroundExtensionView", "UIBandSelectionInteraction", "UIBarAppearance", "UIBarButtonItem", "UIBarButtonItemAppearance", "UIBarButtonItemBadge", "UIBarButtonItemGroup", "UIBarCommon", "UIBarItem", "UIBehavioralStyle", "UIBezierPath", "UIBlurEffect", "UIButton", "UIButtonConfiguration", "UICalendarSelection", "UICalendarSelectionMultiDate", "UICalendarSelectionSingleDate", "UICalendarSelectionWeekOfYear", "UICalendarView", "UICalendarViewDecoration", "UICanvasFeedbackGenerator", "UICellAccessory", "UICellConfigurationState", "UICloudSharingController", "UICollectionLayoutList", "UICollectionView", "UICollectionViewCell", "UICollectionViewCompositionalLayout", "UICollectionViewController", "UICollectionViewFlowLayout", "UICollectionViewItemRegistration", "UICollectionViewLayout", "UICollectionViewListCell", "UICollectionViewTransitionLayout", "UICollectionViewUpdateItem", "UICollisionBehavior", "UIColor", "UIColorPickerViewController", "UIColorWell", "UICommand", "UIConfigurationColorTransformer", "UIConfigurationState", "UIContentConfiguration", "UIContentSizeCategory", "UIContentSizeCategoryAdjusting", "UIContentUnavailableButtonProperties", "UIContentUnavailableConfiguration", "UIContentUnavailableConfigurationState", "UIContentUnavailableImageProperties", "UIContentUnavailableTextProperties", "UIContentUnavailableView", "UIContextMenuConfiguration", "UIContextMenuInteraction", "UIContextMenuSystem", "UIContextualAction", "UIControl", "UIConversationContext", "UIConversationEntry", "UICornerConfiguration", "UICornerRadius", "UIDataDetectors", "UIDataSourceTranslating", "UIDatePicker", "UIDeferredMenuElement", "UIDevice", "UIDiffableDataSource", "UIDocument", "UIDocumentBrowserAction", "UIDocumentBrowserViewController", "UIDocumentInteractionController", "UIDocumentMenuViewController", "UIDocumentPickerExtensionViewController", "UIDocumentPickerViewController", "UIDocumentProperties", "UIDocumentViewController", "UIDocumentViewControllerLaunchOptions", "UIDragInteraction", "UIDragItem", "UIDragPreview", "UIDragPreviewParameters", "UIDragSession", "UIDropInteraction", "UIDynamicAnimator", "UIDynamicBehavior", "UIDynamicItemBehavior", "UIEditMenuInteraction", "UIEvent", "UIEventAttribution", "UIEventAttributionView", "UIFeedbackGenerator", "UIFieldBehavior", "UIFindInteraction", "UIFindSession", "UIFocus", "UIFocusAnimationCoordinator", "UIFocusDebugger", "UIFocusDefines", "UIFocusEffect", "UIFocusGuide", "UIFocusMovementHint", "UIFocusSystem", "UIFocusSystem_UIKitAdditions", "UIFocusUpdateContext_UIKitAdditions", "UIFont", "UIFontDescriptor", "UIFontMetrics", "UIFontPickerViewController", "UIFontPickerViewControllerConfiguration", "UIFoundation", "UIGeometry", "UIGestureRecognizer", "UIGestureRecognizerSubclass", "UIGlassEffect", "UIGraphics", "UIGraphicsImageRenderer", "UIGraphicsPDFRenderer", "UIGraphicsRenderer", "UIGraphicsRendererSubclass", "UIGravityBehavior", "UIGuidedAccess", "UIGuidedAccessRestrictions", "UIHoverEffect", "UIHoverEffectLayer", "UIHoverGestureRecognizer", "UIHoverStyle", "UIImage", "UIImageAsset", "UIImageConfiguration", "UIImagePickerController", "UIImageReader", "UIImageSymbolConfiguration", "UIImageView", "UIImpactFeedbackGenerator", "UIIndirectScribbleInteraction", "UIInputSuggestion", "UIInputView", "UIInputViewController", "UIInteraction", "UIInterface", "UIKey", "UIKeyCommand", "UIKeyConstants", "UIKeyboardLayoutGuide", "UIKitCore", "UIKitDefines", "UILabel", "UILargeContentViewer", "UILayoutGuide", "UILetterformAwareAdjusting", "UILexicon", "UIListContentConfiguration", "UIListContentImageProperties", "UIListContentTextProperties", "UIListSeparatorConfiguration", "UILocalNotification", "UILocalizedIndexedCollation", "UILongPressGestureRecognizer", "UIMailConversationContext", "UIMailConversationEntry", "UIMainMenuSystem", "UIManagedDocument", "UIMenu", "UIMenuBuilder", "UIMenuController", "UIMenuDisplayPreferences", "UIMenuElement", "UIMenuLeaf", "UIMenuSystem", "UIMessageConversationContext", "UIMessageConversationEntry", "UIMotionEffect", "UINavigationBar", "UINavigationBarAppearance", "UINavigationController", "UINavigationItem", "UINib", "UINibDeclarations", "UINibLoading", "UINotificationFeedbackGenerator", "UIOpenURLContext", "UIOrientation", "UIPageControl", "UIPageControlProgress", "UIPageViewController", "UIPanGestureRecognizer", "UIPasteConfiguration", "UIPasteConfigurationSupporting", "UIPasteControl", "UIPasteboard", "UIPencilInteraction", "UIPickerView", "UIPinchGestureRecognizer", "UIPointerAccessory", "UIPointerInteraction", "UIPointerLockState", "UIPointerRegion", "UIPointerStyle", "UIPopoverBackgroundView", "UIPopoverController", "UIPopoverPresentationController", "UIPopoverPresentationControllerSourceItem", "UIPopoverSupport", "UIPresentationController", "UIPress", "UIPressesEvent", "UIPreviewInteraction", "UIPreviewParameters", "UIPrintError", "UIPrintFormatter", "UIPrintInfo", "UIPrintInteractionController", "UIPrintPageRenderer", "UIPrintPaper", "UIPrintServiceExtension", "UIPrinter", "UIPrinterPickerController", "UIProgressView", "UIPushBehavior", "UIReferenceLibraryViewController", "UIRefreshControl", "UIRegion", "UIResponder", "UIResponder_UIActivityItemsConfiguration", "UIRotationGestureRecognizer", "UIScene", "UISceneActivationConditions", "UISceneConfiguration", "UISceneDefinitions", "UISceneDestructionCondition", "UISceneEnhancedStateRestoration", "UISceneOptions", "UISceneSession", "UISceneSessionActivationRequest", "UISceneSizeRestrictions", "UISceneSystemProtectionManager", "UISceneWindowingBehaviors", "UISceneWindowingControlStyle", "UIScene_AVAudioSession", "UIScreen", "UIScreenEdgePanGestureRecognizer", "UIScreenMode", "UIScreenshotService", "UIScribbleInteraction", "UIScrollEdgeElementContainerInteraction", "UIScrollView", "UISearchBar", "UISearchContainerViewController", "UISearchController", "UISearchDisplayController", "UISearchSuggestion", "UISearchTab", "UISearchTextField", "UISegmentedControl", "UISelectionFeedbackGenerator", "UIShadowProperties", "UIShape", "UISheetPresentationController", "UISlider", "UISliderTrackConfiguration", "UISmartReplySuggestion", "UISnapBehavior", "UISplitViewController", "UISplitViewControllerLayoutEnvironment", "UISpringLoadedInteraction", "UISpringLoadedInteractionSupporting", "UIStackView", "UIStandardTextCursorView", "UIStateRestoration", "UIStatusBarManager", "UIStepper", "UIStoryboard", "UIStoryboardPopoverSegue", "UIStoryboardSegue", "UIStringDrawing", "UISwipeActionsConfiguration", "UISwipeGestureRecognizer", "UISwitch", "UISymbolContentTransition", "UISymbolEffectCompletion", "UITab", "UITabAccessory", "UITabBar", "UITabBarAppearance", "UITabBarController", "UITabBarControllerSidebar", "UITabBarItem", "UITabGroup", "UITabSidebarItem", "UITableView", "UITableViewCell", "UITableViewController", "UITableViewHeaderFooterView", "UITapGestureRecognizer", "UITargetedDragPreview", "UITargetedPreview", "UITextChecker", "UITextCursorDropPositionAnimator", "UITextCursorView", "UITextDragPreviewRenderer", "UITextDragURLPreviews", "UITextDragging", "UITextDropProposal", "UITextDropping", "UITextField", "UITextFormattingCoordinator", "UITextFormattingViewController", "UITextFormattingViewControllerChangeValue", "UITextFormattingViewControllerComponent", "UITextFormattingViewControllerConfiguration", "UITextFormattingViewControllerFormattingDescriptor", "UITextFormattingViewControllerFormattingStyle", "UITextInput", "UITextInputContext", "UITextInputTraits", "UITextInteraction", "UITextItem", "UITextItemInteraction", "UITextLoupeSession", "UITextPasteConfigurationSupporting", "UITextPasteDelegate", "UITextSearching", "UITextSelectionDisplayInteraction", "UITextSelectionHandleView", "UITextSelectionHighlightView", "UITextView", "UITimingCurveProvider", "UITimingParameters", "UIToolTipInteraction", "UIToolbar", "UIToolbarAppearance", "UITouch", "UITrackingLayoutGuide", "UITrait", "UITraitCollection", "UITraitListEnvironment", "UIUpdateActionPhase", "UIUpdateInfo", "UIUpdateLink", "UIUserActivity", "UIUserNotificationSettings", "UIVibrancyEffect", "UIVideoEditorController", "UIView", "UIViewAnimating", "UIViewConfigurationState", "UIViewController", "UIViewControllerTransition", "UIViewControllerTransitionCoordinator", "UIViewControllerTransitioning", "UIViewLayoutRegion", "UIViewPropertyAnimator", "UIVisualEffect", "UIVisualEffectView", "UIWebView", "UIWindow", "UIWindowScene", "UIWindowSceneActivationAction", "UIWindowSceneActivationConfiguration", "UIWindowSceneActivationInteraction", "UIWindowSceneActivationRequestOptions", "UIWindowSceneDragInteraction", "UIWindowSceneGeometry", "UIWindowSceneGeometryPreferences", "UIWindowSceneGeometryPreferencesIOS", "UIWindowSceneGeometryPreferencesMac", "UIWindowSceneGeometryPreferencesVision", "UIWindowScenePlacement", "UIWindowSceneProminentPlacement", "UIWindowScenePushPlacement", "UIWindowSceneReplacePlacement", "UIWindowSceneStandardPlacement", "UIWritingToolsCoordinator", "UIWritingToolsCoordinatorAnimationParameters", "UIWritingToolsCoordinatorContext", "UIZoomTransitionOptions", "UNNotificationResponse_UIKitAdditions", "alloc", "bitflags", "block2", "default", "objc2-cloud-kit", "objc2-core-data", "objc2-core-foundation", "objc2-core-graphics", "objc2-core-image", "objc2-core-location", "objc2-core-text", "objc2-quartz-core", "objc2-user-notifications", "std"], "parents": ["perry-ui-ios@0.5.1565", "perry-ui-tvos@0.5.1565", "perry-ui-visionos@0.5.1565"], "dependencies": ["bitflags@2.12.1", "block2@0.6.2", "objc2-cloud-kit@0.3.2", "objc2-core-data@0.3.2", "objc2-core-foundation@0.3.2", "objc2-core-graphics@0.3.2", "objc2-core-image@0.3.2", "objc2-core-location@0.3.2", "objc2-core-text@0.3.2", "objc2-foundation@0.3.2", "objc2-quartz-core@0.3.2", "objc2-user-notifications@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2-user-notifications@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["UNNotificationResponse"], "parents": ["objc2-ui-kit@0.3.2"], "dependencies": ["objc2-foundation@0.3.2", "objc2@0.6.4"]}, +{"package": "objc2@0.6.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "std"], "parents": ["block2@0.6.2", "dispatch2@0.3.1", "objc2-app-kit@0.3.2", "objc2-cloud-kit@0.3.2", "objc2-core-data@0.3.2", "objc2-core-foundation@0.3.2", "objc2-core-graphics@0.3.2", "objc2-core-image@0.3.2", "objc2-core-location@0.3.2", "objc2-core-text@0.3.2", "objc2-core-video@0.3.2", "objc2-foundation@0.3.2", "objc2-io-surface@0.3.2", "objc2-quartz-core@0.3.2", "objc2-ui-kit@0.3.2", "objc2-user-notifications@0.3.2", "perry-ui-ios@0.5.1565", "perry-ui-macos@0.5.1565", "perry-ui-tvos@0.5.1565", "perry-ui-visionos@0.5.1565", "perry-ui-watchos@0.5.1565"], "dependencies": ["objc2-encode@4.1.0"]}, +{"package": "object@0.37.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["archive", "coff", "elf", "macho", "pe", "read", "read_core", "std", "unaligned", "xcoff"], "parents": ["ar_archive_writer@0.5.1", "perry@0.5.1565"], "dependencies": ["memchr@2.8.1"]}, +{"package": "once_cell@1.21.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "critical-section", "default", "portable-atomic", "race", "std"], "parents": ["ahash@0.8.12", "borsh-derive@1.6.1", "console@0.15.11", "const-random-macro@0.1.16", "cron@0.17.0", "dashmap@5.5.3", "dashmap@6.2.1", "hickory-proto@0.26.1", "hickory-resolver@0.26.1", "hstr@3.0.6", "js-sys@0.3.99", "mongocrypt@0.4.0", "par-core@2.0.0", "perry-container-compose@0.5.1565", "perry-ffi@0.5.1565", "perry-stdlib@0.5.1565", "quanta@0.12.6", "quinn-udp@0.5.14", "rustls@0.23.43", "swc_atoms@9.0.3", "swc_bundler@37.0.0", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_codegen@21.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_utils@25.0.0", "tempfile@3.27.0", "tracing-core@0.1.36", "tracing-log@0.2.0", "tracing-subscriber@0.3.23", "wasm-bindgen@0.2.122"], "dependencies": ["critical-section@1.2.0", "portable-atomic@1.13.1"]}, +{"package": "once_cell_polyfill@1.70.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["anstyle-wincon@3.0.11"], "dependencies": []}, +{"package": "opaque-debug@0.3.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ghash@0.5.1", "poly1305@0.8.0", "polyval@0.6.2"], "dependencies": []}, +{"package": "openssl-probe@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rustls-native-certs@0.8.4"], "dependencies": []}, +{"package": "option-ext@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["dirs-sys@0.5.0"], "dependencies": []}, +{"package": "option-operations@0.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["gstreamer@0.25.3"], "dependencies": ["pastey@0.2.3"]}, +{"package": "ordered-stream@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zbus@5.16.0"], "dependencies": ["futures-core@0.3.34", "pin-project-lite@0.2.17"]}, +{"package": "ouroboros@0.17.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["allsorts-azul@0.16.5"], "dependencies": ["aliasable@0.1.3", "ouroboros_macro@0.17.2", "static_assertions@1.1.0"]}, +{"package": "ouroboros_macro@0.17.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["ouroboros@0.17.2"], "dependencies": ["heck@0.4.1", "proc-macro-error@1.0.4", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "outref@0.5.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["base64-simd@0.8.0"], "dependencies": []}, +{"package": "p12@0.6.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ext-http@0.5.1565"], "dependencies": ["cbc@0.1.2", "cipher@0.4.4", "des@0.8.1", "getrandom@0.2.17", "hmac@0.12.1", "lazy_static@1.5.0", "rc2@0.8.1", "sha1@0.10.6", "yasna@0.5.2"]}, +{"package": "p256@0.13.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "arithmetic", "default", "digest", "ecdh", "ecdsa", "ecdsa-core", "pem", "pkcs8", "sha2", "sha256", "std"], "parents": ["jsonwebtoken@11.0.0", "perry-stdlib@0.5.1565"], "dependencies": ["ecdsa@0.16.9", "elliptic-curve@0.13.8", "primeorder@0.13.6", "sha2@0.10.9"]}, +{"package": "p384@0.13.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "arithmetic", "default", "digest", "ecdh", "ecdsa", "ecdsa-core", "pem", "pkcs8", "sha2", "sha384", "std"], "parents": ["jsonwebtoken@11.0.0", "perry-stdlib@0.5.1565"], "dependencies": ["ecdsa@0.16.9", "elliptic-curve@0.13.8", "primeorder@0.13.6", "sha2@0.10.9"]}, +{"package": "p521@0.13.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["arithmetic", "digest", "ecdh", "ecdsa", "ecdsa-core", "pem", "pkcs8", "sha512"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["base16ct@0.2.0", "ecdsa@0.16.9", "elliptic-curve@0.13.8", "primeorder@0.13.6", "sha2@0.10.9"]}, +{"package": "pango-sys@0.20.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v1_42", "v1_44", "v1_46", "v1_48", "v1_50"], "parents": ["gdk4-sys@0.9.6", "gsk4-sys@0.9.6", "gtk4-sys@0.9.6", "pango@0.20.12"], "dependencies": ["glib-sys@0.20.10", "gobject-sys@0.20.10", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "pango@0.20.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v1_42", "v1_44", "v1_46", "v1_48", "v1_50"], "parents": ["gdk4@0.9.6", "gsk4@0.9.6", "gtk4@0.9.7"], "dependencies": ["gio@0.20.12", "glib@0.20.12", "libc@0.2.189", "pango-sys@0.20.10"]}, +{"package": "par-core@2.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_utils@25.0.0"], "dependencies": ["once_cell@1.21.4"]}, +{"package": "parking@2.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["async-io@2.6.0", "event-listener@5.4.1", "futures-lite@2.6.1"], "dependencies": []}, +{"package": "parking_lot@0.12.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["futures-intrusive@0.5.0", "governor@0.10.4", "hickory-resolver@0.26.1", "moka@0.12.15", "string_cache@0.9.0", "tokio@1.53.1"], "dependencies": ["lock_api@0.4.14", "parking_lot_core@0.9.12"]}, +{"package": "parking_lot_core@0.9.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["dashmap@5.5.3", "dashmap@6.2.1", "parking_lot@0.12.5"], "dependencies": ["cfg-if@1.0.4", "libc@0.2.189", "redox_syscall@0.5.18", "smallvec@1.15.1", "windows-link@0.2.1"]}, +{"package": "password-hash@0.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "rand_core", "std"], "parents": ["argon2@0.5.3", "scrypt@0.11.0"], "dependencies": ["base64ct@1.8.3", "rand_core@0.6.4", "subtle@2.6.1"]}, +{"package": "paste@1.0.15", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rav1e@0.8.1"], "dependencies": []}, +{"package": "pastey@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["av-scenechange@0.14.1"], "dependencies": []}, +{"package": "pastey@0.2.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gstreamer@0.25.3", "ksni@0.3.6", "option-operations@0.6.1"], "dependencies": []}, +{"package": "pathdiff@0.2.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_loader@18.0.0"], "dependencies": []}, +{"package": "pathfinder_geometry@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["allsorts-azul@0.16.5"], "dependencies": ["log@0.4.34", "pathfinder_simd@0.5.6"]}, +{"package": "pathfinder_simd@0.5.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["pathfinder_geometry@0.5.1"], "dependencies": ["rustc_version@0.4.1"]}, +{"package": "pbkdf2@0.12.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "hmac"], "parents": ["pkcs5@0.7.1", "scrypt@0.11.0"], "dependencies": ["digest@0.10.7", "hmac@0.12.1"]}, +{"package": "pbkdf2@0.13.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "hmac"], "parents": ["mongodb@3.8.2", "perry-stdlib@0.5.1565", "zip@8.6.0"], "dependencies": ["digest@0.11.3", "hmac@0.13.0"]}, +{"package": "pem-rfc7468@0.7.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["der@0.7.10", "elliptic-curve@0.13.8"], "dependencies": ["base64ct@1.8.3"]}, +{"package": "pem-rfc7468@1.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc"], "parents": ["der@0.8.1"], "dependencies": ["base64ct@1.8.3"]}, +{"package": "pem@3.0.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["jsonwebtoken@11.0.0"], "dependencies": ["base64@0.22.1", "serde_core@1.0.229"]}, +{"package": "pem@4.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["perry-ext-node-forge@0.5.1565"], "dependencies": ["base64@0.23.1", "serde_core@1.0.229"]}, +{"package": "percent-encoding@2.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["form_urlencoded@1.2.2", "hyper-util@0.1.20", "lettre@0.11.23", "mongodb@3.8.2", "redis@1.6.0", "reqwest@0.12.28", "sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-sqlite@0.9.0", "url@2.5.8"], "dependencies": []}, +{"package": "perex@0.1.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-perex@0.5.1565", "perry-runtime@0.5.1565"], "dependencies": []}, +{"package": "petgraph@0.7.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "graphmap", "matrix_graph", "stable_graph"], "parents": ["swc_bundler@37.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_graph_analyzer@14.0.2"], "dependencies": ["fixedbitset@0.5.7", "indexmap@2.14.1"]}, +{"package": "phf@0.11.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "macros", "phf_macros", "std"], "parents": ["cron@0.17.0", "swc_ecma_ast@19.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "swc_ecma_transforms_base@32.0.0"], "dependencies": ["phf_macros@0.11.3", "phf_shared@0.11.3"]}, +{"package": "phf@0.12.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["chrono-tz@0.10.4"], "dependencies": ["phf_shared@0.12.1"]}, +{"package": "phf@0.13.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "macros", "phf_macros", "std"], "parents": ["cssparser@0.37.0", "selectors@0.38.0", "web_atoms@0.2.4"], "dependencies": ["phf_macros@0.13.1", "phf_shared@0.13.1", "serde@1.0.229"]}, +{"package": "phf_codegen@0.13.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["selectors@0.38.0", "web_atoms@0.2.4"], "dependencies": ["phf_generator@0.13.1", "phf_shared@0.13.1"]}, +{"package": "phf_generator@0.11.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["phf_macros@0.11.3"], "dependencies": ["phf_shared@0.11.3", "rand@0.8.7"]}, +{"package": "phf_generator@0.13.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["phf_codegen@0.13.1", "phf_macros@0.13.1", "string_cache_codegen@0.6.1"], "dependencies": ["fastrand@2.4.1", "phf_shared@0.13.1"]}, +{"package": "phf_macros@0.11.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["phf@0.11.3"], "dependencies": ["phf_generator@0.11.3", "phf_shared@0.11.3", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "phf_macros@0.13.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["phf@0.13.1"], "dependencies": ["phf_generator@0.13.1", "phf_shared@0.13.1", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "phf_shared@0.11.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["phf@0.11.3", "phf_generator@0.11.3", "phf_macros@0.11.3"], "dependencies": ["siphasher@1.0.3"]}, +{"package": "phf_shared@0.12.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["phf@0.12.1"], "dependencies": ["siphasher@1.0.3"]}, +{"package": "phf_shared@0.13.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["phf@0.13.1", "phf_codegen@0.13.1", "phf_generator@0.13.1", "phf_macros@0.13.1", "string_cache@0.9.0", "string_cache_codegen@0.6.1"], "dependencies": ["siphasher@1.0.3"]}, +{"package": "pin-project-lite@0.2.17", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["async-broadcast@0.7.2", "async-channel@2.5.0", "async-executor@1.14.0", "async-lock@3.4.2", "combine@4.6.7", "event-listener-strategy@0.5.4", "event-listener@5.4.1", "futures-lite@2.6.1", "futures-util@0.3.34", "gio@0.20.12", "gstreamer@0.25.3", "http-body-util@0.1.5", "hyper-util@0.1.20", "hyper@1.11.1", "ordered-stream@0.2.0", "polling@3.11.0", "quinn@0.11.9", "redis@1.6.0", "reqwest@0.12.28", "tokio-stream@0.1.18", "tokio-util@0.7.18", "tokio@1.53.1", "tower-http@0.6.11", "tower@0.5.3", "tracing@0.1.44"], "dependencies": []}, +{"package": "piper@0.2.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "futures-io", "std"], "parents": ["blocking@1.6.2"], "dependencies": ["atomic-waker@1.1.2", "fastrand@2.4.1", "futures-io@0.3.34"]}, +{"package": "pkcs1@0.7.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "pem", "pkcs8", "std", "zeroize"], "parents": ["rsa@0.9.10"], "dependencies": ["der@0.7.10", "pkcs8@0.10.2", "spki@0.7.3"]}, +{"package": "pkcs1@0.8.0-rc.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "pem", "std", "zeroize"], "parents": ["rsa@0.10.0-rc.18"], "dependencies": ["der@0.8.1", "spki@0.8.0"]}, +{"package": "pkcs5@0.7.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "pbes2"], "parents": ["perry-ext-http@0.5.1565", "pkcs8@0.10.2"], "dependencies": ["aes@0.8.4", "cbc@0.1.2", "der@0.7.10", "pbkdf2@0.12.2", "scrypt@0.11.0", "sha2@0.10.9", "spki@0.7.3"]}, +{"package": "pkcs8@0.10.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "encryption", "pem", "pkcs5", "rand_core", "std"], "parents": ["ed25519@2.2.3", "elliptic-curve@0.13.8", "pkcs1@0.7.5", "rsa@0.9.10", "sec1@0.7.3"], "dependencies": ["der@0.7.10", "pkcs5@0.7.1", "rand_core@0.6.4", "spki@0.7.3"]}, +{"package": "pkcs8@0.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "pem", "std"], "parents": ["ed448@0.5.0", "elliptic-curve@0.14.0", "ml-kem@0.3.2", "rsa@0.10.0-rc.18"], "dependencies": ["der@0.8.1", "spki@0.8.0"]}, +{"package": "pkg-config@0.3.33", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["gdk4-sys@0.9.6", "graphene-sys@0.20.10", "libsqlite3-sys@0.37.0", "system-deps@7.0.8", "zstd-sys@2.0.16+zstd.1.5.7"], "dependencies": []}, +{"package": "png@0.18.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["image@0.25.10", "perry-ui-windows@0.5.1565"], "dependencies": ["bitflags@2.12.1", "crc32fast@1.5.0", "fdeflate@0.3.7", "flate2@1.1.10", "miniz_oxide@0.8.9"]}, +{"package": "polling@3.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["async-io@2.6.0"], "dependencies": ["cfg-if@1.0.4", "concurrent-queue@2.5.0", "hermit-abi@0.5.2", "pin-project-lite@0.2.17", "rustix@1.1.4", "windows-sys@0.61.2"]}, +{"package": "poly1305@0.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["chacha20poly1305@0.10.1"], "dependencies": ["cpufeatures@0.2.17", "opaque-debug@0.3.1", "universal-hash@0.5.1"]}, +{"package": "polyval@0.6.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ghash@0.5.1"], "dependencies": ["cfg-if@1.0.4", "cpufeatures@0.2.17", "opaque-debug@0.3.1", "universal-hash@0.5.1"]}, +{"package": "polyval@0.7.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["hazmat"], "parents": ["ghash@0.6.0"], "dependencies": ["cpubits@0.1.1", "cpufeatures@0.3.0", "universal-hash@0.6.1"]}, +{"package": "portable-atomic@1.13.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "fallback", "require-cas"], "parents": ["governor@0.10.4", "indicatif@0.18.6", "moka@0.12.15", "once_cell@1.21.4"], "dependencies": []}, +{"package": "potential_utf@0.1.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "writeable", "zerovec"], "parents": ["icu_collections@2.2.0", "icu_datetime@2.3.0", "icu_locale@2.2.0", "icu_locale_fallback@2.3.0"], "dependencies": ["serde_core@1.0.229", "writeable@0.6.4", "zerovec@0.11.8"]}, +{"package": "powerfmt@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["time@0.3.55"], "dependencies": []}, +{"package": "ppmd-rust@1.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["zip@8.6.0"], "dependencies": []}, +{"package": "ppv-lite86@0.2.21", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["simd", "std"], "parents": ["rand_chacha@0.3.1", "rand_chacha@0.9.0"], "dependencies": ["zerocopy@0.8.50"]}, +{"package": "precomputed-hash@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["scraper@0.27.0", "selectors@0.38.0", "string_cache@0.9.0"], "dependencies": []}, +{"package": "prefix-trie@0.8.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "ipnet"], "parents": ["hickory-proto@0.26.1"], "dependencies": ["either@1.16.0", "ipnet@2.12.0", "num-traits@0.2.19"]}, +{"package": "prettyplease@0.2.37", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wit-bindgen-rust-macro@0.51.0", "wit-bindgen-rust@0.51.0"], "dependencies": ["proc-macro2@1.0.106", "syn@2.0.117"]}, +{"package": "primeorder@0.13.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["p256@0.13.2", "p384@0.13.1", "p521@0.13.3"], "dependencies": ["elliptic-curve@0.13.8"]}, +{"package": "printpdf@0.10.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ext-pdf@0.5.1565"], "dependencies": ["allsorts-azul@0.16.5", "base64@0.22.1", "flate2@1.1.10", "getrandom@0.3.4", "lopdf@0.39.0", "serde@1.0.229", "serde_derive@1.0.229", "serde_json@1.0.151", "time@0.3.55", "wasm-bindgen-futures@0.4.72", "wasm-bindgen@0.2.122", "weezl@0.1.12"]}, +{"package": "proc-macro-crate@3.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["borsh-derive@1.6.1", "glib-macros@0.20.12", "gtk4-macros@0.9.5", "zbus_macros@5.16.0", "zvariant_derive@5.12.0"], "dependencies": ["toml_edit@0.25.12+spec-1.1.0"]}, +{"package": "proc-macro-error-attr@1.0.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["proc-macro-error@1.0.4"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "version_check@0.9.5"]}, +{"package": "proc-macro-error@1.0.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "syn", "syn-error"], "parents": ["ouroboros_macro@0.17.2"], "dependencies": ["proc-macro-error-attr@1.0.4", "proc-macro2@1.0.106", "quote@1.0.45", "syn@1.0.109", "version_check@0.9.5"]}, +{"package": "proc-macro2@1.0.106", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "proc-macro"], "parents": ["arg_enum_proc_macro@0.3.4", "async-recursion@1.1.1", "async-trait@0.1.92", "auto_impl@1.3.0", "bindgen@0.72.1", "borsh-derive@1.6.1", "clap_derive@4.6.4", "curve25519-dalek-derive@0.1.1", "darling_core@0.20.11", "darling_core@0.23.0", "der_derive@0.8.0", "derive-syn-parse@0.2.0", "derive-where@1.6.1", "derive_builder_core@0.20.2", "derive_more-impl@2.1.1", "displaydoc@0.2.6", "enumflags2_derive@0.7.12", "equator-macro@0.4.2", "futures-macro@0.3.34", "glib-macros@0.20.12", "glib-macros@0.22.6", "gtk4-macros@0.9.5", "inkwell_internals@0.14.0", "interpolate_name@0.2.4", "is-macro@0.3.7", "jni-macros@0.22.4", "macro_magic_core@0.5.1", "macro_magic_core_macros@0.5.1", "miette-derive@7.6.0", "mongodb-internal-macros@3.8.2", "num-derive@0.4.2", "ouroboros_macro@0.17.2", "phf_macros@0.11.3", "phf_macros@0.13.1", "prettyplease@0.2.37", "proc-macro-error-attr@1.0.4", "proc-macro-error@1.0.4", "quote@1.0.45", "serde_derive@1.0.229", "serde_repr@0.1.20", "serde_with_macros@3.21.0", "sqlx-macros-core@0.9.0", "sqlx-macros@0.9.0", "string_cache_codegen@0.6.1", "strum_macros@0.27.2", "swc_config_macro@1.0.1", "swc_ecma_codegen_macros@2.0.2", "swc_eq_ignore_macros@1.0.1", "swc_macros_common@1.0.1", "syn@1.0.109", "syn@2.0.117", "syn@3.0.3", "synstructure@0.13.2", "thiserror-impl@1.0.69", "thiserror-impl@2.0.18", "tls_codec_derive@0.4.2", "tokio-macros@2.7.0", "tracing-attributes@0.1.31", "trait-variant@0.1.2", "typed-builder-macro@0.22.0", "wasm-bindgen-macro-support@0.2.122", "webview2-com-macros@0.8.1", "windows-implement@0.60.2", "windows-implement@0.60.2 [vendored]", "windows-interface@0.59.3", "windows-interface@0.59.3 [vendored]", "wit-bindgen-rust-macro@0.51.0", "yoke-derive@0.8.2", "zbus_macros@5.16.0", "zerocopy-derive@0.8.50", "zerofrom-derive@0.1.7", "zeroize_derive@1.4.3", "zerovec-derive@0.11.6", "zvariant_derive@5.12.0", "zvariant_utils@3.4.0"], "dependencies": ["unicode-ident@1.0.24"]}, +{"package": "profiling-procmacros@1.0.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["profiling@1.0.18"], "dependencies": ["quote@1.0.45", "syn@2.0.117"]}, +{"package": "profiling@1.0.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "procmacros", "profiling-procmacros"], "parents": ["rav1e@0.8.1"], "dependencies": ["profiling-procmacros@1.0.18"]}, +{"package": "proptest@1.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["bit-set", "default", "fork", "regex-syntax", "rusty-fork", "std", "tempfile", "timeout"], "parents": ["perry-container-compose@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["bit-set@0.8.0", "bit-vec@0.8.0", "bitflags@2.12.1", "num-traits@0.2.19", "rand@0.9.4", "rand_chacha@0.9.0", "rand_xorshift@0.4.0", "regex-syntax@0.8.11", "rusty-fork@0.3.1", "tempfile@3.27.0", "unarray@0.1.4"]}, +{"package": "psm@0.1.32", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["stacker@0.1.25"], "dependencies": ["ar_archive_writer@0.5.1", "cc@1.4.4"]}, +{"package": "pxfm@0.1.29", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["moxcms@0.8.1"], "dependencies": []}, +{"package": "qoi@0.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["image@0.25.10"], "dependencies": ["bytemuck@1.25.0"]}, +{"package": "qrcodegen@1.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ui-windows@0.5.1565"], "dependencies": []}, +{"package": "quanta@0.12.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "flaky_tests"], "parents": ["governor@0.10.4"], "dependencies": ["crossbeam-utils@0.8.21", "libc@0.2.189", "once_cell@1.21.4", "raw-cpuid@11.6.0", "wasi@0.11.1+wasi-snapshot-preview1", "web-sys@0.3.99", "winapi@0.3.9"]}, +{"package": "quick-error@1.2.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rusty-fork@0.3.1"], "dependencies": []}, +{"package": "quick-error@2.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["image-webp@0.2.4", "ravif@0.13.0", "tiff@0.11.3"], "dependencies": []}, +{"package": "quinn-proto@0.11.15", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["ring", "rustls-ring"], "parents": ["quinn@0.11.9"], "dependencies": ["bytes@1.12.1", "getrandom@0.3.4", "lru-slab@0.1.2", "rand@0.9.4", "ring@0.17.14", "rustc-hash@2.1.2", "rustls-pki-types@1.14.1", "rustls@0.23.43", "slab@0.4.12", "thiserror@2.0.18", "tinyvec@1.11.0", "tracing@0.1.44", "web-time@1.1.0"]}, +{"package": "quinn-udp@0.5.14", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["tracing"], "parents": ["quinn@0.11.9"], "dependencies": ["cfg_aliases@0.2.1", "libc@0.2.189", "once_cell@1.21.4", "socket2@0.6.5", "tracing@0.1.44", "windows-sys@0.60.2"]}, +{"package": "quinn@0.11.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["ring", "runtime-tokio", "rustls", "rustls-ring"], "parents": ["reqwest@0.12.28"], "dependencies": ["bytes@1.12.1", "cfg_aliases@0.2.1", "pin-project-lite@0.2.17", "quinn-proto@0.11.15", "quinn-udp@0.5.14", "rustc-hash@2.1.2", "rustls@0.23.43", "socket2@0.6.5", "thiserror@2.0.18", "tokio@1.53.1", "tracing@0.1.44", "web-time@1.1.0"]}, +{"package": "quote@1.0.45", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "proc-macro"], "parents": ["arg_enum_proc_macro@0.3.4", "ast_node@5.0.0", "async-recursion@1.1.1", "async-trait@0.1.92", "auto_impl@1.3.0", "bindgen@0.72.1", "borsh-derive@1.6.1", "clap_derive@4.6.4", "cssparser-macros@0.7.0", "curve25519-dalek-derive@0.1.1", "darling_core@0.20.11", "darling_core@0.23.0", "darling_macro@0.20.11", "darling_macro@0.23.0", "der_derive@0.8.0", "derive-syn-parse@0.2.0", "derive-where@1.6.1", "derive_builder_core@0.20.2", "derive_more-impl@2.1.1", "displaydoc@0.2.6", "enumflags2_derive@0.7.12", "equator-macro@0.4.2", "futures-macro@0.3.34", "glib-macros@0.20.12", "glib-macros@0.22.6", "gtk4-macros@0.9.5", "inkwell_internals@0.14.0", "interpolate_name@0.2.4", "is-macro@0.3.7", "jni-macros@0.22.4", "jni-sys-macros@0.4.1", "macro_magic@0.5.1", "macro_magic_core@0.5.1", "macro_magic_core_macros@0.5.1", "macro_magic_macros@0.5.1", "miette-derive@7.6.0", "mongodb-internal-macros@3.8.2", "num-derive@0.4.2", "ouroboros_macro@0.17.2", "phf_macros@0.11.3", "phf_macros@0.13.1", "proc-macro-error-attr@1.0.4", "proc-macro-error@1.0.4", "profiling-procmacros@1.0.18", "serde_derive@1.0.229", "serde_repr@0.1.20", "serde_with_macros@3.21.0", "simd_helpers@0.1.0", "sqlx-macros-core@0.9.0", "sqlx-macros@0.9.0", "string_cache_codegen@0.6.1", "string_enum@1.0.2", "strum_macros@0.27.2", "swc_config_macro@1.0.1", "swc_eq_ignore_macros@1.0.1", "swc_macros_common@1.0.1", "syn@2.0.117", "syn@3.0.3", "synstructure@0.13.2", "thiserror-impl@1.0.69", "thiserror-impl@2.0.18", "tls_codec_derive@0.4.2", "tokio-macros@2.7.0", "tracing-attributes@0.1.31", "trait-variant@0.1.2", "typed-builder-macro@0.22.0", "wasm-bindgen-macro-support@0.2.122", "wasm-bindgen-macro@0.2.122", "webview2-com-macros@0.8.1", "windows-implement@0.60.2", "windows-implement@0.60.2 [vendored]", "windows-interface@0.59.3", "windows-interface@0.59.3 [vendored]", "wit-bindgen-rust-macro@0.51.0", "yoke-derive@0.8.2", "zbus_macros@5.16.0", "zerocopy-derive@0.8.50", "zerofrom-derive@0.1.7", "zeroize_derive@1.4.3", "zerovec-derive@0.11.6", "zvariant_derive@5.12.0", "zvariant_utils@3.4.0"], "dependencies": ["proc-macro2@1.0.106"]}, +{"package": "quoted_printable@0.5.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["lettre@0.11.23"], "dependencies": []}, +{"package": "r-efi@5.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["getrandom@0.3.4"], "dependencies": []}, +{"package": "r-efi@6.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["getrandom@0.4.2"], "dependencies": []}, +{"package": "radium@0.7.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["bitvec@1.0.1"], "dependencies": []}, +{"package": "radix_fmt@1.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_bundler@37.0.0"], "dependencies": []}, +{"package": "rand@0.10.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "std", "std_rng", "sys_rng", "thread_rng"], "parents": ["hickory-net@0.26.1", "hickory-proto@0.26.1", "hickory-resolver@0.26.1", "perry-container-compose@0.5.1565", "perry-ext-ethers@0.5.1565", "perry-ext-nanoid@0.5.1565", "perry-ext-node-forge@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-ui-geisterhand@0.5.1565", "perry@0.5.1565", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0"], "dependencies": ["chacha20@0.10.0", "getrandom@0.4.2", "rand_core@0.10.1"]}, +{"package": "rand@0.8.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "getrandom", "libc", "rand_chacha", "small_rng", "std", "std_rng"], "parents": ["jsonwebtoken@11.0.0", "num-bigint-dig@0.8.6", "phf_generator@0.11.3", "rust_decimal@1.43.0", "tungstenite@0.24.0"], "dependencies": ["libc@0.2.189", "rand_chacha@0.3.1", "rand_core@0.6.4"]}, +{"package": "rand@0.9.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "os_rng", "small_rng", "std", "std_rng", "thread_rng"], "parents": ["bson@3.1.0", "governor@0.10.4", "lopdf@0.39.0", "mongodb@3.8.2", "nanoid@0.5.0", "proptest@1.11.0", "quinn-proto@0.11.15", "rav1e@0.8.1", "rust_decimal@1.43.0", "tungstenite@0.29.0"], "dependencies": ["rand_chacha@0.9.0", "rand_core@0.9.5"]}, +{"package": "rand_chacha@0.3.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["rand@0.8.7"], "dependencies": ["ppv-lite86@0.2.21", "rand_core@0.6.4"]}, +{"package": "rand_chacha@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["proptest@1.11.0", "rand@0.9.4", "rav1e@0.8.1"], "dependencies": ["ppv-lite86@0.2.21", "rand_core@0.9.5"]}, +{"package": "rand_core@0.10.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["chacha20@0.10.0", "crypto-bigint@0.7.5", "crypto-common@0.2.2", "crypto-primes@0.7.2", "ed448-goldilocks@0.14.0-pre.15", "elliptic-curve@0.14.0", "ff@0.14.0", "getrandom@0.4.2", "group@0.14.0", "kem@0.3.0", "ml-kem@0.3.2", "rand@0.10.2", "rsa@0.10.0-rc.18", "signature@3.0.0"], "dependencies": []}, +{"package": "rand_core@0.6.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "getrandom", "std"], "parents": ["crypto-bigint@0.5.5", "crypto-common@0.1.7", "ed25519-dalek@2.2.0", "elliptic-curve@0.13.8", "ff@0.13.1", "group@0.13.0", "password-hash@0.5.0", "perry-ext-argon2@0.5.1565", "perry-stdlib@0.5.1565", "pkcs8@0.10.2", "rand@0.8.7", "rand_chacha@0.3.1", "rsa@0.9.10", "signature@2.2.0", "x25519-dalek@2.0.1"], "dependencies": ["getrandom@0.2.17"]}, +{"package": "rand_core@0.9.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["os_rng", "std"], "parents": ["rand@0.9.4", "rand_chacha@0.9.0", "rand_xorshift@0.4.0"], "dependencies": ["getrandom@0.3.4"]}, +{"package": "rand_xorshift@0.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["proptest@1.11.0"], "dependencies": ["rand_core@0.9.5"]}, +{"package": "rangemap@1.7.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["lopdf@0.39.0"], "dependencies": []}, +{"package": "rav1e@0.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["threading", "wasm", "wasm-bindgen"], "parents": ["ravif@0.13.0"], "dependencies": ["aligned-vec@0.6.4", "arbitrary@1.4.2", "arg_enum_proc_macro@0.3.4", "arrayvec@0.7.6", "av-scenechange@0.14.1", "av1-grain@0.2.5", "bitstream-io@4.10.0", "built@0.8.1", "cfg-if@1.0.4", "interpolate_name@0.2.4", "itertools@0.14.0", "libc@0.2.189", "libfuzzer-sys@0.4.12", "log@0.4.34", "maybe-rayon@0.1.1", "new_debug_unreachable@1.0.6", "noop_proc_macro@0.3.0", "num-derive@0.4.2", "num-traits@0.2.19", "paste@1.0.15", "profiling@1.0.18", "rand@0.9.4", "rand_chacha@0.9.0", "simd_helpers@0.1.0", "thiserror@2.0.18", "v_frame@0.3.9", "wasm-bindgen@0.2.122"]}, +{"package": "ravif@0.13.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["threading"], "parents": ["image@0.25.10"], "dependencies": ["avif-serialize@0.8.9", "imgref@1.12.3", "loop9@0.1.5", "quick-error@2.0.1", "rav1e@0.8.1", "rayon@1.12.0", "rgb@0.8.53"]}, +{"package": "raw-cpuid@11.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["quanta@0.12.6"], "dependencies": ["bitflags@2.12.1"]}, +{"package": "rayon-core@1.13.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["exr@1.74.0", "rayon@1.12.0"], "dependencies": ["crossbeam-deque@0.8.6", "crossbeam-utils@0.8.21"]}, +{"package": "rayon@1.12.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["av-scenechange@0.14.1", "dssim-core@3.5.1", "image@0.25.10", "maybe-rayon@0.1.1", "perry@0.5.1565", "ravif@0.13.0"], "dependencies": ["either@1.16.0", "rayon-core@1.13.0"]}, +{"package": "rc2@0.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["p12@0.6.3"], "dependencies": ["cipher@0.4.4"]}, +{"package": "redis@1.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["acl", "aio", "bytes", "connection-manager", "default", "geospatial", "num-bigint", "script", "streams", "tokio-comp"], "parents": ["perry-ext-ioredis@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["arc-swap@1.9.1", "arcstr@1.2.0", "async-lock@3.4.2", "backon@1.6.0", "bytes@1.12.1", "cfg-if@1.0.4", "combine@4.6.7", "futures-channel@0.3.32", "futures-util@0.3.34", "itoa@1.0.18", "num-bigint@0.5.1", "percent-encoding@2.3.2", "pin-project-lite@0.2.17", "ryu@1.0.23", "sha1_smol@1.0.1", "socket2@0.6.5", "tokio-util@0.7.18", "tokio@1.53.1", "url@2.5.8", "xxhash-rust@0.8.18"]}, +{"package": "redox_syscall@0.5.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "userspace"], "parents": ["parking_lot_core@0.9.12"], "dependencies": ["bitflags@2.12.1"]}, +{"package": "redox_users@0.5.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["dirs-sys@0.5.0"], "dependencies": ["getrandom@0.2.17", "libredox@0.1.17", "thiserror@2.0.18"]}, +{"package": "regex-automata@0.4.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "dfa-build", "dfa-onepass", "dfa-search", "hybrid", "meta", "nfa-backtrack", "nfa-pikevm", "nfa-thompson", "perf-inline", "perf-literal", "perf-literal-multisubstring", "perf-literal-substring", "std", "syntax", "unicode", "unicode-age", "unicode-bool", "unicode-case", "unicode-gencat", "unicode-perl", "unicode-script", "unicode-segment", "unicode-word-boundary"], "parents": ["matchers@0.2.0", "regex@1.13.1", "tracing-subscriber@0.3.23"], "dependencies": ["aho-corasick@1.1.4", "memchr@2.8.1", "regex-syntax@0.8.11"]}, +{"package": "regex-lite@0.1.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std", "string"], "parents": ["llvm-sys@221.0.1"], "dependencies": []}, +{"package": "regex-syntax@0.8.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std", "unicode", "unicode-age", "unicode-bool", "unicode-case", "unicode-gencat", "unicode-perl", "unicode-script", "unicode-segment"], "parents": ["proptest@1.11.0", "regex-automata@0.4.18", "regex@1.13.1"], "dependencies": []}, +{"package": "regex@1.13.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "perf", "perf-backtrack", "perf-cache", "perf-dfa", "perf-inline", "perf-literal", "perf-onepass", "std", "unicode", "unicode-age", "unicode-bool", "unicode-case", "unicode-gencat", "unicode-perl", "unicode-script", "unicode-segment"], "parents": ["bindgen@0.72.1", "env_logger@0.10.2", "perry-perex@0.5.1565", "perry-validation@0.5.1565", "swc_ecma_codegen@21.0.0", "validator@0.21.0"], "dependencies": ["aho-corasick@1.1.4", "memchr@2.8.1", "regex-automata@0.4.18", "regex-syntax@0.8.11"]}, +{"package": "relative-path@1.9.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["swc_bundler@37.0.0"], "dependencies": []}, +{"package": "reqwest@0.12.28", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["__rustls", "__rustls-ring", "__tls", "blocking", "h2", "http2", "json", "multipart", "rustls-tls", "rustls-tls-webpki-roots", "rustls-tls-webpki-roots-no-provider"], "parents": ["perry-ext-axios@0.5.1565", "perry-ext-fetch@0.5.1565", "perry-ext-http@0.5.1565", "perry-stdlib@0.5.1565", "perry@0.5.1565"], "dependencies": ["base64@0.22.1", "bytes@1.12.1", "futures-channel@0.3.32", "futures-core@0.3.34", "futures-util@0.3.34", "h2@0.4.19", "http-body-util@0.1.5", "http-body@1.0.1", "http@1.4.1", "hyper-rustls@0.27.9", "hyper-util@0.1.20", "hyper@1.11.1", "js-sys@0.3.99", "log@0.4.34", "mime_guess@2.0.5", "percent-encoding@2.3.2", "pin-project-lite@0.2.17", "quinn@0.11.9", "rustls-pki-types@1.14.1", "rustls@0.23.43", "serde@1.0.229", "serde_json@1.0.151", "serde_urlencoded@0.7.1", "sync_wrapper@1.0.2", "tokio-rustls@0.26.4", "tokio@1.53.1", "tower-http@0.6.11", "tower-service@0.3.3", "tower@0.5.3", "url@2.5.8", "wasm-bindgen-futures@0.4.72", "wasm-bindgen@0.2.122", "web-sys@0.3.99", "webpki-roots@1.0.9"]}, +{"package": "resolv-conf@0.7.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["system"], "parents": ["hickory-resolver@0.26.1", "perry-runtime@0.5.1565"], "dependencies": []}, +{"package": "rfc6979@0.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ecdsa@0.16.9"], "dependencies": ["hmac@0.12.1", "subtle@2.6.1"]}, +{"package": "rgb@0.8.53", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["argb", "as-bytes", "bytemuck", "default", "grb"], "parents": ["dssim-core@3.5.1", "image@0.25.10", "perry-doc-tests@0.5.1565", "ravif@0.13.0"], "dependencies": ["bytemuck@1.25.0"]}, +{"package": "ring@0.17.14", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "dev_urandom_fallback", "std", "wasm32_unknown_unknown_js"], "parents": ["hickory-proto@0.26.1", "perry-ext-http@0.5.1565", "quinn-proto@0.11.15", "rustls-webpki@0.103.13", "rustls@0.23.43"], "dependencies": ["cc@1.4.4", "cfg-if@1.0.4", "getrandom@0.2.17", "libc@0.2.189", "untrusted@0.9.0", "windows-sys@0.52.0"]}, +{"package": "rsa@0.10.0-rc.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "encoding", "sha2", "std"], "parents": ["perry-ext-node-forge@0.5.1565", "sqlx-mysql@0.9.0"], "dependencies": ["const-oid@0.10.2", "crypto-bigint@0.7.5", "crypto-primes@0.7.2", "digest@0.11.3", "pkcs1@0.8.0-rc.4", "pkcs8@0.11.0", "rand_core@0.10.1", "sha2@0.11.0", "signature@3.0.0", "spki@0.8.0", "zeroize@1.8.2"]}, +{"package": "rsa@0.9.10", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "pem", "pkcs5", "sha2", "std", "u64_digit"], "parents": ["jsonwebtoken@11.0.0", "perry-stdlib@0.5.1565"], "dependencies": ["const-oid@0.9.6", "digest@0.10.7", "num-bigint-dig@0.8.6", "num-integer@0.1.46", "num-traits@0.2.19", "pkcs1@0.7.5", "pkcs8@0.10.2", "rand_core@0.6.4", "sha2@0.10.9", "signature@2.2.0", "spki@0.7.3", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "rsqlite-vfs@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["sqlite-wasm-rs@0.5.5"], "dependencies": ["hashbrown@0.16.1", "thiserror@2.0.18"]}, +{"package": "rusqlite@0.39.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["bundled", "cache", "column_decltype", "default", "hashlink", "hooks", "limits", "modern_sqlite", "session"], "parents": ["perry-ext-better-sqlite3@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["bitflags@2.12.1", "fallible-iterator@0.3.0", "fallible-streaming-iterator@0.1.9", "hashlink@0.11.1", "libsqlite3-sys@0.37.0", "smallvec@1.15.1", "sqlite-wasm-rs@0.5.5"]}, +{"package": "rust_decimal@1.43.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "maths", "serde", "std"], "parents": ["perry-ext-decimal@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["arrayvec@0.7.6", "borsh@1.6.1", "bytes@1.12.1", "num-traits@0.2.19", "rand@0.8.7", "rand@0.9.4", "serde@1.0.229", "serde_json@1.0.151", "wasm-bindgen@0.2.122"]}, +{"package": "rustc-demangle@0.1.28", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-runtime@0.5.1565", "perry@0.5.1565"], "dependencies": []}, +{"package": "rustc-hash@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["allsorts-azul@0.16.5"], "dependencies": []}, +{"package": "rustc-hash@2.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["bindgen@0.72.1", "hstr@3.0.6", "quinn-proto@0.11.15", "quinn@0.11.9", "selectors@0.38.0", "swc_allocator@4.0.1", "swc_bundler@37.0.0", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_codegen@21.0.0", "swc_ecma_loader@18.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_transforms_typescript@35.0.0", "swc_ecma_utils@25.0.0", "swc_graph_analyzer@14.0.2", "swc_sourcemap@9.3.4", "windows-reactor@0.0.0 [vendored]"], "dependencies": []}, +{"package": "rustc_version@0.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["curve25519-dalek@4.1.3", "derive_more-impl@2.1.1", "field-offset@0.3.6", "jni-macros@0.22.4", "pathfinder_simd@0.5.6", "rustc_version_runtime@0.3.0", "simd_cesu8@1.1.1"], "dependencies": ["semver@1.0.28"]}, +{"package": "rustc_version_runtime@0.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["mongodb@3.8.2"], "dependencies": ["rustc_version@0.4.1", "semver@1.0.28"]}, +{"package": "rustix@1.1.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "event", "fs", "net", "pipe", "process", "std", "time"], "parents": ["async-io@2.6.0", "async-process@2.5.0", "async-signal@0.2.14", "polling@3.11.0", "tempfile@3.27.0", "xattr@1.6.1", "zbus@5.16.0"], "dependencies": ["bitflags@2.12.1", "errno@0.3.14", "libc@0.2.189", "linux-raw-sys@0.12.1", "windows-sys@0.61.2"]}, +{"package": "rustls-native-certs@0.8.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ext-net@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["openssl-probe@0.2.1", "rustls-pki-types@1.14.1", "schannel@0.1.29", "security-framework@3.7.0"]}, +{"package": "rustls-pemfile@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["perry-ext-http@0.5.1565", "perry-ext-net@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["rustls-pki-types@1.14.1"]}, +{"package": "rustls-pki-types@1.14.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std", "web", "web-time"], "parents": ["quinn-proto@0.11.15", "reqwest@0.12.28", "rustls-native-certs@0.8.4", "rustls-pemfile@2.2.0", "rustls-webpki@0.103.13", "rustls@0.23.43", "tokio-tungstenite@0.29.0", "tungstenite@0.24.0", "tungstenite@0.29.0", "webpki-roots@1.0.9"], "dependencies": ["web-time@1.1.0", "zeroize@1.8.2"]}, +{"package": "rustls-webpki@0.103.13", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "aws-lc-rs", "default", "ring", "std"], "parents": ["perry-ext-http@0.5.1565", "rustls@0.23.43"], "dependencies": ["aws-lc-rs@1.17.0", "ring@0.17.14", "rustls-pki-types@1.14.1", "untrusted@0.9.0"]}, +{"package": "rustls@0.23.43", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["aws-lc-rs", "aws_lc_rs", "default", "log", "logging", "prefer-post-quantum", "ring", "std", "tls12"], "parents": ["hyper-rustls@0.27.9", "lettre@0.11.23", "mongodb@3.8.2", "perry-ext-http@0.5.1565", "perry-ext-net@0.5.1565", "perry-ext-ws@0.5.1565", "perry-stdlib@0.5.1565", "quinn-proto@0.11.15", "quinn@0.11.9", "reqwest@0.12.28", "tokio-rustls@0.26.4", "tokio-tungstenite@0.29.0", "tungstenite@0.24.0", "tungstenite@0.29.0"], "dependencies": ["aws-lc-rs@1.17.0", "log@0.4.34", "once_cell@1.21.4", "ring@0.17.14", "rustls-pki-types@1.14.1", "rustls-webpki@0.103.13", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "rustversion@1.0.22", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["arc-swap@1.9.1", "castaway@0.2.4", "wasm-bindgen@0.2.122"], "dependencies": []}, +{"package": "rusty-fork@0.3.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["timeout", "wait-timeout"], "parents": ["proptest@1.11.0"], "dependencies": ["fnv@1.0.7", "quick-error@1.2.3", "tempfile@3.27.0", "wait-timeout@0.2.1"]}, +{"package": "ryu-js@1.0.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-runtime@0.5.1565", "swc_ecma_codegen@21.0.0", "swc_ecma_utils@25.0.0"], "dependencies": []}, +{"package": "ryu@1.0.23", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["compact_str@0.7.1", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-ui-android@0.5.1565", "redis@1.6.0", "serde_urlencoded@0.7.1", "serde_yaml@0.9.34+deprecated"], "dependencies": []}, +{"package": "salsa20@0.10.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["scrypt@0.11.0"], "dependencies": ["cipher@0.4.4"]}, +{"package": "same-file@1.0.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["walkdir@2.5.0"], "dependencies": ["winapi-util@0.1.11"]}, +{"package": "schannel@0.1.29", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rustls-native-certs@0.8.4"], "dependencies": ["windows-sys@0.61.2"]}, +{"package": "scoped-tls@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["better_scoped_tls@1.0.1"], "dependencies": []}, +{"package": "scopeguard@1.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["lock_api@0.4.14"], "dependencies": []}, +{"package": "scraper@0.27.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "errors", "main"], "parents": ["perry-ext-cheerio@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["cssparser@0.37.0", "ego-tree@0.11.0", "getopts@0.2.24", "html5ever@0.39.0", "precomputed-hash@0.1.1", "selectors@0.38.0", "tendril@0.5.0"]}, +{"package": "scrypt@0.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "password-hash", "simple", "std"], "parents": ["perry-stdlib@0.5.1565", "pkcs5@0.7.1"], "dependencies": ["password-hash@0.5.0", "pbkdf2@0.12.2", "salsa20@0.10.2", "sha2@0.10.9"]}, +{"package": "sec1@0.7.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "der", "pem", "pkcs8", "point", "std", "subtle", "zeroize"], "parents": ["elliptic-curve@0.13.8"], "dependencies": ["base16ct@0.2.0", "der@0.7.10", "generic-array@0.14.7", "pkcs8@0.10.2", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "sec1@0.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "ctutils", "default", "der", "point", "subtle", "zeroize"], "parents": ["elliptic-curve@0.14.0"], "dependencies": ["base16ct@1.0.0", "ctutils@0.4.2", "der@0.8.1", "hybrid-array@0.4.12", "subtle@2.6.1", "zeroize@1.8.2"]}, +{"package": "security-framework-sys@2.17.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["security-framework@3.7.0"], "dependencies": ["core-foundation-sys@0.8.7", "libc@0.2.189"]}, +{"package": "security-framework@3.7.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["OSX_10_14", "alpn", "default", "session-tickets"], "parents": ["rustls-native-certs@0.8.4"], "dependencies": ["bitflags@2.12.1", "core-foundation-sys@0.8.7", "core-foundation@0.10.1", "libc@0.2.189", "security-framework-sys@2.17.0"]}, +{"package": "selectors@0.38.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["scraper@0.27.0"], "dependencies": ["bitflags@2.12.1", "cssparser@0.37.0", "derive_more@2.1.1", "log@0.4.34", "new_debug_unreachable@1.0.6", "phf@0.13.1", "phf_codegen@0.13.1", "precomputed-hash@0.1.1", "rustc-hash@2.1.2", "servo_arc@0.4.3", "smallvec@1.15.1"]}, +{"package": "semver@1.0.28", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["llvm-sys@221.0.1", "perry-updater@0.5.1565", "perry@0.5.1565", "rustc_version@0.4.1", "rustc_version_runtime@0.3.0", "wasmparser@0.244.0", "wasmparser@0.258.0", "wit-parser@0.244.0"], "dependencies": []}, +{"package": "seq-macro@0.3.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0"], "dependencies": []}, +{"package": "serde@1.0.229", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "derive", "rc", "serde_derive", "std"], "parents": ["bson@3.1.0", "bytes-str@0.2.7", "chrono@0.4.45", "debugid@0.8.0", "ed25519-dalek@2.2.0", "either@1.16.0", "enumflags2@0.7.12", "hstr@3.0.6", "icu_locale_core@2.3.0", "icu_pattern@0.5.0", "icu_provider@2.3.1", "icu_time@2.3.0", "indexmap@2.14.1", "ipnet@2.12.0", "jsonwebtoken@11.0.0", "ksni@0.3.6", "mongocrypt@0.4.0", "mongodb@3.8.2", "mpris-server@0.10.0", "node-semver@2.2.0", "num-bigint@0.4.6", "perry-api-manifest@0.5.1565", "perry-codegen@0.5.1565", "perry-container-compose@0.5.1565", "perry-diagnostics@0.5.1565", "perry-doc-tests@0.5.1565", "perry-ext-jsonwebtoken@0.5.1565", "perry-ext-node-forge@0.5.1565", "perry-ext-parcel-watcher@0.5.1565", "perry-ext-typescript@0.5.1565", "perry-hir@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-ui-geisterhand@0.5.1565", "perry-updater@0.5.1565", "perry@0.5.1565", "phf@0.13.1", "printpdf@0.10.1", "reqwest@0.12.28", "rust_decimal@1.43.0", "serde_bytes@0.11.19", "serde_json@1.0.151", "serde_urlencoded@0.7.1", "serde_yaml@0.9.34+deprecated", "serdect@0.4.3", "smallvec@1.15.1", "sqlx-core@0.9.0", "sqlx-macros-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_config@3.1.2", "swc_ecma_codegen@21.0.0", "swc_ecma_loader@18.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_transforms_typescript@35.0.0", "swc_sourcemap@9.3.4", "taffy@0.13.0", "triomphe@0.1.15", "url@2.5.8", "validator@0.21.0", "wasm-bindgen@0.2.122", "wit-component@0.244.0", "wit-parser@0.244.0", "x25519-dalek@2.0.1", "zbus@5.16.0", "zbus_names@4.3.2", "zerovec@0.11.8", "zvariant@5.12.0", "zvariant_utils@3.4.0"], "dependencies": ["serde_core@1.0.229", "serde_derive@1.0.229"]}, +{"package": "serde_bytes@0.11.19", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["bson@3.1.0", "mongodb@3.8.2"], "dependencies": ["serde@1.0.229", "serde_core@1.0.229"]}, +{"package": "serde_core@1.0.229", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "rc", "result", "std"], "parents": ["bitflags@2.12.1", "deranged@0.5.8", "indexmap@2.14.1", "pem@3.0.6", "pem@4.0.0", "potential_utf@0.1.5", "serde@1.0.229", "serde_bytes@0.11.19", "serde_json@1.0.151", "serde_spanned@1.1.1", "serde_with@3.21.0", "time@0.3.55", "tinystr@0.8.4", "toml@1.1.4+spec-1.1.0", "toml_datetime@1.1.1+spec-1.1.0", "uuid@1.26.0"], "dependencies": ["serde_derive@1.0.229"]}, +{"package": "serde_derive@1.0.229", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["printpdf@0.10.1", "serde@1.0.229", "serde_core@1.0.229", "validator@0.21.0", "wit-component@0.244.0", "wit-parser@0.244.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@3.0.3"]}, +{"package": "serde_json@1.0.151", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "indexmap", "preserve_order", "raw_value", "std"], "parents": ["jsonwebtoken@11.0.0", "perry-codegen@0.5.1565", "perry-container-compose@0.5.1565", "perry-diagnostics@0.5.1565", "perry-doc-tests@0.5.1565", "perry-ext-dotenv@0.5.1565", "perry-ext-fastify@0.5.1565", "perry-ext-fetch@0.5.1565", "perry-ext-http@0.5.1565", "perry-ext-jsonwebtoken@0.5.1565", "perry-ext-mongodb@0.5.1565", "perry-ext-mysql2@0.5.1565", "perry-ext-net@0.5.1565", "perry-ext-node-forge@0.5.1565", "perry-ext-parcel-watcher@0.5.1565", "perry-ext-qs@0.5.1565", "perry-ext-typescript@0.5.1565", "perry-ext-undici@0.5.1565", "perry-ext-validator@0.5.1565", "perry-hir@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-ui-android@0.5.1565", "perry-ui-geisterhand@0.5.1565", "perry-updater@0.5.1565", "perry@0.5.1565", "printpdf@0.10.1", "reqwest@0.12.28", "rust_decimal@1.43.0", "sqlx-core@0.9.0", "sqlx-macros-core@0.9.0", "sqlx-postgres@0.9.0", "swc_config@3.1.2", "swc_ecma_transforms_optimization@34.0.0", "swc_sourcemap@9.3.4", "validator@0.21.0", "wit-component@0.244.0", "wit-parser@0.244.0"], "dependencies": ["indexmap@2.14.1", "itoa@1.0.18", "memchr@2.8.1", "serde@1.0.229", "serde_core@1.0.229", "zmij@1.0.21"]}, +{"package": "serde_repr@0.1.20", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zbus@5.16.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "serde_spanned@1.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "serde", "std"], "parents": ["toml@1.1.4+spec-1.1.0"], "dependencies": ["serde_core@1.0.229"]}, +{"package": "serde_urlencoded@0.7.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["reqwest@0.12.28"], "dependencies": ["form_urlencoded@1.2.2", "itoa@1.0.18", "ryu@1.0.23", "serde@1.0.229"]}, +{"package": "serde_with@3.21.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["macros"], "parents": ["mongodb@3.8.2"], "dependencies": ["serde_core@1.0.229", "serde_with_macros@3.21.0"]}, +{"package": "serde_with_macros@3.21.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["serde_with@3.21.0"], "dependencies": ["darling@0.23.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "serde_yaml@0.9.34+deprecated", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-container-compose@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["indexmap@2.14.1", "itoa@1.0.18", "ryu@1.0.23", "serde@1.0.229", "unsafe-libyaml@0.2.11"]}, +{"package": "serdect@0.4.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default"], "parents": ["crypto-bigint@0.7.5", "ed448-goldilocks@0.14.0-pre.15"], "dependencies": ["base16ct@1.0.0", "serde@1.0.229"]}, +{"package": "servo_arc@0.4.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "track_alloc_size"], "parents": ["selectors@0.38.0"], "dependencies": ["stable_deref_trait@1.2.1"]}, +{"package": "sha1@0.10.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["p12@0.6.3", "perry-stdlib@0.5.1565", "swc_ecma_transforms_react@35.0.0", "tungstenite@0.24.0", "tungstenite@0.29.0"], "dependencies": ["cfg-if@1.0.4", "cpufeatures@0.2.17", "digest@0.10.7"]}, +{"package": "sha1@0.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "oid"], "parents": ["mongodb@3.8.2", "perry-stdlib@0.5.1565", "sqlx-mysql@0.9.0", "x509-cert@0.3.0", "zip@8.6.0"], "dependencies": ["cfg-if@1.0.4", "cpufeatures@0.3.0", "digest@0.11.3"]}, +{"package": "sha1_smol@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["redis@1.6.0", "uuid@1.26.0"], "dependencies": []}, +{"package": "sha2@0.10.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "oid", "std"], "parents": ["ed25519-dalek@2.2.0", "jsonwebtoken@11.0.0", "lopdf@0.39.0", "p256@0.13.2", "p384@0.13.1", "p521@0.13.3", "pkcs5@0.7.1", "rsa@0.9.10", "scrypt@0.11.0", "sqlx-core@0.9.0", "sqlx-macros-core@0.9.0"], "dependencies": ["cfg-if@1.0.4", "cpufeatures@0.2.17", "digest@0.10.7"]}, +{"package": "sha2@0.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "oid"], "parents": ["lzma-rust2@0.16.4", "mongodb@3.8.2", "perry-ext-node-forge@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-updater@0.5.1565", "perry@0.5.1565", "rsa@0.10.0-rc.18", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0"], "dependencies": ["cfg-if@1.0.4", "cpufeatures@0.3.0", "digest@0.11.3"]}, +{"package": "sha3-utils@0.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["zerocopy@0.8.50"]}, +{"package": "sha3@0.10.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["digest@0.10.7", "keccak@0.1.6"]}, +{"package": "sha3@0.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["ml-kem@0.3.2"], "dependencies": ["digest@0.11.3", "keccak@0.2.0"]}, +{"package": "sha3@0.12.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "oid"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["digest@0.11.3", "keccak@0.2.0", "sponge-cursor@0.1.0"]}, +{"package": "shake@0.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default"], "parents": ["ed448-goldilocks@0.14.0-pre.15", "perry-stdlib@0.5.1565"], "dependencies": ["digest@0.11.3", "keccak@0.2.0", "sponge-cursor@0.1.0"]}, +{"package": "sharded-slab@0.1.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tracing-subscriber@0.3.23"], "dependencies": ["lazy_static@1.5.0"]}, +{"package": "shell-words@1.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["dialoguer@0.11.0", "dialoguer@0.12.0"], "dependencies": []}, +{"package": "shlex@1.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["bindgen@0.72.1"], "dependencies": []}, +{"package": "shlex@2.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["cc@1.4.4"], "dependencies": []}, +{"package": "signal-hook-registry@1.4.8", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["async-signal@0.2.14", "tokio@1.53.1"], "dependencies": ["errno@0.3.14", "libc@0.2.189"]}, +{"package": "signature@2.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "digest", "rand_core", "std"], "parents": ["ecdsa@0.16.9", "ed25519@2.2.3", "jsonwebtoken@11.0.0", "rsa@0.9.10"], "dependencies": ["digest@0.10.7", "rand_core@0.6.4"]}, +{"package": "signature@3.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "digest", "rand_core"], "parents": ["ed448-goldilocks@0.14.0-pre.15", "ed448@0.5.0", "rsa@0.10.0-rc.18", "x509-cert@0.3.0"], "dependencies": ["digest@0.11.3", "rand_core@0.10.1"]}, +{"package": "simd-adler32@0.3.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["const-generics", "default", "std"], "parents": ["fdeflate@0.3.7", "miniz_oxide@0.8.9", "miniz_oxide@0.9.1", "zopfli@0.8.3", "zune-inflate@0.2.54"], "dependencies": []}, +{"package": "simd_cesu8@1.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["jni-macros@0.22.4", "jni@0.22.4"], "dependencies": ["rustc_version@0.4.1", "simdutf8@0.1.5"]}, +{"package": "simd_helpers@0.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rav1e@0.8.1"], "dependencies": ["quote@1.0.45"]}, +{"package": "simdutf8@0.1.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["bson@3.1.0", "perry-runtime@0.5.1565", "simd_cesu8@1.1.1"], "dependencies": []}, +{"package": "simple_asn1@0.6.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["jsonwebtoken@11.0.0"], "dependencies": ["num-bigint@0.4.6", "num-traits@0.2.19", "thiserror@2.0.18", "time@0.3.55"]}, +{"package": "siphasher@0.3.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["swc_common@18.0.1"], "dependencies": []}, +{"package": "siphasher@1.0.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["phf_shared@0.11.3", "phf_shared@0.12.1", "phf_shared@0.13.1"], "dependencies": []}, +{"package": "slab@0.4.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["async-executor@1.14.0", "async-io@2.6.0", "async-signal@0.2.14", "futures-util@0.3.34", "h2@0.4.19", "quinn-proto@0.11.15"], "dependencies": []}, +{"package": "slotmap@1.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["taffy@0.13.0"], "dependencies": ["version_check@0.9.5"]}, +{"package": "smallvec@1.15.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["const_generics", "const_new", "serde", "union", "write"], "parents": ["cfg-expr@0.20.8", "cssparser@0.37.0", "exr@1.74.0", "fixed_decimal@0.7.2", "gio@0.20.12", "glib@0.20.12", "glib@0.22.7", "governor@0.10.4", "gstreamer@0.25.3", "hickory-resolver@0.26.1", "hyper@1.11.1", "icu_normalizer@2.2.0", "idna@1.1.0", "moka@0.12.15", "num-bigint-dig@0.8.6", "parking_lot_core@0.9.12", "rusqlite@0.39.0", "selectors@0.38.0", "sqlx-core@0.9.0", "sqlx-postgres@0.9.0", "tracing-subscriber@0.3.23"], "dependencies": ["serde@1.0.229"]}, +{"package": "smartstring@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0"], "dependencies": ["autocfg@1.5.1", "static_assertions@1.1.0", "version_check@0.9.5"]}, +{"package": "socket2@0.6.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["all"], "parents": ["hyper-util@0.1.20", "ipconfig@0.3.4", "lettre@0.11.23", "mongodb@3.8.2", "perry-ext-fastify@0.5.1565", "perry-ext-http@0.5.1565", "perry-runtime@0.5.1565", "quinn-udp@0.5.14", "quinn@0.11.9", "redis@1.6.0", "tokio@1.53.1"], "dependencies": ["libc@0.2.189", "windows-sys@0.61.2"]}, +{"package": "soup3-sys@0.7.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["v3_0"], "parents": ["soup3@0.7.0", "webkit6-sys@0.4.0"], "dependencies": ["gio-sys@0.20.10", "glib-sys@0.20.10", "gobject-sys@0.20.10", "libc@0.2.189", "system-deps@7.0.8"]}, +{"package": "soup3@0.7.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["webkit6@0.4.0"], "dependencies": ["futures-channel@0.3.32", "gio@0.20.12", "glib@0.20.12", "libc@0.2.189", "soup3-sys@0.7.0"]}, +{"package": "spin@0.9.8", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["barrier", "default", "lazy", "lock_api", "lock_api_crate", "mutex", "once", "rwlock", "spin_mutex"], "parents": ["flume@0.12.0", "lazy_static@1.5.0", "wasmi@1.1.0"], "dependencies": ["lock_api@0.4.14"]}, +{"package": "spinning_top@0.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["governor@0.10.4"], "dependencies": ["lock_api@0.4.14"]}, +{"package": "spki@0.7.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "pem", "std"], "parents": ["ecdsa@0.16.9", "pkcs1@0.7.5", "pkcs5@0.7.1", "pkcs8@0.10.2", "rsa@0.9.10"], "dependencies": ["base64ct@1.8.3", "der@0.7.10"]}, +{"package": "spki@0.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "pem", "std"], "parents": ["perry-ext-node-forge@0.5.1565", "perry-stdlib@0.5.1565", "pkcs1@0.8.0-rc.4", "pkcs8@0.11.0", "rsa@0.10.0-rc.18", "x509-cert@0.3.0"], "dependencies": ["base64ct@1.8.3", "der@0.8.1"]}, +{"package": "sponge-cursor@0.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["sha3@0.12.0", "shake@0.1.0"], "dependencies": []}, +{"package": "sqlite-wasm-rs@0.5.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rusqlite@0.39.0"], "dependencies": ["cc@1.4.4", "js-sys@0.3.99", "rsqlite-vfs@0.1.1", "wasm-bindgen@0.2.122"]}, +{"package": "sqlx-core@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["_rt-tokio", "any", "chrono", "crc", "default", "json", "migrate", "offline", "serde", "serde_json", "sha2", "tokio", "tokio-stream"], "parents": ["sqlx-macros-core@0.9.0", "sqlx-macros@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "sqlx@0.9.0"], "dependencies": ["base64@0.22.1", "bytes@1.12.1", "cfg-if@1.0.4", "chrono@0.4.45", "crc@3.4.0", "crossbeam-queue@0.3.12", "either@1.16.0", "event-listener@5.4.1", "futures-core@0.3.34", "futures-intrusive@0.5.0", "futures-io@0.3.34", "futures-util@0.3.34", "hashbrown@0.16.1", "hashlink@0.11.1", "indexmap@2.14.1", "log@0.4.34", "memchr@2.8.1", "percent-encoding@2.3.2", "serde@1.0.229", "serde_json@1.0.151", "sha2@0.10.9", "smallvec@1.15.1", "thiserror@2.0.18", "tokio-stream@0.1.18", "tokio@1.53.1", "tracing@0.1.44", "url@2.5.8"]}, +{"package": "sqlx-macros-core@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["_rt-tokio", "chrono", "default", "json", "mysql", "mysql-rsa", "postgres", "sqlx-mysql", "sqlx-postgres", "tokio"], "parents": ["sqlx-macros@0.9.0"], "dependencies": ["cfg-if@1.0.4", "dotenvy@0.15.7", "either@1.16.0", "heck@0.5.0", "hex@0.4.3", "proc-macro2@1.0.106", "quote@1.0.45", "serde@1.0.229", "serde_json@1.0.151", "sha2@0.10.9", "sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "syn@2.0.117", "tokio@1.53.1", "url@2.5.8"]}, +{"package": "sqlx-macros@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["_rt-tokio", "chrono", "default", "json", "mysql", "mysql-rsa", "postgres"], "parents": ["sqlx@0.9.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "sqlx-core@0.9.0", "sqlx-macros-core@0.9.0", "syn@2.0.117"]}, +{"package": "sqlx-mysql@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["chrono", "json", "migrate", "offline", "rsa", "serde"], "parents": ["sqlx-macros-core@0.9.0", "sqlx@0.9.0"], "dependencies": ["bitflags@2.12.1", "byteorder@1.5.0", "bytes@1.12.1", "chrono@0.4.45", "crc@3.4.0", "digest@0.11.3", "dotenvy@0.15.7", "either@1.16.0", "futures-core@0.3.34", "futures-util@0.3.34", "generic-array@0.14.7", "log@0.4.34", "percent-encoding@2.3.2", "rand@0.10.2", "rsa@0.10.0-rc.18", "serde@1.0.229", "sha1@0.11.0", "sha2@0.11.0", "sqlx-core@0.9.0", "thiserror@2.0.18", "tracing@0.1.44"]}, +{"package": "sqlx-postgres@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["chrono", "json", "migrate", "offline"], "parents": ["sqlx-macros-core@0.9.0", "sqlx@0.9.0"], "dependencies": ["atoi@2.0.0", "base64@0.22.1", "bitflags@2.12.1", "byteorder@1.5.0", "chrono@0.4.45", "crc@3.4.0", "dotenvy@0.15.7", "etcetera@0.11.0", "futures-channel@0.3.32", "futures-core@0.3.34", "futures-util@0.3.34", "hex@0.4.3", "hkdf@0.13.0", "hmac@0.13.0", "itoa@1.0.18", "log@0.4.34", "md-5@0.11.0", "memchr@2.8.1", "rand@0.10.2", "serde@1.0.229", "serde_json@1.0.151", "sha2@0.11.0", "smallvec@1.15.1", "sqlx-core@0.9.0", "stringprep@0.1.5", "thiserror@2.0.18", "tracing@0.1.44", "whoami@2.1.2"]}, +{"package": "sqlx-sqlite@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["chrono", "json", "migrate", "offline", "serde"], "parents": ["sqlx-macros-core@0.9.0", "sqlx@0.9.0"], "dependencies": ["atoi@2.0.0", "chrono@0.4.45", "flume@0.12.0", "form_urlencoded@1.2.2", "futures-channel@0.3.32", "futures-core@0.3.34", "futures-executor@0.3.32", "futures-intrusive@0.5.0", "futures-util@0.3.34", "libsqlite3-sys@0.37.0", "log@0.4.34", "percent-encoding@2.3.2", "serde@1.0.229", "sqlx-core@0.9.0", "thiserror@2.0.18", "tracing@0.1.44", "url@2.5.8"]}, +{"package": "sqlx@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["_rt-tokio", "chrono", "json", "mysql", "mysql-rsa", "postgres", "runtime-tokio", "sqlx-mysql", "sqlx-postgres"], "parents": ["perry-ext-mysql2@0.5.1565", "perry-ext-pg@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["sqlx-core@0.9.0", "sqlx-macros@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0"]}, +{"package": "stable_deref_trait@1.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["as-slice@0.2.1", "icu_provider@2.3.1", "servo_arc@0.4.3", "triomphe@0.1.15", "yoke@0.8.3"], "dependencies": []}, +{"package": "stacker@0.1.25", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-hir@0.5.1565", "swc_ecma_parser@32.0.0"], "dependencies": ["cc@1.4.4", "cfg-if@1.0.4", "libc@0.2.189", "psm@0.1.32", "windows-sys@0.61.2"]}, +{"package": "static_assertions@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["compact_str@0.7.1", "kstring@2.0.2", "ouroboros@0.17.2", "smartstring@1.0.1"], "dependencies": []}, +{"package": "string_cache@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["web_atoms@0.2.4"], "dependencies": ["new_debug_unreachable@1.0.6", "parking_lot@0.12.5", "phf_shared@0.13.1", "precomputed-hash@0.1.1"]}, +{"package": "string_cache_codegen@0.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["web_atoms@0.2.4"], "dependencies": ["phf_generator@0.13.1", "phf_shared@0.13.1", "proc-macro2@1.0.106", "quote@1.0.45"]}, +{"package": "string_enum@1.0.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_ast@19.0.0", "swc_ecma_transforms_react@35.0.0"], "dependencies": ["quote@1.0.45", "swc_macros_common@1.0.1", "syn@2.0.117"]}, +{"package": "stringprep@0.1.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["lopdf@0.39.0", "mongodb@3.8.2", "sqlx-postgres@0.9.0"], "dependencies": ["unicode-bidi@0.3.18", "unicode-normalization@0.1.25", "unicode-properties@0.1.4"]}, +{"package": "strsim@0.11.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["clap_builder@4.6.6", "darling_core@0.20.11", "darling_core@0.23.0", "mongodb@3.8.2"], "dependencies": []}, +{"package": "strum@0.27.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "derive", "std", "strum_macros"], "parents": ["croner@3.0.1"], "dependencies": ["strum_macros@0.27.2"]}, +{"package": "strum_macros@0.27.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["strum@0.27.2"], "dependencies": ["heck@0.5.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "subtle@2.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["const-generics", "i128"], "parents": ["aes-gcm@0.10.3", "bcrypt@0.19.3", "crypto-bigint@0.5.5", "crypto-bigint@0.7.5", "ctutils@0.4.2", "curve25519-dalek@4.1.3", "digest@0.10.7", "ed25519-dalek@2.2.0", "ed448-goldilocks@0.14.0-pre.15", "elliptic-curve@0.13.8", "elliptic-curve@0.14.0", "ff@0.13.1", "ff@0.14.0", "group@0.13.0", "group@0.14.0", "hybrid-array@0.4.12", "password-hash@0.5.0", "rfc6979@0.4.0", "rsa@0.9.10", "rustls@0.23.43", "sec1@0.7.3", "sec1@0.8.1", "universal-hash@0.5.1"], "dependencies": []}, +{"package": "swc_allocator@4.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["hashbrown"], "parents": ["swc_ecma_codegen@21.0.0"], "dependencies": ["allocator-api2@0.2.21", "bumpalo@3.20.3", "hashbrown@0.14.5", "rustc-hash@2.1.2"]}, +{"package": "swc_atoms@9.0.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_bundler@37.0.0", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_codegen@21.0.0", "swc_ecma_loader@18.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_transforms_typescript@35.0.0", "swc_ecma_utils@25.0.0", "swc_ecma_visit@19.0.0"], "dependencies": ["hstr@3.0.6", "once_cell@1.21.4", "serde@1.0.229"]}, +{"package": "swc_bundler@37.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-ext-typescript@0.5.1565"], "dependencies": ["anyhow@1.0.104", "crc@2.1.0", "indexmap@2.14.1", "is-macro@0.3.7", "once_cell@1.21.4", "petgraph@0.7.1", "radix_fmt@1.0.0", "relative-path@1.9.3", "rustc-hash@2.1.2", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_codegen@21.0.0", "swc_ecma_loader@18.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_utils@25.0.0", "swc_ecma_visit@19.0.0", "swc_graph_analyzer@14.0.2", "tracing@0.1.44"]}, +{"package": "swc_common@18.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-ext-typescript@0.5.1565", "perry-hir@0.5.1565", "perry-parser@0.5.1565", "perry@0.5.1565", "swc_bundler@37.0.0", "swc_ecma_ast@19.0.0", "swc_ecma_codegen@21.0.0", "swc_ecma_loader@18.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_transforms_typescript@35.0.0", "swc_ecma_utils@25.0.0", "swc_ecma_visit@19.0.0"], "dependencies": ["anyhow@1.0.104", "ast_node@5.0.0", "better_scoped_tls@1.0.1", "bytes-str@0.2.7", "either@1.16.0", "from_variant@3.0.0", "num-bigint@0.4.6", "once_cell@1.21.4", "rustc-hash@2.1.2", "serde@1.0.229", "siphasher@0.3.11", "swc_atoms@9.0.3", "swc_eq_ignore_macros@1.0.1", "swc_visit@2.0.1", "tracing@0.1.44", "unicode-width@0.2.2", "url@2.5.8"]}, +{"package": "swc_config@3.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_transforms_react@35.0.0"], "dependencies": ["anyhow@1.0.104", "bytes-str@0.2.7", "indexmap@2.14.1", "serde@1.0.229", "serde_json@1.0.151", "swc_config_macro@1.0.1"]}, +{"package": "swc_config_macro@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_config@3.1.2"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "swc_macros_common@1.0.1", "syn@2.0.117"]}, +{"package": "swc_ecma_ast@19.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-ext-typescript@0.5.1565", "perry-hir@0.5.1565", "perry-parser@0.5.1565", "perry@0.5.1565", "swc_bundler@37.0.0", "swc_ecma_codegen@21.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_transforms_typescript@35.0.0", "swc_ecma_utils@25.0.0", "swc_ecma_visit@19.0.0"], "dependencies": ["bitflags@2.12.1", "is-macro@0.3.7", "num-bigint@0.4.6", "once_cell@1.21.4", "phf@0.11.3", "rustc-hash@2.1.2", "string_enum@1.0.2", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_visit@2.0.1", "unicode-id-start@1.4.0"]}, +{"package": "swc_ecma_codegen@21.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ext-typescript@0.5.1565", "perry-hir@0.5.1565", "swc_bundler@37.0.0"], "dependencies": ["ascii@1.1.0", "compact_str@0.7.1", "memchr@2.8.1", "num-bigint@0.4.6", "once_cell@1.21.4", "regex@1.13.1", "rustc-hash@2.1.2", "ryu-js@1.0.3", "serde@1.0.229", "swc_allocator@4.0.1", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_codegen_macros@2.0.2", "swc_sourcemap@9.3.4", "tracing@0.1.44"]}, +{"package": "swc_ecma_codegen_macros@2.0.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_codegen@21.0.0"], "dependencies": ["proc-macro2@1.0.106", "swc_macros_common@1.0.1", "syn@2.0.117"]}, +{"package": "swc_ecma_loader@18.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-ext-typescript@0.5.1565", "swc_bundler@37.0.0"], "dependencies": ["anyhow@1.0.104", "pathdiff@0.2.3", "rustc-hash@2.1.2", "serde@1.0.229", "swc_atoms@9.0.3", "swc_common@18.0.1", "tracing@0.1.44"]}, +{"package": "swc_ecma_parser@29.0.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["typescript"], "parents": ["swc_bundler@37.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0"], "dependencies": ["bitflags@2.12.1", "either@1.16.0", "num-bigint@0.4.6", "phf@0.11.3", "rustc-hash@2.1.2", "seq-macro@0.3.6", "serde@1.0.229", "smartstring@1.0.1", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "tracing@0.1.44"]}, +{"package": "swc_ecma_parser@32.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "stacker", "typescript"], "parents": ["perry-ext-typescript@0.5.1565", "perry-parser@0.5.1565"], "dependencies": ["bitflags@2.12.1", "either@1.16.0", "num-bigint@0.4.6", "phf@0.11.3", "rustc-hash@2.1.2", "seq-macro@0.3.6", "serde@1.0.229", "smartstring@1.0.1", "stacker@0.1.25", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "tracing@0.1.44"]}, +{"package": "swc_ecma_transforms_base@32.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ext-typescript@0.5.1565", "perry-hir@0.5.1565", "perry-parser@0.5.1565", "perry@0.5.1565", "swc_bundler@37.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_transforms_typescript@35.0.0"], "dependencies": ["better_scoped_tls@1.0.1", "indexmap@2.14.1", "once_cell@1.21.4", "par-core@2.0.0", "phf@0.11.3", "rustc-hash@2.1.2", "serde@1.0.229", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_utils@25.0.0", "swc_ecma_visit@19.0.0", "tracing@0.1.44"]}, +{"package": "swc_ecma_transforms_optimization@34.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_bundler@37.0.0"], "dependencies": ["bytes-str@0.2.7", "dashmap@5.5.3", "indexmap@2.14.1", "once_cell@1.21.4", "par-core@2.0.0", "petgraph@0.7.1", "rustc-hash@2.1.2", "serde_json@1.0.151", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_transforms_base@32.0.0", "swc_ecma_utils@25.0.0", "swc_ecma_visit@19.0.0", "tracing@0.1.44"]}, +{"package": "swc_ecma_transforms_react@35.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "serde", "serde-impl"], "parents": ["perry-ext-typescript@0.5.1565", "swc_ecma_transforms_typescript@35.0.0"], "dependencies": ["base64@0.22.1", "bytes-str@0.2.7", "indexmap@2.14.1", "once_cell@1.21.4", "rustc-hash@2.1.2", "serde@1.0.229", "sha1@0.10.6", "string_enum@1.0.2", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_config@3.1.2", "swc_ecma_ast@19.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_transforms_base@32.0.0", "swc_ecma_utils@25.0.0", "swc_ecma_visit@19.0.0"]}, +{"package": "swc_ecma_transforms_typescript@35.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ext-typescript@0.5.1565"], "dependencies": ["bytes-str@0.2.7", "rustc-hash@2.1.2", "serde@1.0.229", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_utils@25.0.0", "swc_ecma_visit@19.0.0"]}, +{"package": "swc_ecma_utils@25.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_bundler@37.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_transforms_typescript@35.0.0"], "dependencies": ["indexmap@2.14.1", "num_cpus@1.17.0", "once_cell@1.21.4", "par-core@2.0.0", "rustc-hash@2.1.2", "ryu-js@1.0.3", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_visit@19.0.0", "tracing@0.1.44"]}, +{"package": "swc_ecma_visit@19.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-ext-typescript@0.5.1565", "perry-hir@0.5.1565", "perry-parser@0.5.1565", "perry@0.5.1565", "swc_bundler@37.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_transforms_react@35.0.0", "swc_ecma_transforms_typescript@35.0.0", "swc_ecma_utils@25.0.0"], "dependencies": ["new_debug_unreachable@1.0.6", "num-bigint@0.4.6", "swc_atoms@9.0.3", "swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_visit@2.0.1", "tracing@0.1.44"]}, +{"package": "swc_eq_ignore_macros@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_common@18.0.1"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "swc_graph_analyzer@14.0.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_bundler@37.0.0"], "dependencies": ["auto_impl@1.3.0", "petgraph@0.7.1", "rustc-hash@2.1.2", "tracing@0.1.44"]}, +{"package": "swc_macros_common@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ast_node@5.0.0", "from_variant@3.0.0", "string_enum@1.0.2", "swc_config_macro@1.0.1", "swc_ecma_codegen_macros@2.0.2"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "swc_sourcemap@9.3.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_codegen@21.0.0"], "dependencies": ["base64-simd@0.8.0", "bitvec@1.0.1", "bytes-str@0.2.7", "data-encoding@2.11.0", "debugid@0.8.0", "if_chain@1.0.3", "rustc-hash@2.1.2", "serde@1.0.229", "serde_json@1.0.151", "unicode-id-start@1.4.0", "url@2.5.8"]}, +{"package": "swc_visit@2.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_common@18.0.1", "swc_ecma_ast@19.0.0", "swc_ecma_visit@19.0.0"], "dependencies": ["either@1.16.0", "new_debug_unreachable@1.0.6"]}, +{"package": "syn@1.0.109", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["proc-macro-error@1.0.4"], "dependencies": ["proc-macro2@1.0.106", "unicode-ident@1.0.24"]}, +{"package": "syn@2.0.117", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["clone-impls", "default", "derive", "extra-traits", "fold", "full", "parsing", "printing", "proc-macro", "visit", "visit-mut"], "parents": ["arg_enum_proc_macro@0.3.4", "ast_node@5.0.0", "async-recursion@1.1.1", "auto_impl@1.3.0", "bindgen@0.72.1", "borsh-derive@1.6.1", "cssparser-macros@0.7.0", "curve25519-dalek-derive@0.1.1", "darling_core@0.20.11", "darling_core@0.23.0", "darling_macro@0.20.11", "darling_macro@0.23.0", "der_derive@0.8.0", "derive-syn-parse@0.2.0", "derive-where@1.6.1", "derive_builder_core@0.20.2", "derive_builder_macro@0.20.2", "derive_more-impl@2.1.1", "displaydoc@0.2.6", "enumflags2_derive@0.7.12", "equator-macro@0.4.2", "from_variant@3.0.0", "glib-macros@0.20.12", "glib-macros@0.22.6", "gtk4-macros@0.9.5", "inkwell_internals@0.14.0", "interpolate_name@0.2.4", "is-macro@0.3.7", "jni-macros@0.22.4", "jni-sys-macros@0.4.1", "macro_magic@0.5.1", "macro_magic_core@0.5.1", "macro_magic_core_macros@0.5.1", "macro_magic_macros@0.5.1", "miette-derive@7.6.0", "mongodb-internal-macros@3.8.2", "num-derive@0.4.2", "ouroboros_macro@0.17.2", "phf_macros@0.11.3", "phf_macros@0.13.1", "prettyplease@0.2.37", "profiling-procmacros@1.0.18", "serde_repr@0.1.20", "serde_with_macros@3.21.0", "sqlx-macros-core@0.9.0", "sqlx-macros@0.9.0", "string_enum@1.0.2", "strum_macros@0.27.2", "swc_config_macro@1.0.1", "swc_ecma_codegen_macros@2.0.2", "swc_eq_ignore_macros@1.0.1", "swc_macros_common@1.0.1", "synstructure@0.13.2", "thiserror-impl@1.0.69", "thiserror-impl@2.0.18", "tls_codec_derive@0.4.2", "tokio-macros@2.7.0", "tracing-attributes@0.1.31", "trait-variant@0.1.2", "typed-builder-macro@0.22.0", "wasm-bindgen-macro-support@0.2.122", "webview2-com-macros@0.8.1", "windows-implement@0.60.2", "windows-implement@0.60.2 [vendored]", "windows-interface@0.59.3", "windows-interface@0.59.3 [vendored]", "wit-bindgen-rust-macro@0.51.0", "wit-bindgen-rust@0.51.0", "yoke-derive@0.8.2", "zbus_macros@5.16.0", "zerocopy-derive@0.8.50", "zerofrom-derive@0.1.7", "zeroize_derive@1.4.3", "zvariant_derive@5.12.0", "zvariant_utils@3.4.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "unicode-ident@1.0.24"]}, +{"package": "syn@3.0.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["clone-impls", "default", "derive", "extra-traits", "full", "parsing", "printing", "proc-macro", "visit-mut"], "parents": ["async-trait@0.1.92", "clap_derive@4.6.4", "futures-macro@0.3.34", "serde_derive@1.0.229", "zerovec-derive@0.11.6"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "unicode-ident@1.0.24"]}, +{"package": "sync_wrapper@1.0.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["futures", "futures-core"], "parents": ["reqwest@0.12.28", "tower@0.5.3"], "dependencies": ["futures-core@0.3.34"]}, +{"package": "synstructure@0.13.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "proc-macro"], "parents": ["yoke-derive@0.8.2", "zerofrom-derive@0.1.7"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "system-configuration-sys@0.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["system-configuration@0.7.0"], "dependencies": ["core-foundation-sys@0.8.7", "libc@0.2.189"]}, +{"package": "system-configuration@0.7.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["hickory-resolver@0.26.1"], "dependencies": ["bitflags@2.12.1", "core-foundation@0.9.4", "system-configuration-sys@0.6.0"]}, +{"package": "system-deps@7.0.8", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["cairo-sys-rs@0.20.10", "cairo-sys-rs@0.22.0", "gdk-pixbuf-sys@0.20.10", "gdk4-sys@0.9.6", "gio-sys@0.20.10", "gio-sys@0.22.0", "glib-sys@0.20.10", "glib-sys@0.22.6", "gobject-sys@0.20.10", "gobject-sys@0.22.6", "graphene-sys@0.20.10", "gsk4-sys@0.9.6", "gstreamer-app-sys@0.25.0", "gstreamer-base-sys@0.25.0", "gstreamer-sys@0.25.2", "gtk4-sys@0.9.6", "javascriptcore6-sys@0.4.0", "libshumate-sys@0.6.0", "pango-sys@0.20.10", "soup3-sys@0.7.0", "webkit6-sys@0.4.0"], "dependencies": ["cfg-expr@0.20.8", "heck@0.5.0", "pkg-config@0.3.33", "toml@1.1.4+spec-1.1.0", "version-compare@0.2.1"]}, +{"package": "taffy@0.13.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["flexbox", "std", "taffy_tree"], "parents": ["perry-runtime@0.5.1565"], "dependencies": ["arrayvec@0.7.6", "serde@1.0.229", "slotmap@1.1.1"]}, +{"package": "tagptr@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["moka@0.12.15"], "dependencies": []}, +{"package": "take_mut@0.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["mongodb@3.8.2"], "dependencies": []}, +{"package": "tap@1.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["bitvec@1.0.1", "wyz@0.5.1"], "dependencies": []}, +{"package": "tar@0.4.46", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "xattr"], "parents": ["perry@0.5.1565"], "dependencies": ["filetime@0.2.29", "libc@0.2.189", "xattr@1.6.1"]}, +{"package": "target-lexicon@0.13.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["cfg-expr@0.20.8"], "dependencies": []}, +{"package": "tempfile@3.27.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "getrandom"], "parents": ["dialoguer@0.11.0", "dialoguer@0.12.0", "perry-doc-tests@0.5.1565", "perry-ext-parcel-watcher@0.5.1565", "perry-ui@0.5.1565", "perry-updater@0.5.1565", "perry@0.5.1565", "proptest@1.11.0", "rusty-fork@0.3.1", "uds_windows@1.2.1"], "dependencies": ["fastrand@2.4.1", "getrandom@0.4.2", "once_cell@1.21.4", "rustix@1.1.4", "windows-sys@0.61.2"]}, +{"package": "temporal_rs@0.2.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["compiled_data", "std", "tzdb"], "parents": ["perry-runtime@0.5.1565"], "dependencies": ["calendrical_calculations@0.2.4", "core_maths@0.1.1", "icu_calendar@2.3.0", "icu_locale_core@2.3.0", "ixdtf@0.6.5", "num-traits@0.2.19", "timezone_provider@0.2.6", "tinystr@0.8.4", "writeable@0.6.4"]}, +{"package": "tendril@0.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["markup5ever@0.39.0", "scraper@0.27.0"], "dependencies": ["new_debug_unreachable@1.0.6", "utf-8@0.7.6"]}, +{"package": "termcolor@1.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["env_logger@0.10.2"], "dependencies": ["winapi-util@0.1.11"]}, +{"package": "thiserror-impl@1.0.69", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["thiserror@1.0.69"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "thiserror-impl@2.0.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["thiserror@2.0.18"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "thiserror@1.0.69", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["dialoguer@0.11.0", "node-semver@2.2.0", "perry-codegen@0.5.1565", "perry-container-compose@0.5.1565", "perry-hir@0.5.1565", "perry-parser@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry-transform@0.5.1565", "tungstenite@0.24.0"], "dependencies": ["thiserror-impl@1.0.69"]}, +{"package": "thiserror@2.0.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["av-scenechange@0.14.1", "bson@3.1.0", "fast_image_resize@6.1.0", "gstreamer@0.25.3", "hickory-net@0.26.1", "hickory-proto@0.26.1", "hickory-resolver@0.26.1", "inkwell@0.9.0", "jni@0.22.4", "lopdf@0.39.0", "mongodb@3.8.2", "quinn-proto@0.11.15", "quinn@0.11.9", "rav1e@0.8.1", "redox_users@0.5.2", "rsqlite-vfs@0.1.1", "simple_asn1@0.6.4", "sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "tungstenite@0.29.0", "webview2-com-sys@0.39.1"], "dependencies": ["thiserror-impl@2.0.18"]}, +{"package": "thread_local@1.1.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tracing-subscriber@0.3.23"], "dependencies": ["cfg-if@1.0.4"]}, +{"package": "tiff@0.11.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "deflate", "fax", "jpeg", "lzw"], "parents": ["image@0.25.10"], "dependencies": ["fax@0.2.7", "flate2@1.1.10", "half@2.7.1", "quick-error@2.0.1", "weezl@0.1.12", "zune-jpeg@0.5.15"]}, +{"package": "time-core@0.1.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["time-macros@0.2.32", "time@0.3.55"], "dependencies": []}, +{"package": "time-macros@0.2.32", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["formatting", "parsing", "serde"], "parents": ["time@0.3.55"], "dependencies": ["num-conv@0.2.2", "time-core@0.1.9"]}, +{"package": "time@0.3.55", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "formatting", "macros", "parsing", "serde", "serde-human-readable", "std", "wasm-bindgen"], "parents": ["bson@3.1.0", "lopdf@0.39.0", "perry-ext-node-forge@0.5.1565", "printpdf@0.10.1", "simple_asn1@0.6.4", "zip@8.6.0"], "dependencies": ["deranged@0.5.8", "js-sys@0.3.99", "num-conv@0.2.2", "powerfmt@0.2.0", "serde_core@1.0.229", "time-core@0.1.9", "time-macros@0.2.32"]}, +{"package": "timezone_provider@0.2.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["std", "tzif"], "parents": ["perry-runtime@0.5.1565", "temporal_rs@0.2.6"], "dependencies": ["combine@4.6.7", "jiff-tzdb@0.1.6", "tinystr@0.8.4", "tzif@0.4.1", "zerotrie@0.2.5", "zerovec@0.11.8"]}, +{"package": "tiny-keccak@2.0.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "shake"], "parents": ["const-random-macro@0.1.16"], "dependencies": ["crunchy@0.2.4"]}, +{"package": "tiny_http@0.12.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-ui-geisterhand@0.5.1565"], "dependencies": ["ascii@1.1.0", "chunked_transfer@1.5.0", "httpdate@1.0.3", "log@0.4.34"]}, +{"package": "tinystr@0.8.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "zerovec"], "parents": ["icu_calendar@2.3.0", "icu_datetime@2.3.0", "icu_locale@2.2.0", "icu_locale_core@2.3.0", "icu_locale_fallback@2.3.0", "temporal_rs@0.2.6", "timezone_provider@0.2.6"], "dependencies": ["displaydoc@0.2.6", "serde_core@1.0.229", "zerovec@0.11.8"]}, +{"package": "tinyvec@1.11.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "rustc_1_57", "std", "tinyvec_macros"], "parents": ["allsorts-azul@0.16.5", "hickory-net@0.26.1", "hickory-proto@0.26.1", "quinn-proto@0.11.15", "unicode-normalization@0.1.25"], "dependencies": ["tinyvec_macros@0.1.1"]}, +{"package": "tinyvec_macros@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tinyvec@1.11.0"], "dependencies": []}, +{"package": "tls_codec@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["derive", "std", "tls_codec_derive"], "parents": ["x509-cert@0.3.0"], "dependencies": ["tls_codec_derive@0.4.2", "zeroize@1.8.2"]}, +{"package": "tls_codec_derive@0.4.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["tls_codec@0.4.2"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "tokio-cron-scheduler@0.15.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["chrono-tz@0.10.4", "chrono@0.4.45", "croner@3.0.1", "num-derive@0.4.2", "num-traits@0.2.19", "tokio@1.53.1", "tracing@0.1.44", "uuid@1.26.0"]}, +{"package": "tokio-macros@2.7.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tokio@1.53.1"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "tokio-rustls@0.26.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["aws_lc_rs", "default", "logging", "ring", "tls12"], "parents": ["hyper-rustls@0.27.9", "lettre@0.11.23", "mongodb@3.8.2", "perry-ext-http@0.5.1565", "perry-ext-net@0.5.1565", "perry-stdlib@0.5.1565", "reqwest@0.12.28", "tokio-tungstenite@0.29.0"], "dependencies": ["rustls@0.23.43", "tokio@1.53.1"]}, +{"package": "tokio-stream@0.1.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "fs", "time"], "parents": ["sqlx-core@0.9.0"], "dependencies": ["futures-core@0.3.34", "pin-project-lite@0.2.17", "tokio@1.53.1"]}, +{"package": "tokio-tungstenite@0.29.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["__rustls-tls", "connect", "default", "handshake", "rustls", "rustls-pki-types", "rustls-tls-webpki-roots", "stream", "tokio-rustls", "webpki-roots"], "parents": ["perry-ext-fastify@0.5.1565", "perry-ext-http@0.5.1565", "perry-ext-ws@0.5.1565", "perry-stdlib@0.5.1565", "perry@0.5.1565"], "dependencies": ["futures-util@0.3.34", "log@0.4.34", "rustls-pki-types@1.14.1", "rustls@0.23.43", "tokio-rustls@0.26.4", "tokio@1.53.1", "tungstenite@0.29.0", "webpki-roots@0.26.11"]}, +{"package": "tokio-util@0.7.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["codec", "compat", "default", "futures-io", "futures-util", "io", "rt"], "parents": ["combine@4.6.7", "h2@0.4.19", "mongodb@3.8.2", "redis@1.6.0"], "dependencies": ["bytes@1.12.1", "futures-core@0.3.34", "futures-io@0.3.34", "futures-sink@0.3.34", "futures-util@0.3.34", "pin-project-lite@0.2.17", "tokio@1.53.1"]}, +{"package": "tokio@1.53.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["bytes", "default", "fs", "full", "io-std", "io-util", "libc", "macros", "mio", "net", "parking_lot", "process", "rt", "rt-multi-thread", "signal", "signal-hook-registry", "socket2", "sync", "time", "tokio-macros", "tracing", "windows-sys"], "parents": ["combine@4.6.7", "h2@0.4.19", "hickory-net@0.26.1", "hickory-resolver@0.26.1", "hyper-rustls@0.27.9", "hyper-util@0.1.20", "hyper@1.11.1", "ksni@0.3.6", "lettre@0.11.23", "mongodb@3.8.2", "perry-container-compose@0.5.1565", "perry-ext-axios@0.5.1565", "perry-ext-fastify@0.5.1565", "perry-ext-fetch@0.5.1565", "perry-ext-http@0.5.1565", "perry-ext-ioredis@0.5.1565", "perry-ext-mongodb@0.5.1565", "perry-ext-mysql2@0.5.1565", "perry-ext-net@0.5.1565", "perry-ext-nodemailer@0.5.1565", "perry-ext-pg@0.5.1565", "perry-ext-ws@0.5.1565", "perry-stdlib@0.5.1565", "perry-ui-gtk4@0.5.1565", "perry@0.5.1565", "quinn@0.11.9", "redis@1.6.0", "reqwest@0.12.28", "sqlx-core@0.9.0", "sqlx-macros-core@0.9.0", "tokio-cron-scheduler@0.15.1", "tokio-rustls@0.26.4", "tokio-stream@0.1.18", "tokio-tungstenite@0.29.0", "tokio-util@0.7.18", "tower@0.5.3", "zbus@5.16.0"], "dependencies": ["bytes@1.12.1", "libc@0.2.189", "mio@1.2.1", "parking_lot@0.12.5", "pin-project-lite@0.2.17", "signal-hook-registry@1.4.8", "socket2@0.6.5", "tokio-macros@2.7.0", "tracing@0.1.44", "windows-sys@0.61.2"]}, +{"package": "toml@1.1.4+spec-1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "display", "parse", "serde", "std"], "parents": ["perry-runtime@0.5.1565", "perry@0.5.1565", "system-deps@7.0.8", "winresource@0.1.31"], "dependencies": ["indexmap@2.14.1", "serde_core@1.0.229", "serde_spanned@1.1.1", "toml_datetime@1.1.1+spec-1.1.0", "toml_parser@1.1.3+spec-1.1.0", "toml_writer@1.1.2+spec-1.1.0", "winnow@1.0.3"]}, +{"package": "toml_datetime@1.1.1+spec-1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "serde", "std"], "parents": ["toml@1.1.4+spec-1.1.0", "toml_edit@0.25.12+spec-1.1.0"], "dependencies": ["serde_core@1.0.229"]}, +{"package": "toml_edit@0.25.12+spec-1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["parse"], "parents": ["proc-macro-crate@3.5.0"], "dependencies": ["indexmap@2.14.1", "toml_datetime@1.1.1+spec-1.1.0", "toml_parser@1.1.3+spec-1.1.0", "winnow@1.0.3"]}, +{"package": "toml_parser@1.1.3+spec-1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["toml@1.1.4+spec-1.1.0", "toml_edit@0.25.12+spec-1.1.0"], "dependencies": ["winnow@1.0.3"]}, +{"package": "toml_writer@1.1.2+spec-1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "std"], "parents": ["toml@1.1.4+spec-1.1.0"], "dependencies": []}, +{"package": "tower-http@0.6.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["follow-redirect", "futures-util", "tower"], "parents": ["reqwest@0.12.28"], "dependencies": ["bitflags@2.12.1", "bytes@1.12.1", "futures-util@0.3.34", "http-body@1.0.1", "http@1.4.1", "pin-project-lite@0.2.17", "tower-layer@0.3.3", "tower-service@0.3.3", "tower@0.5.3", "url@2.5.8"]}, +{"package": "tower-layer@0.3.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tower-http@0.6.11", "tower@0.5.3"], "dependencies": []}, +{"package": "tower-service@0.3.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["hyper-rustls@0.27.9", "hyper-util@0.1.20", "reqwest@0.12.28", "tower-http@0.6.11", "tower@0.5.3"], "dependencies": []}, +{"package": "tower@0.5.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["futures-core", "futures-util", "pin-project-lite", "retry", "sync_wrapper", "timeout", "tokio", "util"], "parents": ["reqwest@0.12.28", "tower-http@0.6.11"], "dependencies": ["futures-core@0.3.34", "futures-util@0.3.34", "pin-project-lite@0.2.17", "sync_wrapper@1.0.2", "tokio@1.53.1", "tower-layer@0.3.3", "tower-service@0.3.3"]}, +{"package": "tracing-attributes@0.1.31", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tracing@0.1.44"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "tracing-core@0.1.36", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "once_cell", "std"], "parents": ["tracing-log@0.2.0", "tracing-subscriber@0.3.23", "tracing@0.1.44"], "dependencies": ["once_cell@1.21.4", "valuable@0.1.1"]}, +{"package": "tracing-log@0.2.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["log-tracer", "std"], "parents": ["tracing-subscriber@0.3.23"], "dependencies": ["log@0.4.34", "once_cell@1.21.4", "tracing-core@0.1.36"]}, +{"package": "tracing-subscriber@0.3.23", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "ansi", "default", "env-filter", "fmt", "matchers", "nu-ansi-term", "once_cell", "registry", "sharded-slab", "smallvec", "std", "thread_local", "tracing", "tracing-log"], "parents": ["perry-container-compose@0.5.1565"], "dependencies": ["matchers@0.2.0", "nu-ansi-term@0.50.3", "once_cell@1.21.4", "regex-automata@0.4.18", "sharded-slab@0.1.7", "smallvec@1.15.1", "thread_local@1.1.9", "tracing-core@0.1.36", "tracing-log@0.2.0", "tracing@0.1.44"]}, +{"package": "tracing@0.1.44", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["attributes", "default", "log", "std", "tracing-attributes"], "parents": ["h2@0.4.19", "hickory-net@0.26.1", "hickory-proto@0.26.1", "hickory-resolver@0.26.1", "hyper-util@0.1.20", "perry-container-compose@0.5.1565", "quinn-proto@0.11.15", "quinn-udp@0.5.14", "quinn@0.11.9", "sqlx-core@0.9.0", "sqlx-mysql@0.9.0", "sqlx-postgres@0.9.0", "sqlx-sqlite@0.9.0", "swc_bundler@37.0.0", "swc_common@18.0.1", "swc_ecma_codegen@21.0.0", "swc_ecma_loader@18.0.0", "swc_ecma_parser@29.0.2", "swc_ecma_parser@32.0.0", "swc_ecma_transforms_base@32.0.0", "swc_ecma_transforms_optimization@34.0.0", "swc_ecma_utils@25.0.0", "swc_ecma_visit@19.0.0", "swc_graph_analyzer@14.0.2", "tokio-cron-scheduler@0.15.1", "tokio@1.53.1", "tracing-subscriber@0.3.23", "zbus@5.16.0"], "dependencies": ["log@0.4.34", "pin-project-lite@0.2.17", "tracing-attributes@0.1.31", "tracing-core@0.1.36"]}, +{"package": "trait-variant@0.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["mpris-server@0.10.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "triomphe@0.1.15", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "serde", "stable_deref_trait", "std"], "parents": ["hstr@3.0.6"], "dependencies": ["serde@1.0.229", "stable_deref_trait@1.2.1"]}, +{"package": "try-lock@0.2.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["want@0.3.1"], "dependencies": []}, +{"package": "ttf-parser@0.25.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["apple-layout", "default", "glyph-names", "opentype-layout", "std", "variable-fonts"], "parents": ["lopdf@0.39.0"], "dependencies": []}, +{"package": "tungstenite@0.24.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["__rustls-tls", "data-encoding", "default", "handshake", "http", "httparse", "rustls", "rustls-pki-types", "rustls-tls-webpki-roots", "sha1", "webpki-roots"], "parents": ["perry-ui-android@0.5.1565"], "dependencies": ["byteorder@1.5.0", "bytes@1.12.1", "data-encoding@2.11.0", "http@1.4.1", "httparse@1.10.1", "log@0.4.34", "rand@0.8.7", "rustls-pki-types@1.14.1", "rustls@0.23.43", "sha1@0.10.6", "thiserror@1.0.69", "utf-8@0.7.6", "webpki-roots@0.26.11"]}, +{"package": "tungstenite@0.29.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["__rustls-tls", "data-encoding", "handshake", "http", "httparse", "rustls", "rustls-pki-types", "sha1"], "parents": ["tokio-tungstenite@0.29.0"], "dependencies": ["bytes@1.12.1", "data-encoding@2.11.0", "http@1.4.1", "httparse@1.10.1", "log@0.4.34", "rand@0.9.4", "rustls-pki-types@1.14.1", "rustls@0.23.43", "sha1@0.10.6", "thiserror@2.0.18"]}, +{"package": "typed-builder-macro@0.22.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["typed-builder@0.22.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "typed-builder@0.22.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["mongodb@3.8.2"], "dependencies": ["typed-builder-macro@0.22.0"]}, +{"package": "typed-path@0.12.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["zip@8.6.0"], "dependencies": []}, +{"package": "typenum@1.20.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["const-generics"], "parents": ["crypto-common@0.1.7", "generic-array@0.14.7", "hybrid-array@0.4.12"], "dependencies": []}, +{"package": "tzif@0.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["timezone_provider@0.2.6"], "dependencies": ["combine@4.6.7"]}, +{"package": "ucd-trie@0.1.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["allsorts-azul@0.16.5"], "dependencies": []}, +{"package": "uds_windows@1.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zbus@5.16.0"], "dependencies": ["memoffset@0.9.1", "tempfile@3.27.0", "windows-sys@0.61.2"]}, +{"package": "unarray@0.1.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["proptest@1.11.0"], "dependencies": []}, +{"package": "unicase@2.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["mime_guess@2.0.5"], "dependencies": []}, +{"package": "unicode-bidi@0.3.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "hardcoded-data", "std"], "parents": ["stringprep@0.1.5"], "dependencies": []}, +{"package": "unicode-canonical-combining-class@1.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["allsorts-azul@0.16.5"], "dependencies": []}, +{"package": "unicode-general-category@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["allsorts-azul@0.16.5"], "dependencies": []}, +{"package": "unicode-id-start@1.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["swc_ecma_ast@19.0.0", "swc_sourcemap@9.3.4"], "dependencies": []}, +{"package": "unicode-ident@1.0.24", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["proc-macro2@1.0.106", "syn@1.0.109", "syn@2.0.117", "syn@3.0.3", "wasm-bindgen-shared@0.2.122"], "dependencies": []}, +{"package": "unicode-joining-type@1.0.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["allsorts-azul@0.16.5"], "dependencies": []}, +{"package": "unicode-normalization@0.1.25", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["perry-runtime@0.5.1565", "stringprep@0.1.5"], "dependencies": ["tinyvec@1.11.0"]}, +{"package": "unicode-properties@0.1.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "emoji", "general-category"], "parents": ["stringprep@0.1.5"], "dependencies": []}, +{"package": "unicode-segmentation@1.13.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["convert_case@0.10.0", "perry-runtime@0.5.1565"], "dependencies": []}, +{"package": "unicode-width@0.1.14", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["cjk", "default"], "parents": ["miette@7.6.0"], "dependencies": []}, +{"package": "unicode-width@0.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["cjk", "default"], "parents": ["console@0.15.11", "console@0.16.4", "getopts@0.2.24", "indicatif@0.18.6", "swc_common@18.0.1"], "dependencies": []}, +{"package": "unicode-xid@0.2.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["derive_more-impl@2.1.1", "wit-parser@0.244.0"], "dependencies": []}, +{"package": "unit-prefix@0.5.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["indicatif@0.18.6"], "dependencies": []}, +{"package": "universal-hash@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["poly1305@0.8.0", "polyval@0.6.2"], "dependencies": ["crypto-common@0.1.7", "subtle@2.6.1"]}, +{"package": "universal-hash@0.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["polyval@0.7.3"], "dependencies": ["crypto-common@0.2.2", "ctutils@0.4.2"]}, +{"package": "unsafe-libyaml@0.2.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-runtime@0.5.1565", "serde_yaml@0.9.34+deprecated"], "dependencies": []}, +{"package": "untrusted@0.9.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ring@0.17.14", "rustls-webpki@0.103.13"], "dependencies": []}, +{"package": "url@2.5.8", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["hickory-net@0.26.1", "hickory-proto@0.26.1", "lettre@0.11.23", "perry-runtime@0.5.1565", "perry-validation@0.5.1565", "perry@0.5.1565", "redis@1.6.0", "reqwest@0.12.28", "sqlx-core@0.9.0", "sqlx-macros-core@0.9.0", "sqlx-sqlite@0.9.0", "swc_common@18.0.1", "swc_sourcemap@9.3.4", "tower-http@0.6.11", "validator@0.21.0"], "dependencies": ["form_urlencoded@1.2.2", "idna@1.1.0", "percent-encoding@2.3.2", "serde@1.0.229"]}, +{"package": "utf-8@0.7.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["tendril@0.5.0", "tungstenite@0.24.0"], "dependencies": []}, +{"package": "utf8_iter@1.0.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["icu_collections@2.2.0", "idna@1.1.0"], "dependencies": []}, +{"package": "utf8parse@0.2.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["anstream@1.0.0", "anstyle-parse@1.0.0"], "dependencies": []}, +{"package": "uuid@1.26.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["atomic", "default", "js", "md5", "rng", "serde", "sha1", "std", "v1", "v3", "v4", "v5", "v7"], "parents": ["bson@3.1.0", "debugid@0.8.0", "moka@0.12.15", "mongodb@3.8.2", "perry-ext-nodemailer@0.5.1565", "perry-ext-uuid@0.5.1565", "perry-stdlib@0.5.1565", "tokio-cron-scheduler@0.15.1", "zbus@5.16.0"], "dependencies": ["atomic@0.6.1", "getrandom@0.4.2", "js-sys@0.3.99", "md-5@0.10.6", "serde_core@1.0.229", "sha1_smol@1.0.1", "wasm-bindgen@0.2.122"]}, +{"package": "v_frame@0.3.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["av-scenechange@0.14.1", "av1-grain@0.2.5", "rav1e@0.8.1"], "dependencies": ["aligned-vec@0.6.4", "num-traits@0.2.19", "wasm-bindgen@0.2.122"]}, +{"package": "validator@0.21.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-validation@0.5.1565"], "dependencies": ["idna@1.1.0", "regex@1.13.1", "serde@1.0.229", "serde_derive@1.0.229", "serde_json@1.0.151", "url@2.5.8"]}, +{"package": "valuable@0.1.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "std"], "parents": ["tracing-core@0.1.36"], "dependencies": []}, +{"package": "vcpkg@0.2.15", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["libsqlite3-sys@0.37.0"], "dependencies": []}, +{"package": "version-compare@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["system-deps@7.0.8"], "dependencies": []}, +{"package": "version_check@0.9.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["ahash@0.8.12", "generic-array@0.14.7", "proc-macro-error-attr@1.0.4", "proc-macro-error@1.0.4", "slotmap@1.1.1", "smartstring@1.0.1", "winresource@0.1.31"], "dependencies": []}, +{"package": "vsimd@0.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "detect", "std"], "parents": ["base64-simd@0.8.0"], "dependencies": []}, +{"package": "wait-timeout@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["rusty-fork@0.3.1"], "dependencies": ["libc@0.2.189"]}, +{"package": "walkdir@2.5.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["jni@0.22.4", "notify@6.1.1", "perry-doc-tests@0.5.1565", "perry@0.5.1565"], "dependencies": ["same-file@1.0.6", "winapi-util@0.1.11"]}, +{"package": "want@0.3.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["hyper@1.11.1"], "dependencies": ["try-lock@0.2.5"]}, +{"package": "wasi@0.11.1+wasi-snapshot-preview1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["getrandom@0.2.17", "mio@0.8.11", "mio@1.2.1", "quanta@0.12.6"], "dependencies": []}, +{"package": "wasip2@1.0.3+wasi-0.2.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["getrandom@0.3.4", "getrandom@0.4.2"], "dependencies": ["wit-bindgen@0.57.1"]}, +{"package": "wasip3@0.4.0+wasi-0.3.0-rc-2026-01-06", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["getrandom@0.4.2"], "dependencies": ["wit-bindgen@0.51.0"]}, +{"package": "wasm-bindgen-futures@0.4.72", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["printpdf@0.10.1", "reqwest@0.12.28"], "dependencies": ["js-sys@0.3.99", "wasm-bindgen@0.2.122"]}, +{"package": "wasm-bindgen-macro-support@0.2.122", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wasm-bindgen-macro@0.2.122"], "dependencies": ["bumpalo@3.20.3", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117", "wasm-bindgen-shared@0.2.122"]}, +{"package": "wasm-bindgen-macro@0.2.122", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wasm-bindgen@0.2.122"], "dependencies": ["quote@1.0.45", "wasm-bindgen-macro-support@0.2.122"]}, +{"package": "wasm-bindgen-shared@0.2.122", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wasm-bindgen-macro-support@0.2.122", "wasm-bindgen@0.2.122"], "dependencies": ["unicode-ident@1.0.24"]}, +{"package": "wasm-bindgen@0.2.122", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "serde", "std"], "parents": ["chrono@0.4.45", "getrandom@0.2.17", "getrandom@0.3.4", "getrandom@0.4.2", "iana-time-zone@0.1.65", "js-sys@0.3.99", "printpdf@0.10.1", "rav1e@0.8.1", "reqwest@0.12.28", "rust_decimal@1.43.0", "sqlite-wasm-rs@0.5.5", "uuid@1.26.0", "v_frame@0.3.9", "wasm-bindgen-futures@0.4.72", "web-sys@0.3.99", "web-time@1.1.0"], "dependencies": ["cfg-if@1.0.4", "once_cell@1.21.4", "rustversion@1.0.22", "serde@1.0.229", "wasm-bindgen-macro@0.2.122", "wasm-bindgen-shared@0.2.122"]}, +{"package": "wasm-encoder@0.244.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["component-model", "std", "wasmparser"], "parents": ["wasm-metadata@0.244.0", "wit-component@0.244.0"], "dependencies": ["leb128fmt@0.1.0", "wasmparser@0.244.0"]}, +{"package": "wasm-encoder@0.258.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["component-model", "default", "std"], "parents": ["perry-codegen-wasm@0.5.1565"], "dependencies": ["leb128fmt@0.1.0", "wasmparser@0.258.0"]}, +{"package": "wasm-metadata@0.244.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wit-bindgen-rust@0.51.0", "wit-component@0.244.0"], "dependencies": ["anyhow@1.0.104", "indexmap@2.14.1", "wasm-encoder@0.244.0", "wasmparser@0.244.0"]}, +{"package": "wasmi@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["simd"], "parents": ["perry-wasm-host@0.5.1565"], "dependencies": ["spin@0.9.8", "wasmi_collections@1.1.0", "wasmi_core@1.1.0", "wasmi_ir@1.1.0", "wasmparser@0.239.0"]}, +{"package": "wasmi_collections@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wasmi@1.1.0"], "dependencies": []}, +{"package": "wasmi_core@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["simd"], "parents": ["wasmi@1.1.0", "wasmi_ir@1.1.0"], "dependencies": ["libm@0.2.16"]}, +{"package": "wasmi_ir@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["simd"], "parents": ["wasmi@1.1.0"], "dependencies": ["wasmi_core@1.1.0"]}, +{"package": "wasmparser@0.239.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["features", "simd", "validate"], "parents": ["wasmi@1.1.0"], "dependencies": ["bitflags@2.12.1"]}, +{"package": "wasmparser@0.244.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["component-model", "features", "hash-collections", "simd", "std", "validate"], "parents": ["wasm-encoder@0.244.0", "wasm-metadata@0.244.0", "wit-component@0.244.0", "wit-parser@0.244.0"], "dependencies": ["bitflags@2.12.1", "hashbrown@0.15.5", "indexmap@2.14.1", "semver@1.0.28"]}, +{"package": "wasmparser@0.258.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["component-model", "simd", "std"], "parents": ["wasm-encoder@0.258.0"], "dependencies": ["bitflags@2.12.1", "indexmap@2.14.1", "semver@1.0.28"]}, +{"package": "web-sys@0.3.99", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["AbortController", "AbortSignal", "Blob", "BlobPropertyBag", "EventTarget", "File", "FormData", "Headers", "Performance", "ReadableStream", "Request", "RequestCache", "RequestCredentials", "RequestInit", "RequestMode", "Response", "ServiceWorkerGlobalScope", "Window", "WorkerGlobalScope", "default", "std"], "parents": ["quanta@0.12.6", "reqwest@0.12.28"], "dependencies": ["js-sys@0.3.99", "wasm-bindgen@0.2.122"]}, +{"package": "web-time@1.1.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["governor@0.10.4", "indicatif@0.18.6", "quinn-proto@0.11.15", "quinn@0.11.9", "rustls-pki-types@1.14.1"], "dependencies": ["js-sys@0.3.99", "wasm-bindgen@0.2.122"]}, +{"package": "web_atoms@0.2.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["markup5ever@0.39.0"], "dependencies": ["phf@0.13.1", "phf_codegen@0.13.1", "string_cache@0.9.0", "string_cache_codegen@0.6.1"]}, +{"package": "webkit6-sys@0.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["webkit6@0.4.0"], "dependencies": ["gdk4-sys@0.9.6", "gio-sys@0.20.10", "glib-sys@0.20.10", "gobject-sys@0.20.10", "gtk4-sys@0.9.6", "javascriptcore6-sys@0.4.0", "libc@0.2.189", "soup3-sys@0.7.0", "system-deps@7.0.8"]}, +{"package": "webkit6@0.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ui-gtk4@0.5.1565"], "dependencies": ["gdk4@0.9.6", "gio@0.20.12", "glib@0.20.12", "gtk4@0.9.7", "javascriptcore6@0.4.0", "libc@0.2.189", "soup3@0.7.0", "webkit6-sys@0.4.0"]}, +{"package": "webpki-roots@0.26.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["tokio-tungstenite@0.29.0", "tungstenite@0.24.0"], "dependencies": ["webpki-roots@1.0.9"]}, +{"package": "webpki-roots@1.0.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["hyper-rustls@0.27.9", "lettre@0.11.23", "mongodb@3.8.2", "perry-ext-http@0.5.1565", "reqwest@0.12.28", "webpki-roots@0.26.11"], "dependencies": ["rustls-pki-types@1.14.1"]}, +{"package": "webview2-com-macros@0.8.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["webview2-com@0.39.1"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "webview2-com-sys@0.39.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["webview2-com@0.39.1"], "dependencies": ["thiserror@2.0.18", "windows-core@0.62.2", "windows@0.62.2"]}, +{"package": "webview2-com@0.39.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": [], "parents": ["perry-ui-windows@0.5.1565"], "dependencies": ["webview2-com-macros@0.8.1", "webview2-com-sys@0.39.1", "windows-core@0.62.2", "windows@0.62.2"]}, +{"package": "weezl@0.1.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["gif@0.14.2", "lopdf@0.39.0", "printpdf@0.10.1", "tiff@0.11.3"], "dependencies": []}, +{"package": "which@8.0.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "real-sys"], "parents": ["perry-container-compose@0.5.1565"], "dependencies": ["libc@0.2.189"]}, +{"package": "whoami@2.1.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["sqlx-postgres@0.9.0"], "dependencies": []}, +{"package": "widestring@1.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["ipconfig@0.3.4"], "dependencies": []}, +{"package": "winapi-i686-pc-windows-gnu@0.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["winapi@0.3.9"], "dependencies": []}, +{"package": "winapi-util@0.1.11", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["same-file@1.0.6", "termcolor@1.4.1", "walkdir@2.5.0"], "dependencies": ["windows-sys@0.61.2"]}, +{"package": "winapi-x86_64-pc-windows-gnu@0.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["winapi@0.3.9"], "dependencies": []}, +{"package": "winapi@0.3.9", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["consoleapi", "errhandlingapi", "fileapi", "handleapi", "minwinbase", "minwindef", "processenv", "processthreadsapi", "profileapi", "synchapi", "winbase", "winerror", "winnt"], "parents": ["atty@0.2.14", "fslock@0.2.1", "quanta@0.12.6"], "dependencies": ["winapi-i686-pc-windows-gnu@0.4.0", "winapi-x86_64-pc-windows-gnu@0.4.0"]}, +{"package": "windows-collections@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["windows@0.62.2"], "dependencies": ["windows-core@0.62.2"]}, +{"package": "windows-collections@0.3.2 [vendored]", "source": "third_party/windows-winui/windows-collections/Cargo.toml", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["windows-reactor@0.0.0 [vendored]"], "dependencies": ["windows-core@0.62.2 [vendored]"]}, +{"package": "windows-core@0.62.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "std"], "parents": ["iana-time-zone@0.1.65", "perry-ui-windows@0.5.1565", "webview2-com-sys@0.39.1", "webview2-com@0.39.1", "windows-collections@0.3.2", "windows-future@0.3.2", "windows-numerics@0.3.1", "windows@0.62.2"], "dependencies": ["windows-implement@0.60.2", "windows-interface@0.59.3", "windows-link@0.2.1", "windows-result@0.4.1", "windows-strings@0.5.1"]}, +{"package": "windows-core@0.62.2 [vendored]", "source": "third_party/windows-winui/windows-core/Cargo.toml", "name_is_direct_dependency": true, "lock_features": ["default", "proc-macros", "std"], "parents": ["windows-collections@0.3.2 [vendored]", "windows-future@0.3.2 [vendored]", "windows-numerics@0.3.1 [vendored]", "windows-reactor@0.0.0 [vendored]", "windows-reference@0.1.0 [vendored]", "windows-time@0.1.0 [vendored]"], "dependencies": ["windows-implement@0.60.2 [vendored]", "windows-interface@0.59.3 [vendored]", "windows-link@0.2.1 [vendored]", "windows-result@0.4.1 [vendored]", "windows-strings@0.5.1 [vendored]"]}, +{"package": "windows-future@0.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["windows@0.62.2"], "dependencies": ["windows-core@0.62.2", "windows-link@0.2.1", "windows-threading@0.2.1"]}, +{"package": "windows-future@0.3.2 [vendored]", "source": "third_party/windows-winui/windows-future/Cargo.toml", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["windows-reactor@0.0.0 [vendored]"], "dependencies": ["windows-core@0.62.2 [vendored]", "windows-link@0.2.1 [vendored]", "windows-threading@0.2.1 [vendored]"]}, +{"package": "windows-implement@0.60.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-core@0.62.2"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "windows-implement@0.60.2 [vendored]", "source": "third_party/windows-winui/windows-implement/Cargo.toml", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-core@0.62.2 [vendored]"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "windows-interface@0.59.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-core@0.62.2"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "windows-interface@0.59.3 [vendored]", "source": "third_party/windows-winui/windows-interface/Cargo.toml", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-core@0.62.2 [vendored]"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "windows-link@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["chrono@0.4.45", "hostname@0.4.2", "jni@0.22.4", "libloading@0.8.9", "parking_lot_core@0.9.12", "windows-core@0.62.2", "windows-future@0.3.2", "windows-numerics@0.3.1", "windows-registry@0.6.1", "windows-result@0.4.1", "windows-strings@0.5.1", "windows-sys@0.61.2", "windows-targets@0.53.5", "windows-threading@0.2.1"], "dependencies": []}, +{"package": "windows-link@0.2.1 [vendored]", "source": "third_party/windows-winui/windows-link/Cargo.toml", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-core@0.62.2 [vendored]", "windows-future@0.3.2 [vendored]", "windows-numerics@0.3.1 [vendored]", "windows-result@0.4.1 [vendored]", "windows-strings@0.5.1 [vendored]", "windows-threading@0.2.1 [vendored]"], "dependencies": []}, +{"package": "windows-numerics@0.3.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["windows@0.62.2"], "dependencies": ["windows-core@0.62.2", "windows-link@0.2.1"]}, +{"package": "windows-numerics@0.3.1 [vendored]", "source": "third_party/windows-winui/windows-numerics/Cargo.toml", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["windows-reactor@0.0.0 [vendored]"], "dependencies": ["windows-core@0.62.2 [vendored]", "windows-link@0.2.1 [vendored]"]}, +{"package": "windows-reactor@0.0.0 [vendored]", "source": "third_party/windows-winui/windows-reactor/Cargo.toml", "name_is_direct_dependency": true, "lock_features": ["default", "diagnostics"], "parents": ["perry-ui-windows-winui@0.5.1565"], "dependencies": ["rustc-hash@2.1.2", "windows-collections@0.3.2 [vendored]", "windows-core@0.62.2 [vendored]", "windows-future@0.3.2 [vendored]", "windows-numerics@0.3.1 [vendored]", "windows-reference@0.1.0 [vendored]", "windows-threading@0.2.1 [vendored]", "windows-time@0.1.0 [vendored]"]}, +{"package": "windows-reference@0.1.0 [vendored]", "source": "third_party/windows-winui/windows-reference/Cargo.toml", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["windows-reactor@0.0.0 [vendored]"], "dependencies": ["windows-core@0.62.2 [vendored]", "windows-time@0.1.0 [vendored]"]}, +{"package": "windows-registry@0.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["ipconfig@0.3.4"], "dependencies": ["windows-link@0.2.1", "windows-result@0.4.1", "windows-strings@0.5.1"]}, +{"package": "windows-result@0.4.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["ipconfig@0.3.4", "windows-core@0.62.2", "windows-registry@0.6.1"], "dependencies": ["windows-link@0.2.1"]}, +{"package": "windows-result@0.4.1 [vendored]", "source": "third_party/windows-winui/windows-result/Cargo.toml", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["windows-core@0.62.2 [vendored]"], "dependencies": ["windows-link@0.2.1 [vendored]"]}, +{"package": "windows-strings@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["windows-core@0.62.2", "windows-registry@0.6.1"], "dependencies": ["windows-link@0.2.1"]}, +{"package": "windows-strings@0.5.1 [vendored]", "source": "third_party/windows-winui/windows-strings/Cargo.toml", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["windows-core@0.62.2 [vendored]"], "dependencies": ["windows-link@0.2.1 [vendored]"]}, +{"package": "windows-sys@0.48.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["Win32", "Win32_Foundation", "Win32_Networking", "Win32_Networking_WinSock", "Win32_Security", "Win32_Storage", "Win32_Storage_FileSystem", "Win32_System", "Win32_System_IO", "Win32_System_Pipes", "Win32_System_Threading", "Win32_System_WindowsProgramming", "default"], "parents": ["mio@0.8.11", "notify@6.1.1"], "dependencies": ["windows-targets@0.48.5"]}, +{"package": "windows-sys@0.52.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["Win32", "Win32_Foundation", "Win32_System", "Win32_System_Threading", "default"], "parents": ["ring@0.17.14"], "dependencies": ["windows-targets@0.52.6"]}, +{"package": "windows-sys@0.59.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["Win32", "Win32_Foundation", "Win32_Networking", "Win32_Networking_WinSock", "Win32_Storage", "Win32_Storage_FileSystem", "Win32_System", "Win32_System_Console", "Win32_UI", "Win32_UI_Input", "Win32_UI_Input_KeyboardAndMouse", "default"], "parents": ["console@0.15.11", "gio-sys@0.20.10"], "dependencies": ["windows-targets@0.52.6"]}, +{"package": "windows-sys@0.60.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["Win32", "Win32_Foundation", "Win32_Networking", "Win32_Networking_WinSock", "Win32_System", "Win32_System_IO", "default"], "parents": ["quinn-udp@0.5.14"], "dependencies": ["windows-targets@0.53.5"]}, +{"package": "windows-sys@0.61.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["Wdk", "Wdk_Foundation", "Wdk_Storage", "Wdk_Storage_FileSystem", "Wdk_System", "Wdk_System_IO", "Win32", "Win32_Foundation", "Win32_Globalization", "Win32_NetworkManagement", "Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_Ndis", "Win32_Networking", "Win32_Networking_WinSock", "Win32_Security", "Win32_Security_Authentication", "Win32_Security_Authentication_Identity", "Win32_Security_Authorization", "Win32_Security_Credentials", "Win32_Security_Cryptography", "Win32_Storage", "Win32_Storage_FileSystem", "Win32_System", "Win32_System_Com", "Win32_System_Console", "Win32_System_Diagnostics", "Win32_System_Diagnostics_Debug", "Win32_System_IO", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Pipes", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_WindowsProgramming", "Win32_UI", "Win32_UI_Input", "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_Shell", "default"], "parents": ["anstyle-query@1.1.5", "anstyle-wincon@3.0.11", "async-io@2.6.0", "async-signal@0.2.14", "console@0.16.4", "dirs-sys@0.5.0", "errno@0.3.14", "etcetera@0.11.0", "gio-sys@0.22.0", "ipconfig@0.3.4", "is-terminal@0.4.17", "mio@1.2.1", "nu-ansi-term@0.50.3", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry@0.5.1565", "polling@3.11.0", "rustix@1.1.4", "schannel@0.1.29", "socket2@0.6.5", "stacker@0.1.25", "tempfile@3.27.0", "tokio@1.53.1", "uds_windows@1.2.1", "winapi-util@0.1.11", "zbus@5.16.0"], "dependencies": ["windows-link@0.2.1"]}, +{"package": "windows-targets@0.48.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-sys@0.48.0"], "dependencies": ["windows_aarch64_gnullvm@0.48.5", "windows_aarch64_msvc@0.48.5", "windows_i686_gnu@0.48.5", "windows_i686_msvc@0.48.5", "windows_x86_64_gnu@0.48.5", "windows_x86_64_gnullvm@0.48.5", "windows_x86_64_msvc@0.48.5"]}, +{"package": "windows-targets@0.52.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-sys@0.52.0", "windows-sys@0.59.0"], "dependencies": ["windows_aarch64_gnullvm@0.52.6", "windows_aarch64_msvc@0.52.6", "windows_i686_gnu@0.52.6", "windows_i686_gnullvm@0.52.6", "windows_i686_msvc@0.52.6", "windows_x86_64_gnu@0.52.6", "windows_x86_64_gnullvm@0.52.6", "windows_x86_64_msvc@0.52.6"]}, +{"package": "windows-targets@0.53.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-sys@0.60.2"], "dependencies": ["windows-link@0.2.1", "windows_aarch64_gnullvm@0.53.1", "windows_aarch64_msvc@0.53.1", "windows_i686_gnu@0.53.1", "windows_i686_gnullvm@0.53.1", "windows_i686_msvc@0.53.1", "windows_x86_64_gnu@0.53.1", "windows_x86_64_gnullvm@0.53.1", "windows_x86_64_msvc@0.53.1"]}, +{"package": "windows-threading@0.2.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-future@0.3.2"], "dependencies": ["windows-link@0.2.1"]}, +{"package": "windows-threading@0.2.1 [vendored]", "source": "third_party/windows-winui/windows-threading/Cargo.toml", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["windows-future@0.3.2 [vendored]", "windows-reactor@0.0.0 [vendored]"], "dependencies": ["windows-link@0.2.1 [vendored]"]}, +{"package": "windows-time@0.1.0 [vendored]", "source": "third_party/windows-winui/windows-time/Cargo.toml", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["windows-reactor@0.0.0 [vendored]", "windows-reference@0.1.0 [vendored]"], "dependencies": ["windows-core@0.62.2 [vendored]"]}, +{"package": "windows@0.35.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["Devices", "Devices_Geolocation", "Foundation", "Foundation_Collections", "UI", "UI_Xaml", "UI_Xaml_Controls", "UI_Xaml_Controls_Maps", "UI_Xaml_Hosting", "Win32", "Win32_Foundation", "Win32_System", "Win32_System_WinRT", "Win32_System_WinRT_Xaml", "Win32_UI", "Win32_UI_WindowsAndMessaging", "default"], "parents": ["perry-ui-windows@0.5.1565"], "dependencies": ["windows_aarch64_msvc@0.35.0", "windows_i686_gnu@0.35.0", "windows_i686_msvc@0.35.0", "windows_x86_64_gnu@0.35.0", "windows_x86_64_msvc@0.35.0"]}, +{"package": "windows@0.62.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["Data", "Data_Pdf", "Foundation", "Media", "Media_Core", "Media_Playback", "Storage", "Storage_Streams", "Win32", "Win32_Foundation", "Win32_Globalization", "Win32_Graphics", "Win32_Graphics_Gdi", "Win32_Graphics_GdiPlus", "Win32_Media", "Win32_Media_Audio", "Win32_Networking", "Win32_Networking_WinHttp", "Win32_Storage", "Win32_Storage_Xps", "Win32_System", "Win32_System_Com", "Win32_System_Com_StructuredStorage", "Win32_System_DataExchange", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Ole", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_Variant", "Win32_System_WinRT", "Win32_UI", "Win32_UI_Controls", "Win32_UI_HiDpi", "Win32_UI_Input", "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_Shell", "Win32_UI_Shell_Common", "Win32_UI_WindowsAndMessaging", "default", "std"], "parents": ["perry-ui-windows-winui@0.5.1565", "perry-ui-windows@0.5.1565", "webview2-com-sys@0.39.1", "webview2-com@0.39.1"], "dependencies": ["windows-collections@0.3.2", "windows-core@0.62.2", "windows-future@0.3.2", "windows-numerics@0.3.1"]}, +{"package": "windows_aarch64_gnullvm@0.48.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.48.5"], "dependencies": []}, +{"package": "windows_aarch64_gnullvm@0.52.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.52.6"], "dependencies": []}, +{"package": "windows_aarch64_gnullvm@0.53.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.53.5"], "dependencies": []}, +{"package": "windows_aarch64_msvc@0.35.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows@0.35.0"], "dependencies": []}, +{"package": "windows_aarch64_msvc@0.48.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.48.5"], "dependencies": []}, +{"package": "windows_aarch64_msvc@0.52.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.52.6"], "dependencies": []}, +{"package": "windows_aarch64_msvc@0.53.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.53.5"], "dependencies": []}, +{"package": "windows_i686_gnu@0.35.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows@0.35.0"], "dependencies": []}, +{"package": "windows_i686_gnu@0.48.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.48.5"], "dependencies": []}, +{"package": "windows_i686_gnu@0.52.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.52.6"], "dependencies": []}, +{"package": "windows_i686_gnu@0.53.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.53.5"], "dependencies": []}, +{"package": "windows_i686_gnullvm@0.52.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.52.6"], "dependencies": []}, +{"package": "windows_i686_gnullvm@0.53.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.53.5"], "dependencies": []}, +{"package": "windows_i686_msvc@0.35.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows@0.35.0"], "dependencies": []}, +{"package": "windows_i686_msvc@0.48.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.48.5"], "dependencies": []}, +{"package": "windows_i686_msvc@0.52.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.52.6"], "dependencies": []}, +{"package": "windows_i686_msvc@0.53.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.53.5"], "dependencies": []}, +{"package": "windows_x86_64_gnu@0.35.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows@0.35.0"], "dependencies": []}, +{"package": "windows_x86_64_gnu@0.48.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.48.5"], "dependencies": []}, +{"package": "windows_x86_64_gnu@0.52.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.52.6"], "dependencies": []}, +{"package": "windows_x86_64_gnu@0.53.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.53.5"], "dependencies": []}, +{"package": "windows_x86_64_gnullvm@0.48.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.48.5"], "dependencies": []}, +{"package": "windows_x86_64_gnullvm@0.52.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.52.6"], "dependencies": []}, +{"package": "windows_x86_64_gnullvm@0.53.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.53.5"], "dependencies": []}, +{"package": "windows_x86_64_msvc@0.35.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows@0.35.0"], "dependencies": []}, +{"package": "windows_x86_64_msvc@0.48.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.48.5"], "dependencies": []}, +{"package": "windows_x86_64_msvc@0.52.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.52.6"], "dependencies": []}, +{"package": "windows_x86_64_msvc@0.53.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["windows-targets@0.53.5"], "dependencies": []}, +{"package": "winnow@0.7.15", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "std"], "parents": ["cron@0.17.0"], "dependencies": ["memchr@2.8.1"]}, +{"package": "winnow@1.0.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "ascii", "binary", "default", "parser", "std"], "parents": ["toml@1.1.4+spec-1.1.0", "toml_edit@0.25.12+spec-1.1.0", "toml_parser@1.1.3+spec-1.1.0", "zbus@5.16.0", "zbus_names@4.3.2", "zvariant@5.12.0", "zvariant_utils@3.4.0"], "dependencies": ["memchr@2.8.1"]}, +{"package": "winresource@0.1.31", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "toml"], "parents": ["perry@0.5.1565"], "dependencies": ["toml@1.1.4+spec-1.1.0", "version_check@0.9.5"]}, +{"package": "wit-bindgen-core@0.51.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wit-bindgen-rust-macro@0.51.0", "wit-bindgen-rust@0.51.0"], "dependencies": ["anyhow@1.0.104", "heck@0.5.0", "wit-parser@0.244.0"]}, +{"package": "wit-bindgen-rust-macro@0.51.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["async"], "parents": ["wit-bindgen@0.51.0"], "dependencies": ["anyhow@1.0.104", "prettyplease@0.2.37", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117", "wit-bindgen-core@0.51.0", "wit-bindgen-rust@0.51.0"]}, +{"package": "wit-bindgen-rust@0.51.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wit-bindgen-rust-macro@0.51.0"], "dependencies": ["anyhow@1.0.104", "heck@0.5.0", "indexmap@2.14.1", "prettyplease@0.2.37", "syn@2.0.117", "wasm-metadata@0.244.0", "wit-bindgen-core@0.51.0", "wit-component@0.244.0"]}, +{"package": "wit-bindgen@0.51.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["async", "std"], "parents": ["wasip3@0.4.0+wasi-0.3.0-rc-2026-01-06"], "dependencies": ["wit-bindgen-rust-macro@0.51.0"]}, +{"package": "wit-bindgen@0.57.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wasip2@1.0.3+wasi-0.2.9"], "dependencies": []}, +{"package": "wit-component@0.244.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["wit-bindgen-rust@0.51.0"], "dependencies": ["anyhow@1.0.104", "bitflags@2.12.1", "indexmap@2.14.1", "log@0.4.34", "serde@1.0.229", "serde_derive@1.0.229", "serde_json@1.0.151", "wasm-encoder@0.244.0", "wasm-metadata@0.244.0", "wasmparser@0.244.0", "wit-parser@0.244.0"]}, +{"package": "wit-parser@0.244.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["decoding", "default", "serde", "serde_json"], "parents": ["wit-bindgen-core@0.51.0", "wit-component@0.244.0"], "dependencies": ["anyhow@1.0.104", "id-arena@2.3.0", "indexmap@2.14.1", "log@0.4.34", "semver@1.0.28", "serde@1.0.229", "serde_derive@1.0.229", "serde_json@1.0.151", "unicode-xid@0.2.6", "wasmparser@0.244.0"]}, +{"package": "writeable@0.6.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "either"], "parents": ["fixed_decimal@0.7.2", "icu_datetime@2.3.0", "icu_decimal@2.3.0", "icu_locale_core@2.3.0", "icu_pattern@0.5.0", "icu_provider@2.3.1", "perry-runtime@0.5.1565", "potential_utf@0.1.5", "temporal_rs@0.2.6"], "dependencies": ["either@1.16.0"]}, +{"package": "wyz@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["bitvec@1.0.1"], "dependencies": ["tap@1.0.1"]}, +{"package": "x25519-dalek@2.0.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["alloc", "default", "precomputed-tables", "static_secrets", "zeroize"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["curve25519-dalek@4.1.3", "rand_core@0.6.4", "serde@1.0.229", "zeroize@1.8.2"]}, +{"package": "x448@0.14.0-pre.12", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["default", "getrandom", "static_secrets"], "parents": ["perry-stdlib@0.5.1565"], "dependencies": ["ed448-goldilocks@0.14.0-pre.15", "zeroize@1.8.2"]}, +{"package": "x509-cert@0.3.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["builder", "default", "hazmat", "pem", "signature", "std"], "parents": ["perry-ext-http@0.5.1565", "perry-ext-node-forge@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565"], "dependencies": ["const-oid@0.10.2", "der@0.8.1", "sha1@0.11.0", "signature@3.0.0", "spki@0.8.0", "tls_codec@0.4.2"]}, +{"package": "xattr@1.6.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "unsupported"], "parents": ["tar@0.4.46"], "dependencies": ["libc@0.2.189", "rustix@1.1.4"]}, +{"package": "xxhash-rust@0.8.18", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["xxh3", "xxh64"], "parents": ["perry-runtime@0.5.1565", "redis@1.6.0"], "dependencies": []}, +{"package": "y4m@0.8.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["av-scenechange@0.14.1"], "dependencies": []}, +{"package": "yasna@0.5.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "std"], "parents": ["p12@0.6.3"], "dependencies": []}, +{"package": "yoke-derive@0.8.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["yoke@0.8.3"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117", "synstructure@0.13.2"]}, +{"package": "yoke@0.8.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "derive", "zerofrom"], "parents": ["icu_collections@2.2.0", "icu_provider@2.3.1", "zerotrie@0.2.5", "zerovec@0.11.8"], "dependencies": ["stable_deref_trait@1.2.1", "yoke-derive@0.8.2", "zerofrom@0.1.8"]}, +{"package": "zbus@5.16.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["async-executor", "async-fs", "async-io", "async-lock", "async-process", "async-task", "blocking", "blocking-api", "default", "tokio"], "parents": ["ksni@0.3.6", "mpris-server@0.10.0"], "dependencies": ["async-broadcast@0.7.2", "async-executor@1.14.0", "async-io@2.6.0", "async-lock@3.4.2", "async-process@2.5.0", "async-recursion@1.1.1", "async-task@4.7.1", "async-trait@0.1.92", "blocking@1.6.2", "enumflags2@0.7.12", "event-listener@5.4.1", "futures-core@0.3.34", "futures-lite@2.6.1", "hex@0.4.3", "libc@0.2.189", "ordered-stream@0.2.0", "rustix@1.1.4", "serde@1.0.229", "serde_repr@0.1.20", "tokio@1.53.1", "tracing@0.1.44", "uds_windows@1.2.1", "uuid@1.26.0", "windows-sys@0.61.2", "winnow@1.0.3", "zbus_macros@5.16.0", "zbus_names@4.3.2", "zvariant@5.12.0"]}, +{"package": "zbus_macros@5.16.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["blocking-api", "default"], "parents": ["zbus@5.16.0"], "dependencies": ["proc-macro-crate@3.5.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117", "zbus_names@4.3.2", "zvariant@5.12.0", "zvariant_utils@3.4.0"]}, +{"package": "zbus_names@4.3.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zbus@5.16.0", "zbus_macros@5.16.0"], "dependencies": ["serde@1.0.229", "winnow@1.0.3", "zvariant@5.12.0"]}, +{"package": "zerocopy-derive@0.8.50", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zerocopy@0.8.50"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "zerocopy@0.8.50", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["derive", "simd", "zerocopy-derive"], "parents": ["ahash@0.8.12", "half@2.7.1", "ppv-lite86@0.2.21", "sha3-utils@0.5.0"], "dependencies": ["zerocopy-derive@0.8.50"]}, +{"package": "zerofrom-derive@0.1.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zerofrom@0.1.8"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117", "synstructure@0.13.2"]}, +{"package": "zerofrom@0.1.8", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "derive"], "parents": ["icu_collections@2.2.0", "icu_provider@2.3.1", "yoke@0.8.3", "zerotrie@0.2.5", "zerovec@0.11.8"], "dependencies": ["zerofrom-derive@0.1.7"]}, +{"package": "zeroize@1.8.2", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "derive", "zeroize_derive"], "parents": ["aws-lc-rs@1.17.0", "bcrypt@0.19.3", "block-buffer@0.12.0", "chacha20poly1305@0.10.1", "cipher@0.4.4", "crypto-bigint@0.5.5", "crypto-bigint@0.7.5", "curve25519-dalek@4.1.3", "der@0.7.10", "der@0.8.1", "dialoguer@0.11.0", "dialoguer@0.12.0", "digest@0.11.3", "ed25519-dalek@2.2.0", "elliptic-curve@0.13.8", "elliptic-curve@0.14.0", "generic-array@0.14.7", "hybrid-array@0.4.12", "jsonwebtoken@11.0.0", "num-bigint-dig@0.8.6", "rsa@0.10.0-rc.18", "rsa@0.9.10", "rustls-pki-types@1.14.1", "rustls@0.23.43", "sec1@0.7.3", "sec1@0.8.1", "tls_codec@0.4.2", "x25519-dalek@2.0.1", "x448@0.14.0-pre.12", "zip@8.6.0"], "dependencies": ["zeroize_derive@1.4.3"]}, +{"package": "zeroize_derive@1.4.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zeroize@1.8.2"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117"]}, +{"package": "zerotrie@0.2.5", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "default", "yoke", "zerofrom"], "parents": ["icu_properties@2.2.0", "icu_provider@2.3.1", "icu_time@2.3.0", "timezone_provider@0.2.6"], "dependencies": ["displaydoc@0.2.6", "yoke@0.8.3", "zerofrom@0.1.8", "zerovec@0.11.8"]}, +{"package": "zerovec-derive@0.11.6", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["zerovec@0.11.8"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "syn@3.0.3"]}, +{"package": "zerovec@0.11.8", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["alloc", "derive", "yoke"], "parents": ["icu_calendar@2.3.0", "icu_collections@2.2.0", "icu_datetime@2.3.0", "icu_decimal@2.3.0", "icu_locale@2.2.0", "icu_locale_core@2.3.0", "icu_locale_fallback@2.3.0", "icu_normalizer@2.2.0", "icu_pattern@0.5.0", "icu_plurals@2.3.0", "icu_properties@2.2.0", "icu_provider@2.3.1", "icu_time@2.3.0", "potential_utf@0.1.5", "timezone_provider@0.2.6", "tinystr@0.8.4", "zerotrie@0.2.5"], "dependencies": ["serde@1.0.229", "yoke@0.8.3", "zerofrom@0.1.8", "zerovec-derive@0.11.6"]}, +{"package": "zip@8.6.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["_bzip2_any", "_deflate-any", "aes-crypto", "bzip2", "default", "deflate", "deflate-flate2", "deflate-flate2-zlib-rs", "deflate-zopfli", "deflate64", "getrandom", "lzma", "ppmd", "time", "xz", "zstd"], "parents": ["perry@0.5.1565"], "dependencies": ["aes@0.9.1", "bzip2@0.6.1", "constant_time_eq@0.4.2", "crc32fast@1.5.0", "deflate64@0.1.12", "flate2@1.1.10", "getrandom@0.4.2", "hmac@0.13.0", "indexmap@2.14.1", "lzma-rust2@0.16.4", "memchr@2.8.1", "pbkdf2@0.13.0", "ppmd-rust@1.4.0", "sha1@0.11.0", "time@0.3.55", "typed-path@0.12.3", "zeroize@1.8.2", "zopfli@0.8.3", "zstd@0.13.3"]}, +{"package": "zlib-rs@0.6.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["rust-allocator", "std"], "parents": ["flate2@1.1.10"], "dependencies": []}, +{"package": "zmij@1.0.21", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": [], "parents": ["serde_json@1.0.151"], "dependencies": []}, +{"package": "zopfli@0.8.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "gzip", "std", "zlib"], "parents": ["zip@8.6.0"], "dependencies": ["bumpalo@3.20.3", "crc32fast@1.5.0", "log@0.4.34", "simd-adler32@0.3.9"]}, +{"package": "zstd-safe@7.2.4", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["arrays", "legacy", "std", "zdict_builder"], "parents": ["zstd@0.13.3"], "dependencies": ["zstd-sys@2.0.16+zstd.1.5.7"]}, +{"package": "zstd-sys@2.0.16+zstd.1.5.7", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["legacy", "std", "zdict_builder"], "parents": ["zstd-safe@7.2.4"], "dependencies": ["cc@1.4.4", "pkg-config@0.3.33"]}, +{"package": "zstd@0.13.3", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": true, "lock_features": ["arrays", "default", "legacy", "zdict_builder"], "parents": ["perry-ext-zlib@0.5.1565", "perry-runtime@0.5.1565", "perry-stdlib@0.5.1565", "perry@0.5.1565", "zip@8.6.0"], "dependencies": ["zstd-safe@7.2.4"]}, +{"package": "zune-core@0.5.1", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["std"], "parents": ["image@0.25.10", "zune-jpeg@0.5.15"], "dependencies": []}, +{"package": "zune-inflate@0.2.54", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["simd-adler32", "zlib"], "parents": ["exr@1.74.0"], "dependencies": ["simd-adler32@0.3.9"]}, +{"package": "zune-jpeg@0.5.15", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "neon", "std", "x86"], "parents": ["image@0.25.10", "tiff@0.11.3"], "dependencies": ["zune-core@0.5.1"]}, +{"package": "zvariant@5.12.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default", "enumflags2"], "parents": ["zbus@5.16.0", "zbus_macros@5.16.0", "zbus_names@4.3.2"], "dependencies": ["endi@1.1.1", "enumflags2@0.7.12", "serde@1.0.229", "winnow@1.0.3", "zvariant_derive@5.12.0", "zvariant_utils@3.4.0"]}, +{"package": "zvariant_derive@5.12.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["zvariant@5.12.0"], "dependencies": ["proc-macro-crate@3.5.0", "proc-macro2@1.0.106", "quote@1.0.45", "syn@2.0.117", "zvariant_utils@3.4.0"]}, +{"package": "zvariant_utils@3.4.0", "source": "registry+https://github.com/rust-lang/crates.io-index", "name_is_direct_dependency": false, "lock_features": ["default"], "parents": ["zbus_macros@5.16.0", "zvariant@5.12.0", "zvariant_derive@5.12.0"], "dependencies": ["proc-macro2@1.0.106", "quote@1.0.45", "serde@1.0.229", "syn@2.0.117", "winnow@1.0.3"]} +], +"other_manifests": [ +{"manifest": "benchmarks/compiler_output/fixtures/native_memory_fixture_project/node_modules/@perry-fixtures/native-memory-fixture/native/Cargo.toml", "vendored": false, "external_declarations": []}, +{"manifest": "benchmarks/honest_bench/workloads/1_json_pipeline/rust/Cargo.toml", "vendored": false, "external_declarations": [{"name": "serde", "kind": "dependencies", "target": null, "version": "1", "features": ["derive"]}, {"name": "serde_json", "kind": "dependencies", "target": null, "version": "1"}]}, +{"manifest": "benchmarks/honest_bench/workloads/3_image_convolution/rust/Cargo.toml", "vendored": false, "external_declarations": []}, +{"manifest": "benchmarks/json_performance/results/json-depth-scanning/prototypes/depth19/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-depth-scanning/prototypes/depth20/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-depth-scanning/prototypes/depth21/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-depth-scanning/prototypes/depth22/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-depth-scanning/prototypes/depth23/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-depth-scanning/prototypes/depth24/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-escaped-decoding/prototypes/decode13/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-escaped-decoding/prototypes/decode14/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-escaped-decoding/prototypes/decode15/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-escaped-decoding/prototypes/decode17-prototype/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libc", "kind": "dev-dependencies", "target": null, "version": "0.2"}]}, +{"manifest": "benchmarks/json_performance/results/json-string-counting/fused/Cargo.toml", "vendored": false, "external_declarations": []}, +{"manifest": "benchmarks/json_polyglot/Cargo.toml", "vendored": false, "external_declarations": [{"name": "serde", "kind": "dependencies", "target": null, "version": "1", "features": ["derive"]}, {"name": "serde_json", "kind": "dependencies", "target": null, "version": "1"}]}, +{"manifest": "crates/perry-container-compose/fuzz/Cargo.toml", "vendored": false, "external_declarations": [{"name": "libfuzzer-sys", "kind": "dependencies", "target": null, "version": "0.4"}]}, +{"manifest": "experiments/llvm-inprocess-spike/Cargo.toml", "vendored": false, "external_declarations": [{"name": "inkwell", "kind": "dependencies", "target": null, "version": "0.9.0", "features": ["llvm22-1"]}, {"name": "llvm-sys", "kind": "dependencies", "target": null, "version": "221"}]}, +{"manifest": "tests/fixtures/issue_8075_provider_gc/stdlib-provider/Cargo.toml", "vendored": false, "external_declarations": []}, +{"manifest": "tests/fixtures/next-app-route/provider/Cargo.toml", "vendored": false, "external_declarations": []}, +{"manifest": "tests/release/packages/next-app-route/provider/Cargo.toml", "vendored": false, "external_declarations": []}, +{"manifest": "tests/release/packages/next-app-route/provider/runtime/Cargo.toml", "vendored": false, "external_declarations": []}, +{"manifest": "tests/release/packages/next-app-route/provider/stdlib/Cargo.toml", "vendored": false, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-collections/Cargo.toml", "vendored": true, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-core/Cargo.toml", "vendored": true, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-future/Cargo.toml", "vendored": true, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-implement/Cargo.toml", "vendored": true, "external_declarations": [{"name": "proc-macro2", "kind": "dependencies", "target": null, "version": "1.0", "default-features": false}, {"name": "quote", "kind": "dependencies", "target": null, "version": "1.0", "default-features": false}, {"name": "syn", "kind": "dependencies", "target": null, "version": "2.0", "default-features": false, "features": ["parsing", "proc-macro", "printing", "full", "clone-impls"]}]}, +{"manifest": "third_party/windows-winui/windows-interface/Cargo.toml", "vendored": true, "external_declarations": [{"name": "proc-macro2", "kind": "dependencies", "target": null, "version": "1.0", "default-features": false}, {"name": "quote", "kind": "dependencies", "target": null, "version": "1.0", "default-features": false}, {"name": "syn", "kind": "dependencies", "target": null, "version": "2.0", "default-features": false, "features": ["parsing", "proc-macro", "printing", "full", "clone-impls"]}]}, +{"manifest": "third_party/windows-winui/windows-link/Cargo.toml", "vendored": true, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-numerics/Cargo.toml", "vendored": true, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-reactor/Cargo.toml", "vendored": true, "external_declarations": [{"name": "rustc-hash", "kind": "dependencies", "target": null, "version": "2"}]}, +{"manifest": "third_party/windows-winui/windows-reference/Cargo.toml", "vendored": true, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-result/Cargo.toml", "vendored": true, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-strings/Cargo.toml", "vendored": true, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-threading/Cargo.toml", "vendored": true, "external_declarations": []}, +{"manifest": "third_party/windows-winui/windows-time/Cargo.toml", "vendored": true, "external_declarations": []} +] +} diff --git a/docs/audits/rust-dependency-build-graphs-2026-09-14.json b/docs/audits/rust-dependency-build-graphs-2026-09-14.json new file mode 100644 index 0000000000..cd657e2e6d --- /dev/null +++ b/docs/audits/rust-dependency-build-graphs-2026-09-14.json @@ -0,0 +1,25 @@ +{ +"semantics": "Deduplicated external package-version identities from cargo tree normal+build, locked/offline. Graph approximates Cargo builds; no builds or binary/performance measurement.", +"graphs": [ +{"configuration": "CLI default", "target": "x86_64-pc-windows-msvc", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry", "-e", "normal,build", "--target", "x86_64-pc-windows-msvc", "--prefix", "none", "--format", "{p}"], "external_package_versions": 352, "packages": ["adler2 v2.0.1", "aes v0.9.1", "ahash v0.8.12", "aho-corasick v1.1.4", "allocator-api2 v0.2.21", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anstyle-wincon v3.0.11", "anyhow v1.0.104", "ar_archive_writer v0.5.1", "arrayvec v0.7.6", "ast_node v5.0.0", "atomic-waker v1.1.2", "autocfg v1.5.1", "base16ct v0.2.0", "base64 v0.22.1", "base64ct v1.8.3", "better_scoped_tls v1.0.1", "bitflags v2.12.1", "block-buffer v0.10.4", "block-buffer v0.12.0", "bumpalo v3.20.3", "bytes v1.12.1", "bytes-str v0.2.7", "bzip2 v0.6.1", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "chrono v0.4.45", "cipher v0.5.2", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "cmov v0.5.4", "colorchoice v1.0.5", "console v0.16.4", "const-oid v0.10.2", "const-oid v0.9.6", "constant_time_eq v0.4.2", "cpubits v0.1.1", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "crc32fast v1.5.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-deque v0.8.6", "crossbeam-epoch v0.9.20", "crossbeam-utils v0.8.21", "crypto-bigint v0.5.5", "crypto-common v0.1.7", "crypto-common v0.2.2", "ctutils v0.4.2", "curve25519-dalek v4.1.3", "curve25519-dalek-derive v0.1.1", "data-encoding v2.11.0", "deflate64 v0.1.12", "der v0.7.10", "der v0.8.1", "der_derive v0.8.0", "deranged v0.5.8", "dialoguer v0.12.0", "digest v0.10.7", "digest v0.11.3", "dirs v6.0.0", "dirs-sys v0.5.0", "displaydoc v0.2.6", "dotenvy v0.15.7", "ecdsa v0.16.9", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "either v1.16.0", "elliptic-curve v0.13.8", "encode_unicode v1.0.0", "encoding_rs v0.8.35", "env_logger v0.10.2", "equivalent v1.0.2", "fastrand v2.4.1", "ff v0.13.1", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "flate2 v1.1.10", "form_urlencoded v1.2.2", "from_variant v3.0.0", "fslock v0.2.1", "futures-channel v0.3.32", "futures-core v0.3.34", "futures-io v0.3.34", "futures-macro v0.3.34", "futures-sink v0.3.34", "futures-task v0.3.34", "futures-util v0.3.34", "generic-array v0.14.7", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "group v0.13.0", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hex v0.4.3", "hickory-proto v0.26.1", "hkdf v0.12.4", "hmac v0.12.1", "hmac v0.13.0", "hstr v3.0.6", "http v1.4.1", "http-body v1.0.1", "http-body-util v0.1.5", "httparse v1.10.1", "humantime v2.3.0", "hybrid-array v0.4.12", "hyper v1.11.1", "hyper-rustls v0.27.9", "hyper-util v0.1.20", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "indexmap v2.14.1", "indicatif v0.18.6", "inkwell v0.9.0", "inkwell_internals v0.14.0", "inout v0.2.2", "ipnet v2.12.0", "is-macro v0.3.7", "is-terminal v0.4.17", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "jobserver v0.1.34", "jsonwebtoken v11.0.0", "lazy_static v1.5.0", "leb128fmt v0.1.0", "libbz2-rs-sys v0.2.5", "libc v0.2.189", "libm v0.2.16", "litemap v0.8.2", "llvm-sys v221.0.1", "lock_api v0.4.14", "log v0.4.34", "lzma-rust2 v0.16.4", "memchr v2.8.1", "mime v0.3.17", "mime_guess v2.0.5", "miniz_oxide v0.9.1", "mio v1.2.1", "new_debug_unreachable v1.0.6", "notify v6.1.1", "num-bigint v0.4.6", "num-bigint-dig v0.8.6", "num-conv v0.2.2", "num-integer v0.1.46", "num-iter v0.1.45", "num-traits v0.2.19", "num_cpus v1.17.0", "object v0.37.3", "once_cell v1.21.4", "once_cell_polyfill v1.70.2", "option-ext v0.2.0", "p256 v0.13.2", "p384 v0.13.1", "par-core v2.0.0", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "pbkdf2 v0.13.0", "pem v3.0.6", "pem-rfc7468 v0.7.0", "percent-encoding v2.3.2", "perex v0.1.4", "phf v0.11.3", "phf_generator v0.11.3", "phf_macros v0.11.3", "phf_shared v0.11.3", "pin-project-lite v0.2.17", "pkcs1 v0.7.5", "pkcs8 v0.10.2", "pkg-config v0.3.33", "portable-atomic v1.13.1", "potential_utf v0.1.5", "powerfmt v0.2.0", "ppmd-rust v1.4.0", "ppv-lite86 v0.2.21", "primeorder v0.13.6", "proc-macro2 v1.0.106", "psm v0.1.32", "quote v1.0.45", "rand v0.10.2", "rand v0.8.7", "rand v0.9.4", "rand_chacha v0.3.1", "rand_chacha v0.9.0", "rand_core v0.10.1", "rand_core v0.6.4", "rand_core v0.9.5", "rayon v1.12.0", "rayon-core v1.13.0", "regex v1.13.1", "regex-automata v0.4.18", "regex-lite v0.1.9", "regex-syntax v0.8.11", "reqwest v0.12.28", "resolv-conf v0.7.6", "rfc6979 v0.4.0", "ring v0.17.14", "rsa v0.9.10", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "rustc_version v0.4.1", "rustls v0.23.43", "rustls-pki-types v1.14.1", "rustls-webpki v0.103.13", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scoped-tls v1.0.1", "scopeguard v1.2.0", "sec1 v0.7.3", "semver v1.0.28", "seq-macro v0.3.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_spanned v1.1.1", "serde_urlencoded v0.7.1", "sha1 v0.10.6", "sha1 v0.11.0", "sha2 v0.10.9", "sha2 v0.11.0", "shell-words v1.1.1", "shlex v2.0.1", "signature v2.2.0", "simd-adler32 v0.3.9", "simdutf8 v0.1.5", "simple_asn1 v0.6.4", "siphasher v0.3.11", "siphasher v1.0.3", "slab v0.4.12", "slotmap v1.1.1", "smallvec v1.15.1", "smartstring v1.0.1", "socket2 v0.6.5", "spin v0.9.8", "spki v0.7.3", "spki v0.8.0", "stable_deref_trait v1.2.1", "stacker v0.1.25", "static_assertions v1.1.0", "string_enum v1.0.2", "strsim v0.11.1", "subtle v2.6.1", "swc_atoms v9.0.3", "swc_common v18.0.1", "swc_ecma_ast v19.0.0", "swc_ecma_parser v29.0.2", "swc_ecma_parser v32.0.0", "swc_ecma_transforms_base v32.0.0", "swc_ecma_utils v25.0.0", "swc_ecma_visit v19.0.0", "swc_eq_ignore_macros v1.0.1", "swc_macros_common v1.0.1", "swc_visit v2.0.1", "syn v2.0.117", "syn v3.0.3", "sync_wrapper v1.0.2", "synstructure v0.13.2", "taffy v0.13.0", "tar v0.4.46", "tempfile v3.27.0", "termcolor v1.4.1", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "time v0.3.55", "time-core v0.1.9", "time-macros v0.2.32", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tokio v1.53.1", "tokio-macros v2.7.0", "tokio-rustls v0.26.4", "tokio-tungstenite v0.29.0", "toml v1.1.4+spec-1.1.0", "toml_datetime v1.1.1+spec-1.1.0", "toml_parser v1.1.3+spec-1.1.0", "toml_writer v1.1.2+spec-1.1.0", "tower v0.5.3", "tower-http v0.6.11", "tower-layer v0.3.3", "tower-service v0.3.3", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "triomphe v0.1.15", "try-lock v0.2.5", "tungstenite v0.29.0", "typed-path v0.12.3", "typenum v1.20.1", "unicase v2.9.0", "unicode-id-start v1.4.0", "unicode-ident v1.0.24", "unicode-width v0.2.2", "unit-prefix v0.5.2", "untrusted v0.9.0", "url v2.5.8", "utf8_iter v1.0.4", "utf8parse v0.2.2", "version_check v0.9.5", "walkdir v2.5.0", "want v0.3.1", "wasm-encoder v0.258.0", "webpki-roots v0.26.11", "webpki-roots v1.0.9", "winapi v0.3.9", "winapi-util v0.1.11", "windows-link v0.2.1", "windows-sys v0.48.0", "windows-sys v0.61.2", "windows-targets v0.48.5", "windows_x86_64_msvc v0.48.5", "winnow v1.0.3", "winresource v0.1.31", "writeable v0.6.4", "x509-cert v0.3.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zeroize_derive v1.4.3", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zip v8.6.0", "zlib-rs v0.6.4", "zmij v1.0.21", "zopfli v0.8.3", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7"]}, +{"configuration": "CLI dev", "target": "x86_64-pc-windows-msvc", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry", "--no-default-features", "--features", "dev-cli", "-e", "normal,build", "--target", "x86_64-pc-windows-msvc", "--prefix", "none", "--format", "{p}"], "external_package_versions": 350, "packages": ["adler2 v2.0.1", "aes v0.9.1", "ahash v0.8.12", "aho-corasick v1.1.4", "allocator-api2 v0.2.21", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anstyle-wincon v3.0.11", "anyhow v1.0.104", "ar_archive_writer v0.5.1", "arrayvec v0.7.6", "ast_node v5.0.0", "atomic-waker v1.1.2", "autocfg v1.5.1", "base16ct v0.2.0", "base64 v0.22.1", "base64ct v1.8.3", "better_scoped_tls v1.0.1", "bitflags v2.12.1", "block-buffer v0.10.4", "block-buffer v0.12.0", "bumpalo v3.20.3", "bytes v1.12.1", "bytes-str v0.2.7", "bzip2 v0.6.1", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "chrono v0.4.45", "cipher v0.5.2", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "cmov v0.5.4", "colorchoice v1.0.5", "console v0.16.4", "const-oid v0.10.2", "const-oid v0.9.6", "constant_time_eq v0.4.2", "cpubits v0.1.1", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "crc32fast v1.5.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-deque v0.8.6", "crossbeam-epoch v0.9.20", "crossbeam-utils v0.8.21", "crypto-bigint v0.5.5", "crypto-common v0.1.7", "crypto-common v0.2.2", "ctutils v0.4.2", "curve25519-dalek v4.1.3", "curve25519-dalek-derive v0.1.1", "data-encoding v2.11.0", "deflate64 v0.1.12", "der v0.7.10", "der v0.8.1", "der_derive v0.8.0", "deranged v0.5.8", "dialoguer v0.12.0", "digest v0.10.7", "digest v0.11.3", "dirs v6.0.0", "dirs-sys v0.5.0", "displaydoc v0.2.6", "dotenvy v0.15.7", "ecdsa v0.16.9", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "either v1.16.0", "elliptic-curve v0.13.8", "encode_unicode v1.0.0", "encoding_rs v0.8.35", "env_logger v0.10.2", "equivalent v1.0.2", "fastrand v2.4.1", "ff v0.13.1", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "flate2 v1.1.10", "form_urlencoded v1.2.2", "from_variant v3.0.0", "fslock v0.2.1", "futures-channel v0.3.32", "futures-core v0.3.34", "futures-io v0.3.34", "futures-macro v0.3.34", "futures-sink v0.3.34", "futures-task v0.3.34", "futures-util v0.3.34", "generic-array v0.14.7", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "group v0.13.0", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hex v0.4.3", "hickory-proto v0.26.1", "hkdf v0.12.4", "hmac v0.12.1", "hmac v0.13.0", "hstr v3.0.6", "http v1.4.1", "http-body v1.0.1", "http-body-util v0.1.5", "httparse v1.10.1", "humantime v2.3.0", "hybrid-array v0.4.12", "hyper v1.11.1", "hyper-rustls v0.27.9", "hyper-util v0.1.20", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "indexmap v2.14.1", "indicatif v0.18.6", "inkwell v0.9.0", "inkwell_internals v0.14.0", "inout v0.2.2", "ipnet v2.12.0", "is-macro v0.3.7", "is-terminal v0.4.17", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "jobserver v0.1.34", "jsonwebtoken v11.0.0", "lazy_static v1.5.0", "libbz2-rs-sys v0.2.5", "libc v0.2.189", "libm v0.2.16", "litemap v0.8.2", "llvm-sys v221.0.1", "lock_api v0.4.14", "log v0.4.34", "lzma-rust2 v0.16.4", "memchr v2.8.1", "mime v0.3.17", "mime_guess v2.0.5", "miniz_oxide v0.9.1", "mio v1.2.1", "new_debug_unreachable v1.0.6", "notify v6.1.1", "num-bigint v0.4.6", "num-bigint-dig v0.8.6", "num-conv v0.2.2", "num-integer v0.1.46", "num-iter v0.1.45", "num-traits v0.2.19", "num_cpus v1.17.0", "object v0.37.3", "once_cell v1.21.4", "once_cell_polyfill v1.70.2", "option-ext v0.2.0", "p256 v0.13.2", "p384 v0.13.1", "par-core v2.0.0", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "pbkdf2 v0.13.0", "pem v3.0.6", "pem-rfc7468 v0.7.0", "percent-encoding v2.3.2", "perex v0.1.4", "phf v0.11.3", "phf_generator v0.11.3", "phf_macros v0.11.3", "phf_shared v0.11.3", "pin-project-lite v0.2.17", "pkcs1 v0.7.5", "pkcs8 v0.10.2", "pkg-config v0.3.33", "portable-atomic v1.13.1", "potential_utf v0.1.5", "powerfmt v0.2.0", "ppmd-rust v1.4.0", "ppv-lite86 v0.2.21", "primeorder v0.13.6", "proc-macro2 v1.0.106", "psm v0.1.32", "quote v1.0.45", "rand v0.10.2", "rand v0.8.7", "rand v0.9.4", "rand_chacha v0.3.1", "rand_chacha v0.9.0", "rand_core v0.10.1", "rand_core v0.6.4", "rand_core v0.9.5", "rayon v1.12.0", "rayon-core v1.13.0", "regex v1.13.1", "regex-automata v0.4.18", "regex-lite v0.1.9", "regex-syntax v0.8.11", "reqwest v0.12.28", "resolv-conf v0.7.6", "rfc6979 v0.4.0", "ring v0.17.14", "rsa v0.9.10", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "rustc_version v0.4.1", "rustls v0.23.43", "rustls-pki-types v1.14.1", "rustls-webpki v0.103.13", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scoped-tls v1.0.1", "scopeguard v1.2.0", "sec1 v0.7.3", "semver v1.0.28", "seq-macro v0.3.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_spanned v1.1.1", "serde_urlencoded v0.7.1", "sha1 v0.10.6", "sha1 v0.11.0", "sha2 v0.10.9", "sha2 v0.11.0", "shell-words v1.1.1", "shlex v2.0.1", "signature v2.2.0", "simd-adler32 v0.3.9", "simdutf8 v0.1.5", "simple_asn1 v0.6.4", "siphasher v0.3.11", "siphasher v1.0.3", "slab v0.4.12", "slotmap v1.1.1", "smallvec v1.15.1", "smartstring v1.0.1", "socket2 v0.6.5", "spin v0.9.8", "spki v0.7.3", "spki v0.8.0", "stable_deref_trait v1.2.1", "stacker v0.1.25", "static_assertions v1.1.0", "string_enum v1.0.2", "strsim v0.11.1", "subtle v2.6.1", "swc_atoms v9.0.3", "swc_common v18.0.1", "swc_ecma_ast v19.0.0", "swc_ecma_parser v29.0.2", "swc_ecma_parser v32.0.0", "swc_ecma_transforms_base v32.0.0", "swc_ecma_utils v25.0.0", "swc_ecma_visit v19.0.0", "swc_eq_ignore_macros v1.0.1", "swc_macros_common v1.0.1", "swc_visit v2.0.1", "syn v2.0.117", "syn v3.0.3", "sync_wrapper v1.0.2", "synstructure v0.13.2", "taffy v0.13.0", "tar v0.4.46", "tempfile v3.27.0", "termcolor v1.4.1", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "time v0.3.55", "time-core v0.1.9", "time-macros v0.2.32", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tokio v1.53.1", "tokio-macros v2.7.0", "tokio-rustls v0.26.4", "tokio-tungstenite v0.29.0", "toml v1.1.4+spec-1.1.0", "toml_datetime v1.1.1+spec-1.1.0", "toml_parser v1.1.3+spec-1.1.0", "toml_writer v1.1.2+spec-1.1.0", "tower v0.5.3", "tower-http v0.6.11", "tower-layer v0.3.3", "tower-service v0.3.3", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "triomphe v0.1.15", "try-lock v0.2.5", "tungstenite v0.29.0", "typed-path v0.12.3", "typenum v1.20.1", "unicase v2.9.0", "unicode-id-start v1.4.0", "unicode-ident v1.0.24", "unicode-width v0.2.2", "unit-prefix v0.5.2", "untrusted v0.9.0", "url v2.5.8", "utf8_iter v1.0.4", "utf8parse v0.2.2", "version_check v0.9.5", "walkdir v2.5.0", "want v0.3.1", "webpki-roots v0.26.11", "webpki-roots v1.0.9", "winapi v0.3.9", "winapi-util v0.1.11", "windows-link v0.2.1", "windows-sys v0.48.0", "windows-sys v0.61.2", "windows-targets v0.48.5", "windows_x86_64_msvc v0.48.5", "winnow v1.0.3", "winresource v0.1.31", "writeable v0.6.4", "x509-cert v0.3.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zeroize_derive v1.4.3", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zip v8.6.0", "zlib-rs v0.6.4", "zmij v1.0.21", "zopfli v0.8.3", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7"]}, +{"configuration": "Runtime default", "target": "x86_64-pc-windows-msvc", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-runtime", "-e", "normal,build", "--target", "x86_64-pc-windows-msvc", "--prefix", "none", "--format", "{p}"], "external_package_versions": 218, "packages": ["ahash v0.8.12", "allocator-api2 v0.2.21", "anyhow v1.0.104", "ar_archive_writer v0.5.1", "arrayvec v0.7.6", "ast_node v5.0.0", "autocfg v1.5.1", "base64 v0.22.1", "better_scoped_tls v1.0.1", "bitflags v2.12.1", "block-buffer v0.12.0", "bytecount v0.6.9", "bytes v1.12.1", "bytes-str v0.2.7", "calendrical_calculations v0.2.4", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "combine v4.6.7", "const-oid v0.10.2", "core_maths v0.1.1", "cpufeatures v0.3.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-utils v0.8.21", "crypto-common v0.2.2", "cty v0.2.2", "data-encoding v2.11.0", "der v0.8.1", "der_derive v0.8.0", "digest v0.11.3", "dirs v6.0.0", "dirs-sys v0.5.0", "displaydoc v0.2.6", "either v1.16.0", "encoding_rs v0.8.35", "equivalent v1.0.2", "filetime v0.2.29", "find-msvc-tools v0.1.11", "fixed_decimal v0.7.2", "flagset v0.4.7", "form_urlencoded v1.2.2", "from_variant v3.0.0", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hickory-proto v0.26.1", "hostname v0.4.2", "hstr v3.0.6", "hybrid-array v0.4.12", "icu_calendar v2.3.0", "icu_calendar_data v2.3.0", "icu_collections v2.2.0", "icu_datetime v2.3.0", "icu_datetime_data v2.3.0", "icu_decimal v2.3.0", "icu_decimal_data v2.3.0", "icu_locale v2.2.0", "icu_locale_core v2.3.0", "icu_locale_data v2.2.0", "icu_locale_fallback v2.3.0", "icu_locale_fallback_data v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_pattern v0.5.0", "icu_plurals v2.3.0", "icu_plurals_data v2.3.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "icu_time v2.3.0", "icu_time_data v2.3.0", "idna v1.1.0", "idna_adapter v1.2.2", "indexmap v2.14.1", "ipnet v2.12.0", "is-macro v0.3.7", "itoa v1.0.18", "ixdtf v0.6.5", "jiff-tzdb v0.1.6", "jobserver v0.1.34", "lazy_static v1.5.0", "libc v0.2.189", "libm v0.2.16", "libmimalloc-sys v0.1.49", "litemap v0.8.2", "log v0.4.34", "memchr v2.8.1", "miette v7.6.0", "miette-derive v7.6.0", "mimalloc v0.1.52", "minimal-lexical v0.2.1", "new_debug_unreachable v1.0.6", "node-semver v2.2.0", "nom v7.1.3", "notify v6.1.1", "num-bigint v0.4.6", "num-integer v0.1.46", "num-traits v0.2.19", "num_cpus v1.17.0", "object v0.37.3", "once_cell v1.21.4", "option-ext v0.2.0", "par-core v2.0.0", "percent-encoding v2.3.2", "perex v0.1.4", "phf v0.11.3", "phf_generator v0.11.3", "phf_macros v0.11.3", "phf_shared v0.11.3", "pin-project-lite v0.2.17", "pkg-config v0.3.33", "portable-atomic v1.13.1", "potential_utf v0.1.5", "proc-macro2 v1.0.106", "psm v0.1.32", "quote v1.0.45", "rand v0.10.2", "rand v0.8.7", "rand_core v0.10.1", "rand_core v0.6.4", "resolv-conf v0.7.6", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scoped-tls v1.0.1", "seq-macro v0.3.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_spanned v1.1.1", "sha2 v0.11.0", "shlex v2.0.1", "simdutf8 v0.1.5", "siphasher v0.3.11", "siphasher v1.0.3", "slotmap v1.1.1", "smallvec v1.15.1", "smartstring v1.0.1", "socket2 v0.6.5", "spki v0.8.0", "stable_deref_trait v1.2.1", "stacker v0.1.25", "static_assertions v1.1.0", "string_enum v1.0.2", "swc_atoms v9.0.3", "swc_common v18.0.1", "swc_ecma_ast v19.0.0", "swc_ecma_parser v29.0.2", "swc_ecma_parser v32.0.0", "swc_ecma_transforms_base v32.0.0", "swc_ecma_utils v25.0.0", "swc_ecma_visit v19.0.0", "swc_eq_ignore_macros v1.0.1", "swc_macros_common v1.0.1", "swc_visit v2.0.1", "syn v2.0.117", "syn v3.0.3", "synstructure v0.13.2", "taffy v0.13.0", "temporal_rs v0.2.6", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "timezone_provider v0.2.6", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "toml v1.1.4+spec-1.1.0", "toml_datetime v1.1.1+spec-1.1.0", "toml_parser v1.1.3+spec-1.1.0", "toml_writer v1.1.2+spec-1.1.0", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "triomphe v0.1.15", "typenum v1.20.1", "tzif v0.4.1", "unicode-id-start v1.4.0", "unicode-ident v1.0.24", "unicode-normalization v0.1.25", "unicode-segmentation v1.13.3", "unicode-width v0.1.14", "unicode-width v0.2.2", "unsafe-libyaml v0.2.11", "url v2.5.8", "utf8_iter v1.0.4", "version_check v0.9.5", "walkdir v2.5.0", "winapi-util v0.1.11", "windows-link v0.2.1", "windows-sys v0.48.0", "windows-sys v0.61.2", "windows-targets v0.48.5", "windows_x86_64_msvc v0.48.5", "winnow v1.0.3", "writeable v0.6.4", "x509-cert v0.3.0", "xxhash-rust v0.8.18", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7"]}, +{"configuration": "Runtime minimal", "target": "x86_64-pc-windows-msvc", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-runtime", "--no-default-features", "-e", "normal,build", "--target", "x86_64-pc-windows-msvc", "--prefix", "none", "--format", "{p}"], "external_package_versions": 108, "packages": ["ahash v0.8.12", "anyhow v1.0.104", "arrayvec v0.7.6", "base64 v0.22.1", "block-buffer v0.12.0", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "const-oid v0.10.2", "cpufeatures v0.3.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-utils v0.8.21", "crypto-common v0.2.2", "data-encoding v2.11.0", "der v0.8.1", "der_derive v0.8.0", "digest v0.11.3", "displaydoc v0.2.6", "encoding_rs v0.8.35", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "form_urlencoded v1.2.2", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "hickory-proto v0.26.1", "hybrid-array v0.4.12", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "ipnet v2.12.0", "itoa v1.0.18", "lazy_static v1.5.0", "libc v0.2.189", "litemap v0.8.2", "log v0.4.34", "memchr v2.8.1", "notify v6.1.1", "once_cell v1.21.4", "percent-encoding v2.3.2", "pin-project-lite v0.2.17", "portable-atomic v1.13.1", "potential_utf v0.1.5", "proc-macro2 v1.0.106", "quote v1.0.45", "rand v0.10.2", "rand_core v0.10.1", "resolv-conf v0.7.6", "rustc-demangle v0.1.28", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "sha2 v0.11.0", "shlex v2.0.1", "simdutf8 v0.1.5", "slotmap v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "spki v0.8.0", "stable_deref_trait v1.2.1", "syn v2.0.117", "syn v3.0.3", "synstructure v0.13.2", "taffy v0.13.0", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tracing v0.1.44", "tracing-core v0.1.36", "typenum v1.20.1", "unicode-ident v1.0.24", "url v2.5.8", "utf8_iter v1.0.4", "version_check v0.9.5", "walkdir v2.5.0", "winapi-util v0.1.11", "windows-link v0.2.1", "windows-sys v0.48.0", "windows-sys v0.61.2", "windows-targets v0.48.5", "windows_x86_64_msvc v0.48.5", "writeable v0.6.4", "x509-cert v0.3.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21"]}, +{"configuration": "Stdlib default", "target": "x86_64-pc-windows-msvc", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-stdlib", "-e", "normal,build", "--target", "x86_64-pc-windows-msvc", "--prefix", "none", "--format", "{p}"], "external_package_versions": 556, "packages": ["adler2 v2.0.1", "aead v0.5.2", "aes v0.8.4", "aes v0.9.1", "aes-gcm v0.10.3", "aes-kw v0.3.1", "ahash v0.8.12", "aligned v0.4.3", "aligned-vec v0.6.4", "alloc-no-stdlib v2.0.4", "alloc-stdlib v0.2.2", "allocator-api2 v0.2.21", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anstyle-wincon v3.0.11", "anyhow v1.0.104", "arc-swap v1.9.1", "arcstr v1.2.0", "arg_enum_proc_macro v0.3.4", "argon2 v0.5.3", "arrayvec v0.7.6", "as-slice v0.2.1", "async-lock v3.4.2", "async-trait v0.1.92", "atoi v2.0.0", "atomic v0.6.1", "atomic-waker v1.1.2", "autocfg v1.5.1", "av-scenechange v0.14.1", "av1-grain v0.2.5", "avif-serialize v0.8.9", "aws-lc-rs v1.17.0", "aws-lc-sys v0.41.0", "backon v1.6.0", "base16ct v0.2.0", "base16ct v1.0.0", "base64 v0.22.1", "base64 v0.23.1", "base64ct v1.8.3", "bcrypt v0.19.3", "bindgen v0.72.1", "bit_field v0.10.3", "bitflags v2.12.1", "bitstream-io v4.10.0", "bitvec v1.0.1", "blake2 v0.10.6", "block-buffer v0.10.4", "block-buffer v0.12.0", "block-padding v0.3.3", "block-padding v0.4.2", "blowfish v0.10.0", "brotli v8.0.4", "brotli-decompressor v5.0.1", "bson v3.1.0", "built v0.8.1", "bytemuck v1.25.0", "byteorder v1.5.0", "byteorder-lite v0.1.0", "bytes v1.12.1", "cbc v0.1.2", "cbc v0.2.1", "cc v1.4.4", "cexpr v0.6.0", "cfg-if v1.0.4", "chacha20 v0.10.0", "chacha20 v0.9.1", "chacha20poly1305 v0.10.1", "chrono v0.4.45", "chrono-tz v0.10.4", "cipher v0.4.4", "cipher v0.5.2", "clang-sys v1.8.1", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "cmake v0.1.58", "cmov v0.5.4", "color_quant v1.1.0", "colorchoice v1.0.5", "combine v4.6.7", "concurrent-queue v2.5.0", "const-oid v0.10.2", "const-oid v0.9.6", "const-random v0.1.18", "const-random-macro v0.1.16", "convert_case v0.10.0", "cpubits v0.1.1", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "crc v3.4.0", "crc-catalog v2.5.0", "crc32fast v1.5.0", "critical-section v1.2.0", "cron v0.17.0", "croner v3.0.1", "crossbeam-channel v0.5.15", "crossbeam-deque v0.8.6", "crossbeam-epoch v0.9.20", "crossbeam-queue v0.3.12", "crossbeam-utils v0.8.21", "crunchy v0.2.4", "crypto-bigint v0.5.5", "crypto-bigint v0.7.5", "crypto-common v0.1.7", "crypto-common v0.2.2", "cssparser v0.37.0", "cssparser-macros v0.7.0", "ctr v0.9.2", "ctutils v0.4.2", "curve25519-dalek v4.1.3", "curve25519-dalek-derive v0.1.1", "darling v0.20.11", "darling v0.23.0", "darling_core v0.20.11", "darling_core v0.23.0", "darling_macro v0.20.11", "darling_macro v0.23.0", "dashmap v6.2.1", "data-encoding v2.11.0", "der v0.7.10", "der v0.8.1", "der_derive v0.8.0", "deranged v0.5.8", "derive-syn-parse v0.2.0", "derive-where v1.6.1", "derive_builder v0.20.2", "derive_builder_core v0.20.2", "derive_builder_macro v0.20.2", "derive_more v2.1.1", "derive_more-impl v2.1.1", "digest v0.10.7", "digest v0.11.3", "displaydoc v0.2.6", "dotenvy v0.15.7", "dtoa v1.0.11", "dtoa-short v0.3.5", "dunce v1.0.5", "ecb v0.2.1", "ecdsa v0.16.9", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "ed448 v0.5.0", "ed448-goldilocks v0.14.0-pre.15", "ego-tree v0.11.0", "either v1.16.0", "elliptic-curve v0.13.8", "elliptic-curve v0.14.0", "email-encoding v0.4.1", "email_address v0.2.9", "encoding_rs v0.8.35", "equator v0.4.2", "equator-macro v0.4.2", "equivalent v1.0.2", "etcetera v0.11.0", "event-listener v5.4.1", "event-listener-strategy v0.5.4", "exr v1.74.0", "fallible-iterator v0.3.0", "fallible-streaming-iterator v0.1.9", "fastrand v2.4.1", "fax v0.2.7", "fdeflate v0.3.7", "ff v0.13.1", "ff v0.14.0", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "flate2 v1.1.10", "fnv v1.0.7", "foldhash v0.2.0", "form_urlencoded v1.2.2", "fs_extra v1.3.0", "funty v2.0.0", "futures-channel v0.3.32", "futures-core v0.3.34", "futures-intrusive v0.5.0", "futures-io v0.3.34", "futures-macro v0.3.34", "futures-sink v0.3.34", "futures-task v0.3.34", "futures-timer v3.0.4", "futures-util v0.3.34", "generic-array v0.14.7", "getopts v0.2.24", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "ghash v0.5.1", "ghash v0.6.0", "gif v0.14.2", "gimli v0.34.0", "glob v0.3.3", "governor v0.10.4", "group v0.13.0", "group v0.14.0", "h2 v0.4.19", "half v2.7.1", "hash2curve v0.14.0", "hashbrown v0.14.5", "hashbrown v0.16.1", "hashbrown v0.17.1", "hashlink v0.11.1", "heck v0.5.0", "hex v0.4.3", "hickory-net v0.26.1", "hickory-proto v0.26.1", "hickory-resolver v0.26.1", "hkdf v0.12.4", "hkdf v0.13.0", "hmac v0.12.1", "hmac v0.13.0", "hostname v0.4.2", "html5ever v0.39.0", "http v1.4.1", "http-body v1.0.1", "http-body-util v0.1.5", "httparse v1.10.1", "httpdate v1.0.3", "hybrid-array v0.4.12", "hyper v1.11.1", "hyper-rustls v0.27.9", "hyper-util v0.1.20", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "ident_case v1.0.1", "idna v1.1.0", "idna_adapter v1.2.2", "image v0.25.10", "image-webp v0.2.4", "imgref v1.12.3", "indexmap v2.14.1", "inout v0.1.4", "inout v0.2.2", "ipconfig v0.3.4", "ipnet v2.12.0", "is_terminal_polyfill v1.70.2", "itertools v0.12.1", "itertools v0.14.0", "itoa v1.0.18", "jobserver v0.1.34", "jsonwebtoken v11.0.0", "keccak v0.1.6", "keccak v0.2.0", "kem v0.3.0", "lazy_static v1.5.0", "lebe v0.5.3", "lettre v0.11.23", "libc v0.2.189", "libloading v0.8.9", "libm v0.2.16", "libsqlite3-sys v0.37.0", "litemap v0.8.2", "lock_api v0.4.14", "log v0.4.34", "loop9 v0.1.5", "lru v0.18.3", "macro_magic v0.5.1", "macro_magic_core v0.5.1", "macro_magic_core_macros v0.5.1", "macro_magic_macros v0.5.1", "markup5ever v0.39.0", "maybe-rayon v0.1.1", "md-5 v0.10.6", "md-5 v0.11.0", "memchr v2.8.1", "mime v0.3.17", "minimal-lexical v0.2.1", "miniz_oxide v0.8.9", "miniz_oxide v0.9.1", "mio v1.2.1", "ml-kem v0.3.2", "module-lattice v0.2.3", "moka v0.12.15", "mongodb v3.8.2", "mongodb-internal-macros v3.8.2", "moxcms v0.8.1", "nanoid v0.5.0", "new_debug_unreachable v1.0.6", "no_std_io2 v0.9.4", "nom v7.1.3", "nom v8.0.0", "nonzero_ext v0.3.0", "noop_proc_macro v0.3.0", "notify v6.1.1", "num-bigint v0.4.6", "num-bigint v0.5.1", "num-bigint-dig v0.8.6", "num-conv v0.2.2", "num-derive v0.4.2", "num-integer v0.1.46", "num-iter v0.1.45", "num-rational v0.4.2", "num-traits v0.2.19", "once_cell v1.21.4", "once_cell_polyfill v1.70.2", "opaque-debug v0.3.1", "p256 v0.13.2", "p384 v0.13.1", "p521 v0.13.3", "parking v2.2.1", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "password-hash v0.5.0", "paste v1.0.15", "pastey v0.1.1", "pbkdf2 v0.12.2", "pbkdf2 v0.13.0", "pem v3.0.6", "pem-rfc7468 v0.7.0", "pem-rfc7468 v1.0.0", "percent-encoding v2.3.2", "phf v0.11.3", "phf v0.12.1", "phf v0.13.1", "phf_codegen v0.13.1", "phf_generator v0.11.3", "phf_generator v0.13.1", "phf_macros v0.11.3", "phf_macros v0.13.1", "phf_shared v0.11.3", "phf_shared v0.12.1", "phf_shared v0.13.1", "pin-project-lite v0.2.17", "pkcs1 v0.7.5", "pkcs5 v0.7.1", "pkcs8 v0.10.2", "pkcs8 v0.11.0", "pkg-config v0.3.33", "png v0.18.1", "poly1305 v0.8.0", "polyval v0.6.2", "polyval v0.7.3", "portable-atomic v1.13.1", "potential_utf v0.1.5", "powerfmt v0.2.0", "ppv-lite86 v0.2.21", "precomputed-hash v0.1.1", "prefix-trie v0.8.4", "primeorder v0.13.6", "proc-macro2 v1.0.106", "profiling v1.0.18", "profiling-procmacros v1.0.18", "pxfm v0.1.29", "qoi v0.4.1", "quanta v0.12.6", "quick-error v2.0.1", "quote v1.0.45", "quoted_printable v0.5.2", "radium v0.7.0", "rand v0.10.2", "rand v0.8.7", "rand v0.9.4", "rand_chacha v0.3.1", "rand_chacha v0.9.0", "rand_core v0.10.1", "rand_core v0.6.4", "rand_core v0.9.5", "rav1e v0.8.1", "ravif v0.13.0", "raw-cpuid v11.6.0", "rayon v1.12.0", "rayon-core v1.13.0", "redis v1.6.0", "regex v1.13.1", "regex-automata v0.4.18", "regex-syntax v0.8.11", "reqwest v0.12.28", "resolv-conf v0.7.6", "rfc6979 v0.4.0", "rgb v0.8.53", "ring v0.17.14", "rsa v0.9.10", "rusqlite v0.39.0", "rust_decimal v1.43.0", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "rustc_version v0.4.1", "rustc_version_runtime v0.3.0", "rustls v0.23.43", "rustls-native-certs v0.8.4", "rustls-pemfile v2.2.0", "rustls-pki-types v1.14.1", "rustls-webpki v0.103.13", "rustversion v1.0.22", "ryu v1.0.23", "ryu-js v1.0.3", "salsa20 v0.10.2", "same-file v1.0.6", "schannel v0.1.29", "scopeguard v1.2.0", "scraper v0.27.0", "scrypt v0.11.0", "sec1 v0.7.3", "sec1 v0.8.1", "selectors v0.38.0", "semver v1.0.28", "serde v1.0.229", "serde_bytes v0.11.19", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_urlencoded v0.7.1", "serde_with v3.21.0", "serde_with_macros v3.21.0", "servo_arc v0.4.3", "sha1 v0.10.6", "sha1 v0.11.0", "sha1_smol v1.0.1", "sha2 v0.10.9", "sha2 v0.11.0", "sha3 v0.10.9", "sha3 v0.11.0", "sha3 v0.12.0", "sha3-utils v0.5.0", "shake v0.1.0", "shlex v1.3.0", "shlex v2.0.1", "signature v2.2.0", "signature v3.0.0", "simd-adler32 v0.3.9", "simd_helpers v0.1.0", "simdutf8 v0.1.5", "simple_asn1 v0.6.4", "siphasher v1.0.3", "slab v0.4.12", "slotmap v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "spin v0.9.8", "spinning_top v0.3.0", "spki v0.7.3", "spki v0.8.0", "sponge-cursor v0.1.0", "sqlx v0.9.0", "sqlx-core v0.9.0", "sqlx-mysql v0.9.0", "sqlx-postgres v0.9.0", "stable_deref_trait v1.2.1", "string_cache v0.9.0", "string_cache_codegen v0.6.1", "stringprep v0.1.5", "strsim v0.11.1", "strum v0.27.2", "strum_macros v0.27.2", "subtle v2.6.1", "syn v2.0.117", "syn v3.0.3", "sync_wrapper v1.0.2", "synstructure v0.13.2", "taffy v0.13.0", "tagptr v0.2.0", "take_mut v0.2.2", "tap v1.0.1", "tendril v0.5.0", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "tiff v0.11.3", "time v0.3.55", "time-core v0.1.9", "time-macros v0.2.32", "tiny-keccak v2.0.2", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tokio v1.53.1", "tokio-cron-scheduler v0.15.1", "tokio-macros v2.7.0", "tokio-rustls v0.26.4", "tokio-stream v0.1.18", "tokio-tungstenite v0.29.0", "tokio-util v0.7.18", "tower v0.5.3", "tower-http v0.6.11", "tower-layer v0.3.3", "tower-service v0.3.3", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "try-lock v0.2.5", "tungstenite v0.29.0", "typed-builder v0.22.0", "typed-builder-macro v0.22.0", "typenum v1.20.1", "unicode-bidi v0.3.18", "unicode-ident v1.0.24", "unicode-normalization v0.1.25", "unicode-properties v0.1.4", "unicode-segmentation v1.13.3", "unicode-width v0.2.2", "unicode-xid v0.2.6", "universal-hash v0.5.1", "universal-hash v0.6.1", "untrusted v0.9.0", "url v2.5.8", "utf-8 v0.7.6", "utf8_iter v1.0.4", "utf8parse v0.2.2", "uuid v1.26.0", "v_frame v0.3.9", "vcpkg v0.2.15", "version_check v0.9.5", "walkdir v2.5.0", "want v0.3.1", "web-time v1.1.0", "web_atoms v0.2.4", "webpki-roots v0.26.11", "webpki-roots v1.0.9", "weezl v0.1.12", "whoami v2.1.2", "widestring v1.2.1", "winapi v0.3.9", "winapi-util v0.1.11", "windows-link v0.2.1", "windows-registry v0.6.1", "windows-result v0.4.1", "windows-strings v0.5.1", "windows-sys v0.48.0", "windows-sys v0.61.2", "windows-targets v0.48.5", "windows_x86_64_msvc v0.48.5", "winnow v0.7.15", "writeable v0.6.4", "wyz v0.5.1", "x25519-dalek v2.0.1", "x448 v0.14.0-pre.12", "x509-cert v0.3.0", "xxhash-rust v0.8.18", "y4m v0.8.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerocopy-derive v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zeroize_derive v1.4.3", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7", "zune-core v0.5.1", "zune-inflate v0.2.54", "zune-jpeg v0.5.15"]}, +{"configuration": "Stdlib minimal", "target": "x86_64-pc-windows-msvc", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-stdlib", "--no-default-features", "-e", "normal,build", "--target", "x86_64-pc-windows-msvc", "--prefix", "none", "--format", "{p}"], "external_package_versions": 149, "packages": ["ahash v0.8.12", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anstyle-wincon v3.0.11", "anyhow v1.0.104", "arrayvec v0.7.6", "autocfg v1.5.1", "base64 v0.22.1", "block-buffer v0.10.4", "block-buffer v0.12.0", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "chrono v0.4.45", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "colorchoice v1.0.5", "const-oid v0.10.2", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-utils v0.8.21", "crypto-common v0.1.7", "crypto-common v0.2.2", "curve25519-dalek v4.1.3", "curve25519-dalek-derive v0.1.1", "dashmap v6.2.1", "data-encoding v2.11.0", "der v0.8.1", "der_derive v0.8.0", "digest v0.10.7", "digest v0.11.3", "displaydoc v0.2.6", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "encoding_rs v0.8.35", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "form_urlencoded v1.2.2", "generic-array v0.14.7", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "hashbrown v0.14.5", "heck v0.5.0", "hex v0.4.3", "hickory-proto v0.26.1", "hybrid-array v0.4.12", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "ipnet v2.12.0", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "lazy_static v1.5.0", "libc v0.2.189", "litemap v0.8.2", "lock_api v0.4.14", "log v0.4.34", "memchr v2.8.1", "notify v6.1.1", "num-traits v0.2.19", "once_cell v1.21.4", "once_cell_polyfill v1.70.2", "parking_lot_core v0.9.12", "percent-encoding v2.3.2", "pin-project-lite v0.2.17", "portable-atomic v1.13.1", "potential_utf v0.1.5", "proc-macro2 v1.0.106", "quote v1.0.45", "rand v0.10.2", "rand_core v0.10.1", "rand_core v0.6.4", "resolv-conf v0.7.6", "rustc-demangle v0.1.28", "rustc_version v0.4.1", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scopeguard v1.2.0", "semver v1.0.28", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "sha2 v0.10.9", "sha2 v0.11.0", "shlex v2.0.1", "signature v2.2.0", "simdutf8 v0.1.5", "slotmap v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "spki v0.8.0", "stable_deref_trait v1.2.1", "strsim v0.11.1", "subtle v2.6.1", "syn v2.0.117", "syn v3.0.3", "synstructure v0.13.2", "taffy v0.13.0", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tracing v0.1.44", "tracing-core v0.1.36", "typenum v1.20.1", "unicode-ident v1.0.24", "url v2.5.8", "utf8_iter v1.0.4", "utf8parse v0.2.2", "version_check v0.9.5", "walkdir v2.5.0", "winapi-util v0.1.11", "windows-link v0.2.1", "windows-sys v0.48.0", "windows-sys v0.61.2", "windows-targets v0.48.5", "windows_x86_64_msvc v0.48.5", "writeable v0.6.4", "x509-cert v0.3.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21"]}, +{"configuration": "Compose", "target": "x86_64-pc-windows-msvc", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-container-compose", "-e", "normal,build", "--target", "x86_64-pc-windows-msvc", "--prefix", "none", "--format", "{p}"], "external_package_versions": 98, "packages": ["anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anstyle-wincon v3.0.11", "anyhow v1.0.104", "async-trait v0.1.92", "atty v0.2.14", "block-buffer v0.12.0", "bytes v1.12.1", "cfg-if v1.0.4", "chacha20 v0.10.0", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "colorchoice v1.0.5", "console v0.15.11", "console v0.16.4", "const-oid v0.10.2", "cpufeatures v0.3.0", "crossbeam-utils v0.8.21", "crypto-common v0.2.2", "dashmap v6.2.1", "dialoguer v0.11.0", "digest v0.11.3", "dotenvy v0.15.7", "encode_unicode v1.0.0", "equivalent v1.0.2", "fastrand v2.4.1", "getrandom v0.4.2", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hex v0.4.3", "hybrid-array v0.4.12", "indexmap v2.14.1", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "lazy_static v1.5.0", "libc v0.2.189", "lock_api v0.4.14", "log v0.4.34", "matchers v0.2.0", "md-5 v0.11.0", "memchr v2.8.1", "mio v1.2.1", "nu-ansi-term v0.50.3", "once_cell v1.21.4", "once_cell_polyfill v1.70.2", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "pin-project-lite v0.2.17", "proc-macro2 v1.0.106", "quote v1.0.45", "rand v0.10.2", "rand_core v0.10.1", "regex-automata v0.4.18", "regex-syntax v0.8.11", "ryu v1.0.23", "scopeguard v1.2.0", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_yaml v0.9.34+deprecated", "sharded-slab v0.1.7", "shell-words v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "strsim v0.11.1", "syn v2.0.117", "syn v3.0.3", "tempfile v3.27.0", "thiserror v1.0.69", "thiserror-impl v1.0.69", "thread_local v1.1.9", "tokio v1.53.1", "tokio-macros v2.7.0", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "tracing-log v0.2.0", "tracing-subscriber v0.3.23", "typenum v1.20.1", "unicode-ident v1.0.24", "unicode-width v0.2.2", "unsafe-libyaml v0.2.11", "utf8parse v0.2.2", "which v8.0.6", "winapi v0.3.9", "windows-link v0.2.1", "windows-sys v0.59.0", "windows-sys v0.61.2", "windows-targets v0.52.6", "windows_x86_64_msvc v0.52.6", "zeroize v1.8.2", "zmij v1.0.21"]}, +{"configuration": "CLI default", "target": "x86_64-unknown-linux-gnu", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry", "-e", "normal,build", "--target", "x86_64-unknown-linux-gnu", "--prefix", "none", "--format", "{p}"], "external_package_versions": 352, "packages": ["adler2 v2.0.1", "aes v0.9.1", "ahash v0.8.12", "aho-corasick v1.1.4", "allocator-api2 v0.2.21", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "ar_archive_writer v0.5.1", "arrayvec v0.7.6", "ast_node v5.0.0", "atomic-waker v1.1.2", "autocfg v1.5.1", "base16ct v0.2.0", "base64 v0.22.1", "base64ct v1.8.3", "better_scoped_tls v1.0.1", "bitflags v1.3.2", "bitflags v2.12.1", "block-buffer v0.10.4", "block-buffer v0.12.0", "bumpalo v3.20.3", "bytes v1.12.1", "bytes-str v0.2.7", "bzip2 v0.6.1", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "chrono v0.4.45", "cipher v0.5.2", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "cmov v0.5.4", "colorchoice v1.0.5", "console v0.16.4", "const-oid v0.10.2", "const-oid v0.9.6", "constant_time_eq v0.4.2", "cpubits v0.1.1", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "crc32fast v1.5.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-deque v0.8.6", "crossbeam-epoch v0.9.20", "crossbeam-utils v0.8.21", "crypto-bigint v0.5.5", "crypto-common v0.1.7", "crypto-common v0.2.2", "ctutils v0.4.2", "curve25519-dalek v4.1.3", "curve25519-dalek-derive v0.1.1", "data-encoding v2.11.0", "deflate64 v0.1.12", "der v0.7.10", "der v0.8.1", "der_derive v0.8.0", "deranged v0.5.8", "dialoguer v0.12.0", "digest v0.10.7", "digest v0.11.3", "dirs v6.0.0", "dirs-sys v0.5.0", "displaydoc v0.2.6", "dotenvy v0.15.7", "ecdsa v0.16.9", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "either v1.16.0", "elliptic-curve v0.13.8", "encoding_rs v0.8.35", "env_logger v0.10.2", "equivalent v1.0.2", "errno v0.3.14", "fastrand v2.4.1", "ff v0.13.1", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "flate2 v1.1.10", "form_urlencoded v1.2.2", "from_variant v3.0.0", "fslock v0.2.1", "futures-channel v0.3.32", "futures-core v0.3.34", "futures-io v0.3.34", "futures-macro v0.3.34", "futures-sink v0.3.34", "futures-task v0.3.34", "futures-util v0.3.34", "generic-array v0.14.7", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "group v0.13.0", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hex v0.4.3", "hickory-proto v0.26.1", "hkdf v0.12.4", "hmac v0.12.1", "hmac v0.13.0", "hstr v3.0.6", "http v1.4.1", "http-body v1.0.1", "http-body-util v0.1.5", "httparse v1.10.1", "humantime v2.3.0", "hybrid-array v0.4.12", "hyper v1.11.1", "hyper-rustls v0.27.9", "hyper-util v0.1.20", "iana-time-zone v0.1.65", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "indexmap v2.14.1", "indicatif v0.18.6", "inkwell v0.9.0", "inkwell_internals v0.14.0", "inotify v0.9.6", "inotify-sys v0.1.5", "inout v0.2.2", "ipnet v2.12.0", "is-macro v0.3.7", "is-terminal v0.4.17", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "jobserver v0.1.34", "jsonwebtoken v11.0.0", "lazy_static v1.5.0", "leb128fmt v0.1.0", "libbz2-rs-sys v0.2.5", "libc v0.2.189", "libm v0.2.16", "linux-raw-sys v0.12.1", "litemap v0.8.2", "llvm-sys v221.0.1", "lock_api v0.4.14", "log v0.4.34", "lzma-rust2 v0.16.4", "memchr v2.8.1", "mime v0.3.17", "mime_guess v2.0.5", "miniz_oxide v0.9.1", "mio v0.8.11", "mio v1.2.1", "new_debug_unreachable v1.0.6", "notify v6.1.1", "num-bigint v0.4.6", "num-bigint-dig v0.8.6", "num-conv v0.2.2", "num-integer v0.1.46", "num-iter v0.1.45", "num-traits v0.2.19", "num_cpus v1.17.0", "object v0.37.3", "once_cell v1.21.4", "option-ext v0.2.0", "p256 v0.13.2", "p384 v0.13.1", "par-core v2.0.0", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "pbkdf2 v0.13.0", "pem v3.0.6", "pem-rfc7468 v0.7.0", "percent-encoding v2.3.2", "perex v0.1.4", "phf v0.11.3", "phf_generator v0.11.3", "phf_macros v0.11.3", "phf_shared v0.11.3", "pin-project-lite v0.2.17", "pkcs1 v0.7.5", "pkcs8 v0.10.2", "pkg-config v0.3.33", "portable-atomic v1.13.1", "potential_utf v0.1.5", "powerfmt v0.2.0", "ppmd-rust v1.4.0", "ppv-lite86 v0.2.21", "primeorder v0.13.6", "proc-macro2 v1.0.106", "psm v0.1.32", "quote v1.0.45", "rand v0.10.2", "rand v0.8.7", "rand v0.9.4", "rand_chacha v0.3.1", "rand_chacha v0.9.0", "rand_core v0.10.1", "rand_core v0.6.4", "rand_core v0.9.5", "rayon v1.12.0", "rayon-core v1.13.0", "regex v1.13.1", "regex-automata v0.4.18", "regex-lite v0.1.9", "regex-syntax v0.8.11", "reqwest v0.12.28", "resolv-conf v0.7.6", "rfc6979 v0.4.0", "ring v0.17.14", "rsa v0.9.10", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "rustc_version v0.4.1", "rustix v1.1.4", "rustls v0.23.43", "rustls-pki-types v1.14.1", "rustls-webpki v0.103.13", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scoped-tls v1.0.1", "scopeguard v1.2.0", "sec1 v0.7.3", "semver v1.0.28", "seq-macro v0.3.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_spanned v1.1.1", "serde_urlencoded v0.7.1", "sha1 v0.10.6", "sha1 v0.11.0", "sha2 v0.10.9", "sha2 v0.11.0", "shell-words v1.1.1", "shlex v2.0.1", "signal-hook-registry v1.4.8", "signature v2.2.0", "simd-adler32 v0.3.9", "simdutf8 v0.1.5", "simple_asn1 v0.6.4", "siphasher v0.3.11", "siphasher v1.0.3", "slab v0.4.12", "slotmap v1.1.1", "smallvec v1.15.1", "smartstring v1.0.1", "socket2 v0.6.5", "spin v0.9.8", "spki v0.7.3", "spki v0.8.0", "stable_deref_trait v1.2.1", "stacker v0.1.25", "static_assertions v1.1.0", "string_enum v1.0.2", "strsim v0.11.1", "subtle v2.6.1", "swc_atoms v9.0.3", "swc_common v18.0.1", "swc_ecma_ast v19.0.0", "swc_ecma_parser v29.0.2", "swc_ecma_parser v32.0.0", "swc_ecma_transforms_base v32.0.0", "swc_ecma_utils v25.0.0", "swc_ecma_visit v19.0.0", "swc_eq_ignore_macros v1.0.1", "swc_macros_common v1.0.1", "swc_visit v2.0.1", "syn v2.0.117", "syn v3.0.3", "sync_wrapper v1.0.2", "synstructure v0.13.2", "taffy v0.13.0", "tar v0.4.46", "tempfile v3.27.0", "termcolor v1.4.1", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "time v0.3.55", "time-core v0.1.9", "time-macros v0.2.32", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tokio v1.53.1", "tokio-macros v2.7.0", "tokio-rustls v0.26.4", "tokio-tungstenite v0.29.0", "toml v1.1.4+spec-1.1.0", "toml_datetime v1.1.1+spec-1.1.0", "toml_parser v1.1.3+spec-1.1.0", "toml_writer v1.1.2+spec-1.1.0", "tower v0.5.3", "tower-http v0.6.11", "tower-layer v0.3.3", "tower-service v0.3.3", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "triomphe v0.1.15", "try-lock v0.2.5", "tungstenite v0.29.0", "typed-path v0.12.3", "typenum v1.20.1", "unicase v2.9.0", "unicode-id-start v1.4.0", "unicode-ident v1.0.24", "unicode-width v0.2.2", "unit-prefix v0.5.2", "untrusted v0.9.0", "url v2.5.8", "utf8_iter v1.0.4", "utf8parse v0.2.2", "version_check v0.9.5", "walkdir v2.5.0", "want v0.3.1", "wasm-encoder v0.258.0", "webpki-roots v0.26.11", "webpki-roots v1.0.9", "winnow v1.0.3", "winresource v0.1.31", "writeable v0.6.4", "x509-cert v0.3.0", "xattr v1.6.1", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zeroize_derive v1.4.3", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zip v8.6.0", "zlib-rs v0.6.4", "zmij v1.0.21", "zopfli v0.8.3", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7"]}, +{"configuration": "CLI dev", "target": "x86_64-unknown-linux-gnu", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry", "--no-default-features", "--features", "dev-cli", "-e", "normal,build", "--target", "x86_64-unknown-linux-gnu", "--prefix", "none", "--format", "{p}"], "external_package_versions": 350, "packages": ["adler2 v2.0.1", "aes v0.9.1", "ahash v0.8.12", "aho-corasick v1.1.4", "allocator-api2 v0.2.21", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "ar_archive_writer v0.5.1", "arrayvec v0.7.6", "ast_node v5.0.0", "atomic-waker v1.1.2", "autocfg v1.5.1", "base16ct v0.2.0", "base64 v0.22.1", "base64ct v1.8.3", "better_scoped_tls v1.0.1", "bitflags v1.3.2", "bitflags v2.12.1", "block-buffer v0.10.4", "block-buffer v0.12.0", "bumpalo v3.20.3", "bytes v1.12.1", "bytes-str v0.2.7", "bzip2 v0.6.1", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "chrono v0.4.45", "cipher v0.5.2", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "cmov v0.5.4", "colorchoice v1.0.5", "console v0.16.4", "const-oid v0.10.2", "const-oid v0.9.6", "constant_time_eq v0.4.2", "cpubits v0.1.1", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "crc32fast v1.5.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-deque v0.8.6", "crossbeam-epoch v0.9.20", "crossbeam-utils v0.8.21", "crypto-bigint v0.5.5", "crypto-common v0.1.7", "crypto-common v0.2.2", "ctutils v0.4.2", "curve25519-dalek v4.1.3", "curve25519-dalek-derive v0.1.1", "data-encoding v2.11.0", "deflate64 v0.1.12", "der v0.7.10", "der v0.8.1", "der_derive v0.8.0", "deranged v0.5.8", "dialoguer v0.12.0", "digest v0.10.7", "digest v0.11.3", "dirs v6.0.0", "dirs-sys v0.5.0", "displaydoc v0.2.6", "dotenvy v0.15.7", "ecdsa v0.16.9", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "either v1.16.0", "elliptic-curve v0.13.8", "encoding_rs v0.8.35", "env_logger v0.10.2", "equivalent v1.0.2", "errno v0.3.14", "fastrand v2.4.1", "ff v0.13.1", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "flate2 v1.1.10", "form_urlencoded v1.2.2", "from_variant v3.0.0", "fslock v0.2.1", "futures-channel v0.3.32", "futures-core v0.3.34", "futures-io v0.3.34", "futures-macro v0.3.34", "futures-sink v0.3.34", "futures-task v0.3.34", "futures-util v0.3.34", "generic-array v0.14.7", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "group v0.13.0", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hex v0.4.3", "hickory-proto v0.26.1", "hkdf v0.12.4", "hmac v0.12.1", "hmac v0.13.0", "hstr v3.0.6", "http v1.4.1", "http-body v1.0.1", "http-body-util v0.1.5", "httparse v1.10.1", "humantime v2.3.0", "hybrid-array v0.4.12", "hyper v1.11.1", "hyper-rustls v0.27.9", "hyper-util v0.1.20", "iana-time-zone v0.1.65", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "indexmap v2.14.1", "indicatif v0.18.6", "inkwell v0.9.0", "inkwell_internals v0.14.0", "inotify v0.9.6", "inotify-sys v0.1.5", "inout v0.2.2", "ipnet v2.12.0", "is-macro v0.3.7", "is-terminal v0.4.17", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "jobserver v0.1.34", "jsonwebtoken v11.0.0", "lazy_static v1.5.0", "libbz2-rs-sys v0.2.5", "libc v0.2.189", "libm v0.2.16", "linux-raw-sys v0.12.1", "litemap v0.8.2", "llvm-sys v221.0.1", "lock_api v0.4.14", "log v0.4.34", "lzma-rust2 v0.16.4", "memchr v2.8.1", "mime v0.3.17", "mime_guess v2.0.5", "miniz_oxide v0.9.1", "mio v0.8.11", "mio v1.2.1", "new_debug_unreachable v1.0.6", "notify v6.1.1", "num-bigint v0.4.6", "num-bigint-dig v0.8.6", "num-conv v0.2.2", "num-integer v0.1.46", "num-iter v0.1.45", "num-traits v0.2.19", "num_cpus v1.17.0", "object v0.37.3", "once_cell v1.21.4", "option-ext v0.2.0", "p256 v0.13.2", "p384 v0.13.1", "par-core v2.0.0", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "pbkdf2 v0.13.0", "pem v3.0.6", "pem-rfc7468 v0.7.0", "percent-encoding v2.3.2", "perex v0.1.4", "phf v0.11.3", "phf_generator v0.11.3", "phf_macros v0.11.3", "phf_shared v0.11.3", "pin-project-lite v0.2.17", "pkcs1 v0.7.5", "pkcs8 v0.10.2", "pkg-config v0.3.33", "portable-atomic v1.13.1", "potential_utf v0.1.5", "powerfmt v0.2.0", "ppmd-rust v1.4.0", "ppv-lite86 v0.2.21", "primeorder v0.13.6", "proc-macro2 v1.0.106", "psm v0.1.32", "quote v1.0.45", "rand v0.10.2", "rand v0.8.7", "rand v0.9.4", "rand_chacha v0.3.1", "rand_chacha v0.9.0", "rand_core v0.10.1", "rand_core v0.6.4", "rand_core v0.9.5", "rayon v1.12.0", "rayon-core v1.13.0", "regex v1.13.1", "regex-automata v0.4.18", "regex-lite v0.1.9", "regex-syntax v0.8.11", "reqwest v0.12.28", "resolv-conf v0.7.6", "rfc6979 v0.4.0", "ring v0.17.14", "rsa v0.9.10", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "rustc_version v0.4.1", "rustix v1.1.4", "rustls v0.23.43", "rustls-pki-types v1.14.1", "rustls-webpki v0.103.13", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scoped-tls v1.0.1", "scopeguard v1.2.0", "sec1 v0.7.3", "semver v1.0.28", "seq-macro v0.3.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_spanned v1.1.1", "serde_urlencoded v0.7.1", "sha1 v0.10.6", "sha1 v0.11.0", "sha2 v0.10.9", "sha2 v0.11.0", "shell-words v1.1.1", "shlex v2.0.1", "signal-hook-registry v1.4.8", "signature v2.2.0", "simd-adler32 v0.3.9", "simdutf8 v0.1.5", "simple_asn1 v0.6.4", "siphasher v0.3.11", "siphasher v1.0.3", "slab v0.4.12", "slotmap v1.1.1", "smallvec v1.15.1", "smartstring v1.0.1", "socket2 v0.6.5", "spin v0.9.8", "spki v0.7.3", "spki v0.8.0", "stable_deref_trait v1.2.1", "stacker v0.1.25", "static_assertions v1.1.0", "string_enum v1.0.2", "strsim v0.11.1", "subtle v2.6.1", "swc_atoms v9.0.3", "swc_common v18.0.1", "swc_ecma_ast v19.0.0", "swc_ecma_parser v29.0.2", "swc_ecma_parser v32.0.0", "swc_ecma_transforms_base v32.0.0", "swc_ecma_utils v25.0.0", "swc_ecma_visit v19.0.0", "swc_eq_ignore_macros v1.0.1", "swc_macros_common v1.0.1", "swc_visit v2.0.1", "syn v2.0.117", "syn v3.0.3", "sync_wrapper v1.0.2", "synstructure v0.13.2", "taffy v0.13.0", "tar v0.4.46", "tempfile v3.27.0", "termcolor v1.4.1", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "time v0.3.55", "time-core v0.1.9", "time-macros v0.2.32", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tokio v1.53.1", "tokio-macros v2.7.0", "tokio-rustls v0.26.4", "tokio-tungstenite v0.29.0", "toml v1.1.4+spec-1.1.0", "toml_datetime v1.1.1+spec-1.1.0", "toml_parser v1.1.3+spec-1.1.0", "toml_writer v1.1.2+spec-1.1.0", "tower v0.5.3", "tower-http v0.6.11", "tower-layer v0.3.3", "tower-service v0.3.3", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "triomphe v0.1.15", "try-lock v0.2.5", "tungstenite v0.29.0", "typed-path v0.12.3", "typenum v1.20.1", "unicase v2.9.0", "unicode-id-start v1.4.0", "unicode-ident v1.0.24", "unicode-width v0.2.2", "unit-prefix v0.5.2", "untrusted v0.9.0", "url v2.5.8", "utf8_iter v1.0.4", "utf8parse v0.2.2", "version_check v0.9.5", "walkdir v2.5.0", "want v0.3.1", "webpki-roots v0.26.11", "webpki-roots v1.0.9", "winnow v1.0.3", "winresource v0.1.31", "writeable v0.6.4", "x509-cert v0.3.0", "xattr v1.6.1", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zeroize_derive v1.4.3", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zip v8.6.0", "zlib-rs v0.6.4", "zmij v1.0.21", "zopfli v0.8.3", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7"]}, +{"configuration": "Runtime default", "target": "x86_64-unknown-linux-gnu", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-runtime", "-e", "normal,build", "--target", "x86_64-unknown-linux-gnu", "--prefix", "none", "--format", "{p}"], "external_package_versions": 216, "packages": ["ahash v0.8.12", "allocator-api2 v0.2.21", "anyhow v1.0.104", "ar_archive_writer v0.5.1", "arrayvec v0.7.6", "ast_node v5.0.0", "autocfg v1.5.1", "base64 v0.22.1", "better_scoped_tls v1.0.1", "bitflags v1.3.2", "bitflags v2.12.1", "block-buffer v0.12.0", "bytecount v0.6.9", "bytes v1.12.1", "bytes-str v0.2.7", "calendrical_calculations v0.2.4", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "combine v4.6.7", "const-oid v0.10.2", "core_maths v0.1.1", "cpufeatures v0.3.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-utils v0.8.21", "crypto-common v0.2.2", "cty v0.2.2", "data-encoding v2.11.0", "der v0.8.1", "der_derive v0.8.0", "digest v0.11.3", "dirs v6.0.0", "dirs-sys v0.5.0", "displaydoc v0.2.6", "either v1.16.0", "encoding_rs v0.8.35", "equivalent v1.0.2", "filetime v0.2.29", "find-msvc-tools v0.1.11", "fixed_decimal v0.7.2", "flagset v0.4.7", "form_urlencoded v1.2.2", "from_variant v3.0.0", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hickory-proto v0.26.1", "hostname v0.4.2", "hstr v3.0.6", "hybrid-array v0.4.12", "icu_calendar v2.3.0", "icu_calendar_data v2.3.0", "icu_collections v2.2.0", "icu_datetime v2.3.0", "icu_datetime_data v2.3.0", "icu_decimal v2.3.0", "icu_decimal_data v2.3.0", "icu_locale v2.2.0", "icu_locale_core v2.3.0", "icu_locale_data v2.2.0", "icu_locale_fallback v2.3.0", "icu_locale_fallback_data v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_pattern v0.5.0", "icu_plurals v2.3.0", "icu_plurals_data v2.3.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "icu_time v2.3.0", "icu_time_data v2.3.0", "idna v1.1.0", "idna_adapter v1.2.2", "indexmap v2.14.1", "inotify v0.9.6", "inotify-sys v0.1.5", "ipnet v2.12.0", "is-macro v0.3.7", "itoa v1.0.18", "ixdtf v0.6.5", "jiff-tzdb v0.1.6", "jobserver v0.1.34", "lazy_static v1.5.0", "libc v0.2.189", "libm v0.2.16", "libmimalloc-sys v0.1.49", "litemap v0.8.2", "log v0.4.34", "memchr v2.8.1", "miette v7.6.0", "miette-derive v7.6.0", "mimalloc v0.1.52", "minimal-lexical v0.2.1", "mio v0.8.11", "new_debug_unreachable v1.0.6", "node-semver v2.2.0", "nom v7.1.3", "notify v6.1.1", "num-bigint v0.4.6", "num-integer v0.1.46", "num-traits v0.2.19", "num_cpus v1.17.0", "object v0.37.3", "once_cell v1.21.4", "option-ext v0.2.0", "par-core v2.0.0", "percent-encoding v2.3.2", "perex v0.1.4", "phf v0.11.3", "phf_generator v0.11.3", "phf_macros v0.11.3", "phf_shared v0.11.3", "pin-project-lite v0.2.17", "pkg-config v0.3.33", "portable-atomic v1.13.1", "potential_utf v0.1.5", "proc-macro2 v1.0.106", "psm v0.1.32", "quote v1.0.45", "rand v0.10.2", "rand v0.8.7", "rand_core v0.10.1", "rand_core v0.6.4", "resolv-conf v0.7.6", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scoped-tls v1.0.1", "seq-macro v0.3.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_spanned v1.1.1", "sha2 v0.11.0", "shlex v2.0.1", "simdutf8 v0.1.5", "siphasher v0.3.11", "siphasher v1.0.3", "slotmap v1.1.1", "smallvec v1.15.1", "smartstring v1.0.1", "socket2 v0.6.5", "spki v0.8.0", "stable_deref_trait v1.2.1", "stacker v0.1.25", "static_assertions v1.1.0", "string_enum v1.0.2", "swc_atoms v9.0.3", "swc_common v18.0.1", "swc_ecma_ast v19.0.0", "swc_ecma_parser v29.0.2", "swc_ecma_parser v32.0.0", "swc_ecma_transforms_base v32.0.0", "swc_ecma_utils v25.0.0", "swc_ecma_visit v19.0.0", "swc_eq_ignore_macros v1.0.1", "swc_macros_common v1.0.1", "swc_visit v2.0.1", "syn v2.0.117", "syn v3.0.3", "synstructure v0.13.2", "taffy v0.13.0", "temporal_rs v0.2.6", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "timezone_provider v0.2.6", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "toml v1.1.4+spec-1.1.0", "toml_datetime v1.1.1+spec-1.1.0", "toml_parser v1.1.3+spec-1.1.0", "toml_writer v1.1.2+spec-1.1.0", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "triomphe v0.1.15", "typenum v1.20.1", "tzif v0.4.1", "unicode-id-start v1.4.0", "unicode-ident v1.0.24", "unicode-normalization v0.1.25", "unicode-segmentation v1.13.3", "unicode-width v0.1.14", "unicode-width v0.2.2", "unsafe-libyaml v0.2.11", "url v2.5.8", "utf8_iter v1.0.4", "version_check v0.9.5", "walkdir v2.5.0", "winnow v1.0.3", "writeable v0.6.4", "x509-cert v0.3.0", "xxhash-rust v0.8.18", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7"]}, +{"configuration": "Runtime minimal", "target": "x86_64-unknown-linux-gnu", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-runtime", "--no-default-features", "-e", "normal,build", "--target", "x86_64-unknown-linux-gnu", "--prefix", "none", "--format", "{p}"], "external_package_versions": 106, "packages": ["ahash v0.8.12", "anyhow v1.0.104", "arrayvec v0.7.6", "base64 v0.22.1", "bitflags v1.3.2", "block-buffer v0.12.0", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "const-oid v0.10.2", "cpufeatures v0.3.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-utils v0.8.21", "crypto-common v0.2.2", "data-encoding v2.11.0", "der v0.8.1", "der_derive v0.8.0", "digest v0.11.3", "displaydoc v0.2.6", "encoding_rs v0.8.35", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "form_urlencoded v1.2.2", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "hickory-proto v0.26.1", "hybrid-array v0.4.12", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "inotify v0.9.6", "inotify-sys v0.1.5", "ipnet v2.12.0", "itoa v1.0.18", "lazy_static v1.5.0", "libc v0.2.189", "litemap v0.8.2", "log v0.4.34", "memchr v2.8.1", "mio v0.8.11", "notify v6.1.1", "once_cell v1.21.4", "percent-encoding v2.3.2", "pin-project-lite v0.2.17", "portable-atomic v1.13.1", "potential_utf v0.1.5", "proc-macro2 v1.0.106", "quote v1.0.45", "rand v0.10.2", "rand_core v0.10.1", "resolv-conf v0.7.6", "rustc-demangle v0.1.28", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "sha2 v0.11.0", "shlex v2.0.1", "simdutf8 v0.1.5", "slotmap v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "spki v0.8.0", "stable_deref_trait v1.2.1", "syn v2.0.117", "syn v3.0.3", "synstructure v0.13.2", "taffy v0.13.0", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tracing v0.1.44", "tracing-core v0.1.36", "typenum v1.20.1", "unicode-ident v1.0.24", "url v2.5.8", "utf8_iter v1.0.4", "version_check v0.9.5", "walkdir v2.5.0", "writeable v0.6.4", "x509-cert v0.3.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21"]}, +{"configuration": "Stdlib default", "target": "x86_64-unknown-linux-gnu", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-stdlib", "-e", "normal,build", "--target", "x86_64-unknown-linux-gnu", "--prefix", "none", "--format", "{p}"], "external_package_versions": 549, "packages": ["adler2 v2.0.1", "aead v0.5.2", "aes v0.8.4", "aes v0.9.1", "aes-gcm v0.10.3", "aes-kw v0.3.1", "ahash v0.8.12", "aligned v0.4.3", "aligned-vec v0.6.4", "alloc-no-stdlib v2.0.4", "alloc-stdlib v0.2.2", "allocator-api2 v0.2.21", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "arc-swap v1.9.1", "arcstr v1.2.0", "arg_enum_proc_macro v0.3.4", "argon2 v0.5.3", "arrayvec v0.7.6", "as-slice v0.2.1", "async-lock v3.4.2", "async-trait v0.1.92", "atoi v2.0.0", "atomic v0.6.1", "atomic-waker v1.1.2", "autocfg v1.5.1", "av-scenechange v0.14.1", "av1-grain v0.2.5", "avif-serialize v0.8.9", "aws-lc-rs v1.17.0", "aws-lc-sys v0.41.0", "backon v1.6.0", "base16ct v0.2.0", "base16ct v1.0.0", "base64 v0.22.1", "base64 v0.23.1", "base64ct v1.8.3", "bcrypt v0.19.3", "bindgen v0.72.1", "bit_field v0.10.3", "bitflags v1.3.2", "bitflags v2.12.1", "bitstream-io v4.10.0", "bitvec v1.0.1", "blake2 v0.10.6", "block-buffer v0.10.4", "block-buffer v0.12.0", "block-padding v0.3.3", "block-padding v0.4.2", "blowfish v0.10.0", "brotli v8.0.4", "brotli-decompressor v5.0.1", "bson v3.1.0", "built v0.8.1", "bytemuck v1.25.0", "byteorder v1.5.0", "byteorder-lite v0.1.0", "bytes v1.12.1", "cbc v0.1.2", "cbc v0.2.1", "cc v1.4.4", "cexpr v0.6.0", "cfg-if v1.0.4", "chacha20 v0.10.0", "chacha20 v0.9.1", "chacha20poly1305 v0.10.1", "chrono v0.4.45", "chrono-tz v0.10.4", "cipher v0.4.4", "cipher v0.5.2", "clang-sys v1.8.1", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "cmake v0.1.58", "cmov v0.5.4", "color_quant v1.1.0", "colorchoice v1.0.5", "combine v4.6.7", "concurrent-queue v2.5.0", "const-oid v0.10.2", "const-oid v0.9.6", "const-random v0.1.18", "const-random-macro v0.1.16", "convert_case v0.10.0", "cpubits v0.1.1", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "crc v3.4.0", "crc-catalog v2.5.0", "crc32fast v1.5.0", "critical-section v1.2.0", "cron v0.17.0", "croner v3.0.1", "crossbeam-channel v0.5.15", "crossbeam-deque v0.8.6", "crossbeam-epoch v0.9.20", "crossbeam-queue v0.3.12", "crossbeam-utils v0.8.21", "crunchy v0.2.4", "crypto-bigint v0.5.5", "crypto-bigint v0.7.5", "crypto-common v0.1.7", "crypto-common v0.2.2", "cssparser v0.37.0", "cssparser-macros v0.7.0", "ctr v0.9.2", "ctutils v0.4.2", "curve25519-dalek v4.1.3", "curve25519-dalek-derive v0.1.1", "darling v0.20.11", "darling v0.23.0", "darling_core v0.20.11", "darling_core v0.23.0", "darling_macro v0.20.11", "darling_macro v0.23.0", "dashmap v6.2.1", "data-encoding v2.11.0", "der v0.7.10", "der v0.8.1", "der_derive v0.8.0", "deranged v0.5.8", "derive-syn-parse v0.2.0", "derive-where v1.6.1", "derive_builder v0.20.2", "derive_builder_core v0.20.2", "derive_builder_macro v0.20.2", "derive_more v2.1.1", "derive_more-impl v2.1.1", "digest v0.10.7", "digest v0.11.3", "displaydoc v0.2.6", "dotenvy v0.15.7", "dtoa v1.0.11", "dtoa-short v0.3.5", "dunce v1.0.5", "ecb v0.2.1", "ecdsa v0.16.9", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "ed448 v0.5.0", "ed448-goldilocks v0.14.0-pre.15", "ego-tree v0.11.0", "either v1.16.0", "elliptic-curve v0.13.8", "elliptic-curve v0.14.0", "email-encoding v0.4.1", "email_address v0.2.9", "encoding_rs v0.8.35", "equator v0.4.2", "equator-macro v0.4.2", "equivalent v1.0.2", "errno v0.3.14", "event-listener v5.4.1", "event-listener-strategy v0.5.4", "exr v1.74.0", "fallible-iterator v0.3.0", "fallible-streaming-iterator v0.1.9", "fastrand v2.4.1", "fax v0.2.7", "fdeflate v0.3.7", "ff v0.13.1", "ff v0.14.0", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "flate2 v1.1.10", "fnv v1.0.7", "foldhash v0.2.0", "form_urlencoded v1.2.2", "fs_extra v1.3.0", "funty v2.0.0", "futures-channel v0.3.32", "futures-core v0.3.34", "futures-intrusive v0.5.0", "futures-io v0.3.34", "futures-macro v0.3.34", "futures-sink v0.3.34", "futures-task v0.3.34", "futures-timer v3.0.4", "futures-util v0.3.34", "generic-array v0.14.7", "getopts v0.2.24", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "ghash v0.5.1", "ghash v0.6.0", "gif v0.14.2", "gimli v0.34.0", "glob v0.3.3", "governor v0.10.4", "group v0.13.0", "group v0.14.0", "h2 v0.4.19", "half v2.7.1", "hash2curve v0.14.0", "hashbrown v0.14.5", "hashbrown v0.16.1", "hashbrown v0.17.1", "hashlink v0.11.1", "heck v0.5.0", "hex v0.4.3", "hickory-net v0.26.1", "hickory-proto v0.26.1", "hickory-resolver v0.26.1", "hkdf v0.12.4", "hkdf v0.13.0", "hmac v0.12.1", "hmac v0.13.0", "hostname v0.4.2", "html5ever v0.39.0", "http v1.4.1", "http-body v1.0.1", "http-body-util v0.1.5", "httparse v1.10.1", "httpdate v1.0.3", "hybrid-array v0.4.12", "hyper v1.11.1", "hyper-rustls v0.27.9", "hyper-util v0.1.20", "iana-time-zone v0.1.65", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "ident_case v1.0.1", "idna v1.1.0", "idna_adapter v1.2.2", "image v0.25.10", "image-webp v0.2.4", "imgref v1.12.3", "indexmap v2.14.1", "inotify v0.9.6", "inotify-sys v0.1.5", "inout v0.1.4", "inout v0.2.2", "ipnet v2.12.0", "is_terminal_polyfill v1.70.2", "itertools v0.12.1", "itertools v0.14.0", "itoa v1.0.18", "jobserver v0.1.34", "jsonwebtoken v11.0.0", "keccak v0.1.6", "keccak v0.2.0", "kem v0.3.0", "lazy_static v1.5.0", "lebe v0.5.3", "lettre v0.11.23", "libc v0.2.189", "libloading v0.8.9", "libm v0.2.16", "libsqlite3-sys v0.37.0", "litemap v0.8.2", "lock_api v0.4.14", "log v0.4.34", "loop9 v0.1.5", "lru v0.18.3", "macro_magic v0.5.1", "macro_magic_core v0.5.1", "macro_magic_core_macros v0.5.1", "macro_magic_macros v0.5.1", "markup5ever v0.39.0", "maybe-rayon v0.1.1", "md-5 v0.10.6", "md-5 v0.11.0", "memchr v2.8.1", "mime v0.3.17", "minimal-lexical v0.2.1", "miniz_oxide v0.8.9", "miniz_oxide v0.9.1", "mio v0.8.11", "mio v1.2.1", "ml-kem v0.3.2", "module-lattice v0.2.3", "moka v0.12.15", "mongodb v3.8.2", "mongodb-internal-macros v3.8.2", "moxcms v0.8.1", "nanoid v0.5.0", "new_debug_unreachable v1.0.6", "no_std_io2 v0.9.4", "nom v7.1.3", "nom v8.0.0", "nonzero_ext v0.3.0", "noop_proc_macro v0.3.0", "notify v6.1.1", "num-bigint v0.4.6", "num-bigint v0.5.1", "num-bigint-dig v0.8.6", "num-conv v0.2.2", "num-derive v0.4.2", "num-integer v0.1.46", "num-iter v0.1.45", "num-rational v0.4.2", "num-traits v0.2.19", "once_cell v1.21.4", "opaque-debug v0.3.1", "openssl-probe v0.2.1", "p256 v0.13.2", "p384 v0.13.1", "p521 v0.13.3", "parking v2.2.1", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "password-hash v0.5.0", "paste v1.0.15", "pastey v0.1.1", "pbkdf2 v0.12.2", "pbkdf2 v0.13.0", "pem v3.0.6", "pem-rfc7468 v0.7.0", "pem-rfc7468 v1.0.0", "percent-encoding v2.3.2", "phf v0.11.3", "phf v0.12.1", "phf v0.13.1", "phf_codegen v0.13.1", "phf_generator v0.11.3", "phf_generator v0.13.1", "phf_macros v0.11.3", "phf_macros v0.13.1", "phf_shared v0.11.3", "phf_shared v0.12.1", "phf_shared v0.13.1", "pin-project-lite v0.2.17", "pkcs1 v0.7.5", "pkcs5 v0.7.1", "pkcs8 v0.10.2", "pkcs8 v0.11.0", "pkg-config v0.3.33", "png v0.18.1", "poly1305 v0.8.0", "polyval v0.6.2", "polyval v0.7.3", "portable-atomic v1.13.1", "potential_utf v0.1.5", "powerfmt v0.2.0", "ppv-lite86 v0.2.21", "precomputed-hash v0.1.1", "prefix-trie v0.8.4", "primeorder v0.13.6", "proc-macro2 v1.0.106", "profiling v1.0.18", "profiling-procmacros v1.0.18", "pxfm v0.1.29", "qoi v0.4.1", "quanta v0.12.6", "quick-error v2.0.1", "quote v1.0.45", "quoted_printable v0.5.2", "radium v0.7.0", "rand v0.10.2", "rand v0.8.7", "rand v0.9.4", "rand_chacha v0.3.1", "rand_chacha v0.9.0", "rand_core v0.10.1", "rand_core v0.6.4", "rand_core v0.9.5", "rav1e v0.8.1", "ravif v0.13.0", "raw-cpuid v11.6.0", "rayon v1.12.0", "rayon-core v1.13.0", "redis v1.6.0", "regex v1.13.1", "regex-automata v0.4.18", "regex-syntax v0.8.11", "reqwest v0.12.28", "resolv-conf v0.7.6", "rfc6979 v0.4.0", "rgb v0.8.53", "ring v0.17.14", "rsa v0.9.10", "rusqlite v0.39.0", "rust_decimal v1.43.0", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "rustc_version v0.4.1", "rustc_version_runtime v0.3.0", "rustls v0.23.43", "rustls-native-certs v0.8.4", "rustls-pemfile v2.2.0", "rustls-pki-types v1.14.1", "rustls-webpki v0.103.13", "rustversion v1.0.22", "ryu v1.0.23", "ryu-js v1.0.3", "salsa20 v0.10.2", "same-file v1.0.6", "scopeguard v1.2.0", "scraper v0.27.0", "scrypt v0.11.0", "sec1 v0.7.3", "sec1 v0.8.1", "selectors v0.38.0", "semver v1.0.28", "serde v1.0.229", "serde_bytes v0.11.19", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_urlencoded v0.7.1", "serde_with v3.21.0", "serde_with_macros v3.21.0", "servo_arc v0.4.3", "sha1 v0.10.6", "sha1 v0.11.0", "sha1_smol v1.0.1", "sha2 v0.10.9", "sha2 v0.11.0", "sha3 v0.10.9", "sha3 v0.11.0", "sha3 v0.12.0", "sha3-utils v0.5.0", "shake v0.1.0", "shlex v1.3.0", "shlex v2.0.1", "signal-hook-registry v1.4.8", "signature v2.2.0", "signature v3.0.0", "simd-adler32 v0.3.9", "simd_helpers v0.1.0", "simdutf8 v0.1.5", "simple_asn1 v0.6.4", "siphasher v1.0.3", "slab v0.4.12", "slotmap v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "spin v0.9.8", "spinning_top v0.3.0", "spki v0.7.3", "spki v0.8.0", "sponge-cursor v0.1.0", "sqlx v0.9.0", "sqlx-core v0.9.0", "sqlx-mysql v0.9.0", "sqlx-postgres v0.9.0", "stable_deref_trait v1.2.1", "string_cache v0.9.0", "string_cache_codegen v0.6.1", "stringprep v0.1.5", "strsim v0.11.1", "strum v0.27.2", "strum_macros v0.27.2", "subtle v2.6.1", "syn v2.0.117", "syn v3.0.3", "sync_wrapper v1.0.2", "synstructure v0.13.2", "taffy v0.13.0", "tagptr v0.2.0", "take_mut v0.2.2", "tap v1.0.1", "tendril v0.5.0", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "tiff v0.11.3", "time v0.3.55", "time-core v0.1.9", "time-macros v0.2.32", "tiny-keccak v2.0.2", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tokio v1.53.1", "tokio-cron-scheduler v0.15.1", "tokio-macros v2.7.0", "tokio-rustls v0.26.4", "tokio-stream v0.1.18", "tokio-tungstenite v0.29.0", "tokio-util v0.7.18", "tower v0.5.3", "tower-http v0.6.11", "tower-layer v0.3.3", "tower-service v0.3.3", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "try-lock v0.2.5", "tungstenite v0.29.0", "typed-builder v0.22.0", "typed-builder-macro v0.22.0", "typenum v1.20.1", "unicode-bidi v0.3.18", "unicode-ident v1.0.24", "unicode-normalization v0.1.25", "unicode-properties v0.1.4", "unicode-segmentation v1.13.3", "unicode-width v0.2.2", "unicode-xid v0.2.6", "universal-hash v0.5.1", "universal-hash v0.6.1", "untrusted v0.9.0", "url v2.5.8", "utf-8 v0.7.6", "utf8_iter v1.0.4", "utf8parse v0.2.2", "uuid v1.26.0", "v_frame v0.3.9", "vcpkg v0.2.15", "version_check v0.9.5", "walkdir v2.5.0", "want v0.3.1", "web-time v1.1.0", "web_atoms v0.2.4", "webpki-roots v0.26.11", "webpki-roots v1.0.9", "weezl v0.1.12", "whoami v2.1.2", "windows-link v0.2.1", "winnow v0.7.15", "writeable v0.6.4", "wyz v0.5.1", "x25519-dalek v2.0.1", "x448 v0.14.0-pre.12", "x509-cert v0.3.0", "xxhash-rust v0.8.18", "y4m v0.8.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerocopy-derive v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zeroize_derive v1.4.3", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7", "zune-core v0.5.1", "zune-inflate v0.2.54", "zune-jpeg v0.5.15"]}, +{"configuration": "Stdlib minimal", "target": "x86_64-unknown-linux-gnu", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-stdlib", "--no-default-features", "-e", "normal,build", "--target", "x86_64-unknown-linux-gnu", "--prefix", "none", "--format", "{p}"], "external_package_versions": 146, "packages": ["ahash v0.8.12", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "arrayvec v0.7.6", "autocfg v1.5.1", "base64 v0.22.1", "bitflags v1.3.2", "block-buffer v0.10.4", "block-buffer v0.12.0", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "chrono v0.4.45", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "colorchoice v1.0.5", "const-oid v0.10.2", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-utils v0.8.21", "crypto-common v0.1.7", "crypto-common v0.2.2", "curve25519-dalek v4.1.3", "curve25519-dalek-derive v0.1.1", "dashmap v6.2.1", "data-encoding v2.11.0", "der v0.8.1", "der_derive v0.8.0", "digest v0.10.7", "digest v0.11.3", "displaydoc v0.2.6", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "encoding_rs v0.8.35", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "form_urlencoded v1.2.2", "generic-array v0.14.7", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "hashbrown v0.14.5", "heck v0.5.0", "hex v0.4.3", "hickory-proto v0.26.1", "hybrid-array v0.4.12", "iana-time-zone v0.1.65", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "inotify v0.9.6", "inotify-sys v0.1.5", "ipnet v2.12.0", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "lazy_static v1.5.0", "libc v0.2.189", "litemap v0.8.2", "lock_api v0.4.14", "log v0.4.34", "memchr v2.8.1", "mio v0.8.11", "notify v6.1.1", "num-traits v0.2.19", "once_cell v1.21.4", "parking_lot_core v0.9.12", "percent-encoding v2.3.2", "pin-project-lite v0.2.17", "portable-atomic v1.13.1", "potential_utf v0.1.5", "proc-macro2 v1.0.106", "quote v1.0.45", "rand v0.10.2", "rand_core v0.10.1", "rand_core v0.6.4", "resolv-conf v0.7.6", "rustc-demangle v0.1.28", "rustc_version v0.4.1", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scopeguard v1.2.0", "semver v1.0.28", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "sha2 v0.10.9", "sha2 v0.11.0", "shlex v2.0.1", "signature v2.2.0", "simdutf8 v0.1.5", "slotmap v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "spki v0.8.0", "stable_deref_trait v1.2.1", "strsim v0.11.1", "subtle v2.6.1", "syn v2.0.117", "syn v3.0.3", "synstructure v0.13.2", "taffy v0.13.0", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tracing v0.1.44", "tracing-core v0.1.36", "typenum v1.20.1", "unicode-ident v1.0.24", "url v2.5.8", "utf8_iter v1.0.4", "utf8parse v0.2.2", "version_check v0.9.5", "walkdir v2.5.0", "writeable v0.6.4", "x509-cert v0.3.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21"]}, +{"configuration": "Compose", "target": "x86_64-unknown-linux-gnu", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-container-compose", "-e", "normal,build", "--target", "x86_64-unknown-linux-gnu", "--prefix", "none", "--format", "{p}"], "external_package_versions": 94, "packages": ["anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "async-trait v0.1.92", "atty v0.2.14", "bitflags v2.12.1", "block-buffer v0.12.0", "bytes v1.12.1", "cfg-if v1.0.4", "chacha20 v0.10.0", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "colorchoice v1.0.5", "console v0.15.11", "console v0.16.4", "const-oid v0.10.2", "cpufeatures v0.3.0", "crossbeam-utils v0.8.21", "crypto-common v0.2.2", "dashmap v6.2.1", "dialoguer v0.11.0", "digest v0.11.3", "dotenvy v0.15.7", "equivalent v1.0.2", "errno v0.3.14", "fastrand v2.4.1", "getrandom v0.4.2", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hex v0.4.3", "hybrid-array v0.4.12", "indexmap v2.14.1", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "lazy_static v1.5.0", "libc v0.2.189", "linux-raw-sys v0.12.1", "lock_api v0.4.14", "log v0.4.34", "matchers v0.2.0", "md-5 v0.11.0", "memchr v2.8.1", "mio v1.2.1", "nu-ansi-term v0.50.3", "once_cell v1.21.4", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "pin-project-lite v0.2.17", "proc-macro2 v1.0.106", "quote v1.0.45", "rand v0.10.2", "rand_core v0.10.1", "regex-automata v0.4.18", "regex-syntax v0.8.11", "rustix v1.1.4", "ryu v1.0.23", "scopeguard v1.2.0", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_yaml v0.9.34+deprecated", "sharded-slab v0.1.7", "shell-words v1.1.1", "signal-hook-registry v1.4.8", "smallvec v1.15.1", "socket2 v0.6.5", "strsim v0.11.1", "syn v2.0.117", "syn v3.0.3", "tempfile v3.27.0", "thiserror v1.0.69", "thiserror-impl v1.0.69", "thread_local v1.1.9", "tokio v1.53.1", "tokio-macros v2.7.0", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "tracing-log v0.2.0", "tracing-subscriber v0.3.23", "typenum v1.20.1", "unicode-ident v1.0.24", "unicode-width v0.2.2", "unsafe-libyaml v0.2.11", "utf8parse v0.2.2", "which v8.0.6", "zeroize v1.8.2", "zmij v1.0.21"]}, +{"configuration": "CLI default", "target": "aarch64-apple-darwin", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry", "-e", "normal,build", "--target", "aarch64-apple-darwin", "--prefix", "none", "--format", "{p}"], "external_package_versions": 349, "packages": ["adler2 v2.0.1", "aes v0.9.1", "ahash v0.8.12", "aho-corasick v1.1.4", "allocator-api2 v0.2.21", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "ar_archive_writer v0.5.1", "arrayvec v0.7.6", "ast_node v5.0.0", "atomic-waker v1.1.2", "autocfg v1.5.1", "base16ct v0.2.0", "base64 v0.22.1", "base64ct v1.8.3", "better_scoped_tls v1.0.1", "bitflags v2.12.1", "block-buffer v0.10.4", "block-buffer v0.12.0", "bumpalo v3.20.3", "bytes v1.12.1", "bytes-str v0.2.7", "bzip2 v0.6.1", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "chrono v0.4.45", "cipher v0.5.2", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "cmov v0.5.4", "colorchoice v1.0.5", "console v0.16.4", "const-oid v0.10.2", "const-oid v0.9.6", "constant_time_eq v0.4.2", "core-foundation-sys v0.8.7", "cpubits v0.1.1", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "crc32fast v1.5.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-deque v0.8.6", "crossbeam-epoch v0.9.20", "crossbeam-utils v0.8.21", "crypto-bigint v0.5.5", "crypto-common v0.1.7", "crypto-common v0.2.2", "ctutils v0.4.2", "curve25519-dalek v4.1.3", "data-encoding v2.11.0", "deflate64 v0.1.12", "der v0.7.10", "der v0.8.1", "der_derive v0.8.0", "deranged v0.5.8", "dialoguer v0.12.0", "digest v0.10.7", "digest v0.11.3", "dirs v6.0.0", "dirs-sys v0.5.0", "displaydoc v0.2.6", "dotenvy v0.15.7", "ecdsa v0.16.9", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "either v1.16.0", "elliptic-curve v0.13.8", "encoding_rs v0.8.35", "env_logger v0.10.2", "equivalent v1.0.2", "errno v0.3.14", "fastrand v2.4.1", "ff v0.13.1", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "flate2 v1.1.10", "form_urlencoded v1.2.2", "from_variant v3.0.0", "fsevent-sys v4.1.0", "fslock v0.2.1", "futures-channel v0.3.32", "futures-core v0.3.34", "futures-io v0.3.34", "futures-macro v0.3.34", "futures-sink v0.3.34", "futures-task v0.3.34", "futures-util v0.3.34", "generic-array v0.14.7", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "group v0.13.0", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hex v0.4.3", "hickory-proto v0.26.1", "hkdf v0.12.4", "hmac v0.12.1", "hmac v0.13.0", "hstr v3.0.6", "http v1.4.1", "http-body v1.0.1", "http-body-util v0.1.5", "httparse v1.10.1", "humantime v2.3.0", "hybrid-array v0.4.12", "hyper v1.11.1", "hyper-rustls v0.27.9", "hyper-util v0.1.20", "iana-time-zone v0.1.65", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "indexmap v2.14.1", "indicatif v0.18.6", "inkwell v0.9.0", "inkwell_internals v0.14.0", "inout v0.2.2", "ipnet v2.12.0", "is-macro v0.3.7", "is-terminal v0.4.17", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "jobserver v0.1.34", "jsonwebtoken v11.0.0", "lazy_static v1.5.0", "leb128fmt v0.1.0", "libbz2-rs-sys v0.2.5", "libc v0.2.189", "libm v0.2.16", "litemap v0.8.2", "llvm-sys v221.0.1", "lock_api v0.4.14", "log v0.4.34", "lzma-rust2 v0.16.4", "mach2 v0.6.0", "memchr v2.8.1", "mime v0.3.17", "mime_guess v2.0.5", "miniz_oxide v0.9.1", "mio v1.2.1", "new_debug_unreachable v1.0.6", "notify v6.1.1", "num-bigint v0.4.6", "num-bigint-dig v0.8.6", "num-conv v0.2.2", "num-integer v0.1.46", "num-iter v0.1.45", "num-traits v0.2.19", "num_cpus v1.17.0", "object v0.37.3", "once_cell v1.21.4", "option-ext v0.2.0", "p256 v0.13.2", "p384 v0.13.1", "par-core v2.0.0", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "pbkdf2 v0.13.0", "pem v3.0.6", "pem-rfc7468 v0.7.0", "percent-encoding v2.3.2", "perex v0.1.4", "phf v0.11.3", "phf_generator v0.11.3", "phf_macros v0.11.3", "phf_shared v0.11.3", "pin-project-lite v0.2.17", "pkcs1 v0.7.5", "pkcs8 v0.10.2", "pkg-config v0.3.33", "portable-atomic v1.13.1", "potential_utf v0.1.5", "powerfmt v0.2.0", "ppmd-rust v1.4.0", "ppv-lite86 v0.2.21", "primeorder v0.13.6", "proc-macro2 v1.0.106", "psm v0.1.32", "quote v1.0.45", "rand v0.10.2", "rand v0.8.7", "rand v0.9.4", "rand_chacha v0.3.1", "rand_chacha v0.9.0", "rand_core v0.10.1", "rand_core v0.6.4", "rand_core v0.9.5", "rayon v1.12.0", "rayon-core v1.13.0", "regex v1.13.1", "regex-automata v0.4.18", "regex-lite v0.1.9", "regex-syntax v0.8.11", "reqwest v0.12.28", "resolv-conf v0.7.6", "rfc6979 v0.4.0", "ring v0.17.14", "rsa v0.9.10", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "rustc_version v0.4.1", "rustix v1.1.4", "rustls v0.23.43", "rustls-pki-types v1.14.1", "rustls-webpki v0.103.13", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scoped-tls v1.0.1", "scopeguard v1.2.0", "sec1 v0.7.3", "semver v1.0.28", "seq-macro v0.3.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_spanned v1.1.1", "serde_urlencoded v0.7.1", "sha1 v0.10.6", "sha1 v0.11.0", "sha2 v0.10.9", "sha2 v0.11.0", "shell-words v1.1.1", "shlex v2.0.1", "signal-hook-registry v1.4.8", "signature v2.2.0", "simd-adler32 v0.3.9", "simdutf8 v0.1.5", "simple_asn1 v0.6.4", "siphasher v0.3.11", "siphasher v1.0.3", "slab v0.4.12", "slotmap v1.1.1", "smallvec v1.15.1", "smartstring v1.0.1", "socket2 v0.6.5", "spin v0.9.8", "spki v0.7.3", "spki v0.8.0", "stable_deref_trait v1.2.1", "stacker v0.1.25", "static_assertions v1.1.0", "string_enum v1.0.2", "strsim v0.11.1", "subtle v2.6.1", "swc_atoms v9.0.3", "swc_common v18.0.1", "swc_ecma_ast v19.0.0", "swc_ecma_parser v29.0.2", "swc_ecma_parser v32.0.0", "swc_ecma_transforms_base v32.0.0", "swc_ecma_utils v25.0.0", "swc_ecma_visit v19.0.0", "swc_eq_ignore_macros v1.0.1", "swc_macros_common v1.0.1", "swc_visit v2.0.1", "syn v2.0.117", "syn v3.0.3", "sync_wrapper v1.0.2", "synstructure v0.13.2", "taffy v0.13.0", "tar v0.4.46", "tempfile v3.27.0", "termcolor v1.4.1", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "time v0.3.55", "time-core v0.1.9", "time-macros v0.2.32", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tokio v1.53.1", "tokio-macros v2.7.0", "tokio-rustls v0.26.4", "tokio-tungstenite v0.29.0", "toml v1.1.4+spec-1.1.0", "toml_datetime v1.1.1+spec-1.1.0", "toml_parser v1.1.3+spec-1.1.0", "toml_writer v1.1.2+spec-1.1.0", "tower v0.5.3", "tower-http v0.6.11", "tower-layer v0.3.3", "tower-service v0.3.3", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "triomphe v0.1.15", "try-lock v0.2.5", "tungstenite v0.29.0", "typed-path v0.12.3", "typenum v1.20.1", "unicase v2.9.0", "unicode-id-start v1.4.0", "unicode-ident v1.0.24", "unicode-width v0.2.2", "unit-prefix v0.5.2", "untrusted v0.9.0", "url v2.5.8", "utf8_iter v1.0.4", "utf8parse v0.2.2", "version_check v0.9.5", "walkdir v2.5.0", "want v0.3.1", "wasm-encoder v0.258.0", "webpki-roots v0.26.11", "webpki-roots v1.0.9", "winnow v1.0.3", "winresource v0.1.31", "writeable v0.6.4", "x509-cert v0.3.0", "xattr v1.6.1", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zeroize_derive v1.4.3", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zip v8.6.0", "zlib-rs v0.6.4", "zmij v1.0.21", "zopfli v0.8.3", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7"]}, +{"configuration": "CLI dev", "target": "aarch64-apple-darwin", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry", "--no-default-features", "--features", "dev-cli", "-e", "normal,build", "--target", "aarch64-apple-darwin", "--prefix", "none", "--format", "{p}"], "external_package_versions": 347, "packages": ["adler2 v2.0.1", "aes v0.9.1", "ahash v0.8.12", "aho-corasick v1.1.4", "allocator-api2 v0.2.21", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "ar_archive_writer v0.5.1", "arrayvec v0.7.6", "ast_node v5.0.0", "atomic-waker v1.1.2", "autocfg v1.5.1", "base16ct v0.2.0", "base64 v0.22.1", "base64ct v1.8.3", "better_scoped_tls v1.0.1", "bitflags v2.12.1", "block-buffer v0.10.4", "block-buffer v0.12.0", "bumpalo v3.20.3", "bytes v1.12.1", "bytes-str v0.2.7", "bzip2 v0.6.1", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "chrono v0.4.45", "cipher v0.5.2", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "cmov v0.5.4", "colorchoice v1.0.5", "console v0.16.4", "const-oid v0.10.2", "const-oid v0.9.6", "constant_time_eq v0.4.2", "core-foundation-sys v0.8.7", "cpubits v0.1.1", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "crc32fast v1.5.0", "critical-section v1.2.0", "crossbeam-channel v0.5.15", "crossbeam-deque v0.8.6", "crossbeam-epoch v0.9.20", "crossbeam-utils v0.8.21", "crypto-bigint v0.5.5", "crypto-common v0.1.7", "crypto-common v0.2.2", "ctutils v0.4.2", "curve25519-dalek v4.1.3", "data-encoding v2.11.0", "deflate64 v0.1.12", "der v0.7.10", "der v0.8.1", "der_derive v0.8.0", "deranged v0.5.8", "dialoguer v0.12.0", "digest v0.10.7", "digest v0.11.3", "dirs v6.0.0", "dirs-sys v0.5.0", "displaydoc v0.2.6", "dotenvy v0.15.7", "ecdsa v0.16.9", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "either v1.16.0", "elliptic-curve v0.13.8", "encoding_rs v0.8.35", "env_logger v0.10.2", "equivalent v1.0.2", "errno v0.3.14", "fastrand v2.4.1", "ff v0.13.1", "filetime v0.2.29", "find-msvc-tools v0.1.11", "flagset v0.4.7", "flate2 v1.1.10", "form_urlencoded v1.2.2", "from_variant v3.0.0", "fsevent-sys v4.1.0", "fslock v0.2.1", "futures-channel v0.3.32", "futures-core v0.3.34", "futures-io v0.3.34", "futures-macro v0.3.34", "futures-sink v0.3.34", "futures-task v0.3.34", "futures-util v0.3.34", "generic-array v0.14.7", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "group v0.13.0", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hex v0.4.3", "hickory-proto v0.26.1", "hkdf v0.12.4", "hmac v0.12.1", "hmac v0.13.0", "hstr v3.0.6", "http v1.4.1", "http-body v1.0.1", "http-body-util v0.1.5", "httparse v1.10.1", "humantime v2.3.0", "hybrid-array v0.4.12", "hyper v1.11.1", "hyper-rustls v0.27.9", "hyper-util v0.1.20", "iana-time-zone v0.1.65", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "indexmap v2.14.1", "indicatif v0.18.6", "inkwell v0.9.0", "inkwell_internals v0.14.0", "inout v0.2.2", "ipnet v2.12.0", "is-macro v0.3.7", "is-terminal v0.4.17", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "jobserver v0.1.34", "jsonwebtoken v11.0.0", "lazy_static v1.5.0", "libbz2-rs-sys v0.2.5", "libc v0.2.189", "libm v0.2.16", "litemap v0.8.2", "llvm-sys v221.0.1", "lock_api v0.4.14", "log v0.4.34", "lzma-rust2 v0.16.4", "mach2 v0.6.0", "memchr v2.8.1", "mime v0.3.17", "mime_guess v2.0.5", "miniz_oxide v0.9.1", "mio v1.2.1", "new_debug_unreachable v1.0.6", "notify v6.1.1", "num-bigint v0.4.6", "num-bigint-dig v0.8.6", "num-conv v0.2.2", "num-integer v0.1.46", "num-iter v0.1.45", "num-traits v0.2.19", "num_cpus v1.17.0", "object v0.37.3", "once_cell v1.21.4", "option-ext v0.2.0", "p256 v0.13.2", "p384 v0.13.1", "par-core v2.0.0", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "pbkdf2 v0.13.0", "pem v3.0.6", "pem-rfc7468 v0.7.0", "percent-encoding v2.3.2", "perex v0.1.4", "phf v0.11.3", "phf_generator v0.11.3", "phf_macros v0.11.3", "phf_shared v0.11.3", "pin-project-lite v0.2.17", "pkcs1 v0.7.5", "pkcs8 v0.10.2", "pkg-config v0.3.33", "portable-atomic v1.13.1", "potential_utf v0.1.5", "powerfmt v0.2.0", "ppmd-rust v1.4.0", "ppv-lite86 v0.2.21", "primeorder v0.13.6", "proc-macro2 v1.0.106", "psm v0.1.32", "quote v1.0.45", "rand v0.10.2", "rand v0.8.7", "rand v0.9.4", "rand_chacha v0.3.1", "rand_chacha v0.9.0", "rand_core v0.10.1", "rand_core v0.6.4", "rand_core v0.9.5", "rayon v1.12.0", "rayon-core v1.13.0", "regex v1.13.1", "regex-automata v0.4.18", "regex-lite v0.1.9", "regex-syntax v0.8.11", "reqwest v0.12.28", "resolv-conf v0.7.6", "rfc6979 v0.4.0", "ring v0.17.14", "rsa v0.9.10", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "rustc_version v0.4.1", "rustix v1.1.4", "rustls v0.23.43", "rustls-pki-types v1.14.1", "rustls-webpki v0.103.13", "ryu v1.0.23", "ryu-js v1.0.3", "same-file v1.0.6", "scoped-tls v1.0.1", "scopeguard v1.2.0", "sec1 v0.7.3", "semver v1.0.28", "seq-macro v0.3.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_spanned v1.1.1", "serde_urlencoded v0.7.1", "sha1 v0.10.6", "sha1 v0.11.0", "sha2 v0.10.9", "sha2 v0.11.0", "shell-words v1.1.1", "shlex v2.0.1", "signal-hook-registry v1.4.8", "signature v2.2.0", "simd-adler32 v0.3.9", "simdutf8 v0.1.5", "simple_asn1 v0.6.4", "siphasher v0.3.11", "siphasher v1.0.3", "slab v0.4.12", "slotmap v1.1.1", "smallvec v1.15.1", "smartstring v1.0.1", "socket2 v0.6.5", "spin v0.9.8", "spki v0.7.3", "spki v0.8.0", "stable_deref_trait v1.2.1", "stacker v0.1.25", "static_assertions v1.1.0", "string_enum v1.0.2", "strsim v0.11.1", "subtle v2.6.1", "swc_atoms v9.0.3", "swc_common v18.0.1", "swc_ecma_ast v19.0.0", "swc_ecma_parser v29.0.2", "swc_ecma_parser v32.0.0", "swc_ecma_transforms_base v32.0.0", "swc_ecma_utils v25.0.0", "swc_ecma_visit v19.0.0", "swc_eq_ignore_macros v1.0.1", "swc_macros_common v1.0.1", "swc_visit v2.0.1", "syn v2.0.117", "syn v3.0.3", "sync_wrapper v1.0.2", "synstructure v0.13.2", "taffy v0.13.0", "tar v0.4.46", "tempfile v3.27.0", "termcolor v1.4.1", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "time v0.3.55", "time-core v0.1.9", "time-macros v0.2.32", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tokio v1.53.1", "tokio-macros v2.7.0", "tokio-rustls v0.26.4", "tokio-tungstenite v0.29.0", "toml v1.1.4+spec-1.1.0", "toml_datetime v1.1.1+spec-1.1.0", "toml_parser v1.1.3+spec-1.1.0", "toml_writer v1.1.2+spec-1.1.0", "tower v0.5.3", "tower-http v0.6.11", "tower-layer v0.3.3", "tower-service v0.3.3", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "triomphe v0.1.15", "try-lock v0.2.5", "tungstenite v0.29.0", "typed-path v0.12.3", "typenum v1.20.1", "unicase v2.9.0", "unicode-id-start v1.4.0", "unicode-ident v1.0.24", "unicode-width v0.2.2", "unit-prefix v0.5.2", "untrusted v0.9.0", "url v2.5.8", "utf8_iter v1.0.4", "utf8parse v0.2.2", "version_check v0.9.5", "walkdir v2.5.0", "want v0.3.1", "webpki-roots v0.26.11", "webpki-roots v1.0.9", "winnow v1.0.3", "winresource v0.1.31", "writeable v0.6.4", "x509-cert v0.3.0", "xattr v1.6.1", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zeroize_derive v1.4.3", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zip v8.6.0", "zlib-rs v0.6.4", "zmij v1.0.21", "zopfli v0.8.3", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7"]}, +{"configuration": "Runtime default", "target": "aarch64-apple-darwin", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-runtime", "-e", "normal,build", "--target", "aarch64-apple-darwin", "--prefix", "none", "--format", "{p}"], "external_package_versions": 206, "packages": ["ahash v0.8.12", "allocator-api2 v0.2.21", "anyhow v1.0.104", "ar_archive_writer v0.5.1", "arrayvec v0.7.6", "ast_node v5.0.0", "autocfg v1.5.1", "base64 v0.22.1", "better_scoped_tls v1.0.1", "bitflags v2.12.1", "block-buffer v0.12.0", "bytecount v0.6.9", "bytes v1.12.1", "bytes-str v0.2.7", "calendrical_calculations v0.2.4", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "combine v4.6.7", "const-oid v0.10.2", "core_maths v0.1.1", "cpufeatures v0.3.0", "critical-section v1.2.0", "crypto-common v0.2.2", "cty v0.2.2", "data-encoding v2.11.0", "der v0.8.1", "der_derive v0.8.0", "digest v0.11.3", "dirs v6.0.0", "dirs-sys v0.5.0", "displaydoc v0.2.6", "either v1.16.0", "encoding_rs v0.8.35", "equivalent v1.0.2", "find-msvc-tools v0.1.11", "fixed_decimal v0.7.2", "flagset v0.4.7", "form_urlencoded v1.2.2", "from_variant v3.0.0", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hickory-proto v0.26.1", "hostname v0.4.2", "hstr v3.0.6", "hybrid-array v0.4.12", "icu_calendar v2.3.0", "icu_calendar_data v2.3.0", "icu_collections v2.2.0", "icu_datetime v2.3.0", "icu_datetime_data v2.3.0", "icu_decimal v2.3.0", "icu_decimal_data v2.3.0", "icu_locale v2.2.0", "icu_locale_core v2.3.0", "icu_locale_data v2.2.0", "icu_locale_fallback v2.3.0", "icu_locale_fallback_data v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_pattern v0.5.0", "icu_plurals v2.3.0", "icu_plurals_data v2.3.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "icu_time v2.3.0", "icu_time_data v2.3.0", "idna v1.1.0", "idna_adapter v1.2.2", "indexmap v2.14.1", "ipnet v2.12.0", "is-macro v0.3.7", "itoa v1.0.18", "ixdtf v0.6.5", "jiff-tzdb v0.1.6", "jobserver v0.1.34", "lazy_static v1.5.0", "libc v0.2.189", "libm v0.2.16", "libmimalloc-sys v0.1.49", "litemap v0.8.2", "mach2 v0.6.0", "memchr v2.8.1", "miette v7.6.0", "miette-derive v7.6.0", "mimalloc v0.1.52", "minimal-lexical v0.2.1", "new_debug_unreachable v1.0.6", "node-semver v2.2.0", "nom v7.1.3", "num-bigint v0.4.6", "num-integer v0.1.46", "num-traits v0.2.19", "num_cpus v1.17.0", "object v0.37.3", "once_cell v1.21.4", "option-ext v0.2.0", "par-core v2.0.0", "percent-encoding v2.3.2", "perex v0.1.4", "phf v0.11.3", "phf_generator v0.11.3", "phf_macros v0.11.3", "phf_shared v0.11.3", "pin-project-lite v0.2.17", "pkg-config v0.3.33", "portable-atomic v1.13.1", "potential_utf v0.1.5", "proc-macro2 v1.0.106", "psm v0.1.32", "quote v1.0.45", "rand v0.10.2", "rand v0.8.7", "rand_core v0.10.1", "rand_core v0.6.4", "resolv-conf v0.7.6", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "ryu v1.0.23", "ryu-js v1.0.3", "scoped-tls v1.0.1", "seq-macro v0.3.6", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_spanned v1.1.1", "sha2 v0.11.0", "shlex v2.0.1", "simdutf8 v0.1.5", "siphasher v0.3.11", "siphasher v1.0.3", "slotmap v1.1.1", "smallvec v1.15.1", "smartstring v1.0.1", "socket2 v0.6.5", "spki v0.8.0", "stable_deref_trait v1.2.1", "stacker v0.1.25", "static_assertions v1.1.0", "string_enum v1.0.2", "swc_atoms v9.0.3", "swc_common v18.0.1", "swc_ecma_ast v19.0.0", "swc_ecma_parser v29.0.2", "swc_ecma_parser v32.0.0", "swc_ecma_transforms_base v32.0.0", "swc_ecma_utils v25.0.0", "swc_ecma_visit v19.0.0", "swc_eq_ignore_macros v1.0.1", "swc_macros_common v1.0.1", "swc_visit v2.0.1", "syn v2.0.117", "syn v3.0.3", "synstructure v0.13.2", "taffy v0.13.0", "temporal_rs v0.2.6", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "timezone_provider v0.2.6", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "toml v1.1.4+spec-1.1.0", "toml_datetime v1.1.1+spec-1.1.0", "toml_parser v1.1.3+spec-1.1.0", "toml_writer v1.1.2+spec-1.1.0", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "triomphe v0.1.15", "typenum v1.20.1", "tzif v0.4.1", "unicode-id-start v1.4.0", "unicode-ident v1.0.24", "unicode-normalization v0.1.25", "unicode-segmentation v1.13.3", "unicode-width v0.1.14", "unicode-width v0.2.2", "unsafe-libyaml v0.2.11", "url v2.5.8", "utf8_iter v1.0.4", "version_check v0.9.5", "winnow v1.0.3", "writeable v0.6.4", "x509-cert v0.3.0", "xxhash-rust v0.8.18", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7"]}, +{"configuration": "Runtime minimal", "target": "aarch64-apple-darwin", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-runtime", "--no-default-features", "-e", "normal,build", "--target", "aarch64-apple-darwin", "--prefix", "none", "--format", "{p}"], "external_package_versions": 96, "packages": ["ahash v0.8.12", "anyhow v1.0.104", "arrayvec v0.7.6", "base64 v0.22.1", "block-buffer v0.12.0", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "const-oid v0.10.2", "cpufeatures v0.3.0", "critical-section v1.2.0", "crypto-common v0.2.2", "data-encoding v2.11.0", "der v0.8.1", "der_derive v0.8.0", "digest v0.11.3", "displaydoc v0.2.6", "encoding_rs v0.8.35", "find-msvc-tools v0.1.11", "flagset v0.4.7", "form_urlencoded v1.2.2", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "hickory-proto v0.26.1", "hybrid-array v0.4.12", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "ipnet v2.12.0", "itoa v1.0.18", "lazy_static v1.5.0", "libc v0.2.189", "litemap v0.8.2", "mach2 v0.6.0", "memchr v2.8.1", "once_cell v1.21.4", "percent-encoding v2.3.2", "pin-project-lite v0.2.17", "portable-atomic v1.13.1", "potential_utf v0.1.5", "proc-macro2 v1.0.106", "quote v1.0.45", "rand v0.10.2", "rand_core v0.10.1", "resolv-conf v0.7.6", "rustc-demangle v0.1.28", "ryu v1.0.23", "ryu-js v1.0.3", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "sha2 v0.11.0", "shlex v2.0.1", "simdutf8 v0.1.5", "slotmap v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "spki v0.8.0", "stable_deref_trait v1.2.1", "syn v2.0.117", "syn v3.0.3", "synstructure v0.13.2", "taffy v0.13.0", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tracing v0.1.44", "tracing-core v0.1.36", "typenum v1.20.1", "unicode-ident v1.0.24", "url v2.5.8", "utf8_iter v1.0.4", "version_check v0.9.5", "writeable v0.6.4", "x509-cert v0.3.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21"]}, +{"configuration": "Stdlib default", "target": "aarch64-apple-darwin", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-stdlib", "-e", "normal,build", "--target", "aarch64-apple-darwin", "--prefix", "none", "--format", "{p}"], "external_package_versions": 546, "packages": ["adler2 v2.0.1", "aead v0.5.2", "aes v0.8.4", "aes v0.9.1", "aes-gcm v0.10.3", "aes-kw v0.3.1", "ahash v0.8.12", "aligned v0.4.3", "aligned-vec v0.6.4", "alloc-no-stdlib v2.0.4", "alloc-stdlib v0.2.2", "allocator-api2 v0.2.21", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "arc-swap v1.9.1", "arcstr v1.2.0", "arg_enum_proc_macro v0.3.4", "argon2 v0.5.3", "arrayvec v0.7.6", "as-slice v0.2.1", "async-lock v3.4.2", "async-trait v0.1.92", "atoi v2.0.0", "atomic v0.6.1", "atomic-waker v1.1.2", "autocfg v1.5.1", "av-scenechange v0.14.1", "av1-grain v0.2.5", "avif-serialize v0.8.9", "aws-lc-rs v1.17.0", "aws-lc-sys v0.41.0", "backon v1.6.0", "base16ct v0.2.0", "base16ct v1.0.0", "base64 v0.22.1", "base64 v0.23.1", "base64ct v1.8.3", "bcrypt v0.19.3", "bindgen v0.72.1", "bit_field v0.10.3", "bitflags v2.12.1", "bitstream-io v4.10.0", "bitvec v1.0.1", "blake2 v0.10.6", "block-buffer v0.10.4", "block-buffer v0.12.0", "block-padding v0.3.3", "block-padding v0.4.2", "blowfish v0.10.0", "brotli v8.0.4", "brotli-decompressor v5.0.1", "bson v3.1.0", "built v0.8.1", "bytemuck v1.25.0", "byteorder v1.5.0", "byteorder-lite v0.1.0", "bytes v1.12.1", "cbc v0.1.2", "cbc v0.2.1", "cc v1.4.4", "cexpr v0.6.0", "cfg-if v1.0.4", "chacha20 v0.10.0", "chacha20 v0.9.1", "chacha20poly1305 v0.10.1", "chrono v0.4.45", "chrono-tz v0.10.4", "cipher v0.4.4", "cipher v0.5.2", "clang-sys v1.8.1", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "cmake v0.1.58", "cmov v0.5.4", "color_quant v1.1.0", "colorchoice v1.0.5", "combine v4.6.7", "concurrent-queue v2.5.0", "const-oid v0.10.2", "const-oid v0.9.6", "const-random v0.1.18", "const-random-macro v0.1.16", "convert_case v0.10.0", "core-foundation v0.10.1", "core-foundation v0.9.4", "core-foundation-sys v0.8.7", "cpubits v0.1.1", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "crc v3.4.0", "crc-catalog v2.5.0", "crc32fast v1.5.0", "critical-section v1.2.0", "cron v0.17.0", "croner v3.0.1", "crossbeam-channel v0.5.15", "crossbeam-deque v0.8.6", "crossbeam-epoch v0.9.20", "crossbeam-queue v0.3.12", "crossbeam-utils v0.8.21", "crunchy v0.2.4", "crypto-bigint v0.5.5", "crypto-bigint v0.7.5", "crypto-common v0.1.7", "crypto-common v0.2.2", "cssparser v0.37.0", "cssparser-macros v0.7.0", "ctr v0.9.2", "ctutils v0.4.2", "curve25519-dalek v4.1.3", "darling v0.20.11", "darling v0.23.0", "darling_core v0.20.11", "darling_core v0.23.0", "darling_macro v0.20.11", "darling_macro v0.23.0", "dashmap v6.2.1", "data-encoding v2.11.0", "der v0.7.10", "der v0.8.1", "der_derive v0.8.0", "deranged v0.5.8", "derive-syn-parse v0.2.0", "derive-where v1.6.1", "derive_builder v0.20.2", "derive_builder_core v0.20.2", "derive_builder_macro v0.20.2", "derive_more v2.1.1", "derive_more-impl v2.1.1", "digest v0.10.7", "digest v0.11.3", "displaydoc v0.2.6", "dotenvy v0.15.7", "dtoa v1.0.11", "dtoa-short v0.3.5", "dunce v1.0.5", "ecb v0.2.1", "ecdsa v0.16.9", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "ed448 v0.5.0", "ed448-goldilocks v0.14.0-pre.15", "ego-tree v0.11.0", "either v1.16.0", "elliptic-curve v0.13.8", "elliptic-curve v0.14.0", "email-encoding v0.4.1", "email_address v0.2.9", "encoding_rs v0.8.35", "equator v0.4.2", "equator-macro v0.4.2", "equivalent v1.0.2", "errno v0.3.14", "event-listener v5.4.1", "event-listener-strategy v0.5.4", "exr v1.74.0", "fallible-iterator v0.3.0", "fallible-streaming-iterator v0.1.9", "fastrand v2.4.1", "fax v0.2.7", "fdeflate v0.3.7", "ff v0.13.1", "ff v0.14.0", "find-msvc-tools v0.1.11", "flagset v0.4.7", "flate2 v1.1.10", "fnv v1.0.7", "foldhash v0.2.0", "form_urlencoded v1.2.2", "fs_extra v1.3.0", "funty v2.0.0", "futures-channel v0.3.32", "futures-core v0.3.34", "futures-intrusive v0.5.0", "futures-io v0.3.34", "futures-macro v0.3.34", "futures-sink v0.3.34", "futures-task v0.3.34", "futures-timer v3.0.4", "futures-util v0.3.34", "generic-array v0.14.7", "getopts v0.2.24", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "ghash v0.5.1", "ghash v0.6.0", "gif v0.14.2", "gimli v0.34.0", "glob v0.3.3", "governor v0.10.4", "group v0.13.0", "group v0.14.0", "h2 v0.4.19", "half v2.7.1", "hash2curve v0.14.0", "hashbrown v0.14.5", "hashbrown v0.16.1", "hashbrown v0.17.1", "hashlink v0.11.1", "heck v0.5.0", "hex v0.4.3", "hickory-net v0.26.1", "hickory-proto v0.26.1", "hickory-resolver v0.26.1", "hkdf v0.12.4", "hkdf v0.13.0", "hmac v0.12.1", "hmac v0.13.0", "hostname v0.4.2", "html5ever v0.39.0", "http v1.4.1", "http-body v1.0.1", "http-body-util v0.1.5", "httparse v1.10.1", "httpdate v1.0.3", "hybrid-array v0.4.12", "hyper v1.11.1", "hyper-rustls v0.27.9", "hyper-util v0.1.20", "iana-time-zone v0.1.65", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "ident_case v1.0.1", "idna v1.1.0", "idna_adapter v1.2.2", "image v0.25.10", "image-webp v0.2.4", "imgref v1.12.3", "indexmap v2.14.1", "inout v0.1.4", "inout v0.2.2", "ipnet v2.12.0", "is_terminal_polyfill v1.70.2", "itertools v0.12.1", "itertools v0.14.0", "itoa v1.0.18", "jobserver v0.1.34", "jsonwebtoken v11.0.0", "keccak v0.1.6", "keccak v0.2.0", "kem v0.3.0", "lazy_static v1.5.0", "lebe v0.5.3", "lettre v0.11.23", "libc v0.2.189", "libloading v0.8.9", "libm v0.2.16", "libsqlite3-sys v0.37.0", "litemap v0.8.2", "lock_api v0.4.14", "log v0.4.34", "loop9 v0.1.5", "lru v0.18.3", "mach2 v0.6.0", "macro_magic v0.5.1", "macro_magic_core v0.5.1", "macro_magic_core_macros v0.5.1", "macro_magic_macros v0.5.1", "markup5ever v0.39.0", "maybe-rayon v0.1.1", "md-5 v0.10.6", "md-5 v0.11.0", "memchr v2.8.1", "mime v0.3.17", "minimal-lexical v0.2.1", "miniz_oxide v0.8.9", "miniz_oxide v0.9.1", "mio v1.2.1", "ml-kem v0.3.2", "module-lattice v0.2.3", "moka v0.12.15", "mongodb v3.8.2", "mongodb-internal-macros v3.8.2", "moxcms v0.8.1", "nanoid v0.5.0", "new_debug_unreachable v1.0.6", "no_std_io2 v0.9.4", "nom v7.1.3", "nom v8.0.0", "nonzero_ext v0.3.0", "noop_proc_macro v0.3.0", "num-bigint v0.4.6", "num-bigint v0.5.1", "num-bigint-dig v0.8.6", "num-conv v0.2.2", "num-derive v0.4.2", "num-integer v0.1.46", "num-iter v0.1.45", "num-rational v0.4.2", "num-traits v0.2.19", "once_cell v1.21.4", "opaque-debug v0.3.1", "p256 v0.13.2", "p384 v0.13.1", "p521 v0.13.3", "parking v2.2.1", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "password-hash v0.5.0", "paste v1.0.15", "pastey v0.1.1", "pbkdf2 v0.12.2", "pbkdf2 v0.13.0", "pem v3.0.6", "pem-rfc7468 v0.7.0", "pem-rfc7468 v1.0.0", "percent-encoding v2.3.2", "phf v0.11.3", "phf v0.12.1", "phf v0.13.1", "phf_codegen v0.13.1", "phf_generator v0.11.3", "phf_generator v0.13.1", "phf_macros v0.11.3", "phf_macros v0.13.1", "phf_shared v0.11.3", "phf_shared v0.12.1", "phf_shared v0.13.1", "pin-project-lite v0.2.17", "pkcs1 v0.7.5", "pkcs5 v0.7.1", "pkcs8 v0.10.2", "pkcs8 v0.11.0", "pkg-config v0.3.33", "png v0.18.1", "poly1305 v0.8.0", "polyval v0.6.2", "polyval v0.7.3", "portable-atomic v1.13.1", "potential_utf v0.1.5", "powerfmt v0.2.0", "ppv-lite86 v0.2.21", "precomputed-hash v0.1.1", "prefix-trie v0.8.4", "primeorder v0.13.6", "proc-macro2 v1.0.106", "profiling v1.0.18", "profiling-procmacros v1.0.18", "pxfm v0.1.29", "qoi v0.4.1", "quanta v0.12.6", "quick-error v2.0.1", "quote v1.0.45", "quoted_printable v0.5.2", "radium v0.7.0", "rand v0.10.2", "rand v0.8.7", "rand v0.9.4", "rand_chacha v0.3.1", "rand_chacha v0.9.0", "rand_core v0.10.1", "rand_core v0.6.4", "rand_core v0.9.5", "rav1e v0.8.1", "ravif v0.13.0", "rayon v1.12.0", "rayon-core v1.13.0", "redis v1.6.0", "regex v1.13.1", "regex-automata v0.4.18", "regex-syntax v0.8.11", "reqwest v0.12.28", "resolv-conf v0.7.6", "rfc6979 v0.4.0", "rgb v0.8.53", "ring v0.17.14", "rsa v0.9.10", "rusqlite v0.39.0", "rust_decimal v1.43.0", "rustc-demangle v0.1.28", "rustc-hash v2.1.2", "rustc_version v0.4.1", "rustc_version_runtime v0.3.0", "rustls v0.23.43", "rustls-native-certs v0.8.4", "rustls-pemfile v2.2.0", "rustls-pki-types v1.14.1", "rustls-webpki v0.103.13", "rustversion v1.0.22", "ryu v1.0.23", "ryu-js v1.0.3", "salsa20 v0.10.2", "scopeguard v1.2.0", "scraper v0.27.0", "scrypt v0.11.0", "sec1 v0.7.3", "sec1 v0.8.1", "security-framework v3.7.0", "security-framework-sys v2.17.0", "selectors v0.38.0", "semver v1.0.28", "serde v1.0.229", "serde_bytes v0.11.19", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_urlencoded v0.7.1", "serde_with v3.21.0", "serde_with_macros v3.21.0", "servo_arc v0.4.3", "sha1 v0.10.6", "sha1 v0.11.0", "sha1_smol v1.0.1", "sha2 v0.10.9", "sha2 v0.11.0", "sha3 v0.10.9", "sha3 v0.11.0", "sha3 v0.12.0", "sha3-utils v0.5.0", "shake v0.1.0", "shlex v1.3.0", "shlex v2.0.1", "signal-hook-registry v1.4.8", "signature v2.2.0", "signature v3.0.0", "simd-adler32 v0.3.9", "simd_helpers v0.1.0", "simdutf8 v0.1.5", "simple_asn1 v0.6.4", "siphasher v1.0.3", "slab v0.4.12", "slotmap v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "spin v0.9.8", "spinning_top v0.3.0", "spki v0.7.3", "spki v0.8.0", "sponge-cursor v0.1.0", "sqlx v0.9.0", "sqlx-core v0.9.0", "sqlx-mysql v0.9.0", "sqlx-postgres v0.9.0", "stable_deref_trait v1.2.1", "string_cache v0.9.0", "string_cache_codegen v0.6.1", "stringprep v0.1.5", "strsim v0.11.1", "strum v0.27.2", "strum_macros v0.27.2", "subtle v2.6.1", "syn v2.0.117", "syn v3.0.3", "sync_wrapper v1.0.2", "synstructure v0.13.2", "system-configuration v0.7.0", "system-configuration-sys v0.6.0", "taffy v0.13.0", "tagptr v0.2.0", "take_mut v0.2.2", "tap v1.0.1", "tendril v0.5.0", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "tiff v0.11.3", "time v0.3.55", "time-core v0.1.9", "time-macros v0.2.32", "tiny-keccak v2.0.2", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tokio v1.53.1", "tokio-cron-scheduler v0.15.1", "tokio-macros v2.7.0", "tokio-rustls v0.26.4", "tokio-stream v0.1.18", "tokio-tungstenite v0.29.0", "tokio-util v0.7.18", "tower v0.5.3", "tower-http v0.6.11", "tower-layer v0.3.3", "tower-service v0.3.3", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "try-lock v0.2.5", "tungstenite v0.29.0", "typed-builder v0.22.0", "typed-builder-macro v0.22.0", "typenum v1.20.1", "unicode-bidi v0.3.18", "unicode-ident v1.0.24", "unicode-normalization v0.1.25", "unicode-properties v0.1.4", "unicode-segmentation v1.13.3", "unicode-width v0.2.2", "unicode-xid v0.2.6", "universal-hash v0.5.1", "universal-hash v0.6.1", "untrusted v0.9.0", "url v2.5.8", "utf-8 v0.7.6", "utf8_iter v1.0.4", "utf8parse v0.2.2", "uuid v1.26.0", "v_frame v0.3.9", "vcpkg v0.2.15", "version_check v0.9.5", "want v0.3.1", "web-time v1.1.0", "web_atoms v0.2.4", "webpki-roots v0.26.11", "webpki-roots v1.0.9", "weezl v0.1.12", "whoami v2.1.2", "windows-link v0.2.1", "winnow v0.7.15", "writeable v0.6.4", "wyz v0.5.1", "x25519-dalek v2.0.1", "x448 v0.14.0-pre.12", "x509-cert v0.3.0", "xxhash-rust v0.8.18", "y4m v0.8.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerocopy-derive v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zeroize_derive v1.4.3", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21", "zstd v0.13.3", "zstd-safe v7.2.4", "zstd-sys v2.0.16+zstd.1.5.7", "zune-core v0.5.1", "zune-inflate v0.2.54", "zune-jpeg v0.5.15"]}, +{"configuration": "Stdlib minimal", "target": "aarch64-apple-darwin", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-stdlib", "--no-default-features", "-e", "normal,build", "--target", "aarch64-apple-darwin", "--prefix", "none", "--format", "{p}"], "external_package_versions": 137, "packages": ["ahash v0.8.12", "anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "arrayvec v0.7.6", "autocfg v1.5.1", "base64 v0.22.1", "block-buffer v0.10.4", "block-buffer v0.12.0", "cc v1.4.4", "cfg-if v1.0.4", "chacha20 v0.10.0", "chrono v0.4.45", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "colorchoice v1.0.5", "const-oid v0.10.2", "core-foundation-sys v0.8.7", "cpufeatures v0.2.17", "cpufeatures v0.3.0", "critical-section v1.2.0", "crossbeam-utils v0.8.21", "crypto-common v0.1.7", "crypto-common v0.2.2", "curve25519-dalek v4.1.3", "dashmap v6.2.1", "data-encoding v2.11.0", "der v0.8.1", "der_derive v0.8.0", "digest v0.10.7", "digest v0.11.3", "displaydoc v0.2.6", "ed25519 v2.2.3", "ed25519-dalek v2.2.0", "encoding_rs v0.8.35", "find-msvc-tools v0.1.11", "flagset v0.4.7", "form_urlencoded v1.2.2", "generic-array v0.14.7", "getrandom v0.2.17", "getrandom v0.3.4", "getrandom v0.4.2", "gimli v0.34.0", "hashbrown v0.14.5", "heck v0.5.0", "hex v0.4.3", "hickory-proto v0.26.1", "hybrid-array v0.4.12", "iana-time-zone v0.1.65", "icu_collections v2.2.0", "icu_locale_core v2.3.0", "icu_normalizer v2.2.0", "icu_normalizer_data v2.2.0", "icu_properties v2.2.0", "icu_properties_data v2.2.0", "icu_provider v2.3.1", "idna v1.1.0", "idna_adapter v1.2.2", "ipnet v2.12.0", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "lazy_static v1.5.0", "libc v0.2.189", "litemap v0.8.2", "lock_api v0.4.14", "mach2 v0.6.0", "memchr v2.8.1", "num-traits v0.2.19", "once_cell v1.21.4", "parking_lot_core v0.9.12", "percent-encoding v2.3.2", "pin-project-lite v0.2.17", "portable-atomic v1.13.1", "potential_utf v0.1.5", "proc-macro2 v1.0.106", "quote v1.0.45", "rand v0.10.2", "rand_core v0.10.1", "rand_core v0.6.4", "resolv-conf v0.7.6", "rustc-demangle v0.1.28", "rustc_version v0.4.1", "ryu v1.0.23", "ryu-js v1.0.3", "scopeguard v1.2.0", "semver v1.0.28", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "sha2 v0.10.9", "sha2 v0.11.0", "shlex v2.0.1", "signature v2.2.0", "simdutf8 v0.1.5", "slotmap v1.1.1", "smallvec v1.15.1", "socket2 v0.6.5", "spki v0.8.0", "stable_deref_trait v1.2.1", "strsim v0.11.1", "subtle v2.6.1", "syn v2.0.117", "syn v3.0.3", "synstructure v0.13.2", "taffy v0.13.0", "thiserror v1.0.69", "thiserror v2.0.18", "thiserror-impl v1.0.69", "thiserror-impl v2.0.18", "tinystr v0.8.4", "tinyvec v1.11.0", "tinyvec_macros v0.1.1", "tracing v0.1.44", "tracing-core v0.1.36", "typenum v1.20.1", "unicode-ident v1.0.24", "url v2.5.8", "utf8_iter v1.0.4", "utf8parse v0.2.2", "version_check v0.9.5", "writeable v0.6.4", "x509-cert v0.3.0", "yoke v0.8.3", "yoke-derive v0.8.2", "zerocopy v0.8.50", "zerofrom v0.1.8", "zerofrom-derive v0.1.7", "zeroize v1.8.2", "zerotrie v0.2.5", "zerovec v0.11.8", "zerovec-derive v0.11.6", "zmij v1.0.21"]}, +{"configuration": "Compose", "target": "aarch64-apple-darwin", "command": ["cargo", "tree", "--locked", "--offline", "-p", "perry-container-compose", "-e", "normal,build", "--target", "aarch64-apple-darwin", "--prefix", "none", "--format", "{p}"], "external_package_versions": 92, "packages": ["anstream v1.0.0", "anstyle v1.0.14", "anstyle-parse v1.0.0", "anstyle-query v1.1.5", "anyhow v1.0.104", "async-trait v0.1.92", "atty v0.2.14", "bitflags v2.12.1", "block-buffer v0.12.0", "bytes v1.12.1", "cfg-if v1.0.4", "chacha20 v0.10.0", "clap v4.6.6", "clap_builder v4.6.6", "clap_derive v4.6.4", "clap_lex v1.1.0", "colorchoice v1.0.5", "console v0.15.11", "console v0.16.4", "const-oid v0.10.2", "crossbeam-utils v0.8.21", "crypto-common v0.2.2", "dashmap v6.2.1", "dialoguer v0.11.0", "digest v0.11.3", "dotenvy v0.15.7", "equivalent v1.0.2", "errno v0.3.14", "fastrand v2.4.1", "getrandom v0.4.2", "hashbrown v0.14.5", "hashbrown v0.17.1", "heck v0.5.0", "hex v0.4.3", "hybrid-array v0.4.12", "indexmap v2.14.1", "is_terminal_polyfill v1.70.2", "itoa v1.0.18", "lazy_static v1.5.0", "libc v0.2.189", "lock_api v0.4.14", "log v0.4.34", "matchers v0.2.0", "md-5 v0.11.0", "memchr v2.8.1", "mio v1.2.1", "nu-ansi-term v0.50.3", "once_cell v1.21.4", "parking_lot v0.12.5", "parking_lot_core v0.9.12", "pin-project-lite v0.2.17", "proc-macro2 v1.0.106", "quote v1.0.45", "rand v0.10.2", "rand_core v0.10.1", "regex-automata v0.4.18", "regex-syntax v0.8.11", "rustix v1.1.4", "ryu v1.0.23", "scopeguard v1.2.0", "serde v1.0.229", "serde_core v1.0.229", "serde_derive v1.0.229", "serde_json v1.0.151", "serde_yaml v0.9.34+deprecated", "sharded-slab v0.1.7", "shell-words v1.1.1", "signal-hook-registry v1.4.8", "smallvec v1.15.1", "socket2 v0.6.5", "strsim v0.11.1", "syn v2.0.117", "syn v3.0.3", "tempfile v3.27.0", "thiserror v1.0.69", "thiserror-impl v1.0.69", "thread_local v1.1.9", "tokio v1.53.1", "tokio-macros v2.7.0", "tracing v0.1.44", "tracing-attributes v0.1.31", "tracing-core v0.1.36", "tracing-log v0.2.0", "tracing-subscriber v0.3.23", "typenum v1.20.1", "unicode-ident v1.0.24", "unicode-width v0.2.2", "unsafe-libyaml v0.2.11", "utf8parse v0.2.2", "which v8.0.6", "zeroize v1.8.2", "zmij v1.0.21"]} +]} diff --git a/docs/audits/rust-dependency-cleanup-2026-09-14.json b/docs/audits/rust-dependency-cleanup-2026-09-14.json new file mode 100644 index 0000000000..25057e1e3a --- /dev/null +++ b/docs/audits/rust-dependency-cleanup-2026-09-14.json @@ -0,0 +1,297 @@ +{ + "baseline": "4945fc1f7498debc76e9f861d7cf1517da5e67c9", + "semantics": "Combined manifest cleanup. Locked Cargo normal/build trees, no performance measurement.", + "graphs": [ + { + "configuration": "CLI default", + "target": "x86_64-pc-windows-msvc", + "before": 352, + "after": 350, + "removed": [ + "thiserror v1.0.69", + "thiserror-impl v1.0.69" + ], + "added": [], + "command": [ + "cargo", + "tree", + "--locked", + "--offline", + "-p", + "perry", + "-e", + "normal,build", + "--target", + "x86_64-pc-windows-msvc", + "--prefix", + "none", + "--format", + "{p}" + ] + }, + { + "configuration": "CLI dev", + "target": "x86_64-pc-windows-msvc", + "before": 350, + "after": 348, + "removed": [ + "thiserror v1.0.69", + "thiserror-impl v1.0.69" + ], + "added": [], + "command": [ + "cargo", + "tree", + "--locked", + "--offline", + "-p", + "perry", + "--no-default-features", + "--features", + "dev-cli", + "-e", + "normal,build", + "--target", + "x86_64-pc-windows-msvc", + "--prefix", + "none", + "--format", + "{p}" + ] + }, + { + "configuration": "Runtime default", + "target": "x86_64-pc-windows-msvc", + "before": 218, + "after": 218, + "removed": [], + "added": [], + "command": [ + "cargo", + "tree", + "--locked", + "--offline", + "-p", + "perry-runtime", + "-e", + "normal,build", + "--target", + "x86_64-pc-windows-msvc", + "--prefix", + "none", + "--format", + "{p}" + ] + }, + { + "configuration": "Runtime minimal", + "target": "x86_64-pc-windows-msvc", + "before": 108, + "after": 105, + "removed": [ + "anyhow v1.0.104", + "thiserror v1.0.69", + "thiserror-impl v1.0.69" + ], + "added": [], + "command": [ + "cargo", + "tree", + "--locked", + "--offline", + "-p", + "perry-runtime", + "--no-default-features", + "-e", + "normal,build", + "--target", + "x86_64-pc-windows-msvc", + "--prefix", + "none", + "--format", + "{p}" + ] + }, + { + "configuration": "Stdlib default", + "target": "x86_64-pc-windows-msvc", + "before": 556, + "after": 527, + "removed": [ + "anstream v1.0.0", + "anstyle v1.0.14", + "anstyle-parse v1.0.0", + "anstyle-query v1.1.5", + "anstyle-wincon v3.0.11", + "chrono-tz v0.10.4", + "clap v4.6.6", + "clap_builder v4.6.6", + "clap_derive v4.6.4", + "clap_lex v1.1.0", + "colorchoice v1.0.5", + "croner v3.0.1", + "darling v0.20.11", + "darling_core v0.20.11", + "darling_macro v0.20.11", + "derive_builder v0.20.2", + "derive_builder_core v0.20.2", + "derive_builder_macro v0.20.2", + "heck v0.5.0", + "is_terminal_polyfill v1.70.2", + "once_cell_polyfill v1.70.2", + "phf v0.12.1", + "phf_shared v0.12.1", + "strum v0.27.2", + "strum_macros v0.27.2", + "thiserror v1.0.69", + "thiserror-impl v1.0.69", + "tokio-cron-scheduler v0.15.1", + "utf8parse v0.2.2" + ], + "added": [], + "command": [ + "cargo", + "tree", + "--locked", + "--offline", + "-p", + "perry-stdlib", + "-e", + "normal,build", + "--target", + "x86_64-pc-windows-msvc", + "--prefix", + "none", + "--format", + "{p}" + ] + }, + { + "configuration": "Stdlib minimal", + "target": "x86_64-pc-windows-msvc", + "before": 149, + "after": 132, + "removed": [ + "anstream v1.0.0", + "anstyle v1.0.14", + "anstyle-parse v1.0.0", + "anstyle-query v1.1.5", + "anstyle-wincon v3.0.11", + "clap v4.6.6", + "clap_builder v4.6.6", + "clap_derive v4.6.4", + "clap_lex v1.1.0", + "colorchoice v1.0.5", + "heck v0.5.0", + "is_terminal_polyfill v1.70.2", + "once_cell_polyfill v1.70.2", + "strsim v0.11.1", + "thiserror v1.0.69", + "thiserror-impl v1.0.69", + "utf8parse v0.2.2" + ], + "added": [], + "command": [ + "cargo", + "tree", + "--locked", + "--offline", + "-p", + "perry-stdlib", + "--no-default-features", + "-e", + "normal,build", + "--target", + "x86_64-pc-windows-msvc", + "--prefix", + "none", + "--format", + "{p}" + ] + }, + { + "configuration": "Compose", + "target": "x86_64-pc-windows-msvc", + "before": 98, + "after": 91, + "removed": [ + "anyhow v1.0.104", + "atty v0.2.14", + "crossbeam-utils v0.8.21", + "dashmap v6.2.1", + "dotenvy v0.15.7", + "hashbrown v0.14.5", + "winapi v0.3.9" + ], + "added": [], + "command": [ + "cargo", + "tree", + "--locked", + "--offline", + "-p", + "perry-container-compose", + "-e", + "normal,build", + "--target", + "x86_64-pc-windows-msvc", + "--prefix", + "none", + "--format", + "{p}" + ] + } + ], + "removed_declarations": { + "Cargo.toml": [ + "similar = \"2.4\"" + ], + "crates/perry-codegen/Cargo.toml": [ + "thiserror.workspace = true" + ], + "crates/perry-container-compose/Cargo.toml": [ + "anyhow = { workspace = true }", + "dotenvy = { workspace = true }", + "dashmap.workspace = true", + "atty = \"0.2\"" + ], + "crates/perry-ext-fastify/Cargo.toml": [ + "lazy_static.workspace = true" + ], + "crates/perry-hir/Cargo.toml": [ + "thiserror.workspace = true" + ], + "crates/perry-parser/Cargo.toml": [ + "thiserror.workspace = true" + ], + "crates/perry-runtime/Cargo.toml": [ + "thiserror.workspace = true", + "anyhow.workspace = true" + ], + "crates/perry-stdlib/Cargo.toml": [ + "bundled-cron = [\"dep:cron\", \"dep:tokio-cron-scheduler\", \"async-runtime\"]", + "thiserror.workspace = true", + "anyhow.workspace = true", + "itoa.workspace = true", + "ryu.workspace = true", + "tokio-cron-scheduler = { version = \"0.15\", optional = true }", + "clap = { version = \"4.4\", features = [\"derive\"] }" + ], + "crates/perry-transform/Cargo.toml": [ + "thiserror.workspace = true", + "anyhow.workspace = true" + ], + "crates/perry-ui-android/Cargo.toml": [ + "serde_json.workspace = true", + "itoa.workspace = true", + "ryu.workspace = true" + ], + "crates/perry-ui-windows-winui/Cargo.toml": [ + "base64.workspace = true", + "libc.workspace = true" + ], + "crates/perry-updater/Cargo.toml": [ + "serde_json.workspace = true" + ] + } +} diff --git a/docs/audits/rust-dependency-decisions-2026-09-14.json b/docs/audits/rust-dependency-decisions-2026-09-14.json new file mode 100644 index 0000000000..9291bd73d3 --- /dev/null +++ b/docs/audits/rust-dependency-decisions-2026-09-14.json @@ -0,0 +1,197 @@ +{ +"aes": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"aes-gcm": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"aes-kw": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"ahash": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"aho-corasick": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"anyhow": {"decision": "Keep / prune edges", "reason": "Keep real compiler error-context uses; runtime, stdlib, transform and compose edges have no source references."}, +"argon2": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"async-trait": {"decision": "Keep", "reason": "ContainerBackend uses boxed dynamic dispatch; native async trait syntax alone does not preserve that interface."}, +"atty": {"decision": "Remove", "reason": "No compose source references; installer uses console::Term. Future direct terminal checks can use std::io::IsTerminal."}, +"base64": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"bcrypt": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"block2": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"brotli": {"decision": "Keep / gate", "reason": "Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits."}, +"bson": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"bytes": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"cairo-rs": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"cbc": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"cc": {"decision": "Keep / build", "reason": "Build-time native toolchain glue or table generation. These are not runtime library payloads; keep generated artifacts and platform compatibility."}, +"chacha20poly1305": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"chrono": {"decision": "Keep / scope", "reason": "Date adapters, cron and SQL conversions need calendar/local-time semantics; other retainers defeat a blanket rewrite."}, +"clap": {"decision": "Keep CLI / prune stdlib", "reason": "CLI uses derives throughout; stdlib Commander is already handwritten. Removing its unused edge drops 15 packages from minimal Windows stdlib."}, +"console": {"decision": "Keep / align", "reason": "Terminal behavior shared with prompt/progress libraries; align compose dialoguer to eliminate its older console copy."}, +"const-oid": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"cron": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"ctr": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"dashmap": {"decision": "Keep / investigate", "reason": "Handle registries need reentrancy, concurrency, lifetime and GC guarantees. Benchmark any mutex/slab replacement; compose edge appears unused."}, +"der": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"dialoguer": {"decision": "Align / trim", "reason": "Compose 0.11 versus CLI 0.12; alignment drops four packages net in compose. Check editor/password features separately."}, +"dirs": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"dotenvy": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"dssim-core": {"decision": "Keep / tests", "reason": "Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling."}, +"ecb": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"ed25519-dalek": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"ed448-goldilocks": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"encoding_rs": {"decision": "Keep / build", "reason": "Build-time native toolchain glue or table generation. These are not runtime library payloads; keep generated artifacts and platform compatibility."}, +"env_logger": {"decision": "Possible / low priority", "reason": "Only main::init directly uses it. Small log::Log sink is feasible but must preserve RUST_LOG filtering and concurrent output; four exclusive lock packages."}, +"fast_image_resize": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"flate2": {"decision": "Keep / gate", "reason": "Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits."}, +"fslock": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"futures-util": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"ghash": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"gimli": {"decision": "Keep", "reason": "Already read-only with defaults disabled; unwind CFI decoding is correctness-critical."}, +"governor": {"decision": "Candidate / trim first", "reason": "Keyed limiter is already owned; legacy direct limiter still uses GCRA. std-only features drop ten packages from the extension before any rewrite."}, +"gstreamer": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"gstreamer-app": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"gtk4": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"h2": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"hex": {"decision": "Possible / very low priority", "reason": "Shared hex helper is small, but crate remains transitive. Preserve uppercase, validation and allocation behavior; defer behind graph wins."}, +"hickory-proto": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"hkdf": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"hmac": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"hostname": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"http-body-util": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"httpdate": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"hyper": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"hyper-util": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"icu_calendar": {"decision": "Keep / feature edge", "reason": "intl-datetime uses this direct edge to activate compiled calendar data; re-exported types hide lexical references. Review feature propagation before removal."}, +"icu_datetime": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"icu_decimal": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"icu_locale": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"icu_locale_core": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"icu_provider": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"icu_time": {"decision": "Keep / feature edge", "reason": "intl-datetime activates compiled time data through this edge; lexical absence does not prove redundancy."}, +"idna": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"image": {"decision": "Keep / trim formats", "reason": "Default decoder set is broad; review supported inputs before trimming. AVIF output and SIMD resize are real uses."}, +"indexmap": {"decision": "Keep", "reason": "Ordered Compose maps and serde behavior matter; HashMap or linear vector replacements change semantics or scale."}, +"indicatif": {"decision": "Keep / command gate", "reason": "Progress for downloads, publish and remote execution; terminal redraw has modest ownership value."}, +"inkwell": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"itoa": {"decision": "Keep / prune edges", "reason": "Allocation-free runtime formatting; stdlib and Android UI declarations have no lexical uses."}, +"jni": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"jsonwebtoken": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"kamadak-exif": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"ksni": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"lazy_static": {"decision": "Replace with std", "reason": "Migrate owned globals to LazyLock/OnceLock while preserving initialization and poisoning behavior; transitive users retain the crate."}, +"lettre": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"libc": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"libmimalloc-sys": {"decision": "Keep / gate", "reason": "Extended API drives GC allocator maintenance and Apple VM tags; use the existing alloc-mimalloc feature."}, +"libshumate": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"llvm-sys": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"log": {"decision": "Keep", "reason": "Shared logging facade; replacing it fragments logging and saves little."}, +"lru": {"decision": "Possible / low priority", "reason": "One exclusive package. An indexed recency store must preserve O(1) lookup, TTL, eviction and mutable GC roots; justify with workload measurements."}, +"mach2": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"md-5": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"mimalloc": {"decision": "Keep / existing A/B", "reason": "System allocation already selectable; measure that mode. A general allocator rewrite is a separate major project."}, +"ml-kem": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"mongodb": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"mpris-server": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"nanoid": {"decision": "Candidate / small", "reason": "Default/sized generation use nanoid; custom alphabet already uses rand 0.10. Share a small helper with a maintained cryptographic RNG and unbiased selection."}, +"node-semver": {"decision": "Keep", "reason": "Bun needs npm range grammar; Rust semver is not behavior-equivalent. Already gated with bun-cli-utils."}, +"notify": {"decision": "Keep / gate", "reason": "Native file events replaced polling. Preserve native event semantics and platform gating."}, +"objc2": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"objc2-app-kit": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"objc2-core-foundation": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"objc2-foundation": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"objc2-ui-kit": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"object": {"decision": "Keep", "reason": "Read-only ELF/Mach-O/PE reader for size reporting, already feature-trimmed; multi-format hand parsing is poor value."}, +"once_cell": {"decision": "Replace with std", "reason": "Owned uses are sync::Lazy; use LazyLock while preserving shared state and scanner semantics. Upstream users still retain once_cell."}, +"p12": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"p256": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"p384": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"p521": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"pbkdf2": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"pem": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"perex": {"decision": "Already owned", "reason": "Registry metadata points to github.com/PerryTS/perex. Preserve Perry's single regex engine and independent test oracle."}, +"pkcs5": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"png": {"decision": "Keep / gate", "reason": "Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits."}, +"printpdf": {"decision": "Candidate / focused spike", "reason": "Five-operation writer with built-in Helvetica/text/lines/pages; HTML already disabled. Potentially remove 22 exclusive lock packages with a bounded writer."}, +"proptest": {"decision": "Keep / tests", "reason": "Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling."}, +"qrcodegen": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"rand": {"decision": "Keep / align", "reason": "Reuse maintained RNGs; transitive API generations differ. NanoID removal alone cannot remove rand 0.9 from MongoDB/WebSocket/image/PDF graphs."}, +"rand_core": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"rayon": {"decision": "Keep", "reason": "Compiler parallel work benefits from work stealing; custom pool requires scaling and panic-propagation evidence. Other retainers remain."}, +"redis": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"regex": {"decision": "Keep / tests", "reason": "Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling."}, +"reqwest": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"resolv-conf": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"rgb": {"decision": "Keep / tests", "reason": "Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling."}, +"ring": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"rsa": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"rusqlite": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"rust_decimal": {"decision": "Keep / gate", "reason": "Decimal arithmetic and rounding are the adapter contract; replacing them adds substantial correctness work."}, +"rustc-demangle": {"decision": "Keep", "reason": "Small shared implementation of Rust symbol grammar used by stacks and size reports."}, +"rustls": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"rustls-native-certs": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"rustls-pemfile": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"rustls-webpki": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"ryu": {"decision": "Keep / prune edges", "reason": "Retain generic formatting where used; stdlib/Android declarations appear unused. Do not confuse with ECMAScript ryu-js spelling."}, +"ryu-js": {"decision": "Keep", "reason": "ECMAScript shortest-number spelling is a JSON compatibility and hot-path requirement."}, +"scraper": {"decision": "Keep / gate", "reason": "Cheerio requires real HTML and selectors, including malformed-document behavior; preserve the parser and adapter gate."}, +"scrypt": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"semver": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"serde": {"decision": "Keep / scope", "reason": "Typed Rust configuration and interchange across many crates; trim features rather than own a serialization framework."}, +"serde_json": {"decision": "Keep / prune edges", "reason": "JS hot-path JSON is already owned. Keep Rust config/interchange parsing; updater and Android declarations appear unused."}, +"serde_yaml": {"decision": "Migrate upstream", "reason": "Locked 0.9.34+deprecated; evaluate a maintained compatible successor with a Compose regression corpus. Do not own a YAML parser."}, +"sha1": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"sha2": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"sha3": {"decision": "Keep used versions / prune edge", "reason": "Stdlib sha3 0.12 alias has no lexical use; SHAKE uses shake, KMAC uses sha3_010. Audit only the unused version edge."}, +"sha3-utils": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"shake": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"simdutf8": {"decision": "Keep", "reason": "Single hot-path UTF-8 validation use; std::str::from_utf8 is an A/B alternative, not an assumed speed improvement."}, +"socket2": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"spki": {"decision": "Keep / prune stdlib edge", "reason": "node-forge imports it; stdlib has no lexical references. Check PEM/alloc feature propagation before removing that edge."}, +"sqlx": {"decision": "Keep / split features", "reason": "Bundled stdlib enables mysql and postgres together; activate backends from individual features as extensions already do."}, +"stacker": {"decision": "Keep", "reason": "Protects three lowering recursion boundaries and SWC. Remove only with bounded/iterative traversal evidence."}, +"swc_bundler": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"swc_common": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"swc_ecma_ast": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"swc_ecma_codegen": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"swc_ecma_loader": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"swc_ecma_parser": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"swc_ecma_transforms_base": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"swc_ecma_transforms_react": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"swc_ecma_transforms_typescript": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"swc_ecma_visit": {"decision": "Keep / align", "reason": "Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine."}, +"taffy": {"decision": "Keep / gate TUI", "reason": "Already trimmed to flexbox but always a runtime dependency; gate the TUI surface before considering layout-engine ownership."}, +"tar": {"decision": "Keep / gate", "reason": "Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits."}, +"tempfile": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"temporal_rs": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"thiserror": {"decision": "Keep / prune edges", "reason": "Compose uses typed errors; compiler/runtime/stdlib/transform declarations have no lexical uses. Remove stale edges, preserve useful derives."}, +"time": {"decision": "Keep / align", "reason": "Node-forge and upstream formats need date/time handling; no convincing rewrite saving."}, +"timezone_provider": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"tiny_http": {"decision": "Keep / tooling", "reason": "Synchronous chaos/test-control server; owning HTTP parsing offers little payoff on this tooling path."}, +"tokio": {"decision": "Deferred", "reason": "Separate session owns the removal verdict. This audit records dependent adapters and existing feature boundaries."}, +"tokio-cron-scheduler": {"decision": "Remove", "reason": "Zero source references; own cron queues already use cron::Schedule. Deleting the edge removes 13 packages from full Windows stdlib."}, +"tokio-rustls": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"tokio-tungstenite": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"toml": {"decision": "Keep", "reason": "CLI config and gated Bun API require full TOML syntax and diagnostics."}, +"tracing": {"decision": "Keep", "reason": "Shared Compose/upstream instrumentation facade; little marginal value in a custom replacement."}, +"tracing-subscriber": {"decision": "Keep / gate CLI", "reason": "Only compose main installs it; gate with executable functionality when slimming its library."}, +"tungstenite": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"unicode-normalization": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"unicode-segmentation": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"unsafe-libyaml": {"decision": "Keep backend / scope", "reason": "Bun YAML and serde_yaml parser backend; review alongside YAML migration, not a parser rewrite."}, +"url": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"uuid": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"validator": {"decision": "Keep / tests", "reason": "Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling."}, +"walkdir": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"wasm-encoder": {"decision": "Keep / align", "reason": "Binary emission correctness for Wasm; align compatible versions with tooling."}, +"wasmi": {"decision": "Keep / isolate", "reason": "Wasm host already isolated with defaults disabled and required SIMD enabled; interpreter rewrite is a major engine project."}, +"webkit6": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"webpki-roots": {"decision": "Keep / scope", "reason": "Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study."}, +"webview2-com": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"which": {"decision": "Keep", "reason": "Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates."}, +"windows": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"windows-core": {"decision": "Keep / macro dependency", "reason": "COM implement macros emit absolute ::windows_core paths. No lexical reference is a known false positive; keep version alignment."}, +"windows-reactor": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"windows-sys": {"decision": "Keep / platform", "reason": "Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit."}, +"winresource": {"decision": "Keep / build", "reason": "Build-time native toolchain glue or table generation. These are not runtime library payloads; keep generated artifacts and platform compatibility."}, +"writeable": {"decision": "Keep / gate", "reason": "Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility."}, +"x25519-dalek": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"x448": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"x509-cert": {"decision": "Keep", "reason": "Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats."}, +"xxhash-rust": {"decision": "Keep / gate", "reason": "Bun exposes exact xxHash64 output; DefaultHasher changes the contract. Already feature gated."}, +"zip": {"decision": "Keep / trim first", "reason": "Updates/IPA reading and deflated HAP writing; Deflate-only graph drops 17 packages. Validate accepted archive methods before narrowing."}, +"zstd": {"decision": "Keep / gate", "reason": "Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits."} +} diff --git a/docs/audits/rust-dependency-decisions-2026-09-14.md b/docs/audits/rust-dependency-decisions-2026-09-14.md new file mode 100644 index 0000000000..5413b3773d --- /dev/null +++ b/docs/audits/rust-dependency-decisions-2026-09-14.md @@ -0,0 +1,209 @@ +# Rust dependency decisions ? 2026-09-14 + +Baseline `4945fc1f7498debc76e9f861d7cf1517da5e67c9`. All 195 direct external package names are assessed below. Version lists include versions of that name pulled only transitively. Perex is Perry-owned despite being a registry dependency. + +Read [the findings and priorities](../rust-dependency-audit.md) first. Exact manifests, aliases, feature/target predicates, source references, reverse edges and all 1,003 external lock package identities are in [the census](rust-dependencies-2026-09-14.json). [Decision data](rust-dependency-decisions-2026-09-14.json) mirrors this table. + +Owners omit `perry-`. `?` = optional; `@` = target-specific; `(build)` / `(dev)` = dependency kind. Each row links an example source reference or its manifest. Lexical references are review aids, not proof of active/unused code. + +| Library (locked versions) | Direct owners | Recommendation and rationale | Evidence | +|---|---|---|---| +| `aes` (0.8.4, 0.9.1) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/cipher.rs#L70) | +| `aes-gcm` (0.10.3) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/cipher.rs#L70) | +| `aes-kw` (0.3.1) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/cipher.rs#L916) | +| `ahash` (0.8.12) | runtime | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/json/parser.rs#L40) | +| `aho-corasick` (1.1.4) | codegen | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-codegen/src/codegen/retained_source_pool.rs#L5) | +| `anyhow` (1.0.104) | codegen-arkts, codegen-glance, codegen-js, codegen-swiftui, codegen-wasm, codegen-wear-tiles, codegen, container-compose, container-e2e (dev), doc-tests, ext-typescript, hir, parser, runtime, stdlib, transform, updater, perry | **Keep / prune edges** ? Keep real compiler error-context uses; runtime, stdlib, transform and compose edges have no source references. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-codegen-arkts/src/lib.rs#L49) | +| `argon2` (0.5.3) | ext-argon2, stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-argon2/src/lib.rs#L6) | +| `async-trait` (0.1.92) | container-compose | **Keep** ? ContainerBackend uses boxed dynamic dispatch; native async trait syntax alone does not preserve that interface. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/backend/cli_backend.rs#L7) | +| `atty` (0.2.14) | container-compose | **Remove** ? No compose source references; installer uses console::Term. Future direct terminal checks can use std::io::IsTerminal. | [manifest](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/Cargo.toml) | +| `base64` (0.22.1, 0.23.1) | codegen-wasm, ext-http, ext-jsonwebtoken, runtime, stdlib?, ui-android@, ui-gtk4@, ui-ios@, ui-macos@, ui-tvos@, ui-visionos@, ui-windows-winui@, ui-windows@, updater, perry | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-codegen-wasm/src/lib.rs#L12) | +| `bcrypt` (0.19.3) | ext-bcrypt, stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-bcrypt/src/lib.rs#L38) | +| `block2` (0.6.2) | ext-ads?@, ui-ios@, ui-macos@, ui-tvos@, ui-visionos@, ui-watchos@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-ads/src/ios_real.rs#L38) | +| `brotli` (8.0.4) | ext-zlib, stdlib? | **Keep / gate** ? Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-zlib/src/stream.rs#L110) | +| `bson` (3.1.0) | ext-mongodb, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-mongodb/src/lib.rs#L36) | +| `bytes` (1.12.1) | ext-fastify, ext-fetch, ext-http, ext-net, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-fastify/src/context.rs#L667) | +| `cairo-rs` (0.20.12, 0.22.9) | ui-gtk4@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-gtk4/src/widgets/canvas.rs#L207) | +| `cbc` (0.1.2, 0.2.1) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/util.rs#L7) | +| `cc` (1.4.4) | audio-miniaudio (build), runtime (build) | **Keep / build** ? Build-time native toolchain glue or table generation. These are not runtime library payloads; keep generated artifacts and platform compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-audio-miniaudio/build.rs#L18) | +| `chacha20poly1305` (0.10.1) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/webcrypto/aes.rs#L155) | +| `chrono` (0.4.45) | ext-cron, ext-dayjs, ext-moment, ext-mysql2, stdlib, perry | **Keep / scope** ? Date adapters, cron and SQL conversions need calendar/local-time semantics; other retainers defeat a blanket rewrite. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-cron/src/lib.rs#L22) | +| `clap` (4.6.6) | container-compose, doc-tests, stdlib, perry | **Keep CLI / prune stdlib** ? CLI uses derives throughout; stdlib Commander is already handwritten. Removing its unused edge drops 15 packages from minimal Windows stdlib. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/cli.rs#L5) | +| `console` (0.15.11, 0.16.4) | container-compose, perry | **Keep / align** ? Terminal behavior shared with prompt/progress libraries; align compose dialoguer to eliminate its older console copy. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/installer.rs#L5) | +| `const-oid` (0.10.2, 0.9.6) | ext-node-forge | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-node-forge/src/crypto.rs#L19) | +| `cron` (0.17.0) | ext-cron, stdlib? | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-cron/src/lib.rs#L23) | +| `ctr` (0.9.2) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/cipher.rs#L96) | +| `dashmap` (5.5.3, 6.2.1) | container-compose, ffi, stdlib | **Keep / investigate** ? Handle registries need reentrancy, concurrency, lifetime and GC guarantees. Benchmark any mutex/slab replacement; compose edge appears unused. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ffi/src/handle.rs#L75) | +| `der` (0.7.10, 0.8.1) | ext-node-forge | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-node-forge/src/crypto.rs#L20) | +| `dialoguer` (0.11.0, 0.12.0) | container-compose, perry | **Align / trim** ? Compose 0.11 versus CLI 0.12; alignment drops four packages net in compose. Check editor/password features separately. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/installer.rs#L6) | +| `dirs` (6.0.0) | runtime?, ui-gtk4@, ui@, perry | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/os.rs#L169) | +| `dotenvy` (0.15.7) | container-compose, perry | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry/src/commands/publish/mod.rs#L90) | +| `dssim-core` (3.5.1) | doc-tests | **Keep / tests** ? Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-doc-tests/src/image_diff.rs#L61) | +| `ecb` (0.1.2, 0.2.1) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/cipher.rs#L64) | +| `ed25519-dalek` (2.2.0) | stdlib?, updater, perry? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/hash.rs#L51) | +| `ed448-goldilocks` (0.14.0-pre.15) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/webcrypto/hmac.rs#L156) | +| `encoding_rs` (0.8.35) | runtime (build) | **Keep / build** ? Build-time native toolchain glue or table generation. These are not runtime library payloads; keep generated artifacts and platform compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/build.rs#L494) | +| `env_logger` (0.10.2) | perry | **Possible / low priority** ? Only main::init directly uses it. Small log::Log sink is feasible but must preserve RUST_LOG filtering and concurrent output; four exclusive lock packages. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry/src/main.rs#L378) | +| `fast_image_resize` (6.1.0) | ext-sharp | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-sharp/src/lib.rs#L334) | +| `flate2` (1.1.10) | ext-zlib, stdlib?, perry | **Keep / gate** ? Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-zlib/src/lib.rs#L9) | +| `fslock` (0.2.1) | perry | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry/src/commands/compile/optimized_libs/driver.rs#L774) | +| `futures-util` (0.3.34) | ext-mongodb, ext-ws, stdlib?, perry | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-mongodb/src/lib.rs#L37) | +| `ghash` (0.5.1, 0.6.0) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/cipher.rs#L116) | +| `gimli` (0.34.0) | runtime | **Keep** ? Already read-only with defaults disabled; unwind CFI decoding is correctness-critical. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/eh_walker.rs#L32) | +| `governor` (0.10.4) | ext-ratelimit, stdlib? | **Candidate / trim first** ? Keyed limiter is already owned; legacy direct limiter still uses GCRA. std-only features drop ten packages from the extension before any rewrite. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-ratelimit/src/lib.rs#L20) | +| `gstreamer` (0.25.3) | ui-gtk4@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-gtk4/src/camera.rs#L25) | +| `gstreamer-app` (0.25.2) | ui-gtk4@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-gtk4/src/camera.rs#L1) | +| `gtk4` (0.9.7) | ui-gtk4@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-gtk4/src/app.rs#L1) | +| `h2` (0.4.19) | ext-http | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/server/http2_server/session.rs#L322) | +| `hex` (0.4.3) | container-compose, runtime?, stdlib?, updater, perry | **Possible / very low priority** ? Shared hex helper is small, but crate remains transitive. Preserve uppercase, validation and allocation behavior; defer behind graph wins. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/compose.rs#L24) | +| `hickory-proto` (0.26.1) | runtime | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/dns_resolver.rs#L17) | +| `hkdf` (0.12.4, 0.13.0) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/kdf.rs#L1107) | +| `hmac` (0.12.1, 0.13.0) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/hash_handles.rs#L156) | +| `hostname` (0.4.2) | runtime? | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/dns/ffi.rs#L15) | +| `http-body-util` (0.1.5) | ext-fastify, ext-http, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-fastify/src/server.rs#L18) | +| `httpdate` (1.0.3) | ext-http | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/server/response.rs#L591) | +| `hyper` (1.11.1) | ext-fastify, ext-http, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-fastify/src/server.rs#L19) | +| `hyper-util` (0.1.20) | ext-fastify, ext-http, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-fastify/src/server.rs#L22) | +| `icu_calendar` (2.3.0) | runtime? | **Keep / feature edge** ? intl-datetime uses this direct edge to activate compiled calendar data; re-exported types hide lexical references. Review feature propagation before removal. | [manifest](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/Cargo.toml) | +| `icu_datetime` (2.3.0) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/intl/icu_dtf.rs#L10) | +| `icu_decimal` (2.3.0) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/intl/number_format.rs#L513) | +| `icu_locale` (2.2.0) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/intl/locale/likely_subtags.rs#L14) | +| `icu_locale_core` (2.3.0) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/intl/icu_dtf.rs#L17) | +| `icu_provider` (2.3.1) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/intl/number_format.rs#L514) | +| `icu_time` (2.3.0) | runtime? | **Keep / feature edge** ? intl-datetime activates compiled time data through this edge; lexical absence does not prove redundancy. | [manifest](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/Cargo.toml) | +| `idna` (1.1.0) | runtime?, validation | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/tls.rs#L1235) | +| `image` (0.25.10) | doc-tests, ext-sharp, stdlib? | **Keep / trim formats** ? Default decoder set is broad; review supported inputs before trimming. AVIF output and SIMD resize are real uses. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-doc-tests/src/image_diff.rs#L43) | +| `indexmap` (2.14.1) | container-compose | **Keep** ? Ordered Compose maps and serde behavior matter; HashMap or linear vector replacements change semantics or scale. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/compose.rs#L7) | +| `indicatif` (0.18.6) | perry | **Keep / command gate** ? Progress for downloads, publish and remote execution; terminal redraw has modest ownership value. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry/src/commands/publish/mod.rs#L9) | +| `inkwell` (0.9.0) | codegen?@ | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-codegen/src/dialect/eh.rs#L9) | +| `itoa` (1.0.18) | runtime, stdlib, ui-android@ | **Keep / prune edges** ? Allocation-free runtime formatting; stdlib and Android UI declarations have no lexical uses. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/array/join.rs#L498) | +| `jni` (0.22.4) | ui-android@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-android/src/app.rs#L1) | +| `jsonwebtoken` (11.0.0) | ext-jsonwebtoken, stdlib?, perry | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-jsonwebtoken/src/lib.rs#L8) | +| `kamadak-exif` (0.6.1) | ext-sharp | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-sharp/src/lib.rs#L129) | +| `ksni` (0.3.6) | ui-gtk4@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-gtk4/src/tray.rs#L49) | +| `lazy_static` (1.5.0) | ext-fastify, ext-fetch, ext-http, ext-ioredis, ext-streams, ext-ws, runtime, stdlib | **Replace with std** ? Migrate owned globals to LazyLock/OnceLock while preserving initialization and poisoning behavior; transitive users retain the crate. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-fetch/src/lib.rs#L12) | +| `lettre` (0.11.23) | ext-nodemailer, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-nodemailer/src/lib.rs#L13) | +| `libc` (0.2.189) | audio-miniaudio@, runtime, stdlib@, ui-android@, ui-gtk4@, ui-ios@, ui-macos@, ui-tvos@, ui-visionos@, ui-watchos@, ui-windows-winui@, ui-windows@, perry | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-audio-miniaudio/src/lib.rs#L20) | +| `libmimalloc-sys` (0.1.49) | runtime?@ | **Keep / gate** ? Extended API drives GC allocator maintenance and Apple VM tags; use the existing alloc-mimalloc feature. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/gc/census.rs#L650) | +| `libshumate` (0.6.0) | ui-gtk4@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-gtk4/src/widgets/map_view.rs#L18) | +| `llvm-sys` (221.0.1) | codegen?@ | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-codegen/src/dialect/eh.rs#L181) | +| `log` (0.4.34) | codegen, perry | **Keep** ? Shared logging facade; replacing it fragments logging and saves little. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-codegen/src/codegen/mod.rs#L3730) | +| `lru` (0.18.3) | ext-lru-cache, stdlib? | **Possible / low priority** ? One exclusive package. An indexed recency store must preserve O(1) lookup, TTL, eviction and mutable GC roots; justify with workload measurements. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-lru-cache/src/lib.rs#L84) | +| `mach2` (0.6.0) | runtime@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/gc/roots/stack_maps_sections.rs#L25) | +| `md-5` (0.10.6, 0.11.0) | container-compose, stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/compose.rs#L8) | +| `mimalloc` (0.1.52) | runtime?@ | **Keep / existing A/B** ? System allocation already selectable; measure that mode. A general allocator rewrite is a separate major project. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/lib.rs#L34) | +| `ml-kem` (0.3.2) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/webcrypto/encapsulation.rs#L2) | +| `mongodb` (3.8.2) | ext-mongodb, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-mongodb/src/lib.rs#L38) | +| `mpris-server` (0.10.0) | ui-gtk4@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-gtk4/src/media_playback.rs#L561) | +| `nanoid` (0.5.0) | ext-nanoid, stdlib? | **Candidate / small** ? Default/sized generation use nanoid; custom alphabet already uses rand 0.10. Share a small helper with a maintained cryptographic RNG and unbiased selection. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-nanoid/src/lib.rs#L8) | +| `node-semver` (2.2.0) | runtime? | **Keep** ? Bun needs npm range grammar; Rust semver is not behavior-equivalent. Already gated with bun-cli-utils. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/bun_compat/cli_utils.rs#L195) | +| `notify` (6.1.1) | ext-parcel-watcher, runtime@, perry? | **Keep / gate** ? Native file events replaced polling. Preserve native event semantics and platform gating. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-parcel-watcher/src/lib.rs#L8) | +| `objc2` (0.6.4) | ext-ads?@, ui-ios@, ui-macos@, ui-tvos@, ui-visionos@, ui-watchos@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-ads/src/ios_real.rs#L39) | +| `objc2-app-kit` (0.3.2) | ui-macos@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-macos/src/app.rs#L6) | +| `objc2-core-foundation` (0.3.2) | ui-ios@, ui-macos@, ui-tvos@, ui-visionos@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-ios/src/adaptive_layout.rs#L10) | +| `objc2-foundation` (0.3.2) | ext-ads?@, ui-ios@, ui-macos@, ui-tvos@, ui-visionos@, ui-watchos@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-ads/src/ios_real.rs#L42) | +| `objc2-ui-kit` (0.3.2) | ui-ios@, ui-tvos@, ui-visionos@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-ios/src/adaptive_layout.rs#L11) | +| `object` (0.37.3) | perry | **Keep** ? Read-only ELF/Mach-O/PE reader for size reporting, already feature-trimmed; multi-format hand parsing is poor value. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry/src/commands/compile/collect_modules/crypto_ns.rs#L14) | +| `once_cell` (1.21.4) | container-compose, ffi, stdlib | **Replace with std** ? Owned uses are sync::Lazy; use LazyLock while preserving shared state and scanner semantics. Upstream users still retain once_cell. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/compose.rs#L27) | +| `p12` (0.6.3) | ext-http | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/tls_client.rs#L901) | +| `p256` (0.13.2) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/kdf.rs#L1182) | +| `p384` (0.13.1) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/webcrypto/util.rs#L28) | +| `p521` (0.13.3) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/webcrypto/util.rs#L34) | +| `pbkdf2` (0.12.2, 0.13.0) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/kdf.rs#L20) | +| `pem` (3.0.6, 4.0.0) | ext-node-forge | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-node-forge/src/crypto.rs#L476) | +| `perex` (0.1.4) | perex, runtime? | **Already owned** ? Registry metadata points to github.com/PerryTS/perex. Preserve Perry's single regex engine and independent test oracle. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-perex/src/lib.rs#L14) | +| `pkcs5` (0.7.1) | ext-http | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/tls_client.rs#L918) | +| `png` (0.18.1) | ui-windows@ | **Keep / gate** ? Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-windows/src/screenshot.rs#L137) | +| `printpdf` (0.10.1) | ext-pdf | **Candidate / focused spike** ? Five-operation writer with built-in Helvetica/text/lines/pages; HTML already disabled. Potentially remove 22 exclusive lock packages with a bounded writer. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-pdf/src/lib.rs#L46) | +| `proptest` (1.11.0) | container-compose (dev), stdlib (dev) | **Keep / tests** ? Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/yaml.rs#L505) | +| `qrcodegen` (1.8.0) | ui-windows@ | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-windows/src/widgets/qrcode.rs#L62) | +| `rand` (0.10.2, 0.8.7, 0.9.4) | container-compose, ext-ethers, ext-nanoid, ext-node-forge, runtime, stdlib, ui-geisterhand, perry? | **Keep / align** ? Reuse maintained RNGs; transitive API generations differ. NanoID removal alone cannot remove rand 0.9 from MongoDB/WebSocket/image/PDF graphs. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/service.rs#L8) | +| `rand_core` (0.10.1, 0.6.4, 0.9.5) | ext-argon2, stdlib | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-argon2/src/lib.rs#L13) | +| `rayon` (1.12.0) | perry | **Keep** ? Compiler parallel work benefits from work stealing; custom pool requires scaling and panic-propagation evidence. Other retainers remain. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry/src/commands/compile/bootstrap.rs#L1016) | +| `redis` (1.6.0) | ext-ioredis, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-ioredis/src/lib.rs#L17) | +| `regex` (1.13.1) | perex (dev), validation (dev) | **Keep / tests** ? Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-perex/tests/dialect_parity.rs#L177) | +| `reqwest` (0.12.28) | ext-axios, ext-fetch, ext-http, stdlib?, perry | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-axios/src/lib.rs#L81) | +| `resolv-conf` (0.7.6) | runtime | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/dns_resolver.rs#L167) | +| `rgb` (0.8.53) | doc-tests | **Keep / tests** ? Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-doc-tests/src/image_diff.rs#L128) | +| `ring` (0.17.14) | ext-http | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/server/tls.rs#L10) | +| `rsa` (0.10.0-rc.18, 0.9.10) | ext-node-forge, stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-node-forge/src/crypto.rs#L23) | +| `rusqlite` (0.39.0) | ext-better-sqlite3, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-better-sqlite3/src/lib.rs#L21) | +| `rust_decimal` (1.43.0) | ext-decimal, stdlib? | **Keep / gate** ? Decimal arithmetic and rounding are the adapter contract; replacing them adds substantial correctness work. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-decimal/src/lib.rs#L8) | +| `rustc-demangle` (0.1.28) | runtime, perry | **Keep** ? Small shared implementation of Rust symbol grammar used by stacks and size reports. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/error_stack_frames.rs#L459) | +| `rustls` (0.23.43) | ext-http, ext-net, ext-ws, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/server/http2_server.rs#L176) | +| `rustls-native-certs` (0.8.4) | ext-net, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-net/src/tls.rs#L386) | +| `rustls-pemfile` (2.2.0) | ext-http, ext-net, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/server/tls.rs#L259) | +| `rustls-webpki` (0.103.13) | ext-http | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/tls_client.rs#L277) | +| `ryu` (1.0.23) | runtime, stdlib, ui-android@ | **Keep / prune edges** ? Retain generic formatting where used; stdlib/Android declarations appear unused. Do not confuse with ECMAScript ryu-js spelling. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/bun_compat/cli_utils.rs#L1045) | +| `ryu-js` (1.0.3) | runtime | **Keep** ? ECMAScript shortest-number spelling is a JSON compatibility and hot-path requirement. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/json/stringify_api.rs#L365) | +| `scraper` (0.27.0) | ext-cheerio, stdlib? | **Keep / gate** ? Cheerio requires real HTML and selectors, including malformed-document behavior; preserve the parser and adapter gate. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-cheerio/src/lib.rs#L9) | +| `scrypt` (0.11.0) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/kdf.rs#L826) | +| `semver` (1.0.28) | updater, perry | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-updater/src/cli_manifest.rs#L6) | +| `serde` (1.0.229) | api-manifest?, codegen, container-compose, diagnostics, doc-tests, ext-jsonwebtoken, ext-node-forge, ext-parcel-watcher, ext-typescript, hir, runtime, stdlib, ui-geisterhand, updater, perry | **Keep / scope** ? Typed Rust configuration and interchange across many crates; trim features rather than own a serialization framework. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-api-manifest/src/lib.rs#L36) | +| `serde_json` (1.0.151) | codegen, container-compose, diagnostics, diagnostics (dev), doc-tests, ext-dotenv, ext-fastify, ext-fetch, ext-http, ext-jsonwebtoken, ext-mongodb, ext-mysql2, ext-net, ext-node-forge, ext-parcel-watcher, ext-qs, ext-typescript, ext-undici, ext-validator, hir, runtime, stdlib, ui-android@, ui-geisterhand, updater, perry | **Keep / prune edges** ? JS hot-path JSON is already owned. Keep Rust config/interchange parsing; updater and Android declarations appear unused. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-codegen/src/native_value/artifact.rs#L620) | +| `serde_yaml` (0.9.34+deprecated) | container-compose, stdlib (dev) | **Migrate upstream** ? Locked 0.9.34+deprecated; evaluate a maintained compatible successor with a Compose regression corpus. Do not own a YAML parser. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/cli.rs#L195) | +| `sha1` (0.10.6, 0.11.0) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/sign.rs#L225) | +| `sha2` (0.10.9, 0.11.0) | ext-node-forge, runtime?, runtime (build), stdlib?, updater, perry | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-node-forge/src/crypto.rs#L27) | +| `sha3` (0.10.9, 0.11.0, 0.12.0) | stdlib? | **Keep used versions / prune edge** ? Stdlib sha3 0.12 alias has no lexical use; SHAKE uses shake, KMAC uses sha3_010. Audit only the unused version edge. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/webcrypto/util.rs#L1021) | +| `sha3-utils` (0.5.0) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/webcrypto/util.rs#L1027) | +| `shake` (0.1.0) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/hash_handles.rs#L121) | +| `simdutf8` (0.1.5) | runtime | **Keep** ? Single hot-path UTF-8 validation use; std::str::from_utf8 is an A/B alternative, not an assumed speed improvement. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/string/utf16_count.rs#L22) | +| `socket2` (0.6.5) | ext-fastify@, ext-http@, runtime | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-fastify/src/cluster_bind.rs#L29) | +| `spki` (0.7.3, 0.8.0) | ext-node-forge, stdlib? | **Keep / prune stdlib edge** ? node-forge imports it; stdlib has no lexical references. Check PEM/alloc feature propagation before removing that edge. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-node-forge/src/crypto.rs#L40) | +| `sqlx` (0.9.0) | ext-mysql2, ext-pg, stdlib? | **Keep / split features** ? Bundled stdlib enables mysql and postgres together; activate backends from individual features as extensions already do. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-mysql2/src/lib.rs#L23) | +| `stacker` (0.1.25) | hir | **Keep** ? Protects three lowering recursion boundaries and SWC. Remove only with bounded/iterative traversal evidence. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-hir/src/lower/lower_expr.rs#L95) | +| `swc_bundler` (37.0.0) | ext-typescript | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L24) | +| `swc_common` (18.0.1) | ext-typescript, hir, parser, perry | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L28) | +| `swc_ecma_ast` (19.0.0) | ext-typescript, hir, parser, perry | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L32) | +| `swc_ecma_codegen` (21.0.0) | ext-typescript, hir (dev) | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L36) | +| `swc_ecma_loader` (18.0.0) | ext-typescript | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L37) | +| `swc_ecma_parser` (29.0.2, 32.0.0) | ext-typescript, parser | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L38) | +| `swc_ecma_transforms_base` (32.0.0) | ext-typescript, hir, parser, perry | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L39) | +| `swc_ecma_transforms_react` (35.0.0) | ext-typescript | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L40) | +| `swc_ecma_transforms_typescript` (35.0.0) | ext-typescript | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L41) | +| `swc_ecma_visit` (19.0.0) | ext-typescript, hir, parser, perry | **Keep / align** ? Compiler syntax, transforms, ABI and code generation are expensive contracts to own again. Align compatible upstream versions; preserve the engine. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-typescript/src/bun.rs#L42) | +| `taffy` (0.13.0) | runtime | **Keep / gate TUI** ? Already trimmed to flexbox but always a runtime dependency; gate the TUI surface before considering layout-engine ownership. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/tui/layout.rs#L18) | +| `tar` (0.4.46) | perry | **Keep / gate** ? Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry/src/commands/publish/tarball.rs#L143) | +| `tempfile` (3.27.0) | doc-tests (dev), ext-parcel-watcher (dev), ui@, updater (dev), perry, perry (dev) | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-doc-tests/src/image_diff.rs#L171) | +| `temporal_rs` (0.2.6) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/temporal/dispatch.rs#L207) | +| `thiserror` (1.0.69, 2.0.18) | codegen, container-compose, hir, parser, runtime, stdlib, transform | **Keep / prune edges** ? Compose uses typed errors; compiler/runtime/stdlib/transform declarations have no lexical uses. Remove stale edges, preserve useful derives. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/error.rs#L7) | +| `time` (0.3.55) | ext-node-forge | **Keep / align** ? Node-forge and upstream formats need date/time handling; no convincing rewrite saving. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-node-forge/src/crypto.rs#L41) | +| `timezone_provider` (0.2.6) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/date.rs#L324) | +| `tiny_http` (0.12.0) | ui-geisterhand | **Keep / tooling** ? Synchronous chaos/test-control server; owning HTTP parsing offers little payoff on this tooling path. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-geisterhand/src/server.rs#L6) | +| `tokio` (1.53.1) | container-compose, container-compose (dev), ext-axios, ext-fastify, ext-fetch, ext-http, ext-ioredis, ext-mongodb, ext-mysql2, ext-net, ext-nodemailer, ext-pg, ext-ws, stdlib?, ui-gtk4@, perry | **Deferred** ? Separate session owns the removal verdict. This audit records dependent adapters and existing feature boundaries. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/backend/cli_backend.rs#L11) | +| `tokio-cron-scheduler` (0.15.1) | stdlib? | **Remove** ? Zero source references; own cron queues already use cron::Schedule. Deleting the edge removes 13 packages from full Windows stdlib. | [manifest](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/Cargo.toml) | +| `tokio-rustls` (0.26.4) | ext-http, ext-net, stdlib? | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/server/http2_server.rs#L34) | +| `tokio-tungstenite` (0.29.0) | ext-fastify, ext-http, ext-ws, stdlib?, perry | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-fastify/src/server.rs#L899) | +| `toml` (1.1.4+spec-1.1.0) | runtime?, perry | **Keep** ? CLI config and gated Bun API require full TOML syntax and diagnostics. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/bun_compat/cli_utils.rs#L157) | +| `tracing` (0.1.44) | container-compose | **Keep** ? Shared Compose/upstream instrumentation facade; little marginal value in a custom replacement. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/backend/cli_backend.rs#L107) | +| `tracing-subscriber` (0.3.23) | container-compose | **Keep / gate CLI** ? Only compose main installs it; gate with executable functionality when slimming its library. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/main.rs#L5) | +| `tungstenite` (0.24.0, 0.29.0) | ui-android@ | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-android/src/ws.rs#L16) | +| `unicode-normalization` (0.1.25) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/intl/date_collator.rs#L1512) | +| `unicode-segmentation` (1.13.3) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/intl/segmenter.rs#L8) | +| `unsafe-libyaml` (0.2.11) | runtime? | **Keep backend / scope** ? Bun YAML and serde_yaml parser backend; review alongside YAML migration, not a parser rewrite. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/bun_compat/cli_utils.rs#L729) | +| `url` (2.5.8) | runtime?, validation, perry | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/array/flat_clone.rs#L532) | +| `uuid` (1.26.0) | ext-nodemailer, ext-uuid, stdlib? | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-nodemailer/src/lib.rs#L237) | +| `validator` (0.21.0) | validation (dev) | **Keep / tests** ? Testing, visual comparison or differential oracle; retain independent validation. These direct edges are for testing/tooling. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-validation/src/tests.rs#L2) | +| `walkdir` (2.5.0) | doc-tests, perry | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-doc-tests/src/lint.rs#L20) | +| `wasm-encoder` (0.244.0, 0.258.0) | codegen-wasm | **Keep / align** ? Binary emission correctness for Wasm; align compatible versions with tooling. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-codegen-wasm/src/emit/compile.rs#L1235) | +| `wasmi` (1.1.0) | wasm-host | **Keep / isolate** ? Wasm host already isolated with defaults disabled and required SIMD enabled; interpreter rewrite is a major engine project. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-wasm-host/src/host_runtime.rs#L12) | +| `webkit6` (0.4.0) | ui-gtk4@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-gtk4/src/widgets/webview.rs#L14) | +| `webpki-roots` (0.26.11, 1.0.9) | ext-http | **Keep / scope** ? Retain protocol/system interoperability. Narrow features and adapters, and coordinate async-runtime changes with the Tokio study. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/tls_client.rs#L543) | +| `webview2-com` (0.39.1) | ui-windows@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-windows/src/widgets/webview.rs#L35) | +| `which` (8.0.6) | container-compose | **Keep** ? Bounded helper with performance or compatibility details; smaller ownership benefit than the prioritized candidates. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-container-compose/src/backend/detect.rs#L149) | +| `windows` (0.35.0, 0.62.2) | ui-windows-winui@, ui-windows@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-windows-winui/src/app.rs#L7) | +| `windows-core` (0.62.2) | ui-windows@ | **Keep / macro dependency** ? COM implement macros emit absolute ::windows_core paths. No lexical reference is a known false positive; keep version alignment. | [manifest](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-windows/Cargo.toml) | +| `windows-reactor` (0.0.0) | ui-windows-winui@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ui-windows-winui/src/app.rs#L8) | +| `windows-sys` (0.48.0, 0.52.0, 0.59.0, 0.60.2, 0.61.2) | runtime@, stdlib@, perry@ | **Keep / platform** ? Native ABI bindings and platform services; keep target gating. Hand-maintained bindings add compatibility work with little ownership benefit. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/child_process/ipc_transport.rs#L14) | +| `winresource` (0.1.31) | perry (build) | **Keep / build** ? Build-time native toolchain glue or table generation. These are not runtime library payloads; keep generated artifacts and platform compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry/build.rs#L11) | +| `writeable` (0.6.4) | runtime? | **Keep / gate** ? Standards and Unicode/calendar data dominate maintenance. Preserve existing per-program feature boundaries and compatibility. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/intl/icu_dtf.rs#L18) | +| `x25519-dalek` (2.0.1) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/crypto/sign.rs#L552) | +| `x448` (0.14.0-pre.12) | stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-stdlib/src/webcrypto/hmac.rs#L523) | +| `x509-cert` (0.3.0) | ext-http, ext-node-forge, runtime, stdlib? | **Keep** ? Cryptographic primitive or key/certificate format: retain maintained implementations; align compatible versions and prune unused edges while preserving algorithms and formats. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-http/src/tls_client.rs#L441) | +| `xxhash-rust` (0.8.18) | runtime? | **Keep / gate** ? Bun exposes exact xxHash64 output; DefaultHasher changes the contract. Already feature gated. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-runtime/src/bun_compat/cli_utils.rs#L565) | +| `zip` (8.6.0) | perry | **Keep / trim first** ? Updates/IPA reading and deflated HAP writing; Deflate-only graph drops 17 packages. Validate accepted archive methods before narrowing. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry/src/commands/harmonyos_hap.rs#L53) | +| `zstd` (0.13.3) | ext-zlib, runtime?, stdlib?, perry | **Keep / gate** ? Codec/archive format implementation: preserve interoperability and performance; narrow supported features only where the product contract permits. | [source](https://github.com/PerryTS/perry/blob/4945fc1f7498debc76e9f861d7cf1517da5e67c9/crates/perry-ext-zlib/src/stream.rs#L243) | + +The unused `similar` workspace template has no consumer: delete it as housekeeping, with zero dependency-graph saving. + +Transitive-only packages inherit the retain/prune decision of their owning library. The census records each immediate parent so shared subgraphs are not counted repeatedly. This is not an independent algorithm-level or vulnerability audit of every transitive implementation. diff --git a/docs/audits/rust-dependency-experiments-2026-09-14.json b/docs/audits/rust-dependency-experiments-2026-09-14.json new file mode 100644 index 0000000000..38890c09ea --- /dev/null +++ b/docs/audits/rust-dependency-experiments-2026-09-14.json @@ -0,0 +1,200 @@ +{ + "semantics": "Independent Cargo tree counterfactuals, normal+build edges, offline resolution. No compilation, no binary measurement, no correctness validation. All manifests and lock restored byte-for-byte.", + "experiments": [ + { + "experiment": "zip-deflate-only", + "configuration": [ + "-p", + "perry" + ], + "target": "x86_64-pc-windows-msvc", + "before_external_packages": 352, + "after_external_packages": 335, + "removed": [ + "aes v0.9.1", + "bumpalo v3.20.3", + "bzip2 v0.6.1", + "cipher v0.5.2", + "cmov v0.5.4", + "constant_time_eq v0.4.2", + "cpubits v0.1.1", + "ctutils v0.4.2", + "deflate64 v0.1.12", + "hmac v0.13.0", + "inout v0.2.2", + "libbz2-rs-sys v0.2.5", + "lzma-rust2 v0.16.4", + "pbkdf2 v0.13.0", + "ppmd-rust v1.4.0", + "sha1 v0.11.0", + "zopfli v0.8.3" + ], + "added": [], + "manifest_edits": [ + [ + "Cargo.toml", + "zip = \"8\"", + "zip = { version = \"8\", default-features = false, features = [\"deflate-flate2-zlib-rs\"] }" + ] + ] + }, + { + "experiment": "unused-cron-scheduler", + "configuration": [ + "-p", + "perry-stdlib" + ], + "target": "x86_64-pc-windows-msvc", + "before_external_packages": 556, + "after_external_packages": 543, + "removed": [ + "chrono-tz v0.10.4", + "croner v3.0.1", + "darling v0.20.11", + "darling_core v0.20.11", + "darling_macro v0.20.11", + "derive_builder v0.20.2", + "derive_builder_core v0.20.2", + "derive_builder_macro v0.20.2", + "phf v0.12.1", + "phf_shared v0.12.1", + "strum v0.27.2", + "strum_macros v0.27.2", + "tokio-cron-scheduler v0.15.1" + ], + "added": [], + "manifest_edits": [ + [ + "crates/perry-stdlib/Cargo.toml", + "tokio-cron-scheduler = { version = \"0.15\", optional = true }", + "" + ], + [ + "crates/perry-stdlib/Cargo.toml", + "\"dep:tokio-cron-scheduler\", ", + "" + ] + ] + }, + { + "experiment": "unused-stdlib-clap", + "configuration": [ + "-p", + "perry-stdlib", + "--no-default-features" + ], + "target": "x86_64-pc-windows-msvc", + "before_external_packages": 149, + "after_external_packages": 134, + "removed": [ + "anstream v1.0.0", + "anstyle v1.0.14", + "anstyle-parse v1.0.0", + "anstyle-query v1.1.5", + "anstyle-wincon v3.0.11", + "clap v4.6.6", + "clap_builder v4.6.6", + "clap_derive v4.6.4", + "clap_lex v1.1.0", + "colorchoice v1.0.5", + "heck v0.5.0", + "is_terminal_polyfill v1.70.2", + "once_cell_polyfill v1.70.2", + "strsim v0.11.1", + "utf8parse v0.2.2" + ], + "added": [], + "manifest_edits": [ + [ + "crates/perry-stdlib/Cargo.toml", + "clap = { version = \"4.4\", features = [\"derive\"] }", + "" + ] + ] + }, + { + "experiment": "unused-atty", + "configuration": [ + "-p", + "perry-container-compose" + ], + "target": "x86_64-pc-windows-msvc", + "before_external_packages": 98, + "after_external_packages": 96, + "removed": [ + "atty v0.2.14", + "winapi v0.3.9" + ], + "added": [], + "manifest_edits": [ + [ + "crates/perry-container-compose/Cargo.toml", + "atty = \"0.2\"", + "" + ] + ] + }, + { + "experiment": "align-dialoguer", + "configuration": [ + "-p", + "perry-container-compose" + ], + "target": "x86_64-pc-windows-msvc", + "before_external_packages": 98, + "after_external_packages": 94, + "removed": [ + "console v0.15.11", + "dialoguer v0.11.0", + "windows-sys v0.59.0", + "windows-targets v0.52.6", + "windows_x86_64_msvc v0.52.6" + ], + "added": [ + "dialoguer v0.12.0" + ], + "manifest_edits": [ + [ + "crates/perry-container-compose/Cargo.toml", + "dialoguer = \"0.11\"", + "dialoguer.workspace = true" + ] + ] + }, + { + "experiment": "governor-std-only", + "configuration": [ + "-p", + "perry-ext-ratelimit" + ], + "target": "x86_64-pc-windows-msvc", + "before_external_packages": 37, + "after_external_packages": 27, + "removed": [ + "bitflags v2.12.1", + "getrandom v0.3.4", + "ppv-lite86 v0.2.21", + "quanta v0.12.6", + "rand v0.9.4", + "rand_chacha v0.9.0", + "rand_core v0.9.5", + "raw-cpuid v11.6.0", + "winapi v0.3.9", + "zerocopy v0.8.50" + ], + "added": [], + "manifest_edits": [ + [ + "crates/perry-ext-ratelimit/Cargo.toml", + "governor = \"0.10\"", + "governor = { version = \"0.10\", default-features = false, features = [\"std\"] }" + ], + [ + "crates/perry-stdlib/Cargo.toml", + "governor = { version = \"0.10\", optional = true }", + "governor = { version = \"0.10\", default-features = false, features = [\"std\"], optional = true }" + ] + ] + } + ] +} diff --git a/docs/rust-dependency-audit.md b/docs/rust-dependency-audit.md new file mode 100644 index 0000000000..114c0a581a --- /dev/null +++ b/docs/rust-dependency-audit.md @@ -0,0 +1,155 @@ +# Rust dependency audit and initial cleanup — 14 September 2026 + +**Implemented in this PR:** remove 24 unused member dependency declarations and the unused `similar` workspace template, including stdlib's unused Clap and Tokio cron scheduler dependencies. The lockfile loses 15 external package versions, with no added packages, version upgrades or checksum changes to retained packages. Existing Tokio usage and all library implementations remain in place. ZIP feature trimming, Governor changes, version alignment and replacement projects below are recommendations for separate changes. + +The dated census, decisions and graph experiments preserve the **pre-cleanup baseline** so the evidence remains independently reviewable. The removed declarations are listed below; the dependency decision table describes the baseline and is not a census of the post-cleanup tree. + +The best next steps are **remove unused declarations, narrow features, and selectively own small implementations**. The strongest new implementation candidates are NanoID generation, the remaining legacy rate limiter, and the deliberately small PDF writer. Keep the large standards, compiler, protocol, cryptographic and platform libraries. Tokio's removal verdict remains with the separate session. + +This assessment is pinned to `main` commit `4945fc1f7498debc76e9f861d7cf1517da5e67c9` (Perry 0.5.1565). The cleanup branches from that same baseline. `git fetch origin main` and `git pull --ff-only origin main` completed in the isolated `codex/rust-dependency-audit` worktree; the original checkout's concurrent work is preserved. + +**Scope and evidence** + +The workspace has **83 members, 195 distinct direct external package names, 990 registry package versions representing 863 names, and 13 additional vendored package versions**. Exactly 100 registry names occur at multiple versions. These are dependency identities, not the number of libraries linked into an executable. Perex is a registry dependency maintained by Perry itself. + +Every direct library has an individual verdict, rationale, owner list, version list and example source/manifest link in the [195-library decision table](audits/rust-dependency-decisions-2026-09-14.md). The [complete census](audits/rust-dependencies-2026-09-14.json) also records dependency kind, optional/default features, target predicates, renamed imports, lexical usage, every external lock package and its immediate parents. Transitive libraries are assessed through their owning dependency, feature selection and shared reachability; this is not an independent algorithm or vulnerability audit of all 1,003 external package identities. + +All tracked Cargo manifests were enumerated, including 22 additional first-party manifests outside the workspace: benchmark/reference implementations, archived benchmark prototypes, the LLVM spike, fuzzing and provider fixtures. Their external declarations introduce no additional library names beyond the census. Their independent lockfiles are outside the workspace graph measurements; changing a reference benchmark to use Perry's implementation would also invalidate its independence. Vendored Windows manifests are recorded separately. + +The initial assessment uses source inspection, locked Cargo metadata, 21 selected Cargo trees, six independent manifest counterfactuals, and primary upstream documentation. The worktree selects `cargo 1.100.0-nightly (514c56dd7 2026-08-19)`. The baseline experiments did not compile Rust or measure runtime behavior/performance; implementation validation is recorded separately in the PR. No size or speed improvements are claimed. `cargo tree -e normal,build` approximates the build graph but is not an exact list of compilation units or linked code; Cargo documents this distinction in its [tree reference](https://doc.rust-lang.org/cargo/commands/cargo-tree.html). + +**Recommended order** + +| Priority | Work | Why it is worth doing | Acceptance condition | +|---|---|---|---| +| Done in this PR | Remove unused `tokio-cron-scheduler`, stdlib `clap`, compose `atty`, and other stale edges below | Already implemented functionality or no caller; 15 lock package versions disappear | Validation results are recorded in the PR | +| 1 | Limit CLI ZIP support to the archive methods its supported inputs require | Largest demonstrated compiler graph reduction in this audit | Update ZIP, IPA and HAP fixtures still read/write correctly, including failure cases | +| 1 | Align compose `dialoguer` with workspace 0.12 | Removes an avoidable old terminal stack | Installer prompt behavior and noninteractive behavior remain correct | +| 2 | Replace owned `lazy_static` / `once_cell` uses with `std` | Small maintenance simplification; toolchain already supports it | Initialization, concurrency and GC scanner registration semantics preserved | +| 2 | Trim Governor features, then evaluate owning its legacy limiter | Most npm-compatible state logic is already local | Direct GCRA and keyed fixed-window behavior both retain their contracts | +| 2 | Consolidate NanoID generation on the existing RNG/helper path | Very small external API surface; custom alphabet is already local | Secure randomness, unbiased selection, lengths and alphabets preserved | +| 2 | Spike a minimal PDF writer | Five small APIs currently carry a font/PDF-processing graph | Structural, text-encoding and rendering parity plus worthwhile measured savings | +| 3 | Improve feature boundaries: TUI, updater, SQL backends, image formats, CLI-only helpers | Better fit between requested functionality and selected libraries | Relevant APIs enable their features, unrelated programs omit them, dynamic use remains covered | +| 3 | Align TLS providers and compatible duplicated library generations | Potential native build/link savings; already has compatibility constraints | Cross-adapter TLS/key/certificate tests and supported-platform builds | + +These priorities are engineering judgments, not measured benefit-to-effort ratios. The graph experiments make the first few tasks concrete; replacement spikes must still establish performance and maintenance value. + +**Measured graph counterfactuals** + +Each experiment started from the same baseline and changed only the listed manifest declarations. Cargo resolved offline; the original manifests and lockfile were restored byte-for-byte after each experiment. Counts are unique external package versions in the Windows x64 normal/build tree, including build dependencies. These changes were not compiled. Exact edits and package differences are in the [experiment record](audits/rust-dependency-experiments-2026-09-14.json). + +| Independent experiment | Selected package / features | Before → after | Interpretation | +|---|---|---:|---| +| ZIP: disable defaults, enable `deflate-flate2-zlib-rs` | `perry`, default | 352 → 335 | 17 fewer packages, retaining ZIP and Deflate; drops unused codec/encryption branches in this configuration | +| Remove `tokio-cron-scheduler` declaration and feature activation | `perry-stdlib`, default | 556 → 543 | 13 fewer, including its separate cron parser and timezone/derive stack; Tokio itself remains | +| Remove stdlib's `clap` declaration | `perry-stdlib --no-default-features` | 149 → 134 | 15 fewer; Commander is already local code | +| Remove compose's `atty` declaration | `perry-container-compose` | 98 → 96 | Removes `atty` and this graph's `winapi` | +| Inherit workspace `dialoguer` 0.12 | `perry-container-compose` | 98 → 94 | Five old packages disappear and one new Dialoguer version appears: net four fewer | +| Governor: disable defaults, retain `std`, at both declaring edges | `perry-ext-ratelimit` | 37 → 27 | Ten fewer, principally Quanta and its RNG generation; still uses Governor | + +These savings must not be added together across different packages/configurations. Shared dependency and feature unification changes the result of combined edits. In particular, removing an edge from minimal stdlib can have no package-count effect when the CLI or another selected crate independently needs it. + +**What makes sense to own** + +| Library | Assessment | Scope and validation | Expected implementation effort | +|---|---|---|---| +| `lazy_static`, `once_cell` | Yes: use standard library equivalents | Owned `once_cell` sites use `sync::Lazy`; migrate to `LazyLock`, and use `OnceLock` for explicit initialization. Preserve locking, panic behavior and root scanners | Small, mechanical migration with focused concurrency review | +| `nanoid` | Yes: good small replacement candidate | Only default/sized generation needs the crate; custom alphabet is already implemented in both adapters. Share one helper using a maintained cryptographic RNG, with unbiased sampling and compatible length/alphabet behavior | Small implementation and boundary tests | +| `governor` | Plausible after feature trimming | Keyed `RateLimiterMemory` already uses local fixed-window state. Legacy `js_ratelimit_new/check/remaining` still uses Governor's direct GCRA; replacing it with the keyed fixed window would change behavior. Test refill, bursts, multi-point requests, clock boundaries and concurrent callers | Small-to-medium state-machine project | +| `printpdf` | Best focused subsystem spike | Current API: create, add text, add line, new page, save. Built-in Helvetica, explicit page coordinates; HTML is already disabled. A small object/xref/content-stream writer could avoid the font-processing stack. Preserve escaping, non-ASCII behavior, page finalization and I/O failure handling; verify multiple PDF readers and rendered output | Medium project if scope remains exactly this API | +| `lru` | Possible, lower priority | An indexed linked recency list plus lookup map can fit the contract. Existing wrapper additionally handles TTL, arbitrary JS keys/values and mutable GC roots. Preserve O(1) operations, eviction order and moving-GC correctness; avoid a linear scan replacement | Medium; savings need measurement | +| `env_logger` | Possible, lower priority | Only `main` installs it. A compact `log::Log` implementation is feasible if it preserves required `RUST_LOG` filtering, formatting and thread-safe writes. Keep the shared `log` facade | Small-to-medium depending on filter compatibility | +| `hex` | Technically easy, little current payoff | A shared encoding/decoding helper is small. Preserve case, malformed input behavior and allocation patterns. It remains widely used transitively, so this is mainly code ownership | Small, but behind graph-reducing work | +| `dashmap` | Investigate only if profiles justify it | Handles cross FFI, async work, retirement/quarantine and GC scanners. Replacing maps with mutexes or slabs requires a lifetime/reentrancy design and contention measurements. The two handle registries have distinct domains | Substantial review; no blanket replacement recommendation | + +Rust's standard `LazyLock` has been stable since 1.80 and `OnceLock` since 1.70; the [Rust 1.80 announcement](https://blog.rust-lang.org/2024/07/25/Rust-1.80.0/) and [OnceLock documentation](https://doc.rust-lang.org/std/sync/struct.OnceLock.html) describe their initialization contracts. Terminal detection is also available as [`std::io::IsTerminal`](https://doc.rust-lang.org/std/io/trait.IsTerminal.html), though the current unused `atty` edge needs deletion rather than a replacement call. + +For context, a frozen cross-target lock-graph reachability calculation removes **22 package identities for PrintPDF, six for Governor, one for NanoID, one for LRU, four for env_logger, and zero for lazy_static/once_cell** when all direct workspace edges to that name are removed. This is a structural calculation, not a rebuilt graph: third-party edges/features remain fixed, and it includes optional/platform branches. It helps avoid attributing shared dependencies to every candidate. In particular, NanoID's `rand 0.9` remains needed by BSON/MongoDB, WebSocket, image and PDF stacks. Taking ownership of one helper does not remove that RNG generation workspace-wide. + +Relevant source: [NanoID](../crates/perry-ext-nanoid/src/lib.rs), [rate limiting](../crates/perry-ext-ratelimit/src/lib.rs), [PDF writer](../crates/perry-ext-pdf/src/lib.rs), [LRU wrapper](../crates/perry-ext-lru-cache/src/lib.rs), [FFI handles](../crates/perry-ffi/src/handle.rs). Governor's defaults include `dashmap`, `jitter` and `quanta`; its [feature documentation](https://docs.rs/crate/governor/0.10.4/features) supports trimming those independently of the core limiter. Its [state model](https://docs.rs/governor/0.10.4/governor/state/index.html) uses GCRA. + +**Declarations removed in this PR** + +Source searches covered each owner's Rust source, tests, examples, benches and build script, ignoring whole-line comments. The cleanup removes the declarations below and the scheduler's obsolete `dep:tokio-cron-scheduler` feature activation. Lexical absence alone is not a compilation proof; implementation checks and platform limits are recorded in the PR. + +| Owner | No lexical references found | Notes | +|---|---|---| +| `perry-stdlib` | `anyhow`, `thiserror`, `clap`, `itoa`, `ryu`, `tokio-cron-scheduler` | Commander and the cron timer queue are already owned implementations | +| `perry-container-compose` | `anyhow`, `atty`, `dashmap`, `dotenvy` | Installer uses `console::Term`; errors use the crate's `thiserror` type | +| `perry-transform` | `anyhow`, `thiserror` | Remove declarations after target/test checks | +| `perry-runtime` | `anyhow`, `thiserror` | Not a proposal to remove live compiler `anyhow` uses | +| `perry-codegen`, `perry-hir`, `perry-parser` | `thiserror` | `anyhow` is extensively used and stays | +| `perry-updater` | `serde_json` | Keep its actual Serde, signature and hashing dependencies | +| `perry-ext-fastify` | `lazy_static` | Other extension users still use it | +| `perry-ui-android` | `itoa`, `ryu`, `serde_json` | Target-specific validation needed | +| `perry-ui-windows-winui` | `base64`, `libc` | Target-specific validation needed | +| Workspace template | `similar` | No member inherits it; deletion has zero graph effect | + +Three cases require a different verdict: + +- **Keep `windows-core`** in Windows UI. The `windows::core::implement` macro expands to absolute `::windows_core` paths. The manifest documents the build failure if the direct edge is removed. +- **Keep/review feature propagation for `icu_calendar` and `icu_time`**. Runtime enables their `compiled_data` under `intl-datetime`; re-exports hide lexical use. Removing an edge could change selected data even without an import. +- **Review only the unused stdlib version/feature edges for `sha3` and `spki`**. Stdlib's `sha3 0.12` alias has no lexical use, while SHAKE uses `shake` and KMAC uses `sha3_010`. `spki` is directly used by node-forge and can activate PEM/alloc features elsewhere. Preserve the live crypto algorithms and re-export feature contracts. + +**Feature and version work with more potential than rewrites** + +ZIP is a strong immediate target. The CLI reads update ZIPs and IPAs and writes Deflated HAP files. `zip = "8"` enables AES, Bzip2, Deflate64, LZMA/XZ, PPMd, Zstd and an additional Deflate encoder. The experiment retains `deflate-flate2-zlib-rs`; do not use a feature named `deflate` blindly, because that umbrella also enables Zopfli in the locked release. Verify the actual supported archive inputs before narrowing readers. The family feature layout is documented in [Zip 8's feature list](https://docs.rs/crate/zip/8.0.0/features); the precise 8.6.0 manifest and resolved features were inspected locally. + +Image defaults are broad, including EXR, TIFF, QOI and AVIF-related dependencies. `perry-ext-sharp` actually calls automatic input detection, AVIF encoding, JPEG quality encoding and `fast_image_resize`; deleting those formats or the SIMD resizer would change supported behavior/performance. Establish an input-format contract before using `default-features = false`. `perry-doc-tests` is a separate opportunity to request only its fixture formats. Coordinate **every** `image` edge because features are additive. + +`perry-stdlib` currently enables SQLx MySQL and PostgreSQL together on one optional dependency. Its separate bundled backend features can activate the individual `sqlx/mysql` and `sqlx/postgres` branches instead; the extension crates already select their individual backends. Check direct and external-wrapper builds, JSON/Chrono conversions and feature unification. Retain SQLx, MongoDB, Redis and SQLite implementations: protocol authentication, transactions, errors and cancellation are not small helper contracts. + +The always-on runtime dependency `taffy` already disables default features and selects flexbox. The useful next step is a TUI feature boundary, including its dynamic/namespace exposure, rather than owning a flexbox engine. Likewise, stdlib always re-exports `perry-updater`; a dedicated updater gate could stop unrelated minimal stdlib builds from selecting its signature/manifest stack. That would require coordinating compiler feature detection and archive symbol retention, not merely marking the dependency optional. + +TLS uses both providers **intentionally in code today**: HTTP explicitly selects Ring, while net/WebSocket and several bundled stdlib paths select AWS-LC. Some paths install a process-wide default. Unifying providers could reduce native build/link work, but requires changing these call sites together, preserving private-key/certificate algorithms, roots, TLS versions and any provider-specific capability. The default CLI graph already uses Ring alone; the dual-provider finding applies to broader stdlib/extensions and should not be attributed to every executable. Keep Rustls and the crypto libraries. Coordinate networking changes with the Tokio study. + +Version alignment also has concrete boundaries: + +- **Dialoguer 0.11/0.12**: a direct actionable duplicate; align compose, then trim unused prompt features. +- **SWC parser 29/32**: 29 is still pulled by `swc_ecma_transforms_base` and the bundler/transform stack, while direct parsing uses 32. Update compatible SWC families together or reduce unnecessary transform use; a parser rewrite is a major compiler project. +- **Crypto generations** (`digest`, `cipher`, `rand_core`, RSA/DER/SPKI and hash crates): direct aliases bridge real API generations. Upgrade compatible consumers together; forcing one version is not a valid fix. +- **Windows 0.35/0.62**: old XAML Islands/MapControl projections are deliberately isolated behind `windows-xaml`; no blind version unification. COM `windows-core` and WebView2 types must remain aligned. Vendored Reactor dependencies are already separately maintained upstream code, not unused workspace members. +- **GTK/GLib/Cairo generations**: multiple target-only bindings occur across GTK/WebKit and media/tray services. Align supported release families if those paths coexist; do not count them as default compiler payload. +- **`serde_yaml 0.9.34+deprecated`**: an upstream maintenance migration to investigate, with Compose syntax/merge/tag/diagnostic fixtures. Owning a YAML parser is not a good reduction strategy. Coordinate its `unsafe-libyaml` backend with the gated Bun YAML API. + +**Libraries to keep** + +Keep SWC, LLVM/Inkwell, Wasmi, Wasm encoding, cryptographic primitives and certificate formats, HTTP/TLS/WebSocket/DNS/database implementations, compression codecs, Unicode/IDNA/ICU/Temporal data, native UI/service bindings, and the decimal engine. The reason is the breadth of their actual Perry contract. Existing gates are usually the appropriate place to reduce cost. Replacing Inkwell's Rust API does not remove the linked LLVM implementation, and replacing a Rust OS wrapper does not remove the underlying operating-system dependency. + +Also keep the small, performance-sensitive helpers unless an A/B says otherwise: `ahash` for duplicate-key hashing, `aho-corasick` for retained-source matching, `itoa`, `ryu-js`, `simdutf8`, `rayon` for compiler parallelism, `gimli` for unwind CFI, `object` for native object formats, and `stacker` for deep lowering/parsing. A single import can front a substantial algorithmic or correctness contract. `hex`, `base64`, `walkdir`, `which`, `tempfile`, `fslock`, `dirs`, `hostname`, `httpdate`, `qrcodegen`, `cron`, `semver` and EXIF parsing are individually assessed in the decision table; their modest implementation sizes alone do not establish a worthwhile replacement. + +Perry already owns several of the requested replacements: Perex (`PerryTS/perex`), borrowed validators in `perry-validation`, Commander parsing, cron's timer queue, keyed rate limiting, and JS JSON hot paths. Preserve `regex` and `validator` as differential dev oracles. Removing those test edges does not optimize shipped behavior; `regex` may still be selected transitively by unrelated libraries. Preserve general Serde/JSON/TOML parsing for Rust-side configuration and interchange. Rust `semver` and npm `node-semver` also implement different range contracts. + +**Selected graph baseline** + +Each row selects just the named package with normal/build edges; these are not the combined package invocations used to distribute static archives. Platform UI extensions are separately selected. `minimal` means `--no-default-features`, not a claim that this is a representative application's detected feature set. Full commands and package identities are in the [21-graph baseline](audits/rust-dependency-build-graphs-2026-09-14.json). + +| Selected configuration | Windows x64 | Linux x64 | macOS arm64 | +|---|---:|---:|---:| +| CLI default | 352 | 352 | 349 | +| CLI `--no-default-features --features dev-cli` | 350 | 350 | 347 | +| Runtime default | 218 | 216 | 206 | +| Runtime minimal | 108 | 106 | 96 | +| Stdlib default | 556 | 549 | 546 | +| Stdlib minimal | 149 | 146 | 137 | +| Compose default | 98 | 94 | 92 | + +The slim CLI drops only two external package identities in these graphs. Its command features often hide commands while shared command/helper modules and dependencies stay enabled; a genuinely narrower compiler distribution would need more module/dependency separation. Runtime's default and minimal graphs contain no Tokio here, and minimal stdlib's graph also contains no Tokio. These are existing feature configurations, not a verdict about replacing Tokio in networked applications. + +**How to turn a candidate into a decision** + +Use a separate implementation branch for each candidate and pin the same compiler commit, target, profile and package set on both sides. For an archive-affecting change, build `perry-runtime-static` / `perry-stdlib-static` and the same relevant extension set; rebuilding only the rlib crates does not update shipped archives. Pin `PERRY_RUNTIME_DIR`, verify archive provenance, and preserve the shared-library feature/codegen-unit configuration used for linking. The existing repository warning about stale `.a` files applies directly here. + +Measure clean and incremental build time, archive/distribution sizes, final stripped program bytes, startup time/RSS and the candidate's relevant throughput/latency. Include a minimal program, a JSON workload, a TLS HTTP/WebSocket workload, a database workload and the affected specialized API (PDF/image/TUI as appropriate). Use `--report-size` for attribution where useful, while checking final files directly. Keep measurements isolated from concurrent sessions. + +For semantics, use the affected Rust unit tests and existing Node parity fixtures; test malformed/boundary inputs, cancellation/close behavior, and both bundled and external adapter routes. Run runtime tests single-threaded as required by the repository. FFI/handle changes additionally require moving-GC and cross-thread lifetime coverage. PDF replacements need structural parsing plus visual/text validation. Crypto/provider changes need known-answer and certificate interoperability tests. A smaller dependency count alone does not qualify a replacement for landing. + +The read-only census is reproducible with: + +```text +python scripts/rust_dependency_inventory.py --output current-rust-dependency-inventory.json +cargo tree --locked -p perry -e normal,build --target x86_64-pc-windows-msvc +cargo tree --locked --workspace --target all -d +``` + +The first command inventories the current checkout and may download locked sources to Cargo's cache, but does not compile or modify the lockfile. Run it at the pinned baseline commit to reproduce the dated census; use a different output path after cleanup. Lexical use counts are deliberately review aids; the macro and feature-only exceptions above demonstrate why automated deletion based on them would be unsound. diff --git a/scripts/rust_dependency_inventory.py b/scripts/rust_dependency_inventory.py new file mode 100644 index 0000000000..1de45c7968 --- /dev/null +++ b/scripts/rust_dependency_inventory.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 +"""Read-only Rust dependency census; no builds, manifest edits, or lock updates. + +Run from the repository root with Python 3.11+ and Cargo. Metadata describes +the cross-target lock graph, including optional dependencies; it is NOT a +measurement of linked code. Use cargo tree for selected build configurations. +Source references are lexical review aids, not proof that an edge is unused. +""" + +import argparse +from collections import Counter, defaultdict +import json +from pathlib import Path +import re +import subprocess +import tomllib + + +def command(*args): + return subprocess.check_output(args, text=True, encoding="utf-8") + + +def read_json(path): + raw = path.read_bytes() + encoding = "utf-16" if raw.startswith(b"\xff\xfe") else "utf-8-sig" + return json.loads(raw.decode(encoding)) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--metadata", type=Path, help="Reuse cargo metadata JSON") + parser.add_argument("--output", type=Path, required=True) + args = parser.parse_args() + root = Path(command("git", "rev-parse", "--show-toplevel").strip()) + metadata = (read_json(args.metadata) if args.metadata else + json.loads(command("cargo", "metadata", "--locked", "--format-version", "1"))) + packages = {p["id"]: p for p in metadata["packages"]} + members = set(metadata["workspace_members"]) + nodes = {n["id"]: n for n in metadata["resolve"]["nodes"]} + external = set(packages) - members + lib_names = {"md-5": "md5", "cairo-rs": "cairo", "kamadak-exif": "exif", + "rustls-webpki": "webpki"} + + def label(pid): + p = packages[pid] + suffix = " [vendored]" if pid in external and p["source"] is None else "" + return f"{p['name']}@{p['version']}{suffix}" + + def relative(path): + return Path(path).relative_to(root).as_posix() + + def reachable(roots, skip_direct_name=None): + seen = set() + queue = list(roots) + while queue: + pid = queue.pop() + if pid in seen: + continue + seen.add(pid) + for dep in nodes[pid]["deps"]: + target = dep["pkg"] + if pid in members and packages[target]["name"] == skip_direct_name: + continue + queue.append(target) + return seen + + baseline = reachable(members) + direct = defaultdict(list) + token = re.compile(r"\b([A-Za-z_]\w*)\s*(?:::|!|[,;}])") + for pid in sorted(members, key=label): + p = packages[pid] + package_root = Path(p["manifest_path"]).parent + deps = [d for d in p["dependencies"] if d.get("source") or + (d.get("path") and "third_party" in Path(d["path"]).parts)] + aliases = {(d.get("rename") or lib_names.get(d["name"], d["name"])).replace("-", "_") + for d in deps} + references = defaultdict(list) + files = [] + for folder in ("src", "tests", "examples", "benches"): + files.extend((package_root / folder).rglob("*.rs")) + if (package_root / "build.rs").exists(): + files.append(package_root / "build.rs") + for path in sorted(set(files)): + for number, line in enumerate(path.read_text(encoding="utf-8").splitlines(), 1): + if line.lstrip().startswith("//"): + continue + for name in set(token.findall(line)) & aliases: + references[name].append(f"{relative(path)}:{number}") + for dep in deps: + alias = (dep.get("rename") or lib_names.get(dep["name"], dep["name"])).replace("-", "_") + resolved = [d["pkg"] for d in nodes[pid]["deps"] + if d["name"] == alias and packages[d["pkg"]]["name"] == dep["name"]] + # Cargo node names use actual Rust lib names, including renamed edges. + if not resolved: + resolved = [d["pkg"] for d in nodes[pid]["deps"] + if packages[d["pkg"]]["name"] == dep["name"]] + feature_activators = [f for f, values in p["features"].items() + if any(v in {"dep:" + (dep.get("rename") or dep["name"]), + dep.get("rename") or dep["name"]} for v in values)] + direct[dep["name"]].append({ + "owner": p["name"], "manifest": relative(p["manifest_path"]), + "alias": alias, "kind": dep["kind"] or "normal", "target": dep["target"], + "optional": dep["optional"], "requirement": dep["req"], + "default_features": dep["uses_default_features"], "features": dep["features"], + "direct_feature_activators": feature_activators, + "resolved": sorted({label(x) for x in resolved}), + "reference_lines": len(references[alias]), "references": references[alias][:6], + }) + parents = defaultdict(list) + for pid, node in nodes.items(): + for dep in node["deps"]: + parents[dep["pkg"]].append(label(pid)) + records = [] + for pid in sorted(external, key=label): + p = packages[pid] + records.append({ + "package": label(pid), "source": p["source"] or relative(p["manifest_path"]), + "name_is_direct_dependency": p["name"] in direct, + "lock_features": nodes[pid]["features"], + "parents": sorted(parents[pid]), + "dependencies": sorted(label(d["pkg"]) for d in nodes[pid]["deps"]), + }) + direct_records = [] + for name, edges in sorted(direct.items()): + ids = {pid for pid in external if packages[pid]["name"] == name} + lost = (baseline - reachable(members, name)) & external + direct_records.append({ + "name": name, "versions": sorted({packages[pid]["version"] for pid in ids}), + "edges": edges, "lock_closure_packages": len(reachable(ids) & external), + "lock_packages_lost_if_all_workspace_edges_removed": sorted(label(pid) for pid in lost), + }) + owned_manifests = {relative(packages[pid]["manifest_path"]) for pid in members} + other_manifests = [] + manifests = command("git", "ls-files", "--", "*Cargo.toml", "Cargo.toml").splitlines() + for manifest in sorted(set(manifests) - owned_manifests - {"Cargo.toml"}): + parsed = tomllib.loads((root / manifest).read_text(encoding="utf-8")) + sections = [(k, None, parsed.get(k, {})) for k in + ("dependencies", "dev-dependencies", "build-dependencies")] + for target, tables in parsed.get("target", {}).items(): + sections.extend((k, target, tables.get(k, {})) for k in + ("dependencies", "dev-dependencies", "build-dependencies")) + declarations = [] + for kind, target, table in sections: + for alias, value in table.items(): + value = {"version": value} if isinstance(value, str) else value + if not value.get("path") and not value.get("workspace"): + declarations.append({"name": value.get("package", alias), + "kind": kind, "target": target, **value}) + other_manifests.append({"manifest": manifest, + "vendored": manifest.startswith("third_party/"), + "external_declarations": declarations}) + counts = Counter(p["name"] for pid, p in packages.items() if pid in external and p["source"]) + output = { + "commit": command("git", "rev-parse", "HEAD").strip(), + "cargo": command("cargo", "--version").strip(), + "semantics": "Cross-target lock graph, including optional and dev/build dependencies; not linked size. Lexical references need manual review. Marginal counts freeze third-party edges/features and remove all workspace edges to one package name.", + "summary": {"workspace_members": len(members), "direct_external_names": len(direct), + "registry_package_versions": sum(counts.values()), + "registry_package_names": len(counts), + "vendored_package_versions": sum(packages[p]["source"] is None for p in external), + "registry_names_with_multiple_versions": sum(n > 1 for n in counts.values())}, + "direct": direct_records, "external_lock_packages": records, + "other_manifests": other_manifests, + } + args.output.parent.mkdir(parents=True, exist_ok=True) + # One record per line keeps the complete census reviewable without huge indentation. + with args.output.open("w", encoding="utf-8", newline="\n") as f: + f.write("{\n") + for index, (key, value) in enumerate(output.items()): + if index: + f.write(",\n") + f.write(json.dumps(key) + ": ") + if isinstance(value, list): + f.write("[\n" + ",\n".join(json.dumps(v, ensure_ascii=False) for v in value) + "\n]") + else: + f.write(json.dumps(value, ensure_ascii=False)) + f.write("\n}\n") + print(json.dumps(output["summary"], indent=2)) + print(f"Wrote {args.output}") + + +if __name__ == "__main__": + main() From c11377ab8d68e0f35a6b457e7d91c93abae9e9f2 Mon Sep 17 00:00:00 2001 From: Ralph Kuepper Date: Mon, 14 Sep 2026 12:26:02 +0200 Subject: [PATCH 02/11] chore: number dependency cleanup changelog for PR 10262 --- ...ust-dependency-cleanup.md => 10262-rust-dependency-cleanup.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.d/{pending-rust-dependency-cleanup.md => 10262-rust-dependency-cleanup.md} (100%) diff --git a/changelog.d/pending-rust-dependency-cleanup.md b/changelog.d/10262-rust-dependency-cleanup.md similarity index 100% rename from changelog.d/pending-rust-dependency-cleanup.md rename to changelog.d/10262-rust-dependency-cleanup.md From e0ec93070c8ba3789c61c5fd9d2a11f763014220 Mon Sep 17 00:00:00 2001 From: Ralph Kuepper Date: Mon, 14 Sep 2026 12:36:51 +0200 Subject: [PATCH 03/11] fix: retain dependencies used by shared WinUI source --- Cargo.lock | 2 ++ changelog.d/10262-rust-dependency-cleanup.md | 2 +- crates/perry-ui-windows-winui/Cargo.toml | 2 ++ docs/audits/rust-dependency-cleanup-2026-09-14.json | 4 ---- docs/rust-dependency-audit.md | 8 ++++---- scripts/rust_dependency_inventory.py | 2 ++ 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 388c342ab6..d7ddf5f312 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6627,6 +6627,8 @@ dependencies = [ name = "perry-ui-windows-winui" version = "0.5.1569" dependencies = [ + "base64 0.22.1", + "libc", "perry-ffi", "perry-runtime", "perry-ui-windows", diff --git a/changelog.d/10262-rust-dependency-cleanup.md b/changelog.d/10262-rust-dependency-cleanup.md index 138eef1aef..03aedfaf30 100644 --- a/changelog.d/10262-rust-dependency-cleanup.md +++ b/changelog.d/10262-rust-dependency-cleanup.md @@ -1,4 +1,4 @@ -Remove 24 unused Rust dependency declarations and the unused `similar` workspace +Remove 22 unused Rust dependency declarations and the unused `similar` workspace template, including stdlib's unused Clap and Tokio cron scheduler dependencies. The lockfile drops 15 external package versions without upgrading or adding any packages. Existing Tokio usage and public APIs are unchanged. diff --git a/crates/perry-ui-windows-winui/Cargo.toml b/crates/perry-ui-windows-winui/Cargo.toml index d9abd197f8..938e07d88a 100644 --- a/crates/perry-ui-windows-winui/Cargo.toml +++ b/crates/perry-ui-windows-winui/Cargo.toml @@ -20,6 +20,8 @@ crate-type = ["rlib", "staticlib"] perry-ui-windows = { path = "../perry-ui-windows", default-features = false } perry-ffi.workspace = true perry-runtime = { path = "../perry-runtime", default-features = false, features = ["stdlib"] } +base64.workspace = true +libc.workspace = true windows = { version = "0.62", features = ["Win32_Foundation"] } windows-reactor = { path = "../../third_party/windows-winui/windows-reactor" } diff --git a/docs/audits/rust-dependency-cleanup-2026-09-14.json b/docs/audits/rust-dependency-cleanup-2026-09-14.json index 25057e1e3a..b9450c30a9 100644 --- a/docs/audits/rust-dependency-cleanup-2026-09-14.json +++ b/docs/audits/rust-dependency-cleanup-2026-09-14.json @@ -286,10 +286,6 @@ "itoa.workspace = true", "ryu.workspace = true" ], - "crates/perry-ui-windows-winui/Cargo.toml": [ - "base64.workspace = true", - "libc.workspace = true" - ], "crates/perry-updater/Cargo.toml": [ "serde_json.workspace = true" ] diff --git a/docs/rust-dependency-audit.md b/docs/rust-dependency-audit.md index 114c0a581a..39b6510273 100644 --- a/docs/rust-dependency-audit.md +++ b/docs/rust-dependency-audit.md @@ -1,6 +1,6 @@ # Rust dependency audit and initial cleanup — 14 September 2026 -**Implemented in this PR:** remove 24 unused member dependency declarations and the unused `similar` workspace template, including stdlib's unused Clap and Tokio cron scheduler dependencies. The lockfile loses 15 external package versions, with no added packages, version upgrades or checksum changes to retained packages. Existing Tokio usage and all library implementations remain in place. ZIP feature trimming, Governor changes, version alignment and replacement projects below are recommendations for separate changes. +**Implemented in this PR:** remove 22 unused member dependency declarations and the unused `similar` workspace template, including stdlib's unused Clap and Tokio cron scheduler dependencies. The lockfile loses 15 external package versions, with no added packages, version upgrades or checksum changes to retained packages. Existing Tokio usage and all library implementations remain in place. ZIP feature trimming, Governor changes, version alignment and replacement projects below are recommendations for separate changes. The dated census, decisions and graph experiments preserve the **pre-cleanup baseline** so the evidence remains independently reviewable. The removed declarations are listed below; the dependency decision table describes the baseline and is not a census of the post-cleanup tree. @@ -82,12 +82,12 @@ Source searches covered each owner's Rust source, tests, examples, benches and b | `perry-updater` | `serde_json` | Keep its actual Serde, signature and hashing dependencies | | `perry-ext-fastify` | `lazy_static` | Other extension users still use it | | `perry-ui-android` | `itoa`, `ryu`, `serde_json` | Target-specific validation needed | -| `perry-ui-windows-winui` | `base64`, `libc` | Target-specific validation needed | | Workspace template | `similar` | No member inherits it; deletion has zero graph effect | -Three cases require a different verdict: +These cases require a different verdict: - **Keep `windows-core`** in Windows UI. The `windows::core::implement` macro expands to absolute `::windows_core` paths. The manifest documents the build failure if the direct edge is removed. +- **Keep `base64` and `libc` in WinUI**. Its `#[path]` modules compile the shared Windows backend's [system FFI](../crates/perry-ui-windows/src/ffi/system.rs), including Base64 encoding and allocation cleanup, in the WinUI crate. The census scans files inside each package and does not follow shared source paths; Windows compilation confirmed these declarations are required. - **Keep/review feature propagation for `icu_calendar` and `icu_time`**. Runtime enables their `compiled_data` under `intl-datetime`; re-exports hide lexical use. Removing an edge could change selected data even without an import. - **Review only the unused stdlib version/feature edges for `sha3` and `spki`**. Stdlib's `sha3 0.12` alias has no lexical use, while SHAKE uses `shake` and KMAC uses `sha3_010`. `spki` is directly used by node-forge and can activate PEM/alloc features elsewhere. Preserve the live crypto algorithms and re-export feature contracts. @@ -152,4 +152,4 @@ cargo tree --locked -p perry -e normal,build --target x86_64-pc-windows-msvc cargo tree --locked --workspace --target all -d ``` -The first command inventories the current checkout and may download locked sources to Cargo's cache, but does not compile or modify the lockfile. Run it at the pinned baseline commit to reproduce the dated census; use a different output path after cleanup. Lexical use counts are deliberately review aids; the macro and feature-only exceptions above demonstrate why automated deletion based on them would be unsound. +The first command inventories the current checkout and may download locked sources to Cargo's cache, but does not compile or modify the lockfile. Run it at the pinned baseline commit to reproduce the dated census; use a different output path after cleanup. Lexical use counts are deliberately review aids; the shared-source, macro and feature-only exceptions above demonstrate why automated deletion based on them would be unsound. diff --git a/scripts/rust_dependency_inventory.py b/scripts/rust_dependency_inventory.py index 1de45c7968..2010d5f8f6 100644 --- a/scripts/rust_dependency_inventory.py +++ b/scripts/rust_dependency_inventory.py @@ -5,6 +5,8 @@ the cross-target lock graph, including optional dependencies; it is NOT a measurement of linked code. Use cargo tree for selected build configurations. Source references are lexical review aids, not proof that an edge is unused. +Only files within each package are scanned; shared-source #[path] modules, +macro expansion and feature-only dependencies need separate review. """ import argparse From ecd4455d0190543f7d73c0a4c0d28b25ff31752f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Mon, 14 Sep 2026 12:36:05 +0200 Subject: [PATCH 04/11] perf: remove local copy and scalar root-store overhead --- benchmarks/generic-overhead/README.md | 97 ++++++++ benchmarks/generic-overhead/census.py | 68 ++++++ benchmarks/generic-overhead/probes.ts | 10 + .../src/codegen/static_fields.rs | 2 +- .../src/expr/generic_overhead_tests.rs | 126 ++++++++++ .../perry-codegen/src/expr/literals_vars.rs | 10 +- crates/perry-codegen/src/expr/mod.rs | 12 +- .../src/expr/static_field_meta.rs | 4 +- .../perry-codegen/src/expr/write_barrier.rs | 22 ++ crates/perry-codegen/src/stmt/let_stmt.rs | 4 +- crates/perry-transform/src/lib.rs | 4 + crates/perry-transform/src/local_copies.rs | 230 ++++++++++++++++++ .../perry-transform/src/local_copies_tests.rs | 225 +++++++++++++++++ .../test_gap_generic_function_overhead.ts | 104 ++++++++ 14 files changed, 902 insertions(+), 16 deletions(-) create mode 100644 benchmarks/generic-overhead/README.md create mode 100644 benchmarks/generic-overhead/census.py create mode 100644 benchmarks/generic-overhead/probes.ts create mode 100644 crates/perry-codegen/src/expr/generic_overhead_tests.rs create mode 100644 crates/perry-transform/src/local_copies.rs create mode 100644 crates/perry-transform/src/local_copies_tests.rs create mode 100644 test-files/test_gap_generic_function_overhead.ts diff --git a/benchmarks/generic-overhead/README.md b/benchmarks/generic-overhead/README.md new file mode 100644 index 0000000000..ea0ecfac51 --- /dev/null +++ b/benchmarks/generic-overhead/README.md @@ -0,0 +1,97 @@ +# Generic function overhead + +These exported probes measure the fixed instruction cost of local copies, +registered global stores, and calls through a function parameter. They count +ARM64 machine instructions after LLVM optimization, including cold blocks and +excluding callees. They do not measure executed instructions or throughput. + +## Reproduce + +Build the reference and candidate compilers from their own checkouts. No runtime +archives are needed for this object-only census. + +```sh +python3 benchmarks/generic-overhead/census.py \ + --before /path/to/reference/perry \ + --after /path/to/candidate/perry \ + --objdump /path/to/llvm-objdump \ + --out /tmp/perry-generic-overhead-census +``` + +The default is Perry's LLVM `-Os` policy. Repeat with `--opt 3` to check `-O3`. +Each arm retains the compiler log, traced LLVM IR, object, and disassembly. The +JSON report records compiler and source hashes alongside the instruction counts. + +## Measured instruction counts + +Measured against `4945fc1f7498debc76e9f861d7cf1517da5e67c9` on an Apple M1 Max, +using LLVM 22.1.4 and Perry's `apple-m1` target. Both columns count the same +exported probe source; the callback and unknown-value store are controls. + +| Probe | `-Os` before → after | `-O3` before → after | +| --- | ---: | ---: | +| Identity | 3 → 3 | 3 → 3 | +| One local alias | 21 → 3 | 24 → 3 | +| Three local aliases | 43 → 3 | 58 → 3 | +| Dead inert assignments | 43 → 3 | 58 → 3 | +| Alias live across a call | 70 → 54 | 79 → 55 | +| Constant global write | 11 → 6 | 12 → 7 | +| Declared-number global write wrapper | 17 → 17 | 22 → 22 | +| Unknown-value global write fallback | 17 → 17 | 17 → 17 | +| Callback through a function parameter | 97 → 97 | 107 → 107 | + +Compiler SHA-256: + +- Reference: `e5bbbf453f5660f53c54e8978ee10569daa00000489b5a5be09fd61ad7ee42e5` +- Candidate: `39f2a71d54fee3ca253caa3a372121e49453f423dad356ca153acf0fd3562a72` +- Probe source: `fcdab55841ae899da01a6b6d32f1f753ff753f1706dd5e12765a1eddd0b973fc` + +## Optimization boundaries + +- Copy cleanup runs after the HIR shape passes and before codegen emits string + sharing and root shading. It forwards initialized, unwritten local bindings + and removes unused inert stores. It excludes captures, control flow, TDZ + preallocation, parameter defaults, arguments objects, and unsupported HIR + expressions. Effectful discarded assignments keep both their RHS and storage. +- Global and static-field stores reuse the existing construction proof used for + precise local roots. Proven scalar stores remain stores to registered roots; + unknown values and declared-only numeric parameters retain incremental shading. + +This does not change leaf-root laundering, rest/arguments materialization, +callback dispatch, closure allocation/boxing, borrowed global-string reads, or +cross-module GC effect propagation. + +## Semantic coverage + +`test-files/test_gap_generic_function_overhead.ts` compares with the pinned Node +oracle. It covers primitive and heap aliases, source writes, retained captures, +mapped arguments, TDZ, effectful assignments, declared-only number stores, +ordinary/arrow/bound/rest/proxy callbacks, exception propagation, and an object +alias kept live across allocating calls. Run the same executable under moving +GC stress and require nonzero copying collections and moved objects: + +```sh +PERRY_GC_SCHEDULE_SEED=37 PERRY_GC_SCHEDULE_RATE=0.2 \ +PERRY_GC_SCHEDULE_ALLOC_KB=0 PERRY_GC_PROTECT_FROMSPACE=1 \ +PERRY_GC_VERIFY_EVACUATION=1 /path/to/compiled/fixture +``` + +The crate unit tests separately assert removed work and required fallback IR; +an optimized-away fixture cannot satisfy those emission checks. + +The final fixture matches Node 26.5.1 in both native and shadow-root modes, +normally and under the stress settings above. Each stress run performs 1,411 +copying minor collections and moves 91,275 objects. The shadow IR passes both +the moving-root dominance check (180 root stores) and unrooted-alloca check +(162 GC-capable allocas), with zero violations. + +## Callback follow-up + +The callback probe is an unchanged control. A trial that routed function-typed +locals through `js_closure_call1_receiverless` reduced its caller from 97 to 9 +instructions, but increased median CPU time for ordinary callbacks by 54%. +Arrow callbacks improved by 11%. This used five interleaved before/after pairs +of 20 million calls on the same host and matching runtime build profiles. +The trial moved receiver save/root/restore work into the runtime, so the smaller +caller alone was insufficient evidence. That routing change is excluded; optimizing +the ordinary-function runtime path remains follow-up work. diff --git a/benchmarks/generic-overhead/census.py b/benchmarks/generic-overhead/census.py new file mode 100644 index 0000000000..e245bb0969 --- /dev/null +++ b/benchmarks/generic-overhead/census.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +"""Compile the same probes with two Perry builds and count ARM64 instructions. + +Counts include cold blocks and exclude callees. They measure static code, not +executed instructions or elapsed time. Each arm keeps its IR and disassembly. +""" + +import argparse +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess + + +def census(compiler: Path, output: Path, objdump: str, opt: str) -> dict: + output.mkdir(parents=True, exist_ok=True) + source = Path(__file__).with_name("probes.ts").resolve() + env = dict(os.environ, PERRY_NO_AUTO_OPTIMIZE="1", PERRY_LL_OPT_LEVEL=opt) + with (output / "compile.log").open("w") as log: + subprocess.run( + [str(compiler), "compile", str(source), "--no-link", "--no-codegen", + "--trace", "llvm", "-o", str(output / "probes.o")], + cwd=output, env=env, stdout=log, stderr=subprocess.STDOUT, check=True, + ) + asm = subprocess.check_output( + [objdump, "-dr", "--no-show-raw-insn", str(output / "probes.o")], text=True, + ) + if "file format mach-o arm64" not in asm and "file format elf64-littleaarch64" not in asm: + raise RuntimeError("This instruction census expects an ARM64 object") + (output / "probes.asm").write_text(asm) + functions = {} + name = None + for line in asm.splitlines(): + label = re.match(r"^[0-9a-f]+ <(.+)>:$", line) + if label: + symbol = label[1].lstrip("_") + name = symbol.split("__", 1)[1] if symbol.startswith("perry_fn_probes_ts__") else None + if name is not None: + functions[name] = 0 + elif name is not None and re.match(r"^\s+[0-9a-f]+:\s+[a-z][a-z0-9.]*\s", line + " "): + functions[name] += 1 + if not functions: + raise RuntimeError("No probe functions found in disassembly") + return {"compiler": str(compiler), "sha256": hashlib.sha256(compiler.read_bytes()).hexdigest(), + "source_sha256": hashlib.sha256(source.read_bytes()).hexdigest(), + "opt": opt, "static_instructions": functions} + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--before", type=Path, required=True) + parser.add_argument("--after", type=Path, required=True) + parser.add_argument("--out", type=Path, required=True) + parser.add_argument("--objdump", default="llvm-objdump") + parser.add_argument("--opt", choices=["s", "3"], default="s") + args = parser.parse_args() + output = args.out.resolve() + result = {arm: census(getattr(args, arm).resolve(), output / arm, args.objdump, args.opt) + for arm in ["before", "after"]} + report = json.dumps(result, indent=2) + "\n" + (output / "census.json").write_text(report) + print(report, end="") + + +if __name__ == "__main__": + main() diff --git a/benchmarks/generic-overhead/probes.ts b/benchmarks/generic-overhead/probes.ts new file mode 100644 index 0000000000..5a37cb3c18 --- /dev/null +++ b/benchmarks/generic-overhead/probes.ts @@ -0,0 +1,10 @@ +// Exported bodies are the subjects of the machine-instruction census. +export function identity(x: any): any { return x; } +export function aliasOne(x: any): any { const y = x; return y; } +export function aliasThree(x: any): any { const a = x; const b = a; const c = b; return c; } +export function deadAssignments(x: any): any { let y = x; y = x; y = x; return x; } +export function aliasAcrossCall(x: any, visit: () => void): any { const y = x; visit(); return y; } +let counter: number = 0; +export function globalConstantWrite(): void { counter = 3; } +export function globalWrite(x: number): void { counter = x; } +export function callback(f: (x: number) => number, x: number): number { return f(x); } diff --git a/crates/perry-codegen/src/codegen/static_fields.rs b/crates/perry-codegen/src/codegen/static_fields.rs index 2d8e84ff5a..9a79c28d05 100644 --- a/crates/perry-codegen/src/codegen/static_fields.rs +++ b/crates/perry-codegen/src/codegen/static_fields.rs @@ -350,7 +350,7 @@ pub(super) fn init_static_fields_late( } let v = v?; let g_ref = format!("@{}", global_name); - crate::expr::emit_root_nanbox_store_on_block(ctx.block(), &v, &g_ref); + crate::expr::emit_root_nanbox_store_for_expr(ctx, &v, &g_ref, init_expr); emit_static_field_registration(ctx, &v); } // Uninitialized non-computed static fields are now registered in diff --git a/crates/perry-codegen/src/expr/generic_overhead_tests.rs b/crates/perry-codegen/src/expr/generic_overhead_tests.rs new file mode 100644 index 0000000000..32d779ab98 --- /dev/null +++ b/crates/perry-codegen/src/expr/generic_overhead_tests.rs @@ -0,0 +1,126 @@ +//! Pin both the removed generic work and the fallback that remains necessary. + +use crate::testing::root_slots::function_slice; +use crate::{compile_module, CompileOptions}; +use perry_hir::types::Type; +use perry_hir::{CompareOp, Expr, Function, Module, Param, Stmt}; + +fn param(id: u32, ty: Type) -> Param { + Param { + id, + name: format!("p{id}"), + ty, + default: None, + decorators: vec![], + is_rest: false, + arguments_object: None, + } +} + +fn probe_ir(params: Vec, body: Vec) -> String { + let mut module = Module::new("cost_test"); + module.init.push(Stmt::Let { + id: 99, + name: "sink".into(), + ty: Type::Any, + mutable: true, + init: Some(Expr::Number(0.0)), + }); + module.functions.push(Function { + id: 1, + name: "probe".into(), + type_params: vec![], + params, + return_type: Type::Any, + body, + is_async: false, + is_generator: false, + is_strict: true, + is_exported: true, + captures: vec![], + decorators: vec![], + was_plain_async: false, + was_unrolled: false, + }); + let ir = String::from_utf8( + compile_module( + &module, + CompileOptions { + emit_ir_only: true, + is_entry_module: false, + ..CompileOptions::default() + }, + ) + .expect("compile cost probe"), + ) + .unwrap(); + let mut body = function_slice(&ir, "perry_fn_cost_test__probe").to_string(); + // A declared numeric parameter can introduce a guarded ABI wrapper. The + // erased-type fallback, not the wrapper's dispatch, owns its root store. + let generic = "perry_fn_cost_test__probe$generic"; + if ir.contains(&format!("@{generic}(")) { + body.push_str(function_slice(&ir, generic)); + } + body +} + +fn global_store_ir(value: Expr, ty: Type) -> String { + probe_ir( + vec![param(1, ty)], + vec![ + Stmt::Expr(Expr::LocalSet(99, Box::new(value))), + Stmt::Return(Some(Expr::LocalGet(99))), + ], + ) +} + +#[test] +fn scalar_global_stores_keep_the_store_without_root_shading() { + for value in [ + Expr::Number(3.0), + Expr::Number(-0.0), + Expr::Number(f64::NAN), + Expr::Integer(7), + Expr::Bool(true), + Expr::Null, + Expr::Undefined, + Expr::Compare { + op: CompareOp::Eq, + left: Box::new(Expr::LocalGet(1)), + right: Box::new(Expr::Null), + }, + ] { + let ir = global_store_ir(value, Type::Any); + assert!( + ir.lines().any(|line| line.contains("store double") + && line.contains("@perry_global_cost_test__99")), + "store disappeared:\n{ir}" + ); + assert!( + !ir.contains("call void @js_write_barrier_root_nanbox("), + "scalar barrier:\n{ir}" + ); + } +} + +#[test] +fn unknown_and_declared_number_globals_keep_root_shading() { + for ty in [Type::Any, Type::Number] { + let ir = global_store_ir(Expr::LocalGet(1), ty); + assert!( + ir.contains("call void @js_write_barrier_root_nanbox("), + "annotation must not suppress the barrier:\n{ir}" + ); + } + for value in [ + Expr::String("a heap string longer than SSO".into()), + Expr::Array(vec![Expr::Number(3.0)]), + Expr::BigInt("123".into()), + ] { + let ir = global_store_ir(value, Type::Any); + assert!( + ir.contains("call void @js_write_barrier_root_nanbox("), + "heap barrier missing:\n{ir}" + ); + } +} diff --git a/crates/perry-codegen/src/expr/literals_vars.rs b/crates/perry-codegen/src/expr/literals_vars.rs index 007ac9c00b..04bafe41e0 100644 --- a/crates/perry-codegen/src/expr/literals_vars.rs +++ b/crates/perry-codegen/src/expr/literals_vars.rs @@ -17,9 +17,9 @@ use crate::type_analysis::{is_map_expr, is_set_expr, receiver_class_name}; use crate::types::{DOUBLE, I32, I64}; use super::{ - can_lower_expr_as_i32_in_current_region, emit_root_nanbox_store_on_block, - emit_shadow_slot_clear, emit_shadow_slot_update_for_expr, emit_write_barrier, - is_global_this_builtin_function_name, lower_expr, lower_expr_as_i32, + can_lower_expr_as_i32_in_current_region, emit_root_nanbox_store_for_expr, + emit_root_nanbox_store_on_block, emit_shadow_slot_clear, emit_shadow_slot_update_for_expr, + emit_write_barrier, is_global_this_builtin_function_name, lower_expr, lower_expr_as_i32, lower_pod_local_reassignment, materialize_pod_value_copy, nanbox_string_inline, FnCtx, TrustedBoxCapturePtr, }; @@ -772,7 +772,7 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { } else if let Some(global_name) = ctx.module_globals.get(id).cloned() { let g_ref = format!("@{}", global_name); // GC_STORE_AUDIT(ROOT): module global slot is registered as a mutable GC root. - emit_root_nanbox_store_on_block(ctx.block(), &v_dbl, &g_ref); + emit_root_nanbox_store_for_expr(ctx, &v_dbl, &g_ref, value); } if !is_canonical { if let Some(slot_idx) = ctx.shadow_slot_map.get(id).copied() { @@ -879,7 +879,7 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { } else if let Some(global_name) = ctx.module_globals.get(id).cloned() { let g_ref = format!("@{}", global_name); // GC_STORE_AUDIT(ROOT): module global slot is registered as a mutable GC root. - emit_root_nanbox_store_on_block(ctx.block(), &v, &g_ref); + emit_root_nanbox_store_for_expr(ctx, &v, &g_ref, value); } super::record_native_arena_owner_assignment(ctx, *id, value.as_ref()); if ctx.receiver_descriptors.contains_buffer_view(id) diff --git a/crates/perry-codegen/src/expr/mod.rs b/crates/perry-codegen/src/expr/mod.rs index 910ab2a688..cef3f103ff 100644 --- a/crates/perry-codegen/src/expr/mod.rs +++ b/crates/perry-codegen/src/expr/mod.rs @@ -136,12 +136,12 @@ pub(crate) use write_barrier::{ emit_jsvalue_slot_store_pointer_tested, emit_jsvalue_slot_store_scalar_aware_on_block, emit_jsvalue_slot_store_with_flags_on_block, emit_jsvalue_slot_store_with_value_bits_on_block, emit_layout_note_slot_on_block, emit_may_carry_heap_pointer_check, - emit_root_heap_word_store_on_block, emit_root_nanbox_store_on_block, - emit_scalar_aware_store_gated_on_pointerness, emit_write_barrier, - emit_write_barrier_slot_generation_tested, emit_write_barrier_slot_on_block, - emit_write_barrier_slot_value_and_generation_tested, lower_array_super_init, - lower_event_emitter_async_resource_subclass_init, lower_event_emitter_subclass_init, - lower_node_stream_super_init, lower_stream_super_init, + emit_root_heap_word_store_on_block, emit_root_nanbox_store_for_expr, + emit_root_nanbox_store_on_block, emit_scalar_aware_store_gated_on_pointerness, + emit_write_barrier, emit_write_barrier_slot_generation_tested, + emit_write_barrier_slot_on_block, emit_write_barrier_slot_value_and_generation_tested, + lower_array_super_init, lower_event_emitter_async_resource_subclass_init, + lower_event_emitter_subclass_init, lower_node_stream_super_init, lower_stream_super_init, }; // Issue #1098 phase 3: the `FnCtx` definition stays in this trunk, but its diff --git a/crates/perry-codegen/src/expr/static_field_meta.rs b/crates/perry-codegen/src/expr/static_field_meta.rs index 421c055eb6..ca7cf2391c 100644 --- a/crates/perry-codegen/src/expr/static_field_meta.rs +++ b/crates/perry-codegen/src/expr/static_field_meta.rs @@ -13,7 +13,7 @@ use crate::rooting::{ }; use crate::types::{DOUBLE, I32, I64, PTR}; -use super::{emit_root_nanbox_store_on_block, lower_expr, nanbox_pointer_inline, FnCtx}; +use super::{emit_root_nanbox_store_for_expr, lower_expr, nanbox_pointer_inline, FnCtx}; /// The compiled symbols for `template`'s `static { … }` blocks, in declaration /// order (#685). @@ -73,7 +73,7 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { // (register_module_globals_as_gc_roots walks ctx.static_field_globals since the // 2026-07-02 audit fix; before that this comment was aspirational and the slot // was unrooted). - emit_root_nanbox_store_on_block(ctx.block(), &v, &g_ref); + emit_root_nanbox_store_for_expr(ctx, &v, &g_ref, value); } // v0.5.747: also register the static field in the runtime // CLASS_DYNAMIC_PROPS side-table so dynamic-dispatch reads diff --git a/crates/perry-codegen/src/expr/write_barrier.rs b/crates/perry-codegen/src/expr/write_barrier.rs index 01f8adf96e..f16302a85e 100644 --- a/crates/perry-codegen/src/expr/write_barrier.rs +++ b/crates/perry-codegen/src/expr/write_barrier.rs @@ -11,6 +11,10 @@ use crate::nanbox::double_literal; use crate::native_value::LoweredValue; use crate::types::{DOUBLE, I1, I16, I32, I64, I8}; +#[cfg(test)] +#[path = "generic_overhead_tests.rs"] +mod generic_overhead_tests; + /// `GC_LAYOUT_STATE_MASK | GC_OBJ_TYPED_LAYOUT_INTACT` (`0xD000`) as a signed /// i16 — the emitted IR is textual, so the constant is written the way LLVM /// parses an i16 literal (mirrors `class_field_inline_guard`'s convention). @@ -329,6 +333,24 @@ pub(crate) fn emit_write_barrier_slot_value_and_generation_tested( ctx.current_block = done_idx; } +/// Use the same construction proof as precise local roots. A scalar cannot +/// introduce a new heap edge during incremental marking; the registered root +/// slot still receives the store, including overwrites of old heap values. +/// TypeScript annotations alone do not satisfy this proof. +pub(crate) fn emit_root_nanbox_store_for_expr( + ctx: &mut FnCtx<'_>, + value: &str, + root_slot: &str, + expr: &Expr, +) { + if super::expr_is_known_non_pointer_shadow_value(ctx, expr) { + // GC_STORE_AUDIT(ROOT): proven scalar in a registered mutable root. + ctx.block().store(DOUBLE, value, root_slot); + } else { + emit_root_nanbox_store_on_block(ctx.block(), value, root_slot); + } +} + pub(crate) fn emit_root_nanbox_store_on_block(blk: &mut LlBlock, value: &str, root_slot: &str) { // GC_STORE_AUDIT(ROOT): module-global slot registered as a mutable GC // root; the root-barrier call below covers incremental marking. diff --git a/crates/perry-codegen/src/stmt/let_stmt.rs b/crates/perry-codegen/src/stmt/let_stmt.rs index 288e799086..251f4bbd8a 100644 --- a/crates/perry-codegen/src/stmt/let_stmt.rs +++ b/crates/perry-codegen/src/stmt/let_stmt.rs @@ -8,7 +8,7 @@ use super::let_stmt_facts::{ use super::unused_expr::lower_unused_expr; use super::*; use crate::expr::{ - box_i1_for_compat_shadow, emit_root_nanbox_store_on_block, + box_i1_for_compat_shadow, emit_root_nanbox_store_for_expr, expr_produces_non_pointer_bits_by_construction, lower_expr_value, lower_expr_with_expected_type, unbox_str_handle, }; @@ -1167,7 +1167,7 @@ pub(crate) fn lower_let( if let Some(init_expr) = init { let v = lower_expr_with_expected_type(ctx, init_expr, Some(&refined_ty))?; let g_ref = format!("@{}", global_name); - emit_root_nanbox_store_on_block(ctx.block(), &v, &g_ref); + emit_root_nanbox_store_for_expr(ctx, &v, &g_ref, init_expr); // Buffer data-pointer slot: when the HIR facts identify a fresh // immutable u8 buffer, pre-compute the data base pointer (handle + diff --git a/crates/perry-transform/src/lib.rs b/crates/perry-transform/src/lib.rs index 26cdb1dddb..c6fcfc91e9 100644 --- a/crates/perry-transform/src/lib.rs +++ b/crates/perry-transform/src/lib.rs @@ -16,6 +16,7 @@ pub mod finally_inline; pub mod generator; pub mod i18n; pub mod inline; +mod local_copies; pub mod module_const_fold; pub mod prop_cse; mod source_spans; @@ -56,4 +57,7 @@ pub fn post_inline_cleanups(module: &mut perry_hir::Module) { closure_local_inline::run(module); field_push_local_bind::run(module); prop_cse::run(module); + // Let the shape-specific passes consume their bindings first, then remove + // plain copies before codegen attaches string-sharing and root barriers. + local_copies::run(module); } diff --git a/crates/perry-transform/src/local_copies.rs b/crates/perry-transform/src/local_copies.rs new file mode 100644 index 0000000000..5461ba4dcd --- /dev/null +++ b/crates/perry-transform/src/local_copies.rs @@ -0,0 +1,230 @@ +//! Remove copy bookkeeping before codegen turns it into observable runtime +//! calls (string sharing and incremental root shading). +//! +//! This first pass handles straight-line, synchronous function bodies. An +//! alias must copy an initialized, unwritten local, and itself have no writes. +//! Closure/class creation, control flow, TDZ preallocation, parameter defaults +//! and arguments objects reject the body. Unrecognized expression forms, +//! including with and LocalId-bearing intrinsics, also reject it. Constant +//! eval already lowered to ordinary local reads/writes follows the same rules. + +use std::collections::{HashMap, HashSet}; + +use perry_hir::types::LocalId; +use perry_hir::walker::{walk_expr_children, walk_expr_children_mut}; +use perry_hir::{Expr, Function, Module, Stmt}; + +pub fn run(module: &mut Module) { + // Retained function bodies can refer to a sibling's locals. Never change + // the storage named in their capture metadata, even for hand-built HIR. + let mut captured = HashSet::new(); + for f in &module.functions { + captured.extend(f.captures.iter().copied()); + } + for class in &module.classes { + for f in class + .constructor + .iter() + .chain(&class.methods) + .chain(&class.static_methods) + .chain(class.getters.iter().map(|(_, f)| f)) + .chain(class.setters.iter().map(|(_, f)| f)) + .chain(class.computed_members.iter().map(|m| &m.function)) + { + captured.extend(f.captures.iter().copied()); + } + } + // Module-init bindings are registered globals, not function-local copies. + for f in &mut module.functions { + loop { + let before = f.body.len(); + clean_function(f, &captured); + if f.body.len() == before { + break; + } + } + } +} + +#[derive(Default)] +struct Uses { + reads: HashSet, + writes: HashSet, +} + +fn inspect_expr(expr: &Expr, uses: &mut Uses) -> bool { + match expr { + Expr::LocalGet(id) => { + uses.reads.insert(*id); + } + Expr::LocalSet(id, _) | Expr::Update { id, .. } => { + uses.writes.insert(*id); + if matches!(expr, Expr::Update { .. }) { + uses.reads.insert(*id); + } + } + Expr::Undefined + | Expr::Null + | Expr::Bool(_) + | Expr::Number(_) + | Expr::Integer(_) + | Expr::String(_) + | Expr::WtfString(_) + | Expr::BigInt(_) + | Expr::GlobalGet(_) + | Expr::GlobalSet(_, _) + | Expr::FuncRef(_) + | Expr::ExternFuncRef { .. } + | Expr::This + | Expr::Binary { .. } + | Expr::Unary { .. } + | Expr::Compare { .. } + | Expr::Logical { .. } + | Expr::Conditional { .. } + | Expr::Sequence(_) + | Expr::TypeOf(_) + | Expr::Void(_) + | Expr::Call { .. } + | Expr::PropertyGet { .. } + | Expr::PropertySet { .. } + | Expr::IndexGet { .. } + | Expr::IndexSet { .. } + | Expr::Array(_) => {} + _ => return false, + } + let mut supported = true; + walk_expr_children(expr, &mut |e| supported &= inspect_expr(e, uses)); + supported +} + +fn clean_function(f: &mut Function, captured: &HashSet) { + if f.is_async + || f.is_generator + || !f.captures.is_empty() + || f.params.iter().any(|p| { + p.default.is_some() || p.arguments_object.is_some() || !p.decorators.is_empty() + }) + { + return; + } + let mut uses = Uses::default(); + let mut declared: HashSet<_> = f.params.iter().map(|p| p.id).collect(); + let mut mutable = HashSet::new(); + for stmt in &f.body { + let expr = match stmt { + Stmt::Let { + id, + mutable: m, + init, + .. + } => { + if !declared.insert(*id) { + return; + } + if *m { + mutable.insert(*id); + } + init.as_ref() + } + Stmt::Expr(e) | Stmt::Throw(e) => Some(e), + Stmt::Return(e) => e.as_ref(), + _ => return, + }; + if expr.is_some_and(|e| !inspect_expr(e, &mut uses)) { + return; + } + } + if !declared.is_disjoint(captured) { + return; + } + // Do not rely on the lowering pass having already inserted explicit TDZ + // boxes. Reject forward reads/writes before changing any declaration. + let mut available: HashSet<_> = f.params.iter().map(|p| p.id).collect(); + for stmt in &f.body { + let expr = match stmt { + Stmt::Let { init, .. } | Stmt::Return(init) => init.as_ref(), + Stmt::Expr(e) | Stmt::Throw(e) => Some(e), + _ => unreachable!(), + }; + let mut at_stmt = Uses::default(); + if let Some(expr) = expr { + inspect_expr(expr, &mut at_stmt); + } + if at_stmt + .reads + .union(&at_stmt.writes) + .any(|id| declared.contains(id) && !available.contains(id)) + { + return; + } + if let Stmt::Let { id, .. } = stmt { + available.insert(*id); + } + } + let mut initialized: HashSet<_> = f.params.iter().map(|p| p.id).collect(); + let mut aliases = HashMap::new(); + f.body.retain_mut(|stmt| { + // Rewrite only reads, in source order: earlier reads must retain TDZ + // behavior, and assignment targets must keep their original binding. + let expr = match stmt { + Stmt::Let { init, .. } | Stmt::Return(init) => init.as_mut(), + Stmt::Expr(e) | Stmt::Throw(e) => Some(e), + _ => unreachable!(), + }; + if let Some(expr) = expr { + rewrite_reads(expr, &aliases); + } + match stmt { + Stmt::Let { id, init, .. } => { + let alias = match init { + Some(Expr::LocalGet(src)) + if initialized.contains(src) + && !uses.writes.contains(src) + && !uses.writes.contains(id) => + { + Some(*src) + } + _ => None, + }; + let dead = !uses.reads.contains(id) + && !uses.writes.contains(id) + && init.as_ref().is_none_or(|e| inert(e, &initialized)); + initialized.insert(*id); + if let Some(src) = alias { + aliases.insert(*id, src); + false + } else { + !dead + } + } + Stmt::Expr(Expr::LocalSet(id, value)) => { + !(mutable.contains(id) + && initialized.contains(id) + && !uses.reads.contains(id) + && inert(value, &initialized)) + } + _ => true, + } + }); +} + +fn inert(expr: &Expr, initialized: &HashSet) -> bool { + match expr { + Expr::LocalGet(id) => initialized.contains(id), + Expr::Undefined | Expr::Null | Expr::Bool(_) | Expr::Number(_) | Expr::Integer(_) => true, + _ => false, + } +} + +fn rewrite_reads(expr: &mut Expr, aliases: &HashMap) { + if let Expr::LocalGet(id) = expr { + if let Some(src) = aliases.get(id) { + *id = *src; + } + } + walk_expr_children_mut(expr, &mut |e| rewrite_reads(e, aliases)); +} + +#[cfg(test)] +#[path = "local_copies_tests.rs"] +mod tests; diff --git a/crates/perry-transform/src/local_copies_tests.rs b/crates/perry-transform/src/local_copies_tests.rs new file mode 100644 index 0000000000..dd9e915337 --- /dev/null +++ b/crates/perry-transform/src/local_copies_tests.rs @@ -0,0 +1,225 @@ +use super::*; +use perry_hir::types::Type; +use perry_hir::{ArgumentsObjectMeta, Param}; + +fn function(body: Vec) -> Function { + Function { + id: 1, + name: "copies".into(), + type_params: vec![], + params: vec![Param { + id: 1, + name: "x".into(), + ty: Type::Any, + default: None, + decorators: vec![], + is_rest: false, + arguments_object: None, + }], + return_type: Type::Any, + body, + is_async: false, + is_generator: false, + is_strict: true, + is_exported: true, + captures: vec![], + decorators: vec![], + was_plain_async: false, + was_unrolled: false, + } +} + +fn alias(id: u32, src: u32) -> Stmt { + Stmt::Let { + id, + name: format!("v{id}"), + ty: Type::Any, + mutable: true, + init: Some(Expr::LocalGet(src)), + } +} + +fn ret(id: u32) -> Stmt { + Stmt::Return(Some(Expr::LocalGet(id))) +} + +fn set(id: u32, value: Expr) -> Stmt { + Stmt::Expr(Expr::LocalSet(id, Box::new(value))) +} + +fn optimize(f: Function) -> Function { + let mut module = Module::new("copies"); + module.functions.push(f); + run(&mut module); + module.functions.remove(0) +} + +fn unchanged(f: Function) { + let before = format!("{:?}", f.body); + assert_eq!(format!("{:?}", optimize(f).body), before); +} + +#[test] +fn transitive_aliases_become_the_original_value() { + let f = optimize(function(vec![ + alias(2, 1), + alias(3, 2), + alias(4, 3), + ret(4), + ])); + assert!(matches!( + f.body.as_slice(), + [Stmt::Return(Some(Expr::LocalGet(1)))] + )); +} + +#[test] +fn unread_assignments_and_their_declaration_disappear() { + let f = optimize(function(vec![ + alias(2, 1), + set(2, Expr::LocalGet(1)), + set(2, Expr::Number(3.0)), + ret(1), + ])); + assert!(matches!( + f.body.as_slice(), + [Stmt::Return(Some(Expr::LocalGet(1)))] + )); +} + +#[test] +fn source_or_alias_writes_keep_the_copy() { + unchanged(function(vec![ + alias(2, 1), + set(1, Expr::Number(3.0)), + ret(2), + ])); + unchanged(function(vec![ + alias(2, 1), + set(2, Expr::Number(3.0)), + ret(2), + ])); +} + +#[test] +fn discarded_assignments_keep_effectful_rhs_and_storage() { + let call = Expr::Call { + callee: Box::new(Expr::GlobalGet(99)), + args: vec![], + type_args: vec![], + byte_offset: 0, + }; + unchanged(function(vec![alias(2, 1), set(2, call), ret(1)])); + // An assignment nested in another expression also needs the declaration. + unchanged(function(vec![ + alias(2, 1), + Stmt::Expr(Expr::Void(Box::new(Expr::LocalSet( + 2, + Box::new(Expr::Number(3.0)), + )))), + ret(1), + ])); +} + +#[test] +fn unread_const_assignments_still_throw() { + let mut declaration = alias(2, 1); + if let Stmt::Let { mutable, .. } = &mut declaration { + *mutable = false; + } + unchanged(function(vec![ + declaration, + set(2, Expr::LocalGet(1)), + ret(1), + ])); +} + +#[test] +fn forward_reads_and_writes_keep_tdz_behavior() { + unchanged(function(vec![ + Stmt::Expr(Expr::LocalGet(2)), + alias(2, 1), + ret(2), + ])); + unchanged(function(vec![ + set(2, Expr::Number(3.0)), + alias(2, 1), + ret(1), + ])); + unchanged(function(vec![ + Stmt::PreallocateTdzBoxes(vec![2]), + alias(2, 1), + ret(2), + ])); +} + +#[test] +fn arguments_defaults_async_and_captures_are_excluded() { + let f = function(vec![alias(2, 1), ret(2)]); + let mut args = f.clone(); + args.params[0].arguments_object = Some(ArgumentsObjectMeta { + strict: false, + simple_parameters: true, + mapped_parameter_ids: vec![(0, 1)], + restricted_callee: false, + }); + unchanged(args); + let mut defaults = f.clone(); + defaults.params[0].default = Some(Expr::Number(3.0)); + unchanged(defaults); + let mut async_f = f.clone(); + async_f.is_async = true; + unchanged(async_f); + let mut generator = f.clone(); + generator.is_generator = true; + unchanged(generator); + let mut capture = f.clone(); + capture.captures.push(9); + unchanged(capture); + let mut module = Module::new("retained_capture"); + let mut sibling = function(vec![ret(2)]); + sibling.captures.push(2); + module.functions = vec![f.clone(), sibling]; + run(&mut module); + assert_eq!( + format!("{:?}", module.functions[0].body), + format!("{:?}", f.body) + ); +} + +#[test] +fn loops_and_local_id_intrinsics_are_excluded() { + unchanged(function(vec![ + alias(2, 1), + Stmt::While { + condition: Expr::Bool(false), + body: vec![ret(2)], + }, + ret(2), + ])); + unchanged(function(vec![ + alias(2, 1), + Stmt::Expr(Expr::ArrayPop(2)), + ret(2), + ])); +} + +#[test] +fn effectful_use_keeps_evaluation_order_but_loses_the_alias() { + let call = Expr::Call { + callee: Box::new(Expr::LocalGet(1)), + args: vec![Expr::LocalGet(2)], + type_args: vec![], + byte_offset: 17, + }; + let f = optimize(function(vec![alias(2, 1), Stmt::Return(Some(call))])); + assert_eq!(f.body.len(), 1); + let Stmt::Return(Some(Expr::Call { + args, byte_offset, .. + })) = &f.body[0] + else { + panic!() + }; + assert!(matches!(args.as_slice(), [Expr::LocalGet(1)])); + assert_eq!(*byte_offset, 17); +} diff --git a/test-files/test_gap_generic_function_overhead.ts b/test-files/test_gap_generic_function_overhead.ts new file mode 100644 index 0000000000..de65b12a41 --- /dev/null +++ b/test-files/test_gap_generic_function_overhead.ts @@ -0,0 +1,104 @@ +"use strict"; + +// Keep the small functions behind runtime dispatch so inlining cannot hide +// their alias bookkeeping or the closure-typed parameter call under test. +function identity(x: any): any { return x; } +function aliasOne(x: any): any { const y = x; return y; } +function aliasThree(x: any): any { const a = x; const b = a; const c = b; return c; } +function deadAssignments(x: any): any { let y = x; y = x; y = x; return x; } +function changedSource(x: any): any { const y = x; x = "changed"; return y; } +function changedAlias(x: any): any { let y = x; y = "changed"; return y; } +function capturedAlias(x: any): any { const y = x; return () => y; } +function appendedSource(x: any): any { const y = x; x += "-appended"; return y; } +function aliasAcrossCall(x: any, visit: () => void): any { const y = x; visit(); return y; } +const copies: any[] = [identity, aliasOne, aliasThree, deadAssignments, changedSource]; +const values: any[] = [0, -0, NaN, 17, true, null, undefined, + "a string longer than the inline string representation", 12345678901234567890n, + Symbol("value"), { value: 17 }, [1, 2, 3]]; +let copyFailures = 0; +for (let i = 0; i < copies.length; i++) { + for (let j = 0; j < values.length; j++) { + if (!Object.is(copies[i](values[j]), values[j])) copyFailures++; + } +} +console.log("copies", copyFailures, changedAlias("original"), capturedAlias(19)()); +console.log("string-copy", appendedSource("a heap string which must remain unchanged")); + +let effects = 0; +function effect(): any { effects++; return { effects }; } +function deadEffect(x: any): any { let y = x; y = effect(); return x; } +console.log("effects", deadEffect(7), effects); +function tdz(): void { + try { console.log(later); const later = 1; } + catch (e) { console.log("tdz", e instanceof ReferenceError); } +} +tdz(); +// Sloppy mapped arguments can change the source after its alias was copied. +const mapped = Function("x", "const y = x; arguments[0] = 99; return y;"); +console.log("mapped", mapped(7)); + +let sink: any = null; +function storeScalar(): any { sink = 3; return sink; } +function storeUnknown(value: any): any { sink = value; return sink; } +function storeDeclaredNumber(value: number): any { sink = value; return sink; } +const stores: any[] = [storeUnknown, storeDeclaredNumber]; +console.log("scalar", storeScalar()); +let storeFailures = 0; +for (let i = 0; i < stores.length; i++) { + for (let j = 0; j < values.length; j++) { + if (!Object.is(stores[i](values[j]), values[j])) storeFailures++; + } +} +console.log("stores", storeFailures); + +function invoke(callback: (x: any) => any, x: any): any { return callback(x); } +const dispatchers: any[] = [invoke]; +function churn(): number { + const keep: any[] = []; + for (let i = 0; i < 80; i++) keep.push({ i, text: "allocation-" + i, pad: [i] }); + return keep.length; +} +const strictCallback = function (this: any, x: any): any { + "use strict"; + churn(); + return [this === undefined, x]; +}; +const host: any = { + marker: "host", + run: function (this: any, callback: (x: any) => any): any { + const result = dispatchers[0](callback, 23); + return [result, this.marker]; + }, +}; +console.log("strict", JSON.stringify(host.run(strictCallback))); +const lexical: any = { + marker: "lexical", + make: function (this: any): any { return (x: any) => { churn(); return this.marker + x; }; }, +}; +console.log("arrow", JSON.stringify(host.run(lexical.make()))); +const bound = function (this: any, x: any): any { churn(); return this.marker + x; } + .bind({ marker: "bound" }); +console.log("bound", JSON.stringify(host.run(bound))); +const rest = function (this: any, ...xs: any[]): any { + return [this === undefined, xs.length, xs[0]]; +}; +console.log("rest", JSON.stringify(host.run(rest))); +const proxy = new Proxy(strictCallback, { + apply: function (target: any, receiver: any, args: any[]): any { + return [receiver === undefined, Reflect.apply(target, receiver, args)]; + }, +}); +console.log("proxy", JSON.stringify(host.run(proxy))); +try { host.run(function (x: any): any { churn(); throw new Error("callback-" + x); }); } +catch (e: any) { console.log("throw", e.message); } +console.log("after-throw", JSON.stringify(host.run(strictCallback))); +let stressFailures = 0; +const acrossCalls: any[] = [aliasAcrossCall]; +for (let i = 0; i < 40; i++) { + const item: any = { marker: "fresh-" + i, run: host.run }; + const kept = acrossCalls[0](item, churn); + if (kept !== item || kept.marker !== "fresh-" + i) stressFailures++; + const result = item.run(strictCallback); + if (result[0][0] !== true || result[0][1] !== 23 || result[1] !== item.marker) stressFailures++; +} +console.log("stress", stressFailures); From 34bdc50bb3e54ef11f8e48ede9a67cdabe3e1300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Mon, 14 Sep 2026 12:37:32 +0200 Subject: [PATCH 05/11] docs: add changelog for generic overhead reductions --- changelog.d/10264-generic-function-overhead.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 changelog.d/10264-generic-function-overhead.md diff --git a/changelog.d/10264-generic-function-overhead.md b/changelog.d/10264-generic-function-overhead.md new file mode 100644 index 0000000000..015a95414b --- /dev/null +++ b/changelog.d/10264-generic-function-overhead.md @@ -0,0 +1,11 @@ +Remove redundant local copies and unread inert assignments from eligible +straight-line synchronous functions before codegen emits string-sharing and +root-shading work. Global and static-field stores now omit incremental root +shading for values proven scalar by construction; unknown and heap values +retain their barriers. + +On the ARM64 instruction probes at the default LLVM `-Os` level, three local +aliases drop from 43 to 3 instructions, an alias live across a call from 70 to +54, and a constant global write from 11 to 6. These are static code counts, +not throughput measurements. Adds unit tests, Node-parity and moving-GC +coverage, and a reproducible instruction census. From 956875b824958aab2bc878d9f6d2e3d105782c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Mon, 14 Sep 2026 13:08:53 +0200 Subject: [PATCH 06/11] fix(compile): share constructor arity across all heritage forms --- .../10259-imported-default-ctor-arity.md | 10 +- .../src/codegen/artifact_context.rs | 2 + crates/perry-codegen/src/codegen/artifacts.rs | 4 + .../src/codegen/constructor_contracts.rs | 130 + .../perry-codegen/src/codegen/ctor_arity.rs | 14 +- .../src/codegen/emission_order_tests.rs | 1 + .../perry-codegen/src/codegen/entry/tests.rs | 1 + crates/perry-codegen/src/codegen/method.rs | 15 +- crates/perry-codegen/src/codegen/mod.rs | 3 + .../src/codegen/number_exactness_tests.rs | 1 + crates/perry-codegen/src/codegen/opts.rs | 4 + .../collectors/proven_this_routing_tests.rs | 1 + .../src/expr/array_push_guard_tests.rs | 1 + .../src/expr/class_field_barrier_tests.rs | 1 + .../class_method_arguments_object_tests.rs | 1 + .../src/expr/conforming_layout_note_tests.rs | 1 + .../src/expr/property_get/tests.rs | 1 + .../perry-codegen/src/expr/this_super_call.rs | 10 + crates/perry-codegen/src/lib.rs | 10 +- .../src/lower_call/alloc_hot_tests.rs | 1 + .../src/lower_call/field_init.rs | 31 + crates/perry-codegen/src/lower_call/mod.rs | 4 +- crates/perry-codegen/src/lower_call/new.rs | 4 + .../src/lower_call/new_error_init.rs | 11 + .../src/lower_call/typed_shape_bake_tests.rs | 1 + .../src/native_root_coverage/mod.rs | 1 + .../src/runtime_decls/objects.rs | 6 +- .../src/stmt/boxed_slot_no_root_tests.rs | 1 + .../src/stmt/class_field_loop_tests.rs | 1 + .../src/stmt/element_shape_loop_tests.rs | 1 + .../src/stmt/prealloc_module_global_tests.rs | 1 + .../src/temp_root_coverage/mod.rs | 1 + .../src/type_analysis/numeric/tests.rs | 1 + .../tests/app_window_config_options.rs | 1 + .../tests/argless_builtin_extra_args.rs | 1 + .../tests/class_field_store_pointer_test.rs | 1 + .../perry-codegen/tests/class_keys_gc_root.rs | 1 + .../tests/constructor_recursion.rs | 1 + .../tests/destructure_call_location.rs | 1 + .../tests/i64_spec_ternary_recursion.rs | 1 + .../tests/ios_platform_api_lowering.rs | 1 + .../tests/large_object_barriers.rs | 1 + .../tests/loop_safepoint_purity.rs | 1 + .../tests/macos_bundle_chdir_gate.rs | 1 + .../tests/native_proof_buffer_views.rs | 1 + .../tests/native_proof_regressions.rs | 1 + .../tests/node_test_mock_property_presence.rs | 1 + .../tests/perry_builtin_name_collision.rs | 1 + .../tests/release_boxes_lowering.rs | 1 + .../tests/scalar_replaced_slot_roots.rs | 1 + .../tests/shadow_slot_hygiene.rs | 1 + .../tests/static_symbol_hygiene.rs | 1 + .../tests/temp_root_operand_temporaries.rs | 1 + crates/perry-codegen/tests/typed_feedback.rs | 1 + .../typed_shape_declared_at_allocation.rs | 1 + .../tests/typed_shape_descriptor.rs | 1 + .../tests/typed_shape_descriptors.rs | 1 + crates/perry-runtime/src/error.rs | 16 +- .../src/object/class_constructors.rs | 70 +- .../src/object/field_get_set/enumeration.rs | 15 + .../object/field_get_set/enumeration_tests.rs | 15 + .../src/object/global_this/fetch_globals.rs | 9 +- .../src/commands/compile/object_cache.rs | 9 + .../object_cache/object_cache_tests.rs | 18 + .../src/commands/compile/run_pipeline.rs | 4307 +++++++++-------- .../issue_10258.rs | 166 +- .../issue_10258.stdout | 14 + 67 files changed, 2707 insertions(+), 2232 deletions(-) create mode 100644 crates/perry-codegen/src/codegen/constructor_contracts.rs create mode 100644 crates/perry/tests/source_graph_export_regressions/issue_10258.stdout diff --git a/changelog.d/10259-imported-default-ctor-arity.md b/changelog.d/10259-imported-default-ctor-arity.md index 1cc6dba602..42a3efdfc0 100644 --- a/changelog.d/10259-imported-default-ctor-arity.md +++ b/changelog.d/10259-imported-default-ctor-arity.md @@ -1 +1,9 @@ -Fix `new ImportedClass(args)` for an exported class with no own constructor whose `extends` clause is a runtime value (for example effect v4's `class SystemError extends Data.Error {}`). The defining module synthesizes a forwarding constructor with a fixed parameter band because the parent's arity is unknown there, but the imported-class metadata counted only the class's own (absent) constructor and declared it with zero parameters, so the importing module called it with `this` alone and the parent constructor never saw the arguments. Importers now derive the arity from the same rule as the synthesized constructor. This unblocks OpenCode's config loading, where effect's file-not-found `PlatformError` lost its reason and turned a missing optional config file into a fatal error (#10107). +Fix imported default constructors losing arguments for every heritage form, including effect v4's `class SystemError extends Data.Error {}`, a named import of a runtime parent, and cast expressions (#10258; supersedes the partial fix in #10259). + +The defining module emitted an eight-argument forwarding constructor when it could not resolve the parent, while importing modules declared the same symbol with zero arguments. Prepare every module's imports before code generation, resolve constructor contracts in the defining module's scope, and copy the single result to both emitted constructors/runtime registration and imported-class metadata. Real local and imported parent constructors retain their exact arity; the existing standalone/auto-optimize fallback used by Next.js wall 51 remains available. Producer contracts and imported counts are included in object-cache keys. + +The four-module regression uses output captured from Bun and checks LLVM declarations against definitions, including two-parameter real parents, three runtime arguments, named/namespace imports, getters, aliases, and subclasses declared by consumers. This restores the error fields needed for OpenCode's `Effect.catchReason("PlatformError", "NotFound", …)` handling of missing optional configuration files (#10107). + +The tagged-error wrapper probe also exposed three constructor-chain details: default Error forwarding now preserves its options argument and non-enumerable cause, compiler capture slots stay hidden from reflection, and public fields of a dynamically derived class become own properties after its parent runs. The regression compares the wrapper's keys and cause with Bun as well. + +Local construction follows the runtime parent too: `new SystemError(...)` inside its defining module must not mistake the final `Error` component of `Data.Error` for the native Error constructor. This preserves the nested reason used by `catchReason`, as well as a consumer's locally declared `class MyError extends Data.Error {}`. diff --git a/crates/perry-codegen/src/codegen/artifact_context.rs b/crates/perry-codegen/src/codegen/artifact_context.rs index bdc278dea7..48912c9b97 100644 --- a/crates/perry-codegen/src/codegen/artifact_context.rs +++ b/crates/perry-codegen/src/codegen/artifact_context.rs @@ -13,6 +13,7 @@ use super::opts::CrossModuleCtx; /// references after the pipeline has moved other fields into `CrossModuleCtx`. pub(super) struct OptsView<'a> { pub(super) import_function_prefixes: &'a HashMap, + pub(super) constructor_param_counts: &'a std::collections::BTreeMap, pub(super) imported_classes: &'a [super::opts::ImportedClass], pub(super) is_entry_module: bool, pub(super) non_entry_module_prefixes: &'a [String], @@ -28,6 +29,7 @@ pub(super) struct ModuleArtifactsCtx<'a> { pub strings: &'a mut StringPool, pub hir: &'a HirModule, pub import_function_prefixes: &'a HashMap, + pub constructor_param_counts: &'a std::collections::BTreeMap, pub imported_classes: &'a [super::opts::ImportedClass], pub is_entry_module: bool, pub non_entry_module_prefixes: &'a [String], diff --git a/crates/perry-codegen/src/codegen/artifacts.rs b/crates/perry-codegen/src/codegen/artifacts.rs index b94530f303..e5b96f6ba9 100644 --- a/crates/perry-codegen/src/codegen/artifacts.rs +++ b/crates/perry-codegen/src/codegen/artifacts.rs @@ -51,6 +51,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { hir, import_function_prefixes, imported_classes, + constructor_param_counts, is_entry_module, non_entry_module_prefixes, output_type, @@ -91,6 +92,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { let opts = OptsView { import_function_prefixes, imported_classes, + constructor_param_counts, is_entry_module, non_entry_module_prefixes, output_type, @@ -624,6 +626,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { class_table, imported_class_stubs, opts.imported_classes, + opts.constructor_param_counts, ); let found_params: Vec = (0..n) .map(|i| perry_hir::Param { @@ -1931,6 +1934,7 @@ pub(super) fn emit_module_artifacts(c: ModuleArtifactsCtx<'_>) -> Result<()> { class_table, imported_class_stubs, opts.imported_classes, + opts.constructor_param_counts, ) as u32; (name.clone(), n) }) diff --git a/crates/perry-codegen/src/codegen/constructor_contracts.rs b/crates/perry-codegen/src/codegen/constructor_contracts.rs new file mode 100644 index 0000000000..a297d232c4 --- /dev/null +++ b/crates/perry-codegen/src/codegen/constructor_contracts.rs @@ -0,0 +1,130 @@ +//! Resolve standalone constructor ABIs once in each defining module's scope. +//! The pipeline runs this after preparing every import route and before either +//! object-cache lookup or LLVM emission (#10258). + +use std::collections::{BTreeMap, BTreeSet, HashMap}; + +use super::ctor_arity::{context_free_ctor_param_count, UNRESOLVED_PARENT_FWD_ARITY}; +use super::opts::CompileOptions; + +type Symbol = (String, String); + +enum Contract { + Params(usize), + Parent(Symbol, usize), +} + +/// Populate both producer signatures and consumer declarations from one graph +/// of constructor contracts. Symbols use the canonical defining prefix/name; +/// local aliases and namespace keys only participate in scope lookup. +/// +/// Resolving imports first is essential: following a foreign class's bare +/// `extends_name` in the consumer can select an unrelated same-named parent. +/// A runtime heritage with no class binding keeps the existing 8-slot band; +/// a real parent constructor keeps its exact arity, including zero. +pub fn resolve_constructor_contracts<'a>( + modules: impl IntoIterator, +) { + let mut modules: Vec<_> = modules.into_iter().collect(); + let mut contracts = BTreeMap::new(); + for (prefix, module, opts) in &modules { + let mut locals: HashMap<_, _> = module + .classes + .iter() + .map(|class| (class.name.as_str(), class)) + .collect(); + for class in &module.classes { + for alias in &class.aliases { + locals.entry(alias.as_str()).or_insert(class); + } + } + let mut imports = HashMap::new(); + for imported in &opts.imported_classes { + imports.entry(imported.effective_name()).or_insert(imported); + } + for class in &module.classes { + let contract = if let Some(count) = context_free_ctor_param_count(class) { + Contract::Params(count) + } else { + let mut parent = class.extends_name.as_deref(); + let mut visited = BTreeSet::new(); + let mut contract = Contract::Params(UNRESOLVED_PARENT_FWD_ARITY); + while let Some(name) = parent { + if !visited.insert(name) { + break; + } + if let Some(local) = locals.get(name) { + if let Some(ctor) = &local.constructor { + contract = Contract::Params(ctor.params.len()); + break; + } + parent = local.extends_name.as_deref(); + } else if let Some(imported) = imports.get(name) { + contract = Contract::Parent( + (imported.source_prefix.clone(), imported.name.clone()), + imported.constructor_param_count, + ); + break; + } else { + break; + } + } + contract + }; + contracts.insert((prefix.clone(), class.name.clone()), contract); + } + } + + fn resolve( + symbol: &Symbol, + contracts: &BTreeMap, + resolved: &mut BTreeMap, + visiting: &mut BTreeSet, + ) -> usize { + if let Some(count) = resolved.get(symbol) { + return *count; + } + if !visiting.insert(symbol.clone()) { + // Cyclic heritage has no constructor-bearing ancestor. Keep the + // standalone fallback and, crucially, the same ABI on every edge. + return UNRESOLVED_PARENT_FWD_ARITY; + } + let count = match &contracts[symbol] { + Contract::Params(count) => *count, + Contract::Parent(parent, fallback) => { + if contracts.contains_key(parent) { + resolve(parent, contracts, resolved, visiting) + } else { + // Synthetic/native capabilities have no HIR producer in + // this graph and already carry their declared signature. + *fallback + } + } + }; + visiting.remove(symbol); + resolved.insert(symbol.clone(), count); + count + } + + let mut resolved = BTreeMap::new(); + for symbol in contracts.keys() { + resolve(symbol, &contracts, &mut resolved, &mut BTreeSet::new()); + } + for (prefix, module, opts) in &mut modules { + opts.constructor_param_counts = module + .classes + .iter() + .map(|class| { + let count = resolved[&(prefix.clone(), class.name.clone())]; + (class.name.clone(), count) + }) + .collect(); + for imported in &mut opts.imported_classes { + if let Some(count) = + resolved.get(&(imported.source_prefix.clone(), imported.name.clone())) + { + imported.constructor_param_count = *count; + } + } + } +} diff --git a/crates/perry-codegen/src/codegen/ctor_arity.rs b/crates/perry-codegen/src/codegen/ctor_arity.rs index 73917e63e2..4001fceb3e 100644 --- a/crates/perry-codegen/src/codegen/ctor_arity.rs +++ b/crates/perry-codegen/src/codegen/ctor_arity.rs @@ -4,7 +4,7 @@ //! Split out of `codegen/artifacts.rs` for the 2000-line file cap (#8204 took //! it to 2005). Pure code move — no logic change. -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; /// Positional forwarding band for a synthesized default ctor whose parent arity /// cannot be resolved while compiling the defining module (see the tail of @@ -13,12 +13,12 @@ pub const UNRESOLVED_PARENT_FWD_ARITY: usize = 8; /// The standalone-constructor arity of `class` when it can be decided from the /// class definition alone, without the defining module's class table or -/// imports. Importers use this to describe a class they did not compile, so it +/// imports. The source-graph constructor-contract resolver uses this, so it /// MUST agree with [`synthesized_ctor_param_count`] for every case it answers: /// an own constructor, a native parent, no heritage, and a heritage that is only /// a runtime value (`extends_expr` with no resolvable `extends_name`), which /// always synthesizes the fixed forwarding band. `None` means the arity depends -/// on the ancestor walk and callers keep their existing behaviour (#10258). +/// on the defining module's ancestor walk (#10258). pub fn context_free_ctor_param_count(class: &perry_hir::Class) -> Option { if let Some(c) = class.constructor.as_ref() { return Some(c.params.len()); @@ -53,7 +53,15 @@ pub(super) fn synthesized_ctor_param_count( class_table: &HashMap, imported_class_stubs: &[perry_hir::Class], imported_classes: &[super::opts::ImportedClass], + resolved_arities: &BTreeMap, ) -> usize { + // Source-graph builds resolve once, in the defining module's scope, and + // copy this exact contract to every import before hashing either object. + // Standalone/auto-optimize callers keep the existing ancestor walk below. + if let Some(count) = resolved_arities.get(&class.name) { + return *count; + } + if let Some(c) = class.constructor.as_ref() { return c.params.len(); } diff --git a/crates/perry-codegen/src/codegen/emission_order_tests.rs b/crates/perry-codegen/src/codegen/emission_order_tests.rs index 771b31ac4c..84111b9326 100644 --- a/crates/perry-codegen/src/codegen/emission_order_tests.rs +++ b/crates/perry-codegen/src/codegen/emission_order_tests.rs @@ -86,6 +86,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/codegen/entry/tests.rs b/crates/perry-codegen/src/codegen/entry/tests.rs index 10c0bdde44..3ffab742cd 100644 --- a/crates/perry-codegen/src/codegen/entry/tests.rs +++ b/crates/perry-codegen/src/codegen/entry/tests.rs @@ -21,6 +21,7 @@ fn entry_opts(output_type: &str) -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/codegen/method.rs b/crates/perry-codegen/src/codegen/method.rs index c38453e1f3..1c3451e7e6 100644 --- a/crates/perry-codegen/src/codegen/method.rs +++ b/crates/perry-codegen/src/codegen/method.rs @@ -787,6 +787,7 @@ pub(super) fn compile_method( // as uninitialized register values (read as NaN-boxed undefined). let is_constructor_method = method.name == format!("{}_constructor", class.name); if is_constructor_method { + crate::lower_call::defer_dynamic_derived_fields(&mut ctx, class); // #9043: a default-derived chain can reach a dynamic parent through a // constructor-free static ancestor (`Leaf -> Mid -> `). // Keep the owner of that dynamic edge so this standalone Leaf symbol @@ -1013,6 +1014,12 @@ pub(super) fn compile_method( .and_then(|p| ctx.locals.get(&p.id).cloned()) .map(|slot| ctx.block().load(DOUBLE, &slot)) .unwrap_or_else(|| undef_lit.clone()); + let options_box = method + .params + .get(1) + .and_then(|p| ctx.locals.get(&p.id).cloned()) + .map(|slot| ctx.block().load(DOUBLE, &slot)) + .unwrap_or_else(|| undef_lit.clone()); let this_box = ctx .this_stack .last() @@ -1021,8 +1028,12 @@ pub(super) fn compile_method( .unwrap_or_else(|| undef_lit.clone()); let blk = ctx.block(); blk.call_void( - "js_error_subclass_default_init", - &[(DOUBLE, &this_box), (DOUBLE, &msg_box)], + "js_error_subclass_default_init_with_options", + &[ + (DOUBLE, &this_box), + (DOUBLE, &msg_box), + (DOUBLE, &options_box), + ], ); } ("".to_string(), 0) diff --git a/crates/perry-codegen/src/codegen/mod.rs b/crates/perry-codegen/src/codegen/mod.rs index 8b09ca39a5..5b77c5e805 100644 --- a/crates/perry-codegen/src/codegen/mod.rs +++ b/crates/perry-codegen/src/codegen/mod.rs @@ -187,6 +187,8 @@ mod cjs_exports; mod clone_suffix_tests; mod closure; mod closure_collect; +mod constructor_contracts; +pub use constructor_contracts::resolve_constructor_contracts; mod ctor_arity; pub use ctor_arity::{context_free_ctor_param_count, UNRESOLVED_PARENT_FWD_ARITY}; #[cfg(test)] @@ -3628,6 +3630,7 @@ pub fn compile_module(hir: &HirModule, opts: CompileOptions) -> Result> hir, import_function_prefixes: &opts.import_function_prefixes, imported_classes: &opts.imported_classes, + constructor_param_counts: &opts.constructor_param_counts, is_entry_module: opts.is_entry_module, non_entry_module_prefixes: &opts.non_entry_module_prefixes, output_type: &opts.output_type, diff --git a/crates/perry-codegen/src/codegen/number_exactness_tests.rs b/crates/perry-codegen/src/codegen/number_exactness_tests.rs index 03c5825dd8..8aaebfdebb 100644 --- a/crates/perry-codegen/src/codegen/number_exactness_tests.rs +++ b/crates/perry-codegen/src/codegen/number_exactness_tests.rs @@ -45,6 +45,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/codegen/opts.rs b/crates/perry-codegen/src/codegen/opts.rs index 3de45d3620..0b243882c6 100644 --- a/crates/perry-codegen/src/codegen/opts.rs +++ b/crates/perry-codegen/src/codegen/opts.rs @@ -259,6 +259,10 @@ pub struct CompileOptions { /// carries the class HIR, the module prefix of its origin, and an /// optional local alias. pub imported_classes: Vec, + /// Defining-module constructor contracts, resolved across the prepared + /// source graph before cache lookup. Shared with all import declarations. + /// Empty for standalone codegen, which uses its local ancestor walk. + pub constructor_param_counts: std::collections::BTreeMap, /// Whole-program concrete method implementations eligible for the short /// trailing-spread direct-call lowering (#8772). Unlike `imported_classes`, /// this capability also flows from a consumer module back to a generic diff --git a/crates/perry-codegen/src/collectors/proven_this_routing_tests.rs b/crates/perry-codegen/src/collectors/proven_this_routing_tests.rs index 67be82a1af..1849263de4 100644 --- a/crates/perry-codegen/src/collectors/proven_this_routing_tests.rs +++ b/crates/perry-codegen/src/collectors/proven_this_routing_tests.rs @@ -56,6 +56,7 @@ fn ir_opts(is_entry: bool) -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/expr/array_push_guard_tests.rs b/crates/perry-codegen/src/expr/array_push_guard_tests.rs index 50cc970fd9..d566dd2921 100644 --- a/crates/perry-codegen/src/expr/array_push_guard_tests.rs +++ b/crates/perry-codegen/src/expr/array_push_guard_tests.rs @@ -60,6 +60,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/expr/class_field_barrier_tests.rs b/crates/perry-codegen/src/expr/class_field_barrier_tests.rs index db0634bf17..c4aaf66411 100644 --- a/crates/perry-codegen/src/expr/class_field_barrier_tests.rs +++ b/crates/perry-codegen/src/expr/class_field_barrier_tests.rs @@ -78,6 +78,7 @@ pub(super) fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/expr/class_method_arguments_object_tests.rs b/crates/perry-codegen/src/expr/class_method_arguments_object_tests.rs index 419e93b1d3..2a4f58a931 100644 --- a/crates/perry-codegen/src/expr/class_method_arguments_object_tests.rs +++ b/crates/perry-codegen/src/expr/class_method_arguments_object_tests.rs @@ -72,6 +72,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/expr/conforming_layout_note_tests.rs b/crates/perry-codegen/src/expr/conforming_layout_note_tests.rs index 650c977f58..7e27048575 100644 --- a/crates/perry-codegen/src/expr/conforming_layout_note_tests.rs +++ b/crates/perry-codegen/src/expr/conforming_layout_note_tests.rs @@ -52,6 +52,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/expr/property_get/tests.rs b/crates/perry-codegen/src/expr/property_get/tests.rs index de53c55661..824aee5e45 100644 --- a/crates/perry-codegen/src/expr/property_get/tests.rs +++ b/crates/perry-codegen/src/expr/property_get/tests.rs @@ -34,6 +34,7 @@ fn ir_opts(debug_locations: bool, module_source: Option<&str>) -> CompileOptions disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/expr/this_super_call.rs b/crates/perry-codegen/src/expr/this_super_call.rs index 6f9afcc045..d56a6e8c27 100644 --- a/crates/perry-codegen/src/expr/this_super_call.rs +++ b/crates/perry-codegen/src/expr/this_super_call.rs @@ -1638,6 +1638,16 @@ pub(crate) fn lower(ctx: &mut FnCtx<'_>, expr: &Expr) -> Result { &[(I64, &this_handle), (I64, &key_raw), (DOUBLE, msg_val)], ); } + if let Some(options) = lowered_args.get(1) { + let blk = ctx.block(); + let this_box = blk.load(DOUBLE, &this_slot); + let bits = blk.bitcast_double_to_i64(&this_box); + let handle = blk.and(I64, &bits, POINTER_MASK_I64); + blk.call_void( + "js_error_apply_cause_to_object", + &[(I64, &handle), (DOUBLE, options)], + ); + } } } else if let Some(ctor) = ctx .imported_class_ctors diff --git a/crates/perry-codegen/src/lib.rs b/crates/perry-codegen/src/lib.rs index 574f9e1a07..91ebfd8657 100644 --- a/crates/perry-codegen/src/lib.rs +++ b/crates/perry-codegen/src/lib.rs @@ -76,11 +76,11 @@ pub mod unit_cache; pub use codegen::{ compile_module, context_free_ctor_param_count, namespace_member_class_key, - namespace_member_func_key, namespace_member_var_key, resolve_target_triple, - short_spread_method_capabilities, user_function_symbol, AppMetadata, CompileOptions, - ExportedObjectLiteralCapability, FpContractMode, ImportedClass, ImportedObjectLiteral, - ImportedObjectLiteralMethod, NamespaceEntry, NamespaceEntryKind, ObjectLiteralMethodCandidate, - ShortSpreadMethodCandidate, + namespace_member_func_key, namespace_member_var_key, resolve_constructor_contracts, + resolve_target_triple, short_spread_method_capabilities, user_function_symbol, AppMetadata, + CompileOptions, ExportedObjectLiteralCapability, FpContractMode, ImportedClass, + ImportedObjectLiteral, ImportedObjectLiteralMethod, NamespaceEntry, NamespaceEntryKind, + ObjectLiteralMethodCandidate, ShortSpreadMethodCandidate, }; pub use collectors::CjsPreambleCensus; // #9843: the segment-view for-of matcher's counter. Exported so the diff --git a/crates/perry-codegen/src/lower_call/alloc_hot_tests.rs b/crates/perry-codegen/src/lower_call/alloc_hot_tests.rs index 21e2de8c2e..8da0b63824 100644 --- a/crates/perry-codegen/src/lower_call/alloc_hot_tests.rs +++ b/crates/perry-codegen/src/lower_call/alloc_hot_tests.rs @@ -75,6 +75,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/lower_call/field_init.rs b/crates/perry-codegen/src/lower_call/field_init.rs index 39d5f9da35..012acd8a75 100644 --- a/crates/perry-codegen/src/lower_call/field_init.rs +++ b/crates/perry-codegen/src/lower_call/field_init.rs @@ -13,6 +13,37 @@ use crate::expr::{lower_expr, FnCtx}; use crate::nanbox::{double_literal, POINTER_MASK_I64}; use crate::types::{DOUBLE, I32, I64, PTR}; +/// A runtime parent can create arbitrary properties before derived fields run. +/// Retire the allocator's public-field placeholders before entering that parent, +/// so DefineField later creates them in source order. Deletion revokes the old +/// shape; subsequent stores use their existing guarded/by-name fallback. Keep +/// capture/private slots intact: parent methods rely on their inherited layout. +pub(crate) fn defer_dynamic_derived_fields(ctx: &mut FnCtx, class: &perry_hir::Class) { + if class.extends_expr.is_none() || !ctx.scalar_ctor_target.is_empty() { + return; + } + let Some(this_slot) = ctx.this_stack.last().cloned() else { + return; + }; + for field in &class.fields { + if field.is_private || field.key_expr.is_some() || field.name.starts_with("__perry_cap_") { + continue; + } + let key_idx = ctx.strings.intern(&field.name); + let key_global = format!("@{}", ctx.strings.entry(key_idx).handle_global); + let blk = ctx.block(); + let key = blk.load(DOUBLE, &key_global); + // This is compiler-owned allocation state, before the user-visible + // derived-this binding becomes initialized at super(). + let this = blk.load(DOUBLE, &this_slot); + blk.call( + I32, + "js_object_delete_dynamic_value", + &[(DOUBLE, &this), (DOUBLE, &key)], + ); + } +} + /// The field name a constructor-prologue statement assigns from a plain /// parameter, or `None` if the statement is not of that shape. /// diff --git a/crates/perry-codegen/src/lower_call/mod.rs b/crates/perry-codegen/src/lower_call/mod.rs index e421f5024d..4874372745 100644 --- a/crates/perry-codegen/src/lower_call/mod.rs +++ b/crates/perry-codegen/src/lower_call/mod.rs @@ -153,7 +153,9 @@ pub(crate) use native::lower_native_method_call; // Re-export pub(crate) `new.rs` items consumed outside this module // (codegen.rs / expr.rs / stmt.rs) so `crate::lower_call::lower_new` // etc. keep resolving after the split. -pub(crate) use field_init::{apply_field_initializers_recursive, FieldInitMode}; +pub(crate) use field_init::{ + apply_field_initializers_recursive, defer_dynamic_derived_fields, FieldInitMode, +}; pub(crate) use new::{emit_class_capture_writeback, lower_new, lower_new_member_captured}; pub(crate) use new_ctor_args::{ bind_inline_constructor_params, restore_inline_constructor_scope, CaptureFill, diff --git a/crates/perry-codegen/src/lower_call/new.rs b/crates/perry-codegen/src/lower_call/new.rs index fade7668bc..744750c441 100644 --- a/crates/perry-codegen/src/lower_call/new.rs +++ b/crates/perry-codegen/src/lower_call/new.rs @@ -1153,6 +1153,7 @@ fn lower_new_impl_inner<'a>( crate::expr::root_inlined_ctor_pointer_locals(ctx, &ctor.params, &ctor.body); } + super::defer_dynamic_derived_fields(ctx, class); // A dynamic parent constructor owns the fields above its registered edge. // Every local class from the edge owner through the leaf is derived, so // their fields run only after that runtime `super(...args)` returns. @@ -1503,6 +1504,9 @@ fn lower_new_impl_inner<'a>( .unwrap_or(false); if !found_inherited_ctor && !imported_ctor_has_body_or_fields + // A member such as Data.Error names a runtime parent, even when + // its final component looks like a builtin (#10258). + && !defer_to_dynamic_parent && super::new_error_init::emit_default_error_init(ctx, class, &lowered_args) { found_inherited_ctor = true; // skip the imported-ctor fallback below diff --git a/crates/perry-codegen/src/lower_call/new_error_init.rs b/crates/perry-codegen/src/lower_call/new_error_init.rs index 7f529c8e3a..cd7073c2e8 100644 --- a/crates/perry-codegen/src/lower_call/new_error_init.rs +++ b/crates/perry-codegen/src/lower_call/new_error_init.rs @@ -34,6 +34,17 @@ pub(super) fn emit_default_error_init( let mut cur = class.extends_name.clone(); let mut depth = 0usize; while let Some(pname) = cur { + // A foreign default constructor owns its entire super chain. In + // particular, `MemberSub extends ImportedSystemError` must invoke + // the imported forwarding constructor, not skip it because its stub + // eventually names `Error` (#10258). + if ctx + .imported_class_ctors + .get(&pname) + .is_some_and(|ctor| ctor.stops_constructor_walk()) + { + return false; + } if matches!( pname.as_str(), "Error" diff --git a/crates/perry-codegen/src/lower_call/typed_shape_bake_tests.rs b/crates/perry-codegen/src/lower_call/typed_shape_bake_tests.rs index f143848de3..8a8b294d50 100644 --- a/crates/perry-codegen/src/lower_call/typed_shape_bake_tests.rs +++ b/crates/perry-codegen/src/lower_call/typed_shape_bake_tests.rs @@ -130,6 +130,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/native_root_coverage/mod.rs b/crates/perry-codegen/src/native_root_coverage/mod.rs index d4e6ba1852..0b61bebb79 100644 --- a/crates/perry-codegen/src/native_root_coverage/mod.rs +++ b/crates/perry-codegen/src/native_root_coverage/mod.rs @@ -133,6 +133,7 @@ pub(crate) fn ir_opts(target: &str, is_entry: bool) -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/runtime_decls/objects.rs b/crates/perry-codegen/src/runtime_decls/objects.rs index f35aa1b628..7362967250 100644 --- a/crates/perry-codegen/src/runtime_decls/objects.rs +++ b/crates/perry-codegen/src/runtime_decls/objects.rs @@ -123,7 +123,11 @@ pub fn declare_phase_b_objects(module: &mut LlModule) { // #6469/#9440: spec default Error-init for the synthesized standalone ctor // of a no-own-ctor `class X extends Error {}` (this, message). `name` // remains inherited from the terminating Error-family prototype. - module.declare_function("js_error_subclass_default_init", VOID, &[DOUBLE, DOUBLE]); + module.declare_function( + "js_error_subclass_default_init_with_options", + VOID, + &[DOUBLE, DOUBLE, DOUBLE], + ); module.declare_function( "js_object_set_field_by_name_nonconfigurable", VOID, diff --git a/crates/perry-codegen/src/stmt/boxed_slot_no_root_tests.rs b/crates/perry-codegen/src/stmt/boxed_slot_no_root_tests.rs index 3b3d8ef906..055c556e7b 100644 --- a/crates/perry-codegen/src/stmt/boxed_slot_no_root_tests.rs +++ b/crates/perry-codegen/src/stmt/boxed_slot_no_root_tests.rs @@ -42,6 +42,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/stmt/class_field_loop_tests.rs b/crates/perry-codegen/src/stmt/class_field_loop_tests.rs index 77c232353a..a60d788703 100644 --- a/crates/perry-codegen/src/stmt/class_field_loop_tests.rs +++ b/crates/perry-codegen/src/stmt/class_field_loop_tests.rs @@ -51,6 +51,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/stmt/element_shape_loop_tests.rs b/crates/perry-codegen/src/stmt/element_shape_loop_tests.rs index 21d37695bb..82dfe1fb06 100644 --- a/crates/perry-codegen/src/stmt/element_shape_loop_tests.rs +++ b/crates/perry-codegen/src/stmt/element_shape_loop_tests.rs @@ -41,6 +41,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/stmt/prealloc_module_global_tests.rs b/crates/perry-codegen/src/stmt/prealloc_module_global_tests.rs index 3b990bd6ff..c15aca690e 100644 --- a/crates/perry-codegen/src/stmt/prealloc_module_global_tests.rs +++ b/crates/perry-codegen/src/stmt/prealloc_module_global_tests.rs @@ -59,6 +59,7 @@ pub(super) fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/temp_root_coverage/mod.rs b/crates/perry-codegen/src/temp_root_coverage/mod.rs index d46ad2ce0a..fb7d55edf1 100644 --- a/crates/perry-codegen/src/temp_root_coverage/mod.rs +++ b/crates/perry-codegen/src/temp_root_coverage/mod.rs @@ -69,6 +69,7 @@ pub(crate) fn entry_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/src/type_analysis/numeric/tests.rs b/crates/perry-codegen/src/type_analysis/numeric/tests.rs index 5cb2bcfce0..3e9d371f3d 100644 --- a/crates/perry-codegen/src/type_analysis/numeric/tests.rs +++ b/crates/perry-codegen/src/type_analysis/numeric/tests.rs @@ -31,6 +31,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/app_window_config_options.rs b/crates/perry-codegen/tests/app_window_config_options.rs index 1c141060da..68a8c4accf 100644 --- a/crates/perry-codegen/tests/app_window_config_options.rs +++ b/crates/perry-codegen/tests/app_window_config_options.rs @@ -31,6 +31,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/argless_builtin_extra_args.rs b/crates/perry-codegen/tests/argless_builtin_extra_args.rs index d447938513..f206f067e6 100644 --- a/crates/perry-codegen/tests/argless_builtin_extra_args.rs +++ b/crates/perry-codegen/tests/argless_builtin_extra_args.rs @@ -28,6 +28,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/class_field_store_pointer_test.rs b/crates/perry-codegen/tests/class_field_store_pointer_test.rs index 9bc5a82c01..09266057c2 100644 --- a/crates/perry-codegen/tests/class_field_store_pointer_test.rs +++ b/crates/perry-codegen/tests/class_field_store_pointer_test.rs @@ -37,6 +37,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/class_keys_gc_root.rs b/crates/perry-codegen/tests/class_keys_gc_root.rs index 91f0b6130c..4eb3ebd96d 100644 --- a/crates/perry-codegen/tests/class_keys_gc_root.rs +++ b/crates/perry-codegen/tests/class_keys_gc_root.rs @@ -46,6 +46,7 @@ fn entry_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/constructor_recursion.rs b/crates/perry-codegen/tests/constructor_recursion.rs index bc0b09f75e..091fdc72f0 100644 --- a/crates/perry-codegen/tests/constructor_recursion.rs +++ b/crates/perry-codegen/tests/constructor_recursion.rs @@ -21,6 +21,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/destructure_call_location.rs b/crates/perry-codegen/tests/destructure_call_location.rs index 5d72103970..f2a6eccf54 100644 --- a/crates/perry-codegen/tests/destructure_call_location.rs +++ b/crates/perry-codegen/tests/destructure_call_location.rs @@ -38,6 +38,7 @@ fn base_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/i64_spec_ternary_recursion.rs b/crates/perry-codegen/tests/i64_spec_ternary_recursion.rs index 820af0e713..e1f1f3ad68 100644 --- a/crates/perry-codegen/tests/i64_spec_ternary_recursion.rs +++ b/crates/perry-codegen/tests/i64_spec_ternary_recursion.rs @@ -38,6 +38,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/ios_platform_api_lowering.rs b/crates/perry-codegen/tests/ios_platform_api_lowering.rs index 10da70c325..e5e6a98e41 100644 --- a/crates/perry-codegen/tests/ios_platform_api_lowering.rs +++ b/crates/perry-codegen/tests/ios_platform_api_lowering.rs @@ -23,6 +23,7 @@ fn options(target: Option<&str>) -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/large_object_barriers.rs b/crates/perry-codegen/tests/large_object_barriers.rs index 0538054624..bb4228a1e5 100644 --- a/crates/perry-codegen/tests/large_object_barriers.rs +++ b/crates/perry-codegen/tests/large_object_barriers.rs @@ -21,6 +21,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/loop_safepoint_purity.rs b/crates/perry-codegen/tests/loop_safepoint_purity.rs index 8697585c03..51a781a999 100644 --- a/crates/perry-codegen/tests/loop_safepoint_purity.rs +++ b/crates/perry-codegen/tests/loop_safepoint_purity.rs @@ -59,6 +59,7 @@ fn entry_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/macos_bundle_chdir_gate.rs b/crates/perry-codegen/tests/macos_bundle_chdir_gate.rs index 29576286dd..6f143e3453 100644 --- a/crates/perry-codegen/tests/macos_bundle_chdir_gate.rs +++ b/crates/perry-codegen/tests/macos_bundle_chdir_gate.rs @@ -27,6 +27,7 @@ fn entry_opts(target: Option<&str>) -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/native_proof_buffer_views.rs b/crates/perry-codegen/tests/native_proof_buffer_views.rs index b68132c66b..e937b43bc9 100644 --- a/crates/perry-codegen/tests/native_proof_buffer_views.rs +++ b/crates/perry-codegen/tests/native_proof_buffer_views.rs @@ -52,6 +52,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/native_proof_regressions.rs b/crates/perry-codegen/tests/native_proof_regressions.rs index 69480ae817..77f1bdaf22 100644 --- a/crates/perry-codegen/tests/native_proof_regressions.rs +++ b/crates/perry-codegen/tests/native_proof_regressions.rs @@ -49,6 +49,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/node_test_mock_property_presence.rs b/crates/perry-codegen/tests/node_test_mock_property_presence.rs index 9b246f4bba..ea0c1737a6 100644 --- a/crates/perry-codegen/tests/node_test_mock_property_presence.rs +++ b/crates/perry-codegen/tests/node_test_mock_property_presence.rs @@ -24,6 +24,7 @@ fn ir_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/perry_builtin_name_collision.rs b/crates/perry-codegen/tests/perry_builtin_name_collision.rs index cd1fba42ab..fe20c5a00e 100644 --- a/crates/perry-codegen/tests/perry_builtin_name_collision.rs +++ b/crates/perry-codegen/tests/perry_builtin_name_collision.rs @@ -39,6 +39,7 @@ fn base_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/release_boxes_lowering.rs b/crates/perry-codegen/tests/release_boxes_lowering.rs index 62f1582cec..51e9631a71 100644 --- a/crates/perry-codegen/tests/release_boxes_lowering.rs +++ b/crates/perry-codegen/tests/release_boxes_lowering.rs @@ -38,6 +38,7 @@ fn entry_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/scalar_replaced_slot_roots.rs b/crates/perry-codegen/tests/scalar_replaced_slot_roots.rs index e78f586adb..c45aaeb6be 100644 --- a/crates/perry-codegen/tests/scalar_replaced_slot_roots.rs +++ b/crates/perry-codegen/tests/scalar_replaced_slot_roots.rs @@ -78,6 +78,7 @@ fn entry_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/shadow_slot_hygiene.rs b/crates/perry-codegen/tests/shadow_slot_hygiene.rs index a507c3f78d..216e373a6a 100644 --- a/crates/perry-codegen/tests/shadow_slot_hygiene.rs +++ b/crates/perry-codegen/tests/shadow_slot_hygiene.rs @@ -51,6 +51,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/static_symbol_hygiene.rs b/crates/perry-codegen/tests/static_symbol_hygiene.rs index 4f817a3a2a..16dca428f8 100644 --- a/crates/perry-codegen/tests/static_symbol_hygiene.rs +++ b/crates/perry-codegen/tests/static_symbol_hygiene.rs @@ -21,6 +21,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/temp_root_operand_temporaries.rs b/crates/perry-codegen/tests/temp_root_operand_temporaries.rs index 6bfb4f71b5..4bab6a9b6f 100644 --- a/crates/perry-codegen/tests/temp_root_operand_temporaries.rs +++ b/crates/perry-codegen/tests/temp_root_operand_temporaries.rs @@ -78,6 +78,7 @@ fn entry_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/typed_feedback.rs b/crates/perry-codegen/tests/typed_feedback.rs index 557ad75720..3c65cacfbc 100644 --- a/crates/perry-codegen/tests/typed_feedback.rs +++ b/crates/perry-codegen/tests/typed_feedback.rs @@ -105,6 +105,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/typed_shape_declared_at_allocation.rs b/crates/perry-codegen/tests/typed_shape_declared_at_allocation.rs index 1ca85a99d4..dc0936c4d9 100644 --- a/crates/perry-codegen/tests/typed_shape_declared_at_allocation.rs +++ b/crates/perry-codegen/tests/typed_shape_declared_at_allocation.rs @@ -46,6 +46,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/typed_shape_descriptor.rs b/crates/perry-codegen/tests/typed_shape_descriptor.rs index 4d84a99a40..8b24ed1291 100644 --- a/crates/perry-codegen/tests/typed_shape_descriptor.rs +++ b/crates/perry-codegen/tests/typed_shape_descriptor.rs @@ -21,6 +21,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-codegen/tests/typed_shape_descriptors.rs b/crates/perry-codegen/tests/typed_shape_descriptors.rs index 38dd52b960..e3a8221b36 100644 --- a/crates/perry-codegen/tests/typed_shape_descriptors.rs +++ b/crates/perry-codegen/tests/typed_shape_descriptors.rs @@ -24,6 +24,7 @@ fn empty_opts() -> CompileOptions { disable_buffer_fast_path: false, namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), + constructor_param_counts: Default::default(), imported_classes: Vec::new(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), diff --git a/crates/perry-runtime/src/error.rs b/crates/perry-runtime/src/error.rs index 8542c6b3dd..ed21857657 100644 --- a/crates/perry-runtime/src/error.rs +++ b/crates/perry-runtime/src/error.rs @@ -701,11 +701,19 @@ pub extern "C" fn js_error_apply_cause_to_object( if !opts.is_pointer() { return; } - let key = js_string_from_bytes(b"cause".as_ptr(), 5); - let key_f64 = crate::value::js_nanbox_string(key as i64); - let cause = crate::value::js_dyn_index_get(options, key_f64); + let scope = crate::gc::RuntimeHandleScope::new(); + let obj_h = scope.root_raw_mut_ptr(obj); + let options_h = scope.root_nanbox_f64(options); + let key_h = scope.root_string_ptr(js_string_from_bytes(b"cause".as_ptr(), 5)); + let key_f64 = + key_h.with_const_ptr(|key: *const StringHeader| crate::value::js_nanbox_string(key as i64)); + let cause = crate::value::js_dyn_index_get(options_h.get_nanbox_f64(), key_f64); if cause.to_bits() != TAG_UNDEFINED_BITS { - crate::object::js_object_set_field_by_name_nonenum(obj, key as *const StringHeader, cause); + obj_h.with_mut_ptr(|obj| { + key_h.with_const_ptr(|key| { + crate::object::js_object_set_field_by_name_nonenum(obj, key, cause); + }) + }); } } diff --git a/crates/perry-runtime/src/object/class_constructors.rs b/crates/perry-runtime/src/object/class_constructors.rs index 99c9443007..c515904985 100644 --- a/crates/perry-runtime/src/object/class_constructors.rs +++ b/crates/perry-runtime/src/object/class_constructors.rs @@ -1056,45 +1056,18 @@ unsafe fn default_error_init_for_implicit_chain( if !crate::object::extends_builtin_error(class_cid) { return; } - let scope = crate::gc::RuntimeHandleScope::new(); - let this_h = scope.root_nanbox_f64(crate::value::js_nanbox_pointer(inst as i64)); - // Read and root the forwarded value before stack capture can collect; the - // caller-owned argument slice itself is not a runtime handle. - let msg_h = if args_ptr.is_null() || args_len == 0 { - None - } else { - Some(scope.root_nanbox_f64(*args_ptr)) - }; - // #9410: the dynamic replay path is a construction site like any other, - // so the instance gets its own lazily-formatted `stack` here — before the - // message guard below, which returns early for `new X()` with no argument - // and would otherwise leave exactly those instances trace-less. - crate::error::js_error_subclass_capture_stack(this_h.get_nanbox_f64()); - let Some(msg_h) = msg_h else { - return; + let arg = |index| { + if args_ptr.is_null() || index >= args_len { + f64::from_bits(crate::value::TAG_UNDEFINED) + } else { + *args_ptr.add(index) + } }; - let msg = msg_h.get_nanbox_f64(); - if msg.to_bits() == crate::value::TAG_UNDEFINED { - return; - } - let msg_str = crate::value::js_jsvalue_to_string(msg); - if msg_str.is_null() { - return; - } - let msg_str_h = scope.root_string_ptr(msg_str); - let key_h = scope.root_string_ptr(crate::string::js_string_from_bytes( - b"message".as_ptr(), - b"message".len() as u32, - )); - let inst = crate::value::js_nanbox_get_pointer(this_h.get_nanbox_f64()) as *mut ObjectHeader; - msg_str_h.with_const_ptr::(|msg_str| { - let boxed = f64::from_bits( - crate::value::STRING_TAG | (msg_str as u64 & crate::value::POINTER_MASK), - ); - key_h.with_const_ptr::(|key| { - crate::object::js_object_set_field_by_name(inst, key, boxed); - }); - }); + js_error_subclass_default_init_with_options( + crate::value::js_nanbox_pointer(inst as i64), + arg(0), + arg(1), + ); } /// #6469: spec default Error-init, called from the SYNTHESIZED standalone @@ -1149,6 +1122,27 @@ pub unsafe extern "C" fn js_error_subclass_default_init(this_val: f64, msg: f64) } } +/// Default Error forwarding must preserve the options argument even when +/// message is undefined (effect's YieldableError -> Data.Error chain). +#[no_mangle] +pub unsafe extern "C" fn js_error_subclass_default_init_with_options( + this_val: f64, + msg: f64, + options: f64, +) { + let scope = crate::gc::RuntimeHandleScope::new(); + let this_h = scope.root_nanbox_f64(this_val); + let options_h = scope.root_nanbox_f64(options); + js_error_subclass_default_init(this_val, msg); + let inst = crate::value::js_nanbox_get_pointer(this_h.get_nanbox_f64()) as *mut ObjectHeader; + crate::error::js_error_apply_cause_to_object(inst, options_h.get_nanbox_f64()); +} + +#[cfg(feature = "keepalive-anchors")] +#[used] +static KEEP_JS_ERROR_SUBCLASS_DEFAULT_INIT_WITH_OPTIONS: unsafe extern "C" fn(f64, f64, f64) = + js_error_subclass_default_init_with_options; + /// Keepalive: generated code is the only caller (#6469). #[cfg(feature = "keepalive-anchors")] #[used] diff --git a/crates/perry-runtime/src/object/field_get_set/enumeration.rs b/crates/perry-runtime/src/object/field_get_set/enumeration.rs index a02efb07de..610c165113 100644 --- a/crates/perry-runtime/src/object/field_get_set/enumeration.rs +++ b/crates/perry-runtime/src/object/field_get_set/enumeration.rs @@ -1634,6 +1634,7 @@ pub(crate) fn is_internal_runtime_key_bytes(b: &[u8]) -> bool { || b == crate::weakref::WEAK_ENTRIES_KEY || b == crate::object::parent_static::CLASS_OBJECT_PARENT_KEY.as_bytes() || b == b"__perry_ctor_caps" + || is_class_capture_key(b) || b.starts_with(crate::node_stream::NATIVE_BASE_SUPER_PREFIX) || b.starts_with(b"__perry_computed_field_key_") || b == b"#" @@ -1645,6 +1646,20 @@ pub(crate) fn is_internal_runtime_key_bytes(b: &[u8]) -> bool { || b.starts_with(b"# bool { + let Some(suffix) = key.strip_prefix(b"__perry_cap_") else { + return false; + }; + let digits = suffix.iter().take_while(|b| b.is_ascii_digit()).count(); + digits > 0 + && (digits == suffix.len() + || (suffix.get(digits) == Some(&b'm') + && suffix.len() == digits + 13 + && suffix[digits + 1..].iter().all(u8::is_ascii_hexdigit))) +} + /// `&str` form of [`is_internal_runtime_key_bytes`]. #[inline] pub(crate) fn is_internal_runtime_key(s: &str) -> bool { diff --git a/crates/perry-runtime/src/object/field_get_set/enumeration_tests.rs b/crates/perry-runtime/src/object/field_get_set/enumeration_tests.rs index af92382f34..46f88bf0d4 100644 --- a/crates/perry-runtime/src/object/field_get_set/enumeration_tests.rs +++ b/crates/perry-runtime/src/object/field_get_set/enumeration_tests.rs @@ -2,6 +2,21 @@ use super::enumeration::*; +#[test] +fn class_capture_storage_is_hidden_without_hiding_user_lookalikes() { + for name in ["__perry_cap_7", "__perry_cap_13mdeadbeefcafe"] { + assert!(is_internal_runtime_key(name), "{name}"); + } + for name in [ + "__perry_cap_", + "__perry_cap_user", + "__perry_cap_7mine", + "__perry_cap_7mdeadbeefcafeg", + ] { + assert!(!is_internal_runtime_key(name), "{name}"); + } +} + #[cfg(test)] mod lazy_shadow_tests { use super::*; diff --git a/crates/perry-runtime/src/object/global_this/fetch_globals.rs b/crates/perry-runtime/src/object/global_this/fetch_globals.rs index f27c058eec..57693ddb65 100644 --- a/crates/perry-runtime/src/object/global_this/fetch_globals.rs +++ b/crates/perry-runtime/src/object/global_this/fetch_globals.rs @@ -768,7 +768,14 @@ pub unsafe extern "C" fn js_fetch_or_value_super( } else { undef }; - crate::object::class_constructors::js_error_subclass_default_init(this_box, msg); + let options = if !args_ptr.is_null() && args_len >= 2 { + *args_ptr.add(1) + } else { + undef + }; + crate::object::class_constructors::js_error_subclass_default_init_with_options( + this_box, msg, options, + ); return undef; } } diff --git a/crates/perry/src/commands/compile/object_cache.rs b/crates/perry/src/commands/compile/object_cache.rs index 6274c7a400..64e7f9f927 100644 --- a/crates/perry/src/commands/compile/object_cache.rs +++ b/crates/perry/src/commands/compile/object_cache.rs @@ -595,6 +595,15 @@ fn compute_object_cache_key_with_env( h.field("namespace_member_origin_names", &s); } + // Producer contracts change the emitted signature even when local HIR is + // unchanged (e.g. a foreign ancestor gained a constructor parameter). + if !opts.constructor_param_counts.is_empty() { + h.field( + "constructor_param_counts", + &format!("{:?}", opts.constructor_param_counts), + ); + } + // Imported classes — sort by name. Serialize every field that codegen // reads so a changed constructor arity or new method on a re-exported // class invalidates consumers. diff --git a/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs b/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs index ac61b79215..77662c1c25 100644 --- a/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs +++ b/crates/perry/src/commands/compile/object_cache/object_cache_tests.rs @@ -31,6 +31,7 @@ fn empty_opts() -> CompileOptions { namespace_imports: Vec::new(), namespace_member_nested: Vec::new(), imported_classes: Vec::new(), + constructor_param_counts: Default::default(), short_spread_method_candidates: std::sync::Arc::default(), object_literal_method_candidates: std::sync::Arc::default(), imported_enums: Vec::new(), @@ -1152,3 +1153,20 @@ fn pinned_build_id_parses_hex_and_ignores_garbage() { assert_eq!(super::pinned_build_id(Some(String::new())), None); assert_eq!(super::pinned_build_id(None), None); } + +#[test] +fn key_changes_with_defining_constructor_contract() { + let mut opts = empty_opts(); + let previous = compute_object_cache_key(&opts, 123, "same-version"); + opts.constructor_param_counts.insert("Child".into(), 2); + let resolved = compute_object_cache_key(&opts, 123, "same-version"); + assert_ne!( + previous, resolved, + "invalidate objects predating the contract pass" + ); + opts.constructor_param_counts.insert("Child".into(), 8); + assert_ne!( + resolved, + compute_object_cache_key(&opts, 123, "same-version") + ); +} diff --git a/crates/perry/src/commands/compile/run_pipeline.rs b/crates/perry/src/commands/compile/run_pipeline.rs index 1016b348c3..211fbef1a9 100644 --- a/crates/perry/src/commands/compile/run_pipeline.rs +++ b/crates/perry/src/commands/compile/run_pipeline.rs @@ -293,20 +293,12 @@ fn imported_class_from_hir( local_alias, namespace: None, source_prefix, - // #10258: must match the arity of the standalone constructor the - // defining module emits. A class with no own constructor whose parent - // is only a runtime value synthesizes a fixed forwarding band; counting - // just the (absent) own constructor declared it as 0 params here, so - // `new ImportedClass(args)` passed only `this` and the parent ran - // without its arguments. - constructor_param_count: perry_codegen::context_free_ctor_param_count(class) - .unwrap_or_else(|| { - class - .constructor - .as_ref() - .map(|ctor| ctor.params.len()) - .unwrap_or(0) - }), + // Filled from the defining module's constructor contract after all + // import routes have been prepared, before cache lookup or codegen. + constructor_param_count: class + .constructor + .as_ref() + .map_or(0, |ctor| ctor.params.len()), has_own_constructor: class.constructor.is_some(), constructor_has_rest: class .constructor @@ -3141,105 +3133,86 @@ pub fn run_with_parse_cache( .build() .map_err(|error| anyhow!("failed to create module codegen pool: {error}"))?; let module_limiter = ModuleCodegenLimiter::new(module_jobs); - let compile_results: Vec> = module_pool.install(|| { - ctx.native_modules.par_iter().map(|(path, hir_module)| { - let _permit = - module_limiter.acquire(module_codegen_is_exclusive(path, hir_module)); - let _completion = ModuleCodegenCompletion { - completed: &codegen_modules_completed, - total: total_codegen_modules, - started: codegen_started, - enabled: codegen_progress_enabled, - }; - // Compile this module to LLVM IR (or .ll text in bitcode-link mode). - // Linking builds return an artifact for the linker. `--no-link` - // writes each cold object in this worker as soon as it is ready so - // a large graph does not retain every object byte until all module - // jobs finish. - let codegen_index = codegen_modules_started.fetch_add(1, Ordering::Relaxed) + 1; - progress.record(ProgressSnapshot { - stage: "codegen", - module_path: Some(path), - module_name: Some(&hir_module.name), - visited: Some(codegen_index), - total: Some(total_codegen_modules), - collected: Some(total_codegen_modules), - ..Default::default() - }); - let is_entry = path == &entry_path; - // Compute the prefix list of non-entry modules so the - // entry main can call each `__init` in order. - // The prefix derivation must match what - // `perry_codegen::compile_module` does internally - // (sanitize(hir.name)) so the symbols match. LLVM IR - // identifiers cannot start with a digit, so prefix with - // `_` if the first character would be one (handles module - // names like `05_fibonacci.ts`). - let sanitize_name = |s: &str| -> String { - let mut out: String = s - .chars() - .map(|c| { - if c.is_ascii_alphanumeric() || c == '_' { - c - } else { - '_' - } - }) - .collect(); - if out - .chars() - .next() - .map(|c| c.is_ascii_digit()) - .unwrap_or(false) - { - out.insert(0, '_'); - } - out - }; - // CRITICAL: iterate `non_entry_module_names` (topologically - // sorted above) rather than `ctx.native_modules` — the latter - // is a `BTreeMap` and iterates in alphabetical - // path order, which silently reverses the dependency order - // for any project whose leaf modules sort after their - // dependents (e.g. `types/registry.ts` sorting after - // `connection.ts`). When that happens, a top-level - // `registerDefaultCodecs()` call in register-defaults.ts - // runs BEFORE types/registry.ts's init has set up the - // `REGISTRY_OIDS` global — the push-site writes to a stale - // (0.0-initialized) global while the read-site later loads - // from the real one. Symptom: registry appears empty to - // every later consumer even though primitives like - // `let registered = false` look shared (they only need - // storage, not init-order). Fixes GH #32. - let non_entry_module_prefixes: Vec = if is_entry { - non_entry_module_names - .iter() - .map(|name| sanitize_name(name)) - .collect() - } else { - Vec::new() - }; - // Issue #753: every module receives the program-wide set of - // Deferred module prefixes. The entry main filters these - // out of its eager init call sequence; non-entry modules - // ignore it. Empty when no module in the program is - // Deferred (i.e. no dynamic `import()` sites). - let deferred_module_prefixes: std::collections::HashSet = ctx - .native_modules - .iter() - .filter(|(_, m)| m.init_kind == perry_hir::ModuleInitKind::Deferred) - .map(|(_, m)| sanitize_name(&m.name)) - .collect(); - // Next.js wall 54 (part 2): `(absolute_path, prefix)` for every - // `.next/server/**` runtime module so the entry's `main` can record - // its `__init` address by path (`js_register_path_init`). Only the - // entry emits these; the runtime `require(absolutePath)` shim then - // triggers the matching module's lazy init on first load. - let nextjs_path_init_modules: Vec<(String, String)> = if is_entry { - ctx.native_modules + // Prepare the complete import graph before resolving constructor contracts. + // A consumer must use the defining module's context, even through barrels. + let prepared_modules: Result, String> = module_pool.install(|| { + ctx.native_modules + .par_iter() + .map(|(path, hir_module)| { + let is_entry = path == &entry_path; + // Compute the prefix list of non-entry modules so the + // entry main can call each `__init` in order. + // The prefix derivation must match what + // `perry_codegen::compile_module` does internally + // (sanitize(hir.name)) so the symbols match. LLVM IR + // identifiers cannot start with a digit, so prefix with + // `_` if the first character would be one (handles module + // names like `05_fibonacci.ts`). + let sanitize_name = |s: &str| -> String { + let mut out: String = s + .chars() + .map(|c| { + if c.is_ascii_alphanumeric() || c == '_' { + c + } else { + '_' + } + }) + .collect(); + if out + .chars() + .next() + .map(|c| c.is_ascii_digit()) + .unwrap_or(false) + { + out.insert(0, '_'); + } + out + }; + // CRITICAL: iterate `non_entry_module_names` (topologically + // sorted above) rather than `ctx.native_modules` — the latter + // is a `BTreeMap` and iterates in alphabetical + // path order, which silently reverses the dependency order + // for any project whose leaf modules sort after their + // dependents (e.g. `types/registry.ts` sorting after + // `connection.ts`). When that happens, a top-level + // `registerDefaultCodecs()` call in register-defaults.ts + // runs BEFORE types/registry.ts's init has set up the + // `REGISTRY_OIDS` global — the push-site writes to a stale + // (0.0-initialized) global while the read-site later loads + // from the real one. Symptom: registry appears empty to + // every later consumer even though primitives like + // `let registered = false` look shared (they only need + // storage, not init-order). Fixes GH #32. + let non_entry_module_prefixes: Vec = if is_entry { + non_entry_module_names + .iter() + .map(|name| sanitize_name(name)) + .collect() + } else { + Vec::new() + }; + // Issue #753: every module receives the program-wide set of + // Deferred module prefixes. The entry main filters these + // out of its eager init call sequence; non-entry modules + // ignore it. Empty when no module in the program is + // Deferred (i.e. no dynamic `import()` sites). + let deferred_module_prefixes: std::collections::HashSet = ctx + .native_modules .iter() - .filter(|(p, module)| { - module.init_kind == perry_hir::ModuleInitKind::Deferred + .filter(|(_, m)| m.init_kind == perry_hir::ModuleInitKind::Deferred) + .map(|(_, m)| sanitize_name(&m.name)) + .collect(); + // Next.js wall 54 (part 2): `(absolute_path, prefix)` for every + // `.next/server/**` runtime module so the entry's `main` can record + // its `__init` address by path (`js_register_path_init`). Only the + // entry emits these; the runtime `require(absolutePath)` shim then + // triggers the matching module's lazy init on first load. + let nextjs_path_init_modules: Vec<(String, String)> = if is_entry { + ctx.native_modules + .iter() + .filter(|(p, module)| { + module.init_kind == perry_hir::ModuleInitKind::Deferred || self::collect_modules::is_nextjs_runtime_module(p) // A `perry.compilePackages` module may be reachable // ONLY through a runtime-computed require (Next's @@ -3251,1092 +3224,598 @@ pub fn run_with_parse_cache( .compile_package_dirs .iter() .any(|dir| p.starts_with(dir)) - }) - .map(|(p, m)| { - (p.to_string_lossy().into_owned(), sanitize_name(&m.name)) - }) - .collect() - } else { - Vec::new() - }; - // Issue #753: prefixes of this module's static-import + - // re-export source modules (non-entry only — the entry's - // body is in `main`, not a `__init`). The wrapper at - // `__init` calls each dep's `__init` before - // dispatching to `__init_body`; this transitively - // initializes any Deferred dep reached only through this - // module's re-export chain. For Eager modules the calls - // short-circuit on the idempotent guard's first-write - // check (one load + cmp + cond_br each). - let module_init_deps: Vec = if is_entry { - Vec::new() - } else { - let mut deps: Vec = Vec::new(); - let mut seen: std::collections::HashSet = - std::collections::HashSet::new(); - let entry_prefix = ctx - .native_modules - .get(&entry_path) - .map(|m| sanitize_name(&m.name)); - let push_dep = |deps: &mut Vec, - seen: &mut std::collections::HashSet, - prefix: String| { - if Some(&prefix) == entry_prefix.as_ref() { - return; - } - if seen.insert(prefix.clone()) { - deps.push(prefix); - } + }) + .map(|(p, m)| (p.to_string_lossy().into_owned(), sanitize_name(&m.name))) + .collect() + } else { + Vec::new() }; - for import in &hir_module.imports { - // `is_deferred_require`: a function-local `require('S')` - // (lazy in Node). S must NOT chain into this module's init - // — it inits only when the require shim is actually called. - if import.is_dynamic - || import.type_only - || import.runtime_erased - || import.is_deferred_require - { - continue; - } - if let Some(resolved) = &import.resolved_path { - let resolved_path = PathBuf::from(resolved); - if let Some(src_mod) = ctx.native_modules.get(&resolved_path) { - push_dep(&mut deps, &mut seen, sanitize_name(&src_mod.name)); + // Issue #753: prefixes of this module's static-import + + // re-export source modules (non-entry only — the entry's + // body is in `main`, not a `__init`). The wrapper at + // `__init` calls each dep's `__init` before + // dispatching to `__init_body`; this transitively + // initializes any Deferred dep reached only through this + // module's re-export chain. For Eager modules the calls + // short-circuit on the idempotent guard's first-write + // check (one load + cmp + cond_br each). + let module_init_deps: Vec = if is_entry { + Vec::new() + } else { + let mut deps: Vec = Vec::new(); + let mut seen: std::collections::HashSet = + std::collections::HashSet::new(); + let entry_prefix = ctx + .native_modules + .get(&entry_path) + .map(|m| sanitize_name(&m.name)); + let push_dep = |deps: &mut Vec, + seen: &mut std::collections::HashSet, + prefix: String| { + if Some(&prefix) == entry_prefix.as_ref() { + return; } - } - } - for export in &hir_module.exports { - let src = match export { - perry_hir::Export::ExportAll { source } => Some(source.clone()), - perry_hir::Export::ReExport { source, .. } => Some(source.clone()), - perry_hir::Export::NamespaceReExport { source, .. } => { - Some(source.clone()) + if seen.insert(prefix.clone()) { + deps.push(prefix); } - perry_hir::Export::Named { .. } => None, }; - if let Some(src) = src { - if let Some((resolved_path, _)) = resolve_import_with_context( - &src, - path, - &ctx, - ) { + for import in &hir_module.imports { + // `is_deferred_require`: a function-local `require('S')` + // (lazy in Node). S must NOT chain into this module's init + // — it inits only when the require shim is actually called. + if import.is_dynamic + || import.type_only + || import.runtime_erased + || import.is_deferred_require + { + continue; + } + if let Some(resolved) = &import.resolved_path { + let resolved_path = PathBuf::from(resolved); if let Some(src_mod) = ctx.native_modules.get(&resolved_path) { push_dep(&mut deps, &mut seen, sanitize_name(&src_mod.name)); } } } - } - // Drop init-call back-edges (#6463). `topo_sort_non_entry_modules` - // breaks import cycles at the back-edge and the eager main - // sequence runs inits in that order — but the wrapper's nested - // dep-init calls re-derive the order dynamically at runtime. - // When the cycle member the sort placed FIRST runs, its broken - // edge to the member placed second pulled that module's BODY in - // early, before this module's own body had populated anything. - // Effect's web.ts died on this: find-my-way-ts - // internal/router.ts has `import * as Router from "../index.js"` - // used only in type positions (no `type` keyword, so it is a - // value edge), forming a cycle index ⇄ internal. The sort - // correctly placed internal first — matching node's ESM - // evaluation order from the entry — but internal's wrapper then - // called index's init, whose body copied - // `export const make = internal.make` while internal's global - // was still undefined. `FindMyWay.make` stayed undefined - // forever: "TypeError: value is not a function" at - // Layer.launch. Keeping only forward edges (dep positioned - // before this module) is exactly ESM's behavior of skipping a - // module already on the evaluation stack. A dep missing from - // the position map keeps its edge (conservative). - let init_pos: std::collections::HashMap = - non_entry_module_names + for export in &hir_module.exports { + let src = match export { + perry_hir::Export::ExportAll { source } => Some(source.clone()), + perry_hir::Export::ReExport { source, .. } => Some(source.clone()), + perry_hir::Export::NamespaceReExport { source, .. } => { + Some(source.clone()) + } + perry_hir::Export::Named { .. } => None, + }; + if let Some(src) = src { + if let Some((resolved_path, _)) = + resolve_import_with_context(&src, path, &ctx) + { + if let Some(src_mod) = ctx.native_modules.get(&resolved_path) { + push_dep(&mut deps, &mut seen, sanitize_name(&src_mod.name)); + } + } + } + } + // Drop init-call back-edges (#6463). `topo_sort_non_entry_modules` + // breaks import cycles at the back-edge and the eager main + // sequence runs inits in that order — but the wrapper's nested + // dep-init calls re-derive the order dynamically at runtime. + // When the cycle member the sort placed FIRST runs, its broken + // edge to the member placed second pulled that module's BODY in + // early, before this module's own body had populated anything. + // Effect's web.ts died on this: find-my-way-ts + // internal/router.ts has `import * as Router from "../index.js"` + // used only in type positions (no `type` keyword, so it is a + // value edge), forming a cycle index ⇄ internal. The sort + // correctly placed internal first — matching node's ESM + // evaluation order from the entry — but internal's wrapper then + // called index's init, whose body copied + // `export const make = internal.make` while internal's global + // was still undefined. `FindMyWay.make` stayed undefined + // forever: "TypeError: value is not a function" at + // Layer.launch. Keeping only forward edges (dep positioned + // before this module) is exactly ESM's behavior of skipping a + // module already on the evaluation stack. A dep missing from + // the position map keeps its edge (conservative). + let init_pos: std::collections::HashMap = non_entry_module_names .iter() .enumerate() .map(|(i, name)| (sanitize_name(name), i)) .collect(); - if let Some(&self_pos) = init_pos.get(&sanitize_name(&hir_module.name)) { - deps.retain(|dep| init_pos.get(dep).map_or(true, |&p| p < self_pos)); - } - deps - }; - // Build import → source-prefix table for cross-module - // ExternFuncRef calls. For each Named import in this - // module, look up the source module's HIR by resolved - // path and capture its name. The LLVM codegen uses this - // to generate `perry_fn___`. - let mut import_function_prefixes: std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #5621: ergonomic camelCase binding → snake_case - // `js__*` FFI symbol. A `perry.nativeLibrary` package may - // expose spec-faithful camelCase exports (`requestAdapter`) - // over its manifest symbols (`js_webgpu_request_adapter`). When - // a specifier matches a manifest function via the standard - // `js__` ⇒ camelCase derivation (rather than a - // byte-for-byte name match), we skip the wrapper registration - // below AND record the alias here so the call site - // (`lower_call`) rewrites the binding to its manifest symbol. - let mut import_function_ffi_aliases: std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #678: parallel to `import_function_prefixes`. When the - // import traverses a re-export rename (`export { default as render - // } from './render.js'`), the consumer sees `render` but the - // origin module emits the symbol with its own export name - // (`default`). This map captures the consumer-name → origin-name - // override so every `perry_fn___` construction site - // can pick the right suffix. Absent entries (the common case) - // mean no rename — the consumer name is the origin name. - let mut import_function_origin_names: - std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #678 followup: imports landing in `ModuleKind::Interpreted` - // (V8 fallback). The codegen probes this map BEFORE - // `perry_fn___` symbol formation and routes hits - // through `js_call_v8_export(specifier, name, args, argc)`. - // Pre-fix, V8-backed imports were silently dropped from - // `import_function_prefixes`, so the consumer's call - // emitted a bare `call double @` against an - // undefined symbol — every `import { render } from "ink"` - // (or similar where the package fell back to V8) failed at - // link time with `Undefined symbols: _perry_fn_..._render`. - let mut import_function_v8_specifiers: - std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #841: named-import → (submodule_key, exported_name) - // for the five recognized Node submodules with no perry-stdlib - // backing. Populated by a dedicated pass below; consumed by - // codegen's `Expr::ExternFuncRef` value-form catch-all. - let mut import_function_node_submodule: - std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #841 companion: local-namespace → submodule_key for - // `import * as ns from "node:"`. - let mut namespace_node_submodules: - std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #678 followup (namespace branch): local-namespace → - // V8 module specifier for `import * as ns from ""`. - // Populated in the V8-imports pass below at the same site that - // would otherwise no-op on `ImportSpecifier::Namespace`. Used - // by codegen's StaticMethodCall / namespace-member-call - // lowering to route `ns.member(args)` through - // `js_call_v8_export` when nothing else seeded - // `import_function_prefixes` for the member. - let mut namespace_v8_specifiers: - std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #680: per-namespace member resolution. Disambiguates - // `random.make` vs `tracer.make` when multiple namespaces - // export the same member name. Keyed by `(namespace_local, - // member_name)` → `source_prefix`. - let mut namespace_member_prefixes: std::collections::HashMap<(String, String), String> = - std::collections::HashMap::new(); - // Issue #5924 (companion to #680/#678): per-namespace origin-name - // resolution. `import_function_origin_names` is flat (keyed by - // bare member name), so when two namespaces imported into the - // same file both have a member with the same name and only ONE - // of them is a re-export rename, the rename's origin-name - // override clobbers the other namespace's (correct, unrenamed) - // suffix. Keyed by `(namespace_local, member_name)` → - // `origin_name`, mirroring `namespace_member_prefixes`. - let mut namespace_member_origin_names: - std::collections::HashMap<(String, String), String> = - std::collections::HashMap::new(); - let mut namespace_imports: Vec = Vec::new(); - // #7189: members of a namespace whose value is ITSELF a module - // namespace, from `export * as ns from "./m.ts"` in the imported - // module. They resolve to `@__perry_ns_` rather than to a - // `perry_fn___` symbol, because no such symbol exists — - // the member is a whole module, not a binding in one. - let mut namespace_member_nested: std::collections::HashSet<(String, String)> = - std::collections::HashSet::new(); - let mut imported_classes: Vec = Vec::new(); - let mut imported_enums: Vec<(String, Vec<(String, perry_hir::EnumValue)>)> = Vec::new(); - let mut imported_async_set: std::collections::HashSet = - std::collections::HashSet::new(); - let mut imported_param_counts: std::collections::HashMap = - std::collections::HashMap::new(); - let mut imported_return_types: std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #608 — set of imported function names whose source-side - // signature has a trailing `...rest` parameter. Built alongside - // `imported_param_counts` from the source module's - // `exported_func_has_rest` table; consulted by the cross-module - // call site in `lower_call.rs` to bundle trailing args into a - // single rest array. Sparse set (only `true` entries stored). - let mut imported_has_rest: std::collections::HashSet = - std::collections::HashSet::new(); - // #1816: imported functions whose trailing param is the synthesized - // `arguments` rest — the cross-module call must bundle ALL args into - // it, not just trailing. Built alongside `imported_has_rest`. - let mut imported_synthetic_arguments: std::collections::HashSet = - std::collections::HashSet::new(); - let mut imported_vars: std::collections::HashSet = - std::collections::HashSet::new(); - - // Issue #629: register namespace imports BEFORE the main - // resolution loop so unresolved-source bindings still flow - // to the codegen's `namespace_imports` set. Without this, - // the early `continue` for unresolved imports below means - // `import * as fsp from "node:fs/promises"` (when - // fs/promises has no perry-stdlib backing) leaves `fsp` - // off the namespace list — the catch-all in - // `Expr::ExternFuncRef` then returns TAG_TRUE and - // `typeof fsp === "boolean"`. Registering here lets the - // catch-all route through `js_unresolved_namespace_stub` - // (typeof "object", missing properties → undefined). - // - // Issue #684: skip WHOLE-DECL type-only imports - // (`import type * as X from "..."`). They're erased at - // runtime — the local binding never appears in any - // value-position expression, so registering it as a - // namespace would only widen the per-namespace member - // map below. Per-specifier type-only (`import { type Foo, - // bar }`) is still handled because the same import has - // value specifiers; the whole-decl flag is the one that - // makes the entire import a no-op. - for import in &hir_module.imports { - if import.type_only || import.runtime_erased { - continue; - } - for spec in &import.specifiers { - if let perry_hir::ImportSpecifier::Namespace { local } = spec { - if !namespace_imports.contains(local) { - namespace_imports.push(local.clone()); - } + if let Some(&self_pos) = init_pos.get(&sanitize_name(&hir_module.name)) { + deps.retain(|dep| init_pos.get(dep).map_or(true, |&p| p < self_pos)); } - } - } - - for import in &hir_module.imports { - if import.module_kind != perry_hir::ModuleKind::NativeCompiled { - continue; - } - let resolved_path = match &import.resolved_path { - Some(p) => p, - None => continue, - }; - let resolved_path_str = resolved_path.clone(); - let source_module = ctx - .native_modules - .iter() - .find(|(p, _)| p.to_string_lossy() == *resolved_path) - .map(|(_, m)| m); - let source_prefix = match &source_module { - Some(m) => sanitize_name(&m.name), - None => continue, + deps }; - // A whole-declaration `import type` contributes no runtime - // binding or init edge (#684), but a named class annotation - // may still carry useful producer-authored field metadata. - // Attach only that exact class when its defining module is - // already present in the value-reachable graph. Do not touch - // function/namespace maps, imported vars, native libraries, - // or module-init dependencies: those were the collision and - // phantom-load hazards #684 removed. - if import.type_only || import.runtime_erased { + // Build import → source-prefix table for cross-module + // ExternFuncRef calls. For each Named import in this + // module, look up the source module's HIR by resolved + // path and capture its name. The LLVM codegen uses this + // to generate `perry_fn___`. + let mut import_function_prefixes: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #5621: ergonomic camelCase binding → snake_case + // `js__*` FFI symbol. A `perry.nativeLibrary` package may + // expose spec-faithful camelCase exports (`requestAdapter`) + // over its manifest symbols (`js_webgpu_request_adapter`). When + // a specifier matches a manifest function via the standard + // `js__` ⇒ camelCase derivation (rather than a + // byte-for-byte name match), we skip the wrapper registration + // below AND record the alias here so the call site + // (`lower_call`) rewrites the binding to its manifest symbol. + let mut import_function_ffi_aliases: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #678: parallel to `import_function_prefixes`. When the + // import traverses a re-export rename (`export { default as render + // } from './render.js'`), the consumer sees `render` but the + // origin module emits the symbol with its own export name + // (`default`). This map captures the consumer-name → origin-name + // override so every `perry_fn___` construction site + // can pick the right suffix. Absent entries (the common case) + // mean no rename — the consumer name is the origin name. + let mut import_function_origin_names: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #678 followup: imports landing in `ModuleKind::Interpreted` + // (V8 fallback). The codegen probes this map BEFORE + // `perry_fn___` symbol formation and routes hits + // through `js_call_v8_export(specifier, name, args, argc)`. + // Pre-fix, V8-backed imports were silently dropped from + // `import_function_prefixes`, so the consumer's call + // emitted a bare `call double @` against an + // undefined symbol — every `import { render } from "ink"` + // (or similar where the package fell back to V8) failed at + // link time with `Undefined symbols: _perry_fn_..._render`. + let mut import_function_v8_specifiers: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #841: named-import → (submodule_key, exported_name) + // for the five recognized Node submodules with no perry-stdlib + // backing. Populated by a dedicated pass below; consumed by + // codegen's `Expr::ExternFuncRef` value-form catch-all. + let mut import_function_node_submodule: std::collections::HashMap< + String, + (String, String), + > = std::collections::HashMap::new(); + // Issue #841 companion: local-namespace → submodule_key for + // `import * as ns from "node:"`. + let mut namespace_node_submodules: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #678 followup (namespace branch): local-namespace → + // V8 module specifier for `import * as ns from ""`. + // Populated in the V8-imports pass below at the same site that + // would otherwise no-op on `ImportSpecifier::Namespace`. Used + // by codegen's StaticMethodCall / namespace-member-call + // lowering to route `ns.member(args)` through + // `js_call_v8_export` when nothing else seeded + // `import_function_prefixes` for the member. + let mut namespace_v8_specifiers: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #680: per-namespace member resolution. Disambiguates + // `random.make` vs `tracer.make` when multiple namespaces + // export the same member name. Keyed by `(namespace_local, + // member_name)` → `source_prefix`. + let mut namespace_member_prefixes: std::collections::HashMap< + (String, String), + String, + > = std::collections::HashMap::new(); + // Issue #5924 (companion to #680/#678): per-namespace origin-name + // resolution. `import_function_origin_names` is flat (keyed by + // bare member name), so when two namespaces imported into the + // same file both have a member with the same name and only ONE + // of them is a re-export rename, the rename's origin-name + // override clobbers the other namespace's (correct, unrenamed) + // suffix. Keyed by `(namespace_local, member_name)` → + // `origin_name`, mirroring `namespace_member_prefixes`. + let mut namespace_member_origin_names: std::collections::HashMap< + (String, String), + String, + > = std::collections::HashMap::new(); + let mut namespace_imports: Vec = Vec::new(); + // #7189: members of a namespace whose value is ITSELF a module + // namespace, from `export * as ns from "./m.ts"` in the imported + // module. They resolve to `@__perry_ns_` rather than to a + // `perry_fn___` symbol, because no such symbol exists — + // the member is a whole module, not a binding in one. + let mut namespace_member_nested: std::collections::HashSet<(String, String)> = + std::collections::HashSet::new(); + let mut imported_classes: Vec = Vec::new(); + let mut imported_enums: Vec<(String, Vec<(String, perry_hir::EnumValue)>)> = + Vec::new(); + let mut imported_async_set: std::collections::HashSet = + std::collections::HashSet::new(); + let mut imported_param_counts: std::collections::HashMap = + std::collections::HashMap::new(); + let mut imported_return_types: std::collections::HashMap< + String, + perry_hir::types::Type, + > = std::collections::HashMap::new(); + // Issue #608 — set of imported function names whose source-side + // signature has a trailing `...rest` parameter. Built alongside + // `imported_param_counts` from the source module's + // `exported_func_has_rest` table; consulted by the cross-module + // call site in `lower_call.rs` to bundle trailing args into a + // single rest array. Sparse set (only `true` entries stored). + let mut imported_has_rest: std::collections::HashSet = + std::collections::HashSet::new(); + // #1816: imported functions whose trailing param is the synthesized + // `arguments` rest — the cross-module call must bundle ALL args into + // it, not just trailing. Built alongside `imported_has_rest`. + let mut imported_synthetic_arguments: std::collections::HashSet = + std::collections::HashSet::new(); + let mut imported_vars: std::collections::HashSet = + std::collections::HashSet::new(); + + // Issue #629: register namespace imports BEFORE the main + // resolution loop so unresolved-source bindings still flow + // to the codegen's `namespace_imports` set. Without this, + // the early `continue` for unresolved imports below means + // `import * as fsp from "node:fs/promises"` (when + // fs/promises has no perry-stdlib backing) leaves `fsp` + // off the namespace list — the catch-all in + // `Expr::ExternFuncRef` then returns TAG_TRUE and + // `typeof fsp === "boolean"`. Registering here lets the + // catch-all route through `js_unresolved_namespace_stub` + // (typeof "object", missing properties → undefined). + // + // Issue #684: skip WHOLE-DECL type-only imports + // (`import type * as X from "..."`). They're erased at + // runtime — the local binding never appears in any + // value-position expression, so registering it as a + // namespace would only widen the per-namespace member + // map below. Per-specifier type-only (`import { type Foo, + // bar }`) is still handled because the same import has + // value specifiers; the whole-decl flag is the one that + // makes the entire import a no-op. + for import in &hir_module.imports { + if import.type_only || import.runtime_erased { + continue; + } for spec in &import.specifiers { - let perry_hir::ImportSpecifier::Named { imported, local } = spec else { - continue; - }; - let key = (resolved_path_str.clone(), imported.clone()); - let Some(class) = exported_classes.get(&key) else { - continue; - }; - let origin_path = all_module_exports - .get(&resolved_path_str) - .and_then(|exports| exports.get(imported)) - .cloned() - .unwrap_or_else(|| resolved_path_str.clone()); - let effective_prefix = if origin_path != resolved_path_str { - compute_module_prefix(&origin_path, &ctx.project_root) - } else { - source_prefix.clone() - }; - let class_prefix = canonical_class_source_prefix( - class, - &class_canonical_path, - &ctx.project_root, - &effective_prefix, - ); - let local_alias = (local != &class.name).then(|| local.clone()); - let duplicate = imported_classes.iter().any(|existing| { - existing.name == class.name - && existing.local_alias.as_ref() == local_alias.as_ref() - && existing.source_prefix == class_prefix - }); - if !duplicate { - imported_classes.push(imported_class_from_hir( - class, - class_prefix, - local_alias, - proven_this_methods_for_import( - class, - &class_proven_this_methods, - ), - proven_this_methods_for_import( - class, - &class_proven_this_tower_methods, - ), - )); + if let perry_hir::ImportSpecifier::Namespace { local } = spec { + if !namespace_imports.contains(local) { + namespace_imports.push(local.clone()); + } } } - continue; } - // PerryTS/storekit#1: when the import source is a package that - // declares `perry.nativeLibrary` (e.g. `@perryts/storekit`), - // its `.ts` source is a wrapper holding ambient `export - // declare function` signatures — the real implementation lives - // in the linked static library. There is no Perry wrapper - // symbol `perry_fn___` for the source to emit, so - // registering the FFI specifier in `import_function_prefixes` - // would route the caller through an undefined wrapper and - // fail at link time. The per-specifier skip below lets - // `lower_call.rs` fall through to the FFI-manifest path - // (consults `ctx.ffi_signatures`, emits the call against the - // FFI symbol declared in `package.json :: perry.nativeLibrary. - // functions` plus a matching `declare external`). - let native_library_for_import = ctx - .native_libraries - .iter() - .find(|nl| nl.module == import.source); - for spec in &import.specifiers { - // Handle namespace imports (import * as X). - // - // Issue #4872: a DEFAULT import of a compiled module that - // has NO `default` export gets the same treatment. The - // CJS wrap lowers every `require('X')` to `import _req_N - // from 'X'`; when X resolves to an ESM barrel with only - // named exports (rxjs's src/index.ts, uid's index.mjs) or - // to a type-only interface surface with no exports at all - // (nestjs dist `*.interface.js`), there is no - // `perry_fn___default` symbol for the consumer to - // bind — the old fall-through registered the local as a - // callable function import and the link died on - // `__perry_wrap_perry_fn___default`. Node's - // `require(esm)` semantics hand back the module namespace - // object, so route the local through the namespace - // machinery: member reads resolve per-export to origin - // symbols, and a whole-value read materializes the - // namespace object (empty for zero-export modules). - let namespace_like_local: Option<&String> = match spec { - perry_hir::ImportSpecifier::Namespace { local } => Some(local), - perry_hir::ImportSpecifier::Default { local } - if !all_module_exports - .get(&resolved_path_str) - .is_some_and(|exports| exports.contains_key("default")) => - { - Some(local) - } - _ => None, + for import in &hir_module.imports { + if import.module_kind != perry_hir::ModuleKind::NativeCompiled { + continue; + } + let resolved_path = match &import.resolved_path { + Some(p) => p, + None => continue, + }; + let resolved_path_str = resolved_path.clone(); + let source_module = ctx + .native_modules + .iter() + .find(|(p, _)| p.to_string_lossy() == *resolved_path) + .map(|(_, m)| m); + let source_prefix = match &source_module { + Some(m) => sanitize_name(&m.name), + None => continue, }; - if let Some(local) = namespace_like_local { - namespace_imports.push(local.clone()); - // Issue #6586: a namespace import of a CommonJS module - // whose `module.exports` value is itself the export - // (`module.exports = function equal(){}`, no - // `__esModule` marker) is TypeScript's - // esModuleInterop=false interop — `import * as equal - // from "fast-deep-equal"` binds `equal` to the whole - // `require()` result (the default export), so a DIRECT - // call `equal(a, b)` is a call OF that value. ajv's - // `lib/compile/resolve.ts` does exactly this for - // `fast-deep-equal` and `json-schema-traverse`, and - // fast-json-stringify pulls ajv in. The CJS wrap emits - // the value under the module's `default` symbol, but the - // namespace binding had no `import_function_prefixes` - // entry, so the direct call fell through to a bare - // `equal` extern and the link died with - // `Undefined symbols: "_equal"`. Wire the whole-value - // binding to the `default` export exactly like a Default - // specifier does below (member reads `ns.foo` are keyed - // per-namespace via `namespace_member_prefixes` and are - // unaffected). Only genuine namespace imports of a module - // that actually HAS a `default` export qualify — the - // #4872 default-import-of-a-named-only-barrel case that - // also lands here has no `default` and is skipped. - if matches!(spec, perry_hir::ImportSpecifier::Namespace { .. }) { - if let Some(default_origin_path) = all_module_exports + // A whole-declaration `import type` contributes no runtime + // binding or init edge (#684), but a named class annotation + // may still carry useful producer-authored field metadata. + // Attach only that exact class when its defining module is + // already present in the value-reachable graph. Do not touch + // function/namespace maps, imported vars, native libraries, + // or module-init dependencies: those were the collision and + // phantom-load hazards #684 removed. + if import.type_only || import.runtime_erased { + for spec in &import.specifiers { + let perry_hir::ImportSpecifier::Named { imported, local } = spec else { + continue; + }; + let key = (resolved_path_str.clone(), imported.clone()); + let Some(class) = exported_classes.get(&key) else { + continue; + }; + let origin_path = all_module_exports .get(&resolved_path_str) - .and_then(|exports| exports.get("default")) + .and_then(|exports| exports.get(imported)) .cloned() + .unwrap_or_else(|| resolved_path_str.clone()); + let effective_prefix = if origin_path != resolved_path_str { + compute_module_prefix(&origin_path, &ctx.project_root) + } else { + source_prefix.clone() + }; + let class_prefix = canonical_class_source_prefix( + class, + &class_canonical_path, + &ctx.project_root, + &effective_prefix, + ); + let local_alias = (local != &class.name).then(|| local.clone()); + let duplicate = imported_classes.iter().any(|existing| { + existing.name == class.name + && existing.local_alias.as_ref() == local_alias.as_ref() + && existing.source_prefix == class_prefix + }); + if !duplicate { + imported_classes.push(imported_class_from_hir( + class, + class_prefix, + local_alias, + proven_this_methods_for_import( + class, + &class_proven_this_methods, + ), + proven_this_methods_for_import( + class, + &class_proven_this_tower_methods, + ), + )); + } + } + continue; + } + // PerryTS/storekit#1: when the import source is a package that + // declares `perry.nativeLibrary` (e.g. `@perryts/storekit`), + // its `.ts` source is a wrapper holding ambient `export + // declare function` signatures — the real implementation lives + // in the linked static library. There is no Perry wrapper + // symbol `perry_fn___` for the source to emit, so + // registering the FFI specifier in `import_function_prefixes` + // would route the caller through an undefined wrapper and + // fail at link time. The per-specifier skip below lets + // `lower_call.rs` fall through to the FFI-manifest path + // (consults `ctx.ffi_signatures`, emits the call against the + // FFI symbol declared in `package.json :: perry.nativeLibrary. + // functions` plus a matching `declare external`). + let native_library_for_import = ctx + .native_libraries + .iter() + .find(|nl| nl.module == import.source); + + for spec in &import.specifiers { + // Handle namespace imports (import * as X). + // + // Issue #4872: a DEFAULT import of a compiled module that + // has NO `default` export gets the same treatment. The + // CJS wrap lowers every `require('X')` to `import _req_N + // from 'X'`; when X resolves to an ESM barrel with only + // named exports (rxjs's src/index.ts, uid's index.mjs) or + // to a type-only interface surface with no exports at all + // (nestjs dist `*.interface.js`), there is no + // `perry_fn___default` symbol for the consumer to + // bind — the old fall-through registered the local as a + // callable function import and the link died on + // `__perry_wrap_perry_fn___default`. Node's + // `require(esm)` semantics hand back the module namespace + // object, so route the local through the namespace + // machinery: member reads resolve per-export to origin + // symbols, and a whole-value read materializes the + // namespace object (empty for zero-export modules). + let namespace_like_local: Option<&String> = match spec { + perry_hir::ImportSpecifier::Namespace { local } => Some(local), + perry_hir::ImportSpecifier::Default { local } + if !all_module_exports + .get(&resolved_path_str) + .is_some_and(|exports| exports.contains_key("default")) => { - let default_prefix = compute_module_prefix( - &default_origin_path, - &ctx.project_root, - ); - let default_suffix = all_module_export_origin_names + Some(local) + } + _ => None, + }; + if let Some(local) = namespace_like_local { + namespace_imports.push(local.clone()); + // Issue #6586: a namespace import of a CommonJS module + // whose `module.exports` value is itself the export + // (`module.exports = function equal(){}`, no + // `__esModule` marker) is TypeScript's + // esModuleInterop=false interop — `import * as equal + // from "fast-deep-equal"` binds `equal` to the whole + // `require()` result (the default export), so a DIRECT + // call `equal(a, b)` is a call OF that value. ajv's + // `lib/compile/resolve.ts` does exactly this for + // `fast-deep-equal` and `json-schema-traverse`, and + // fast-json-stringify pulls ajv in. The CJS wrap emits + // the value under the module's `default` symbol, but the + // namespace binding had no `import_function_prefixes` + // entry, so the direct call fell through to a bare + // `equal` extern and the link died with + // `Undefined symbols: "_equal"`. Wire the whole-value + // binding to the `default` export exactly like a Default + // specifier does below (member reads `ns.foo` are keyed + // per-namespace via `namespace_member_prefixes` and are + // unaffected). Only genuine namespace imports of a module + // that actually HAS a `default` export qualify — the + // #4872 default-import-of-a-named-only-barrel case that + // also lands here has no `default` and is skipped. + if matches!(spec, perry_hir::ImportSpecifier::Namespace { .. }) { + if let Some(default_origin_path) = all_module_exports .get(&resolved_path_str) - .and_then(|m| m.get("default")) + .and_then(|exports| exports.get("default")) .cloned() - .unwrap_or_else(|| "default".to_string()); - import_function_prefixes - .entry(local.clone()) - .or_insert(default_prefix.clone()); - import_function_origin_names - .entry(local.clone()) - .or_insert(default_suffix.clone()); - // The metadata maps are keyed by - // (declaring-path, exported-name); the default - // is declared at `default_origin_path` under - // `default_suffix` (== "default" unless a - // re-export renamed it). - let key = (default_origin_path.clone(), default_suffix); - // A CJS `module.exports = ` becomes a - // var-shaped default: a value binding emitted as - // a zero-arg getter. A direct call must fetch the - // closure via that getter and THEN invoke it with - // the args (`js_closure_callN`), so mark the local - // as an imported var — otherwise the call site - // treats the getter's return value AS the call - // result and `equal(1, 1)` yields the function - // itself instead of `true`. Mirrors the - // Default-import var classification below. - if exported_var_names.contains(&key) - || exported_var_names.contains(&( - resolved_path_str.clone(), - "default".to_string(), - )) { - imported_vars.insert(local.clone()); - } - // A non-var-shaped default — a `module.exports = - // function foo(){}` static-function or a - // `module.exports = class Foo{}` — is called / - // instantiated through the direct - // `perry_fn___default` symbol, so it needs - // the same arity / rest / synthetic-arguments / - // return-type / async / class / enum metadata the - // Default specifier propagates below. Without it a - // rest-param default mis-bundles its trailing args - // and a class default has no ImportedClass entry - // (so `new ns()` can't resolve). Key everything by - // the namespace LOCAL, the name the consumer's - // ExternFuncRef carries. - if let Some(¶m_count) = exported_func_param_counts.get(&key) { - imported_param_counts.insert(local.clone(), param_count); - } - if exported_func_has_rest.get(&key).copied().unwrap_or(false) { - imported_has_rest.insert(local.clone()); - } - if exported_func_synthetic_arguments.contains(&key) { - imported_synthetic_arguments.insert(local.clone()); - } - if let Some(return_type) = exported_func_return_types.get(&key) { - imported_return_types.insert(local.clone(), return_type.clone()); - } - if exported_async_funcs.contains(&key) { - imported_async_set.insert(local.clone()); - } - if let Some(class) = exported_classes.get(&key) { - let class_prefix = canonical_class_source_prefix( - class, - &class_canonical_path, + let default_prefix = compute_module_prefix( + &default_origin_path, &ctx.project_root, - &default_prefix, ); - imported_classes.push(imported_class_from_hir( - class, - class_prefix, - Some(local.clone()), - proven_this_methods_for_import( + let default_suffix = all_module_export_origin_names + .get(&resolved_path_str) + .and_then(|m| m.get("default")) + .cloned() + .unwrap_or_else(|| "default".to_string()); + import_function_prefixes + .entry(local.clone()) + .or_insert(default_prefix.clone()); + import_function_origin_names + .entry(local.clone()) + .or_insert(default_suffix.clone()); + // The metadata maps are keyed by + // (declaring-path, exported-name); the default + // is declared at `default_origin_path` under + // `default_suffix` (== "default" unless a + // re-export renamed it). + let key = (default_origin_path.clone(), default_suffix); + // A CJS `module.exports = ` becomes a + // var-shaped default: a value binding emitted as + // a zero-arg getter. A direct call must fetch the + // closure via that getter and THEN invoke it with + // the args (`js_closure_callN`), so mark the local + // as an imported var — otherwise the call site + // treats the getter's return value AS the call + // result and `equal(1, 1)` yields the function + // itself instead of `true`. Mirrors the + // Default-import var classification below. + if exported_var_names.contains(&key) + || exported_var_names.contains(&( + resolved_path_str.clone(), + "default".to_string(), + )) + { + imported_vars.insert(local.clone()); + } + // A non-var-shaped default — a `module.exports = + // function foo(){}` static-function or a + // `module.exports = class Foo{}` — is called / + // instantiated through the direct + // `perry_fn___default` symbol, so it needs + // the same arity / rest / synthetic-arguments / + // return-type / async / class / enum metadata the + // Default specifier propagates below. Without it a + // rest-param default mis-bundles its trailing args + // and a class default has no ImportedClass entry + // (so `new ns()` can't resolve). Key everything by + // the namespace LOCAL, the name the consumer's + // ExternFuncRef carries. + if let Some(¶m_count) = exported_func_param_counts.get(&key) + { + imported_param_counts.insert(local.clone(), param_count); + } + if exported_func_has_rest.get(&key).copied().unwrap_or(false) { + imported_has_rest.insert(local.clone()); + } + if exported_func_synthetic_arguments.contains(&key) { + imported_synthetic_arguments.insert(local.clone()); + } + if let Some(return_type) = exported_func_return_types.get(&key) + { + imported_return_types + .insert(local.clone(), return_type.clone()); + } + if exported_async_funcs.contains(&key) { + imported_async_set.insert(local.clone()); + } + if let Some(class) = exported_classes.get(&key) { + let class_prefix = canonical_class_source_prefix( class, - &class_proven_this_methods, - ), - proven_this_methods_for_import( + &class_canonical_path, + &ctx.project_root, + &default_prefix, + ); + imported_classes.push(imported_class_from_hir( class, - &class_proven_this_tower_methods, - ), - )); - } - if let Some(members) = exported_enums.get(&key) { - imported_enums.push((local.clone(), members.clone())); + class_prefix, + Some(local.clone()), + proven_this_methods_for_import( + class, + &class_proven_this_methods, + ), + proven_this_methods_for_import( + class, + &class_proven_this_tower_methods, + ), + )); + } + if let Some(members) = exported_enums.get(&key) { + imported_enums.push((local.clone(), members.clone())); + } } } - } - // Register all exports from the source module - if let Some(exports) = all_module_exports.get(&resolved_path_str) { - for (export_name, origin_path) in exports { - let origin_prefix = - compute_module_prefix(origin_path, &ctx.project_root); - // Issue #5927: namespace members are a - // best-effort fallback in the flat - // `import_function_prefixes` map — the - // authoritative lookup for genuine - // namespace-member accesses is the - // per-namespace `namespace_member_prefixes` - // map populated unconditionally below. Use - // `or_insert` (never overwrite) so a PLAIN - // named import of the same bare name (which - // has NO other resolution path — a bare - // call has no namespace to scope against) - // always wins the flat map, regardless of - // which import statement is processed - // first. Pre-fix, `import { omit } from - // "remeda"` in the same file as `import { - // Context } from "effect"` (where - // effect's Context.ts also exports `omit`) - // meant whichever import was LATER in - // source order silently overwrote the - // other's flat-map entry — opencode's - // `provider.ts` has `Context` imported - // after `omit`, so `omit(...)` (a bare - // remeda call) resolved against - // `Context.ts`'s prefix instead of - // remeda's chunk. - import_function_prefixes - .entry(export_name.clone()) - .or_insert_with(|| origin_prefix.clone()); - // Issue #678: surface origin-name overrides - // for namespace-imported members too. A - // member reached via a re-export rename - // (`export { default as foo }`) needs the - // codegen to call `perry_fn___default` - // when the consumer writes `ns.foo()`. - let resolved_origin_name = all_module_export_origin_names - .get(&resolved_path_str) - .and_then(|m| m.get(export_name)) - .cloned(); - if let Some(ref origin_name) = resolved_origin_name { - if origin_name != export_name { - // Issue #5927: same `or_insert` - // rationale as `import_function_prefixes` - // above — never let a namespace - // member's origin-name rename - // overwrite a plain import's entry. - import_function_origin_names - .entry(export_name.clone()) - .or_insert_with(|| origin_name.clone()); - } - } - // Issue #5924: unconditionally register every - // member under the per-namespace key — - // mirrors `namespace_member_prefixes` below, - // which is also populated for every export, - // not just renamed ones. A *sparse* map here - // (only renamed members) would still force a - // fallback to the flat - // `import_function_origin_names` for - // unrenamed members, and that flat entry may - // belong to a DIFFERENT namespace imported - // into the same file. Storing every member's - // resolved suffix (renamed or not) lets the - // consumer treat a namespace hit as - // authoritative and never fall through. - namespace_member_origin_names.insert( - (local.clone(), export_name.clone()), - resolved_origin_name - .clone() - .unwrap_or_else(|| export_name.clone()), - ); - // Issue #680: also register under the - // per-namespace key so `random.make` and - // `tracer.make` can be disambiguated. - namespace_member_prefixes.insert( - (local.clone(), export_name.clone()), - origin_prefix.clone(), - ); - - let key = (origin_path.clone(), export_name.clone()); - let scoped_func_key = - perry_codegen::namespace_member_func_key(local, export_name); - if let Some(¶m_count) = exported_func_param_counts.get(&key) { - imported_param_counts.insert(export_name.clone(), param_count); - imported_param_counts - .insert(scoped_func_key.clone(), param_count); - } - if exported_func_has_rest.get(&key).copied().unwrap_or(false) { - imported_has_rest.insert(export_name.clone()); - imported_has_rest.insert(scoped_func_key.clone()); - } - if exported_func_synthetic_arguments.contains(&key) { - imported_synthetic_arguments.insert(export_name.clone()); - imported_synthetic_arguments.insert(scoped_func_key); - } - // Issue #636: namespace-imported vars must - // route through the zero-arg getter at - // call sites (`ns.fn(args)` where `fn` is a - // `let`/`const` binding holding a closure - // — the canonical `export const make = (s) - // => ...` shape). Without this, the codegen - // falls through to the direct-call path - // which treats the getter's return value - // as the call result instead of invoking - // the closure with `args`. Mirrors the - // named-import branch at the var-detection - // arm below. The key is namespace-qualified: - // a flat `make` entry lets one namespace's - // variable export misclassify another - // namespace's declared function as a getter. - // - // Issue #4841: when the namespace member is a - // re-export of a CJS submodule's `default` - // (`import sfy from './sfy'; export { sfy }`, - // where `./sfy` is `module.exports = function`), - // the origin module records the var under its - // "default" suffix — NOT the consumer-visible - // member name. Probe both keys (mirrors the - // named-import arm) so the var-vs-function - // classification fires; otherwise `ns.sfy` takes - // the function path and wraps the default getter - // in a singleton closure, so `ns.sfy(args)` - // RETURNS the function value instead of being it - // (Stripe's `qs.stringify(...)` returned the qs - // function ⇒ `.replace is not a function`). - let origin_key_under_origin_name = resolved_origin_name - .as_ref() - .map(|n| (origin_path.clone(), n.clone())); - if exported_var_names.contains(&key) - || origin_key_under_origin_name - .as_ref() - .map(|k| exported_var_names.contains(k)) - .unwrap_or(false) - { - imported_vars.insert(perry_codegen::namespace_member_var_key( - local, - export_name, - )); - } - // #9285: re-export renames keep the class - // metadata under its origin name (`Child`), not - // the namespace-visible alias (`PublicChild`). - // The var path above already consults this - // origin key; class registration must do the - // same or `new ns.PublicChild(arg)` falls - // through to a function wrapper and never runs - // the class constructor. - let imported_class = exported_classes.get(&key).or_else(|| { - origin_key_under_origin_name - .as_ref() - .and_then(|origin_key| exported_classes.get(origin_key)) - }); - if let Some(class) = imported_class { - let class_prefix = canonical_class_source_prefix( - class, - &class_canonical_path, - &ctx.project_root, - &origin_prefix, - ); - let local_alias = if export_name == &class.name { - None - } else { - Some(export_name.clone()) - }; - let mut imported_class = imported_class_from_hir( - class, - class_prefix, - local_alias, - proven_this_methods_for_import( - class, - &class_proven_this_methods, - ), - proven_this_methods_for_import( - class, - &class_proven_this_tower_methods, - ), - ); - // A namespace member is reachable only as - // `local.export_name`; it is not a lexical - // binding named `export_name`. Keeping that - // ownership explicit prevents same-named - // classes from replacing direct imports. - imported_class.namespace = Some(local.clone()); - imported_classes.push(imported_class); - } - if let Some(members) = exported_enums.get(&key) { - imported_enums.push((export_name.clone(), members.clone())); - } - } - } - // Namespace aliases also participate in - // `all_module_exports`, so repeat this after the - // ordinary walk and let the TARGET prefix win over the - // declaring barrel's prefix. - if let Some(nested) = namespace_reexport_targets.get(&resolved_path_str) { - for (alias, target_path) in nested { - let target_prefix = compute_module_prefix( - &target_path.to_string_lossy(), - &ctx.project_root, - ); - namespace_member_prefixes - .insert((local.clone(), alias.clone()), target_prefix); - namespace_member_nested.insert((local.clone(), alias.clone())); - } - } - if source_module.is_some_and(|module| is_wrapped_cjs(module)) { - let default_prefix = compute_module_prefix( - &resolved_path_str, - &ctx.project_root, - ); - let default_is_var = all_module_exports - .get(&resolved_path_str) - .and_then(|exports| exports.get("default")) - .is_some_and(|origin_path| { - let origin_name = all_module_export_origin_names - .get(&resolved_path_str) - .and_then(|names| names.get("default")) - .cloned() - .unwrap_or_else(|| "default".to_string()); - exported_var_names - .contains(&(origin_path.clone(), origin_name)) - }) - || exported_var_names.contains(&( - resolved_path_str.clone(), - "default".to_string(), - )); - // CJS namespace exotic objects expose both names - // as aliases of the evaluated exports object. The - // per-namespace origin map makes `module.exports` - // call the existing `default` getter rather than a - // nonexistent dotted symbol. - for member in ["default", "module.exports"] { - namespace_member_prefixes.insert( - (local.clone(), member.to_string()), - default_prefix.clone(), - ); - namespace_member_origin_names.insert( - (local.clone(), member.to_string()), - "default".to_string(), - ); - import_function_prefixes - .entry(member.to_string()) - .or_insert_with(|| default_prefix.clone()); - import_function_origin_names - .entry(member.to_string()) - .or_insert_with(|| "default".to_string()); - if member == "module.exports" || default_is_var { - imported_vars.insert(perry_codegen::namespace_member_var_key( - local, member, - )); - } - } - } - continue; - } - - let (local_name, exported_name) = match spec { - perry_hir::ImportSpecifier::Named { imported, local } => { - (local.clone(), imported.clone()) - } - perry_hir::ImportSpecifier::Default { local } => { - (local.clone(), "default".to_string()) - } - perry_hir::ImportSpecifier::Namespace { .. } => unreachable!(), - }; - - // PerryTS/storekit#1 + #5621: skip the wrapper-fn - // registration when this specifier names an FFI function - // declared in the source package's - // `perry.nativeLibrary.functions` manifest. The source - // `.ts` is ambient and has no Perry wrapper for the linker - // to resolve, so the FFI-manifest path in `lower_call.rs` - // must win. Two binding conventions route here: - // 1. Exact match — the binding name IS the symbol - // (`js_storekit_load_products`, raw ambient style). - // 2. Ergonomic camelCase (#5621) — the binding - // (`requestAdapter`) is the `js__` ⇒ - // camelCase derivation of the symbol. Record the alias - // (keyed by the *local* binding, since call sites see - // the local name) so the call site rewrites it; exact - // matches need no alias. - if let Some(nl) = native_library_for_import { - let exact_symbol = nl - .functions - .iter() - .find(|f| f.name == exported_name) - .map(|f| f.name.clone()); - // Issue #6715: a REAL module export wins over a derived - // ergonomic alias. The `js__` ⇒ camelCase - // routing (#5621) is a convenience for packages whose - // `.ts` only holds ambient `export declare function` - // signatures (no body) — those are skipped at lowering - // (`module_decl.rs`: `body.is_none()`), so they never - // enter `all_module_exports`. But the documented wrapper - // convention (native-extensions.md) is an ambient - // `declare function js__speak(...)` PLUS a real - // `export async function speak(...)` that transforms args - // and calls the FFI symbol. When such a wrapper's name - // collides with a manifest symbol's derived alias - // (`js_speech_speak` → `speak`), the alias must NOT - // shadow it — the import binds to the wrapper, which the - // module emits a `perry_fn___speak` symbol for and - // the fall-through named-import path registers below. - // Only genuine, implemented value exports land here, so - // ambient-declare-only packages keep the #5621 routing. - let has_genuine_module_export = all_module_exports - .get(&resolved_path_str) - .is_some_and(|exports| exports.contains_key(&exported_name)); - // Collect ALL ergonomic matches so an ambiguous manifest - // (two symbols deriving the same camelCase binding) is - // rejected rather than silently bound to the first. - let ergonomic_matches: Vec = if exact_symbol.is_some() - || has_genuine_module_export - { - Vec::new() - } else { - nl.functions - .iter() - .filter(|f| { - ergonomic_export_alias(&nl.module, &f.name).as_deref() - == Some(exported_name.as_str()) - }) - .map(|f| f.name.clone()) - .collect() - }; - if ergonomic_matches.len() > 1 { - return Err(format!( - "native library `{}` has ambiguous ergonomic exports for \ - `{}`: the manifest symbols {:?} all derive the same \ - camelCase binding. Rename the symbols so each derives a \ - distinct binding, or import one by its raw `js_*` name.", - nl.module, exported_name, ergonomic_matches - )); - } - let matched_symbol = - exact_symbol.or_else(|| ergonomic_matches.into_iter().next()); - if let Some(symbol) = matched_symbol { - // No alias needed when the binding already IS the - // symbol (raw exact-match, unaliased). - if symbol != local_name { - import_function_ffi_aliases.insert(local_name.clone(), symbol); - } - continue; - } - } - - // Issue #5916: the `NamespaceReExport` we are about to scan - // for may not sit in the module we import from — it can be - // one or more `export { X } from "src"` hops upstream. A - // barrel that does - // export { Token } from "./selfns" // ReExport - // where `selfns.ts` declares - // export * as Token from "./selfns" // NamespaceReExport - // exposes `Token` as a NAMESPACE, but the scan below only - // looked at the barrel's own exports, saw a plain `ReExport`, - // and fell through to the ordinary value path. `Token.estimate(…)` - // then lowered to a `StaticMethodCall` referencing - // `__perry_wrap_perry_fn___Token` — a closure wrapper - // no module emits, so the link failed outright. (A ReExport of - // an ordinary function/const across the same hop links fine; - // it is specifically a NAMESPACE-valued binding that needs the - // namespace routing.) - // - // Walk the re-export chain first so the scan runs against the - // module that actually DECLARES the namespace, under the name - // it declares it with. When no hop applies (the overwhelmingly - // common case) this leaves the scan target exactly where it was, - // so behaviour is unchanged. - let mut ns_scan_hir = source_module; - let mut ns_scan_path = resolved_path_str.clone(); - let mut ns_scan_name = exported_name.clone(); - for _ in 0..MAX_REEXPORT_HOPS { - let Some(hir) = ns_scan_hir else { break }; - // Already the declaring module — nothing to follow. - if hir.exports.iter().any(|e| { - matches!( - e, - perry_hir::Export::NamespaceReExport { name, .. } - if *name == ns_scan_name - ) - }) { - break; - } - // Follow either an explicit named re-export or an - // `export *` barrel whose target owns this name. The - // latter is how Effect and OpenCode expose namespace - // values through public entry points. - let named_hop = hir.exports.iter().find_map(|e| match e { - perry_hir::Export::ReExport { - source, - imported, - exported, - } if *exported == ns_scan_name => { - Some((source.clone(), imported.clone())) - } - _ => None, - }); - let export_all_hop = || { - hir.exports.iter().find_map(|e| { - let perry_hir::Export::ExportAll { source } = e else { - return None; - }; - let (target_path, _) = resolve_import_with_context( - source, - std::path::Path::new(&ns_scan_path), - &ctx, - )?; - let target = target_path.to_string_lossy().to_string(); - all_module_exports - .get(&target) - .is_some_and(|exports| exports.contains_key(&ns_scan_name)) - .then(|| (source.clone(), ns_scan_name.clone())) - }) - }; - let Some((hop_src, hop_imported)) = named_hop.or_else(export_all_hop) else { - break; - }; - let Some((hop_path, _)) = resolve_import_with_context( - &hop_src, - std::path::Path::new(&ns_scan_path), - &ctx, - ) else { - break; - }; - let Some(hop_hir) = ctx.native_modules.get(&hop_path) else { - break; - }; - ns_scan_path = hop_path.to_string_lossy().to_string(); - ns_scan_hir = Some(hop_hir); - ns_scan_name = hop_imported; - } - - // Issue #310: when the source module re-exports the - // imported name as a namespace (`export * as Foo from - // "./Foo"`), the local binding behaves identically to - // `import * as Foo from "pkg/Foo"` — `Foo.member` should - // dispatch through the namespace path. Detect this by - // looking at the source module's HIR exports for a - // `NamespaceReExport` whose name matches the imported - // name, then route the local through `namespace_imports` - // + register the namespace target's full export surface. - let mut handled_as_namespace_reexport = false; - if let Some(src_hir) = ns_scan_hir { - for export in &src_hir.exports { - if let perry_hir::Export::NamespaceReExport { - source: ns_src, - name, - } = export - { - if name != &ns_scan_name { - continue; - } - // Native namespace targets (for example - // `export * as NodeWS from "ws"`) have no HIR - // module and no `@__perry_ns_ws` global. The - // declaring module emits a zero-arg namespace - // getter; classify this named import as a var so - // consumer code calls that getter. - if perry_hir::NATIVE_MODULES.contains( - &ns_src.strip_prefix("node:").unwrap_or(ns_src), - ) { - let declaring_prefix = compute_module_prefix( - &ns_scan_path, - &ctx.project_root, - ); - import_function_prefixes - .insert(local_name.clone(), declaring_prefix); - if local_name != ns_scan_name { - import_function_origin_names - .insert(local_name.clone(), ns_scan_name.clone()); - } - imported_vars.insert(local_name.clone()); - handled_as_namespace_reexport = true; - break; - } - let importer = std::path::Path::new(&ns_scan_path); - let Some((ns_target, _)) = resolve_import_with_context( - ns_src, - importer, - &ctx, - ) else { - break; - }; - let ns_target_str = ns_target.to_string_lossy().to_string(); - let Some(target_exports) = all_module_exports.get(&ns_target_str) - else { - break; - }; - namespace_imports.push(local_name.clone()); - for (export_name, origin_path) in target_exports { + // Register all exports from the source module + if let Some(exports) = all_module_exports.get(&resolved_path_str) { + for (export_name, origin_path) in exports { let origin_prefix = compute_module_prefix(origin_path, &ctx.project_root); - // Issue #5927: `or_insert` — see the - // matching rationale on the - // `namespace_like_local` branch above. - // A namespace member is a best-effort - // fallback in this flat map; a PLAIN - // named import of the same bare name - // has no other resolution path and - // must always win, regardless of - // import-statement order. + // Issue #5927: namespace members are a + // best-effort fallback in the flat + // `import_function_prefixes` map — the + // authoritative lookup for genuine + // namespace-member accesses is the + // per-namespace `namespace_member_prefixes` + // map populated unconditionally below. Use + // `or_insert` (never overwrite) so a PLAIN + // named import of the same bare name (which + // has NO other resolution path — a bare + // call has no namespace to scope against) + // always wins the flat map, regardless of + // which import statement is processed + // first. Pre-fix, `import { omit } from + // "remeda"` in the same file as `import { + // Context } from "effect"` (where + // effect's Context.ts also exports `omit`) + // meant whichever import was LATER in + // source order silently overwrote the + // other's flat-map entry — opencode's + // `provider.ts` has `Context` imported + // after `omit`, so `omit(...)` (a bare + // remeda call) resolved against + // `Context.ts`'s prefix instead of + // remeda's chunk. import_function_prefixes .entry(export_name.clone()) .or_insert_with(|| origin_prefix.clone()); - // Issue #5922 (companion to #680): also - // register under the per-namespace key so - // `Context.foo` and `Option.foo` resolve to - // their own sources even when two - // namespace-reexport targets imported into - // the same file happen to export a member - // with the same bare name. Without this, - // codegen's `expr/static_method.rs` (plus - // `namespace_call.rs` / `property_get.rs` - // for lowercase-receiver call/read forms) - // fall through to the flat - // `import_function_prefixes`, which the - // last-registered namespace silently wins. - namespace_member_prefixes.insert( - (local_name.clone(), export_name.clone()), - origin_prefix.clone(), - ); // Issue #678: surface origin-name overrides - // for the NamespaceReExport branch too. + // for namespace-imported members too. A + // member reached via a re-export rename + // (`export { default as foo }`) needs the + // codegen to call `perry_fn___default` + // when the consumer writes `ns.foo()`. let resolved_origin_name = all_module_export_origin_names - .get(&ns_target_str) + .get(&resolved_path_str) .and_then(|m| m.get(export_name)) .cloned(); if let Some(ref origin_name) = resolved_origin_name { if origin_name != export_name { - // Issue #5927: `or_insert` — see - // the matching rationale above. + // Issue #5927: same `or_insert` + // rationale as `import_function_prefixes` + // above — never let a namespace + // member's origin-name rename + // overwrite a plain import's entry. import_function_origin_names .entry(export_name.clone()) .or_insert_with(|| origin_name.clone()); } } - // Issue #5924: unconditionally register - // every member under the per-namespace - // key, mirroring `namespace_member_prefixes` - // above (populated for every export, not - // just renamed ones). Found via a - // real-world `sst/opencode` compile: - // `import { Effect, Layer, Context, - // Schema, Types } from "effect"` - // processes all five namespace-reexport - // targets into this file's shared maps. - // When an EARLIER-processed namespace - // (e.g. `Effect`) re-exports a member - // under a rename (e.g. `Service`), the - // flat `import_function_origin_names` - // entry it leaves behind clobbers a - // LATER-processed namespace's (e.g. - // `Context`'s) *unrenamed* member of the - // same name — `Context.Service` resolved - // to the wrong symbol suffix and linking - // failed with an undefined - // `perry_fn_..._Context_ts__< - // wrong-suffix>` symbol. A *sparse* - // per-namespace map (only renamed - // members) doesn't fully fix this: an - // unrenamed member with no entry here - // would still fall back to the - // (possibly contaminated) flat map, so - // every member gets an entry — the - // resolved origin name when renamed, - // else the export name itself. + // Issue #5924: unconditionally register every + // member under the per-namespace key — + // mirrors `namespace_member_prefixes` below, + // which is also populated for every export, + // not just renamed ones. A *sparse* map here + // (only renamed members) would still force a + // fallback to the flat + // `import_function_origin_names` for + // unrenamed members, and that flat entry may + // belong to a DIFFERENT namespace imported + // into the same file. Storing every member's + // resolved suffix (renamed or not) lets the + // consumer treat a namespace hit as + // authoritative and never fall through. namespace_member_origin_names.insert( - (local_name.clone(), export_name.clone()), + (local.clone(), export_name.clone()), resolved_origin_name .clone() .unwrap_or_else(|| export_name.clone()), ); + // Issue #680: also register under the + // per-namespace key so `random.make` and + // `tracer.make` can be disambiguated. + namespace_member_prefixes.insert( + (local.clone(), export_name.clone()), + origin_prefix.clone(), + ); let key = (origin_path.clone(), export_name.clone()); - let scoped_func_key = - perry_codegen::namespace_member_func_key( - &local_name, - export_name, - ); + let scoped_func_key = perry_codegen::namespace_member_func_key( + local, + export_name, + ); if let Some(¶m_count) = exported_func_param_counts.get(&key) { imported_param_counts @@ -4352,54 +3831,65 @@ pub fn run_with_parse_cache( imported_synthetic_arguments.insert(export_name.clone()); imported_synthetic_arguments.insert(scoped_func_key); } - // Issue #321: NamespaceReExport members - // that are var-shaped exports (the - // canonical `export const succeed = (v) => - // ...` shape in effect/Effect.ts and - // co-equivalent re-export hubs) must land - // in `imported_vars` under a namespace- - // qualified key so the codegen's - // StaticMethodCall and namespace-member - // call sites route through the zero-arg - // getter + `js_closure_callN`. Without - // this, `import { Effect } from "effect"; - // Effect.succeed(42)` emitted a 1-arg - // direct call against the 0-arg getter - // — the source returned the closure - // pointer unchanged and `typeof - // Effect.succeed(42)` was `"function"`, - // and `runSync(program)` then threw - // `Cannot read properties of undefined` - // on `program._tag`. Mirrors the - // `Namespace { local }` branch above. + // Issue #636: namespace-imported vars must + // route through the zero-arg getter at + // call sites (`ns.fn(args)` where `fn` is a + // `let`/`const` binding holding a closure + // — the canonical `export const make = (s) + // => ...` shape). Without this, the codegen + // falls through to the direct-call path + // which treats the getter's return value + // as the call result instead of invoking + // the closure with `args`. Mirrors the + // named-import branch at the var-detection + // arm below. The key is namespace-qualified: + // a flat `make` entry lets one namespace's + // variable export misclassify another + // namespace's declared function as a getter. + // + // Issue #4841: when the namespace member is a + // re-export of a CJS submodule's `default` + // (`import sfy from './sfy'; export { sfy }`, + // where `./sfy` is `module.exports = function`), + // the origin module records the var under its + // "default" suffix — NOT the consumer-visible + // member name. Probe both keys (mirrors the + // named-import arm) so the var-vs-function + // classification fires; otherwise `ns.sfy` takes + // the function path and wraps the default getter + // in a singleton closure, so `ns.sfy(args)` + // RETURNS the function value instead of being it + // (Stripe's `qs.stringify(...)` returned the qs + // function ⇒ `.replace is not a function`). let origin_key_under_origin_name = resolved_origin_name .as_ref() - .map(|name| (origin_path.clone(), name.clone())); + .map(|n| (origin_path.clone(), n.clone())); if exported_var_names.contains(&key) || origin_key_under_origin_name .as_ref() - .map(|key| exported_var_names.contains(key)) + .map(|k| exported_var_names.contains(k)) .unwrap_or(false) { imported_vars.insert( perry_codegen::namespace_member_var_key( - &local_name, + local, export_name, ), ); } - // #9285: a renamed class re-export is - // indexed under its origin name, while this - // namespace exposes `export_name`. Resolve - // through the same origin key used for the - // var classification above so the scoped - // ImportedClass retains both identities. - let imported_class = - exported_classes.get(&key).or_else(|| { - origin_key_under_origin_name.as_ref().and_then( - |origin_key| exported_classes.get(origin_key), - ) - }); + // #9285: re-export renames keep the class + // metadata under its origin name (`Child`), not + // the namespace-visible alias (`PublicChild`). + // The var path above already consults this + // origin key; class registration must do the + // same or `new ns.PublicChild(arg)` falls + // through to a function wrapper and never runs + // the class constructor. + let imported_class = exported_classes.get(&key).or_else(|| { + origin_key_under_origin_name + .as_ref() + .and_then(|origin_key| exported_classes.get(origin_key)) + }); if let Some(class) = imported_class { let class_prefix = canonical_class_source_prefix( class, @@ -4425,1060 +3915,1599 @@ pub fn run_with_parse_cache( &class_proven_this_tower_methods, ), ); - imported_class.namespace = Some(local_name.clone()); + // A namespace member is reachable only as + // `local.export_name`; it is not a lexical + // binding named `export_name`. Keeping that + // ownership explicit prevents same-named + // classes from replacing direct imports. + imported_class.namespace = Some(local.clone()); imported_classes.push(imported_class); } if let Some(members) = exported_enums.get(&key) { imported_enums.push((export_name.clone(), members.clone())); } } - // A named namespace re-export can itself expose - // nested namespace aliases (Zod's `z.core`, - // `z.locales`, `z.iso`, and `z.coerce` shape). - // Mark those members explicitly and overwrite - // the declaring-barrel prefixes registered by - // the ordinary export walk above with the - // namespace TARGET prefixes. - if let Some(nested) = - namespace_reexport_targets.get(&ns_target_str) - { - for (alias, target_path) in nested { - let target_prefix = compute_module_prefix( - &target_path.to_string_lossy(), - &ctx.project_root, - ); - namespace_member_prefixes.insert( - (local_name.clone(), alias.clone()), - target_prefix, + } + // Namespace aliases also participate in + // `all_module_exports`, so repeat this after the + // ordinary walk and let the TARGET prefix win over the + // declaring barrel's prefix. + if let Some(nested) = namespace_reexport_targets.get(&resolved_path_str) + { + for (alias, target_path) in nested { + let target_prefix = compute_module_prefix( + &target_path.to_string_lossy(), + &ctx.project_root, + ); + namespace_member_prefixes + .insert((local.clone(), alias.clone()), target_prefix); + namespace_member_nested.insert((local.clone(), alias.clone())); + } + } + if source_module.is_some_and(|module| is_wrapped_cjs(module)) { + let default_prefix = + compute_module_prefix(&resolved_path_str, &ctx.project_root); + let default_is_var = all_module_exports + .get(&resolved_path_str) + .and_then(|exports| exports.get("default")) + .is_some_and(|origin_path| { + let origin_name = all_module_export_origin_names + .get(&resolved_path_str) + .and_then(|names| names.get("default")) + .cloned() + .unwrap_or_else(|| "default".to_string()); + exported_var_names + .contains(&(origin_path.clone(), origin_name)) + }) + || exported_var_names.contains(&( + resolved_path_str.clone(), + "default".to_string(), + )); + // CJS namespace exotic objects expose both names + // as aliases of the evaluated exports object. The + // per-namespace origin map makes `module.exports` + // call the existing `default` getter rather than a + // nonexistent dotted symbol. + for member in ["default", "module.exports"] { + namespace_member_prefixes.insert( + (local.clone(), member.to_string()), + default_prefix.clone(), + ); + namespace_member_origin_names.insert( + (local.clone(), member.to_string()), + "default".to_string(), + ); + import_function_prefixes + .entry(member.to_string()) + .or_insert_with(|| default_prefix.clone()); + import_function_origin_names + .entry(member.to_string()) + .or_insert_with(|| "default".to_string()); + if member == "module.exports" || default_is_var { + imported_vars.insert( + perry_codegen::namespace_member_var_key(local, member), ); - namespace_member_nested - .insert((local_name.clone(), alias.clone())); } } - handled_as_namespace_reexport = true; - break; } + continue; } - } - if handled_as_namespace_reexport { - continue; - } - let key = (resolved_path_str.clone(), exported_name.clone()); - - // Resolve the ORIGIN path of `exported_name` by following - // re-exports. `index.js`'s `export { pgTable } from "./table.js"` - // means the immediate import resolves to index.js but the - // actual `Let pgTable = (...) => ...` lives in table.js. The - // `exported_var_names` set is keyed by the ORIGIN path, so - // looking up `(index.js, "pgTable")` misses; we need to walk - // the re-export chain to find table.js. Refs #420. - let origin_path: String = - if let Some(exports) = all_module_exports.get(&resolved_path_str) { - if let Some(p) = exports.get(&exported_name) { - p.clone() - } else { - resolved_path_str.clone() + let (local_name, exported_name) = match spec { + perry_hir::ImportSpecifier::Named { imported, local } => { + (local.clone(), imported.clone()) } - } else { - resolved_path_str.clone() + perry_hir::ImportSpecifier::Default { local } => { + (local.clone(), "default".to_string()) + } + perry_hir::ImportSpecifier::Namespace { .. } => unreachable!(), }; - let origin_key = (origin_path.clone(), exported_name.clone()); - // Resolve effective prefix (follow re-exports) - let effective_prefix = if origin_path != resolved_path_str { - compute_module_prefix(&origin_path, &ctx.project_root) - } else { - source_prefix.clone() - }; + // PerryTS/storekit#1 + #5621: skip the wrapper-fn + // registration when this specifier names an FFI function + // declared in the source package's + // `perry.nativeLibrary.functions` manifest. The source + // `.ts` is ambient and has no Perry wrapper for the linker + // to resolve, so the FFI-manifest path in `lower_call.rs` + // must win. Two binding conventions route here: + // 1. Exact match — the binding name IS the symbol + // (`js_storekit_load_products`, raw ambient style). + // 2. Ergonomic camelCase (#5621) — the binding + // (`requestAdapter`) is the `js__` ⇒ + // camelCase derivation of the symbol. Record the alias + // (keyed by the *local* binding, since call sites see + // the local name) so the call site rewrites it; exact + // matches need no alias. + if let Some(nl) = native_library_for_import { + let exact_symbol = nl + .functions + .iter() + .find(|f| f.name == exported_name) + .map(|f| f.name.clone()); + // Issue #6715: a REAL module export wins over a derived + // ergonomic alias. The `js__` ⇒ camelCase + // routing (#5621) is a convenience for packages whose + // `.ts` only holds ambient `export declare function` + // signatures (no body) — those are skipped at lowering + // (`module_decl.rs`: `body.is_none()`), so they never + // enter `all_module_exports`. But the documented wrapper + // convention (native-extensions.md) is an ambient + // `declare function js__speak(...)` PLUS a real + // `export async function speak(...)` that transforms args + // and calls the FFI symbol. When such a wrapper's name + // collides with a manifest symbol's derived alias + // (`js_speech_speak` → `speak`), the alias must NOT + // shadow it — the import binds to the wrapper, which the + // module emits a `perry_fn___speak` symbol for and + // the fall-through named-import path registers below. + // Only genuine, implemented value exports land here, so + // ambient-declare-only packages keep the #5621 routing. + let has_genuine_module_export = all_module_exports + .get(&resolved_path_str) + .is_some_and(|exports| exports.contains_key(&exported_name)); + // Collect ALL ergonomic matches so an ambiguous manifest + // (two symbols deriving the same camelCase binding) is + // rejected rather than silently bound to the first. + let ergonomic_matches: Vec = + if exact_symbol.is_some() || has_genuine_module_export { + Vec::new() + } else { + nl.functions + .iter() + .filter(|f| { + ergonomic_export_alias(&nl.module, &f.name).as_deref() + == Some(exported_name.as_str()) + }) + .map(|f| f.name.clone()) + .collect() + }; + if ergonomic_matches.len() > 1 { + return Err(format!( + "native library `{}` has ambiguous ergonomic exports for \ + `{}`: the manifest symbols {:?} all derive the same \ + camelCase binding. Rename the symbols so each derives a \ + distinct binding, or import one by its raw `js_*` name.", + nl.module, exported_name, ergonomic_matches + )); + } + let matched_symbol = + exact_symbol.or_else(|| ergonomic_matches.into_iter().next()); + if let Some(symbol) = matched_symbol { + // No alias needed when the binding already IS the + // symbol (raw exact-match, unaliased). + if symbol != local_name { + import_function_ffi_aliases.insert(local_name.clone(), symbol); + } + continue; + } + } - // Issue #: only key by `exported_name` in the - // no-rename case (`local_name == exported_name`), where - // the HIR's `ExternFuncRef` genuinely carries that - // string. In the aliased case (#35/#321 above: - // `ExternFuncRef` carries the LOCAL name, unique per - // import site), inserting under `exported_name` too is - // not just redundant — `exported_name` is whatever the - // ORIGIN module happens to call it, so it can collide - // with an unrelated LOCAL alias elsewhere in the same - // file. Concrete repro: `import { a as n, c as a } from - // "./x"; import { a as t } from "./y"` — the second - // specifier's exported name "a" overwrote the first - // import's *local* alias "a" (from `c as a`), silently - // repointing `ExternFuncRef { name: "a" }` at module y - // instead of x. Only inserting the ALIASED case under - // `local_name` (never also under `exported_name`) keeps - // every key in this map unique per file — local names - // can't collide with each other (each `let`/import - // binding needs a distinct identifier), but exported - // names from different source modules can and do. - if local_name == exported_name { - import_function_prefixes - .insert(exported_name.clone(), effective_prefix.clone()); - } else { - import_function_prefixes - .insert(local_name.clone(), effective_prefix.clone()); - } + // Issue #5916: the `NamespaceReExport` we are about to scan + // for may not sit in the module we import from — it can be + // one or more `export { X } from "src"` hops upstream. A + // barrel that does + // export { Token } from "./selfns" // ReExport + // where `selfns.ts` declares + // export * as Token from "./selfns" // NamespaceReExport + // exposes `Token` as a NAMESPACE, but the scan below only + // looked at the barrel's own exports, saw a plain `ReExport`, + // and fell through to the ordinary value path. `Token.estimate(…)` + // then lowered to a `StaticMethodCall` referencing + // `__perry_wrap_perry_fn___Token` — a closure wrapper + // no module emits, so the link failed outright. (A ReExport of + // an ordinary function/const across the same hop links fine; + // it is specifically a NAMESPACE-valued binding that needs the + // namespace routing.) + // + // Walk the re-export chain first so the scan runs against the + // module that actually DECLARES the namespace, under the name + // it declares it with. When no hop applies (the overwhelmingly + // common case) this leaves the scan target exactly where it was, + // so behaviour is unchanged. + let mut ns_scan_hir = source_module; + let mut ns_scan_path = resolved_path_str.clone(); + let mut ns_scan_name = exported_name.clone(); + for _ in 0..MAX_REEXPORT_HOPS { + let Some(hir) = ns_scan_hir else { break }; + // Already the declaring module — nothing to follow. + if hir.exports.iter().any(|e| { + matches!( + e, + perry_hir::Export::NamespaceReExport { name, .. } + if *name == ns_scan_name + ) + }) { + break; + } + // Follow either an explicit named re-export or an + // `export *` barrel whose target owns this name. The + // latter is how Effect and OpenCode expose namespace + // values through public entry points. + let named_hop = hir.exports.iter().find_map(|e| match e { + perry_hir::Export::ReExport { + source, + imported, + exported, + } if *exported == ns_scan_name => { + Some((source.clone(), imported.clone())) + } + _ => None, + }); + let export_all_hop = || { + hir.exports.iter().find_map(|e| { + let perry_hir::Export::ExportAll { source } = e else { + return None; + }; + let (target_path, _) = resolve_import_with_context( + source, + std::path::Path::new(&ns_scan_path), + &ctx, + )?; + let target = target_path.to_string_lossy().to_string(); + all_module_exports + .get(&target) + .is_some_and(|exports| exports.contains_key(&ns_scan_name)) + .then(|| (source.clone(), ns_scan_name.clone())) + }) + }; + let Some((hop_src, hop_imported)) = named_hop.or_else(export_all_hop) + else { + break; + }; + let Some((hop_path, _)) = resolve_import_with_context( + &hop_src, + std::path::Path::new(&ns_scan_path), + &ctx, + ) else { + break; + }; + let Some(hop_hir) = ctx.native_modules.get(&hop_path) else { + break; + }; + ns_scan_path = hop_path.to_string_lossy().to_string(); + ns_scan_hir = Some(hop_hir); + ns_scan_name = hop_imported; + } - // Issue #678: if the import chain renames through a - // re-export (`export { default as render } from - // './render.js'`), the symbol in the origin module - // is `perry_fn___default`, not - // `perry_fn___render`. Surface the deeper - // origin name via `import_function_origin_names` so - // the codegen can pick the right suffix when forming - // the extern symbol. The map is sparse — entries are - // only inserted when origin_name != exported_name. - let resolved_origin_name = all_module_export_origin_names - .get(&resolved_path_str) - .and_then(|m| m.get(&exported_name)) - .cloned(); - if let Some(ref origin_name) = resolved_origin_name { - if origin_name != &exported_name { - // Key by the same rule as `import_function_prefixes` - // above: the LOCAL name for an aliased import, the - // exported name otherwise — the HIR's `ExternFuncRef` - // carries exactly that string. Also inserting an - // aliased import under its EXPORTED name poisons any - // same-file binding that happens to share it: - // `import { XML } from "a"` + `import { XML as C } - // from "b"` (where b's barrel does `export { default - // as XML }`) rewrote a's `XML` suffix to `default` - // and the link failed on `perry_fn___default` - // (the fast-xml-parser × is-unsafe graph). - if local_name == exported_name { - import_function_origin_names - .insert(exported_name.clone(), origin_name.clone()); - } else { - import_function_origin_names - .insert(local_name.clone(), origin_name.clone()); + // Issue #310: when the source module re-exports the + // imported name as a namespace (`export * as Foo from + // "./Foo"`), the local binding behaves identically to + // `import * as Foo from "pkg/Foo"` — `Foo.member` should + // dispatch through the namespace path. Detect this by + // looking at the source module's HIR exports for a + // `NamespaceReExport` whose name matches the imported + // name, then route the local through `namespace_imports` + // + register the namespace target's full export surface. + let mut handled_as_namespace_reexport = false; + if let Some(src_hir) = ns_scan_hir { + for export in &src_hir.exports { + if let perry_hir::Export::NamespaceReExport { + source: ns_src, + name, + } = export + { + if name != &ns_scan_name { + continue; + } + // Native namespace targets (for example + // `export * as NodeWS from "ws"`) have no HIR + // module and no `@__perry_ns_ws` global. The + // declaring module emits a zero-arg namespace + // getter; classify this named import as a var so + // consumer code calls that getter. + if perry_hir::NATIVE_MODULES + .contains(&ns_src.strip_prefix("node:").unwrap_or(ns_src)) + { + let declaring_prefix = + compute_module_prefix(&ns_scan_path, &ctx.project_root); + import_function_prefixes + .insert(local_name.clone(), declaring_prefix); + if local_name != ns_scan_name { + import_function_origin_names + .insert(local_name.clone(), ns_scan_name.clone()); + } + imported_vars.insert(local_name.clone()); + handled_as_namespace_reexport = true; + break; + } + let importer = std::path::Path::new(&ns_scan_path); + let Some((ns_target, _)) = + resolve_import_with_context(ns_src, importer, &ctx) + else { + break; + }; + let ns_target_str = ns_target.to_string_lossy().to_string(); + let Some(target_exports) = + all_module_exports.get(&ns_target_str) + else { + break; + }; + namespace_imports.push(local_name.clone()); + for (export_name, origin_path) in target_exports { + let origin_prefix = + compute_module_prefix(origin_path, &ctx.project_root); + // Issue #5927: `or_insert` — see the + // matching rationale on the + // `namespace_like_local` branch above. + // A namespace member is a best-effort + // fallback in this flat map; a PLAIN + // named import of the same bare name + // has no other resolution path and + // must always win, regardless of + // import-statement order. + import_function_prefixes + .entry(export_name.clone()) + .or_insert_with(|| origin_prefix.clone()); + // Issue #5922 (companion to #680): also + // register under the per-namespace key so + // `Context.foo` and `Option.foo` resolve to + // their own sources even when two + // namespace-reexport targets imported into + // the same file happen to export a member + // with the same bare name. Without this, + // codegen's `expr/static_method.rs` (plus + // `namespace_call.rs` / `property_get.rs` + // for lowercase-receiver call/read forms) + // fall through to the flat + // `import_function_prefixes`, which the + // last-registered namespace silently wins. + namespace_member_prefixes.insert( + (local_name.clone(), export_name.clone()), + origin_prefix.clone(), + ); + // Issue #678: surface origin-name overrides + // for the NamespaceReExport branch too. + let resolved_origin_name = all_module_export_origin_names + .get(&ns_target_str) + .and_then(|m| m.get(export_name)) + .cloned(); + if let Some(ref origin_name) = resolved_origin_name { + if origin_name != export_name { + // Issue #5927: `or_insert` — see + // the matching rationale above. + import_function_origin_names + .entry(export_name.clone()) + .or_insert_with(|| origin_name.clone()); + } + } + // Issue #5924: unconditionally register + // every member under the per-namespace + // key, mirroring `namespace_member_prefixes` + // above (populated for every export, not + // just renamed ones). Found via a + // real-world `sst/opencode` compile: + // `import { Effect, Layer, Context, + // Schema, Types } from "effect"` + // processes all five namespace-reexport + // targets into this file's shared maps. + // When an EARLIER-processed namespace + // (e.g. `Effect`) re-exports a member + // under a rename (e.g. `Service`), the + // flat `import_function_origin_names` + // entry it leaves behind clobbers a + // LATER-processed namespace's (e.g. + // `Context`'s) *unrenamed* member of the + // same name — `Context.Service` resolved + // to the wrong symbol suffix and linking + // failed with an undefined + // `perry_fn_..._Context_ts__< + // wrong-suffix>` symbol. A *sparse* + // per-namespace map (only renamed + // members) doesn't fully fix this: an + // unrenamed member with no entry here + // would still fall back to the + // (possibly contaminated) flat map, so + // every member gets an entry — the + // resolved origin name when renamed, + // else the export name itself. + namespace_member_origin_names.insert( + (local_name.clone(), export_name.clone()), + resolved_origin_name + .clone() + .unwrap_or_else(|| export_name.clone()), + ); + + let key = (origin_path.clone(), export_name.clone()); + let scoped_func_key = + perry_codegen::namespace_member_func_key( + &local_name, + export_name, + ); + if let Some(¶m_count) = + exported_func_param_counts.get(&key) + { + imported_param_counts + .insert(export_name.clone(), param_count); + imported_param_counts + .insert(scoped_func_key.clone(), param_count); + } + if exported_func_has_rest + .get(&key) + .copied() + .unwrap_or(false) + { + imported_has_rest.insert(export_name.clone()); + imported_has_rest.insert(scoped_func_key.clone()); + } + if exported_func_synthetic_arguments.contains(&key) { + imported_synthetic_arguments + .insert(export_name.clone()); + imported_synthetic_arguments.insert(scoped_func_key); + } + // Issue #321: NamespaceReExport members + // that are var-shaped exports (the + // canonical `export const succeed = (v) => + // ...` shape in effect/Effect.ts and + // co-equivalent re-export hubs) must land + // in `imported_vars` under a namespace- + // qualified key so the codegen's + // StaticMethodCall and namespace-member + // call sites route through the zero-arg + // getter + `js_closure_callN`. Without + // this, `import { Effect } from "effect"; + // Effect.succeed(42)` emitted a 1-arg + // direct call against the 0-arg getter + // — the source returned the closure + // pointer unchanged and `typeof + // Effect.succeed(42)` was `"function"`, + // and `runSync(program)` then threw + // `Cannot read properties of undefined` + // on `program._tag`. Mirrors the + // `Namespace { local }` branch above. + let origin_key_under_origin_name = resolved_origin_name + .as_ref() + .map(|name| (origin_path.clone(), name.clone())); + if exported_var_names.contains(&key) + || origin_key_under_origin_name + .as_ref() + .map(|key| exported_var_names.contains(key)) + .unwrap_or(false) + { + imported_vars.insert( + perry_codegen::namespace_member_var_key( + &local_name, + export_name, + ), + ); + } + // #9285: a renamed class re-export is + // indexed under its origin name, while this + // namespace exposes `export_name`. Resolve + // through the same origin key used for the + // var classification above so the scoped + // ImportedClass retains both identities. + let imported_class = + exported_classes.get(&key).or_else(|| { + origin_key_under_origin_name.as_ref().and_then( + |origin_key| exported_classes.get(origin_key), + ) + }); + if let Some(class) = imported_class { + let class_prefix = canonical_class_source_prefix( + class, + &class_canonical_path, + &ctx.project_root, + &origin_prefix, + ); + let local_alias = if export_name == &class.name { + None + } else { + Some(export_name.clone()) + }; + let mut imported_class = imported_class_from_hir( + class, + class_prefix, + local_alias, + proven_this_methods_for_import( + class, + &class_proven_this_methods, + ), + proven_this_methods_for_import( + class, + &class_proven_this_tower_methods, + ), + ); + imported_class.namespace = Some(local_name.clone()); + imported_classes.push(imported_class); + } + if let Some(members) = exported_enums.get(&key) { + imported_enums + .push((export_name.clone(), members.clone())); + } + } + // A named namespace re-export can itself expose + // nested namespace aliases (Zod's `z.core`, + // `z.locales`, `z.iso`, and `z.coerce` shape). + // Mark those members explicitly and overwrite + // the declaring-barrel prefixes registered by + // the ordinary export walk above with the + // namespace TARGET prefixes. + if let Some(nested) = + namespace_reexport_targets.get(&ns_target_str) + { + for (alias, target_path) in nested { + let target_prefix = compute_module_prefix( + &target_path.to_string_lossy(), + &ctx.project_root, + ); + namespace_member_prefixes.insert( + (local_name.clone(), alias.clone()), + target_prefix, + ); + namespace_member_nested + .insert((local_name.clone(), alias.clone())); + } + } + handled_as_namespace_reexport = true; + break; + } } } - } + if handled_as_namespace_reexport { + continue; + } - // Issue #35 (#321): companion to the HIR-side change in - // `module_decl.rs` (Named specifier now registers - // `(local, local)`, so an ALIASED named import's - // `ExternFuncRef` carries the unique LOCAL name). The - // origin module still emits its symbol under the EXPORTED - // name, so map `local → exported_name` (or the deeper - // re-export origin name when one applies) here so codegen - // forms `perry_fn___` rather than - // `perry_fn___`. Mirrors the #901 Default-import - // override below. Only needed when `local != exported` - // (the alias case); the no-alias case carries the export - // name verbatim. Skip if the re-export-rename block above - // already inserted a (deeper) override for this local. - if matches!(spec, perry_hir::ImportSpecifier::Named { .. }) - && local_name != exported_name - && !import_function_origin_names.contains_key(&local_name) - { - import_function_origin_names - .insert(local_name.clone(), exported_name.clone()); - } + let key = (resolved_path_str.clone(), exported_name.clone()); + + // Resolve the ORIGIN path of `exported_name` by following + // re-exports. `index.js`'s `export { pgTable } from "./table.js"` + // means the immediate import resolves to index.js but the + // actual `Let pgTable = (...) => ...` lives in table.js. The + // `exported_var_names` set is keyed by the ORIGIN path, so + // looking up `(index.js, "pgTable")` misses; we need to walk + // the re-export chain to find table.js. Refs #420. + let origin_path: String = + if let Some(exports) = all_module_exports.get(&resolved_path_str) { + if let Some(p) = exports.get(&exported_name) { + p.clone() + } else { + resolved_path_str.clone() + } + } else { + resolved_path_str.clone() + }; + let origin_key = (origin_path.clone(), exported_name.clone()); - // Issue #901: companion to the HIR-side change at - // `crates/perry-hir/src/lower.rs`'s Default specifier - // (which now registers `(local, local)` instead of - // `(local, "default")`). The HIR's `ExternFuncRef` now - // carries the LOCAL name (unique per import site), so - // `import_function_prefixes.get(local)` resolves to the - // right source module. But the symbol the codegen emits - // must still be `perry_fn___default` (or whatever - // origin-name the source actually exports default as), - // not `perry_fn___` — the source module emits - // its default-export symbol under the literal "default" - // suffix. Insert the local→"default" override (or the - // resolved origin name, when a re-export renamed it) so - // every `perry_fn___` construction site - // probing `import_function_origin_names` picks the right - // suffix. Pre-fix two same-file default imports of - // different modules collided on the "default" key and - // pino's `SORTING_ORDER.ASC` threw because `_req_9` - // (`./lib/constants`) and `_req_10` (`./lib/tools`) both - // resolved to `./lib/tools`. Pairs with the HIR change; - // both must land for the resolution to be correct. - if matches!(spec, perry_hir::ImportSpecifier::Default { .. }) { - let suffix = resolved_origin_name - .clone() - .unwrap_or_else(|| exported_name.clone()); - import_function_origin_names - .insert(local_name.clone(), suffix); - } + // Resolve effective prefix (follow re-exports) + let effective_prefix = if origin_path != resolved_path_str { + compute_module_prefix(&origin_path, &ctx.project_root) + } else { + source_prefix.clone() + }; - // Imported variables (not functions) — ExternFuncRef-as-value - // should call the getter, not wrap as closure. Look up by the - // ORIGIN path (where the `Let X = ...` actually lives), not - // the immediate import path. Without this, re-exports through - // `index.js` barrel files (drizzle's `pg-core/index.js`, - // hono's adapter index files, etc.) silently fall through to - // the direct-call path which treats the zero-arg getter's - // return value AS the call result — pgTable("users", cols) - // returned the closure handle (typeof === "function") with no - // pgTable body actually invoked. - // - // Issue #678 followup: when a re-export rename routes - // the import through `export default `, the origin - // module's `exported_objects` carries the synthetic - // "default" entry (the only thing exported at that - // shape) — not the consumer-visible name. Probe both - // keys so the var-vs-function classification fires - // even when re-export renaming is in play. - let origin_key_under_origin_name = resolved_origin_name - .as_ref() - .map(|n| (origin_path.clone(), n.clone())); - let source_exports_object = - exported_var_names.contains(&(resolved_path_str.clone(), exported_name.clone())); - if source_exports_object - || exported_var_names.contains(&origin_key) - || origin_key_under_origin_name - .as_ref() - .map(|k| exported_var_names.contains(k)) - .unwrap_or(false) - { - imported_vars.insert(exported_name.clone()); - if local_name != exported_name { - imported_vars.insert(local_name.clone()); + // Issue #: only key by `exported_name` in the + // no-rename case (`local_name == exported_name`), where + // the HIR's `ExternFuncRef` genuinely carries that + // string. In the aliased case (#35/#321 above: + // `ExternFuncRef` carries the LOCAL name, unique per + // import site), inserting under `exported_name` too is + // not just redundant — `exported_name` is whatever the + // ORIGIN module happens to call it, so it can collide + // with an unrelated LOCAL alias elsewhere in the same + // file. Concrete repro: `import { a as n, c as a } from + // "./x"; import { a as t } from "./y"` — the second + // specifier's exported name "a" overwrote the first + // import's *local* alias "a" (from `c as a`), silently + // repointing `ExternFuncRef { name: "a" }` at module y + // instead of x. Only inserting the ALIASED case under + // `local_name` (never also under `exported_name`) keeps + // every key in this map unique per file — local names + // can't collide with each other (each `let`/import + // binding needs a distinct identifier), but exported + // names from different source modules can and do. + if local_name == exported_name { + import_function_prefixes + .insert(exported_name.clone(), effective_prefix.clone()); + } else { + import_function_prefixes + .insert(local_name.clone(), effective_prefix.clone()); } - let origin_export_name = resolved_origin_name - .clone() - .unwrap_or_else(|| exported_name.clone()); - if let Some(capability) = exported_object_literals - .get(&(origin_path.clone(), origin_export_name.clone())) + // Issue #678: if the import chain renames through a + // re-export (`export { default as render } from + // './render.js'`), the symbol in the origin module + // is `perry_fn___default`, not + // `perry_fn___render`. Surface the deeper + // origin name via `import_function_origin_names` so + // the codegen can pick the right suffix when forming + // the extern symbol. The map is sparse — entries are + // only inserted when origin_name != exported_name. + let resolved_origin_name = all_module_export_origin_names + .get(&resolved_path_str) + .and_then(|m| m.get(&exported_name)) + .cloned(); + if let Some(ref origin_name) = resolved_origin_name { + if origin_name != &exported_name { + // Key by the same rule as `import_function_prefixes` + // above: the LOCAL name for an aliased import, the + // exported name otherwise — the HIR's `ExternFuncRef` + // carries exactly that string. Also inserting an + // aliased import under its EXPORTED name poisons any + // same-file binding that happens to share it: + // `import { XML } from "a"` + `import { XML as C } + // from "b"` (where b's barrel does `export { default + // as XML }`) rewrote a's `XML` suffix to `default` + // and the link failed on `perry_fn___default` + // (the fast-xml-parser × is-unsafe graph). + if local_name == exported_name { + import_function_origin_names + .insert(exported_name.clone(), origin_name.clone()); + } else { + import_function_origin_names + .insert(local_name.clone(), origin_name.clone()); + } + } + } + + // Issue #35 (#321): companion to the HIR-side change in + // `module_decl.rs` (Named specifier now registers + // `(local, local)`, so an ALIASED named import's + // `ExternFuncRef` carries the unique LOCAL name). The + // origin module still emits its symbol under the EXPORTED + // name, so map `local → exported_name` (or the deeper + // re-export origin name when one applies) here so codegen + // forms `perry_fn___` rather than + // `perry_fn___`. Mirrors the #901 Default-import + // override below. Only needed when `local != exported` + // (the alias case); the no-alias case carries the export + // name verbatim. Skip if the re-export-rename block above + // already inserted a (deeper) override for this local. + if matches!(spec, perry_hir::ImportSpecifier::Named { .. }) + && local_name != exported_name + && !import_function_origin_names.contains_key(&local_name) { - imported_classes.push(imported_object_literal_from_capability( - capability, - effective_prefix.clone(), - origin_export_name, - local_name.clone(), - )); + import_function_origin_names + .insert(local_name.clone(), exported_name.clone()); } - } - // Imported classes - if let Some(class) = exported_classes.get(&key) { - let class_prefix = canonical_class_source_prefix( - class, - &class_canonical_path, - &ctx.project_root, - &effective_prefix, - ); - // Issue #665: when the user wrote `import X from "pkg"` - // and `pkg`'s default export is a class, the importer - // still registers `exported_name="default"` into - // `import_function_prefixes` above. Codegen's wrapper- - // emission loop iterates that map and — for any name - // NOT in `imported_class_names` — emits a function - // wrapper that calls `perry_fn___default`, which - // the source module never defines (the source only has - // a `_Child_constructor` symbol). That declares an - // unresolved extern and the link step errors with - // `Undefined symbols: ___perry_wrap_perry_fn___default`. - // Push a SECOND ImportedClass entry whose `local_alias` - // is the exported_name (`"default"` for default imports, - // or the original-name for `{ Foo as Bar }`-style - // renames). codegen's `imported_class_names` builder - // adds both `ic.name` and `ic.local_alias`, so the - // exported_name lands in the set and the wrapper- - // emission loop takes the `is_class` no-op-stub branch - // instead of declaring a phantom function. The second - // entry also registers `class_ids[exported_name]`, - // letting consumer-side `Expr::ExternFuncRef { name: - // exported_name }` resolve to the class-id NaN-box. - if local_name != exported_name { - imported_classes.push(imported_class_from_hir( + // Issue #901: companion to the HIR-side change at + // `crates/perry-hir/src/lower.rs`'s Default specifier + // (which now registers `(local, local)` instead of + // `(local, "default")`). The HIR's `ExternFuncRef` now + // carries the LOCAL name (unique per import site), so + // `import_function_prefixes.get(local)` resolves to the + // right source module. But the symbol the codegen emits + // must still be `perry_fn___default` (or whatever + // origin-name the source actually exports default as), + // not `perry_fn___` — the source module emits + // its default-export symbol under the literal "default" + // suffix. Insert the local→"default" override (or the + // resolved origin name, when a re-export renamed it) so + // every `perry_fn___` construction site + // probing `import_function_origin_names` picks the right + // suffix. Pre-fix two same-file default imports of + // different modules collided on the "default" key and + // pino's `SORTING_ORDER.ASC` threw because `_req_9` + // (`./lib/constants`) and `_req_10` (`./lib/tools`) both + // resolved to `./lib/tools`. Pairs with the HIR change; + // both must land for the resolution to be correct. + if matches!(spec, perry_hir::ImportSpecifier::Default { .. }) { + let suffix = resolved_origin_name + .clone() + .unwrap_or_else(|| exported_name.clone()); + import_function_origin_names.insert(local_name.clone(), suffix); + } + + // Imported variables (not functions) — ExternFuncRef-as-value + // should call the getter, not wrap as closure. Look up by the + // ORIGIN path (where the `Let X = ...` actually lives), not + // the immediate import path. Without this, re-exports through + // `index.js` barrel files (drizzle's `pg-core/index.js`, + // hono's adapter index files, etc.) silently fall through to + // the direct-call path which treats the zero-arg getter's + // return value AS the call result — pgTable("users", cols) + // returned the closure handle (typeof === "function") with no + // pgTable body actually invoked. + // + // Issue #678 followup: when a re-export rename routes + // the import through `export default `, the origin + // module's `exported_objects` carries the synthetic + // "default" entry (the only thing exported at that + // shape) — not the consumer-visible name. Probe both + // keys so the var-vs-function classification fires + // even when re-export renaming is in play. + let origin_key_under_origin_name = resolved_origin_name + .as_ref() + .map(|n| (origin_path.clone(), n.clone())); + let source_exports_object = exported_var_names + .contains(&(resolved_path_str.clone(), exported_name.clone())); + if source_exports_object + || exported_var_names.contains(&origin_key) + || origin_key_under_origin_name + .as_ref() + .map(|k| exported_var_names.contains(k)) + .unwrap_or(false) + { + imported_vars.insert(exported_name.clone()); + if local_name != exported_name { + imported_vars.insert(local_name.clone()); + } + + let origin_export_name = resolved_origin_name + .clone() + .unwrap_or_else(|| exported_name.clone()); + if let Some(capability) = exported_object_literals + .get(&(origin_path.clone(), origin_export_name.clone())) + { + imported_classes.push(imported_object_literal_from_capability( + capability, + effective_prefix.clone(), + origin_export_name, + local_name.clone(), + )); + } + } + + // Imported classes + if let Some(class) = exported_classes.get(&key) { + let class_prefix = canonical_class_source_prefix( class, - class_prefix.clone(), - Some(exported_name.clone()), - proven_this_methods_for_import( + &class_canonical_path, + &ctx.project_root, + &effective_prefix, + ); + // Issue #665: when the user wrote `import X from "pkg"` + // and `pkg`'s default export is a class, the importer + // still registers `exported_name="default"` into + // `import_function_prefixes` above. Codegen's wrapper- + // emission loop iterates that map and — for any name + // NOT in `imported_class_names` — emits a function + // wrapper that calls `perry_fn___default`, which + // the source module never defines (the source only has + // a `_Child_constructor` symbol). That declares an + // unresolved extern and the link step errors with + // `Undefined symbols: ___perry_wrap_perry_fn___default`. + // Push a SECOND ImportedClass entry whose `local_alias` + // is the exported_name (`"default"` for default imports, + // or the original-name for `{ Foo as Bar }`-style + // renames). codegen's `imported_class_names` builder + // adds both `ic.name` and `ic.local_alias`, so the + // exported_name lands in the set and the wrapper- + // emission loop takes the `is_class` no-op-stub branch + // instead of declaring a phantom function. The second + // entry also registers `class_ids[exported_name]`, + // letting consumer-side `Expr::ExternFuncRef { name: + // exported_name }` resolve to the class-id NaN-box. + if local_name != exported_name { + imported_classes.push(imported_class_from_hir( class, - &class_proven_this_methods, - ), + class_prefix.clone(), + Some(exported_name.clone()), + proven_this_methods_for_import( + class, + &class_proven_this_methods, + ), + proven_this_methods_for_import( + class, + &class_proven_this_tower_methods, + ), + )); + } + imported_classes.push(imported_class_from_hir( + class, + class_prefix, + if local_name != class.name { + Some(local_name.clone()) + } else { + None + }, + proven_this_methods_for_import(class, &class_proven_this_methods), proven_this_methods_for_import( class, &class_proven_this_tower_methods, ), )); } - imported_classes.push(imported_class_from_hir( - class, - class_prefix, - if local_name != class.name { - Some(local_name.clone()) - } else { - None - }, - proven_this_methods_for_import(class, &class_proven_this_methods), - proven_this_methods_for_import( - class, - &class_proven_this_tower_methods, - ), - )); - } - // Imported param counts - if let Some(¶m_count) = exported_func_param_counts.get(&key) { - imported_param_counts.insert(exported_name.clone(), param_count); - if local_name != exported_name { - imported_param_counts.insert(local_name.clone(), param_count); + // Imported param counts + if let Some(¶m_count) = exported_func_param_counts.get(&key) { + imported_param_counts.insert(exported_name.clone(), param_count); + if local_name != exported_name { + imported_param_counts.insert(local_name.clone(), param_count); + } } - } - // Issue #608 — propagate has_rest alongside the param - // count so the cross-module call site can pack the - // trailing args into a rest array. - if exported_func_has_rest.get(&key).copied().unwrap_or(false) { - imported_has_rest.insert(exported_name.clone()); - if local_name != exported_name { - imported_has_rest.insert(local_name.clone()); + // Issue #608 — propagate has_rest alongside the param + // count so the cross-module call site can pack the + // trailing args into a rest array. + if exported_func_has_rest.get(&key).copied().unwrap_or(false) { + imported_has_rest.insert(exported_name.clone()); + if local_name != exported_name { + imported_has_rest.insert(local_name.clone()); + } } - } - if exported_func_synthetic_arguments.contains(&key) { - imported_synthetic_arguments.insert(exported_name.clone()); - if local_name != exported_name { - imported_synthetic_arguments.insert(local_name.clone()); + if exported_func_synthetic_arguments.contains(&key) { + imported_synthetic_arguments.insert(exported_name.clone()); + if local_name != exported_name { + imported_synthetic_arguments.insert(local_name.clone()); + } } - } - // Imported return types - if let Some(return_type) = exported_func_return_types.get(&key) { - imported_return_types.insert(local_name.clone(), return_type.clone()); - } + // Imported return types + if let Some(return_type) = exported_func_return_types.get(&key) { + imported_return_types.insert(local_name.clone(), return_type.clone()); + } - // #7170 R2: cross-module return-shape provenance. Resolve - // the same exact origin path/name the call-symbol plumbing - // above uses, then install both halves atomically: - // - // * LOCAL ExternFuncRef name -> returned shape, and - // * the source class's field metadata in imported_classes. - // - // The producer pre-pass exports anonymous record shapes - // only. Their names content-address the complete field - // shape, so a same-named local class is the same layout; - // named user classes remain fail-closed in this increment. - let return_shape_origin_name = resolved_origin_name - .as_ref() - .unwrap_or(&exported_name) - .clone(); - let return_shape_key = (origin_path.clone(), return_shape_origin_name); - if let Some(class) = exported_return_shapes.get(&return_shape_key).copied() { - let imported_index = match imported_classes - .iter() - .position(|imported| imported.name == class.name) + // #7170 R2: cross-module return-shape provenance. Resolve + // the same exact origin path/name the call-symbol plumbing + // above uses, then install both halves atomically: + // + // * LOCAL ExternFuncRef name -> returned shape, and + // * the source class's field metadata in imported_classes. + // + // The producer pre-pass exports anonymous record shapes + // only. Their names content-address the complete field + // shape, so a same-named local class is the same layout; + // named user classes remain fail-closed in this increment. + let return_shape_origin_name = resolved_origin_name + .as_ref() + .unwrap_or(&exported_name) + .clone(); + let return_shape_key = (origin_path.clone(), return_shape_origin_name); + if let Some(class) = exported_return_shapes.get(&return_shape_key).copied() { - Some(index) => index, - None => { - let class_prefix = - compute_module_prefix(&origin_path, &ctx.project_root); - imported_classes.push(imported_class_from_hir( - class, - class_prefix, - None, - proven_this_methods_for_import( - class, - &class_proven_this_methods, - ), - proven_this_methods_for_import( + let imported_index = match imported_classes + .iter() + .position(|imported| imported.name == class.name) + { + Some(index) => index, + None => { + let class_prefix = + compute_module_prefix(&origin_path, &ctx.project_root); + imported_classes.push(imported_class_from_hir( class, - &class_proven_this_tower_methods, - ), - )); - imported_classes.len() - 1 + class_prefix, + None, + proven_this_methods_for_import( + class, + &class_proven_this_methods, + ), + proven_this_methods_for_import( + class, + &class_proven_this_tower_methods, + ), + )); + imported_classes.len() - 1 + } + }; + let imported = &mut imported_classes[imported_index]; + if !imported.return_shape_imports.contains(&local_name) { + imported.return_shape_imports.push(local_name.clone()); } - }; - let imported = &mut imported_classes[imported_index]; - if !imported.return_shape_imports.contains(&local_name) { - imported.return_shape_imports.push(local_name.clone()); } - } - // Imported async functions - if exported_async_funcs.contains(&key) { - imported_async_set.insert(local_name.clone()); - if local_name != exported_name { - imported_async_set.insert(exported_name.clone()); + // Imported async functions + if exported_async_funcs.contains(&key) { + imported_async_set.insert(local_name.clone()); + if local_name != exported_name { + imported_async_set.insert(exported_name.clone()); + } } - } - // Imported enums - if let Some(members) = exported_enums.get(&key) { - imported_enums.push((local_name.clone(), members.clone())); + // Imported enums + if let Some(members) = exported_enums.get(&key) { + imported_enums.push((local_name.clone(), members.clone())); + } } - } - // Named imports only bring in explicitly-imported symbols, so - // a class that leaks out of the source module as the return - // type of an imported *function* (e.g. `import { makeThing }` - // where `makeThing(): Promise`) leaves `Thing` invisible - // to this module's dispatch tables. `t.doWork(...)` then can't - // find `("Thing", "doWork")` in `ctx.methods` and falls through - // to `js_native_call_method`, which returns the receiver's - // ObjectHeader as a stub. Closes #83. - // - // Mirror the namespace-import behavior: for every - // native-compiled module we import from (and every module that - // module transitively re-exports from), enumerate every class - // defined in that module and register it for dispatch, even - // when the class name wasn't in the specifier list. Local - // classes with the same name take precedence in - // `compile_module` (the `class_table.contains_key` check), so - // this doesn't clobber anything. - // - // We iterate `ctx.native_modules` directly — NOT the - // `exported_classes` BTreeMap. `exported_classes` gets alias - // entries stamped under every re-exporter's path (the - // `Export::ReExport` / `Export::ExportAll` propagation loop - // above), so iterating it would hand us the class keyed by - // `index.ts` when it was actually compiled under - // `pool.ts`. Using each module's own `hir.classes` Vec guarantees - // `src_path` is the TRUE defining module, so the mangled - // `perry_method_____` symbol - // matches what that module actually emitted (otherwise the - // linker fails with "undefined symbol - // _perry_method_src_index_ts__Pool__query" when Pool was - // compiled under src_pool_ts). - let mut origin_paths: std::collections::HashSet = - std::collections::HashSet::new(); - origin_paths.insert(resolved_path_str.clone()); - if let Some(exports) = all_module_exports.get(&resolved_path_str) { - for origin_path in exports.values() { - origin_paths.insert(origin_path.clone()); - } - } - for (src_pathbuf, src_hir) in &ctx.native_modules { - let src_path = src_pathbuf.to_string_lossy().to_string(); - if !origin_paths.contains(&src_path) { - continue; - } - for class in &src_hir.classes { - if !class.is_exported { - continue; + // Named imports only bring in explicitly-imported symbols, so + // a class that leaks out of the source module as the return + // type of an imported *function* (e.g. `import { makeThing }` + // where `makeThing(): Promise`) leaves `Thing` invisible + // to this module's dispatch tables. `t.doWork(...)` then can't + // find `("Thing", "doWork")` in `ctx.methods` and falls through + // to `js_native_call_method`, which returns the receiver's + // ObjectHeader as a stub. Closes #83. + // + // Mirror the namespace-import behavior: for every + // native-compiled module we import from (and every module that + // module transitively re-exports from), enumerate every class + // defined in that module and register it for dispatch, even + // when the class name wasn't in the specifier list. Local + // classes with the same name take precedence in + // `compile_module` (the `class_table.contains_key` check), so + // this doesn't clobber anything. + // + // We iterate `ctx.native_modules` directly — NOT the + // `exported_classes` BTreeMap. `exported_classes` gets alias + // entries stamped under every re-exporter's path (the + // `Export::ReExport` / `Export::ExportAll` propagation loop + // above), so iterating it would hand us the class keyed by + // `index.ts` when it was actually compiled under + // `pool.ts`. Using each module's own `hir.classes` Vec guarantees + // `src_path` is the TRUE defining module, so the mangled + // `perry_method_____` symbol + // matches what that module actually emitted (otherwise the + // linker fails with "undefined symbol + // _perry_method_src_index_ts__Pool__query" when Pool was + // compiled under src_pool_ts). + let mut origin_paths: std::collections::HashSet = + std::collections::HashSet::new(); + origin_paths.insert(resolved_path_str.clone()); + if let Some(exports) = all_module_exports.get(&resolved_path_str) { + for origin_path in exports.values() { + origin_paths.insert(origin_path.clone()); } - // Dedup across multiple import statements: the same class - // may be transitively reachable from several imports, and - // the same-class-twice case would produce duplicate - // `@perry_class_keys___` globals in IR. - // Same-name local classes win via `compile_module`'s - // class_table check, so this filter is strictly about - // cross-module twinning. - if imported_classes.iter().any(|c| c.name == class.name) { + } + for (src_pathbuf, src_hir) in &ctx.native_modules { + let src_path = src_pathbuf.to_string_lossy().to_string(); + if !origin_paths.contains(&src_path) { continue; } - let class_prefix = compute_module_prefix(&src_path, &ctx.project_root); - imported_classes.push(imported_class_from_hir( - class, - class_prefix, - None, - proven_this_methods_for_import(class, &class_proven_this_methods), - proven_this_methods_for_import( + for class in &src_hir.classes { + if !class.is_exported { + continue; + } + // Dedup across multiple import statements: the same class + // may be transitively reachable from several imports, and + // the same-class-twice case would produce duplicate + // `@perry_class_keys___` globals in IR. + // Same-name local classes win via `compile_module`'s + // class_table check, so this filter is strictly about + // cross-module twinning. + if imported_classes.iter().any(|c| c.name == class.name) { + continue; + } + let class_prefix = compute_module_prefix(&src_path, &ctx.project_root); + imported_classes.push(imported_class_from_hir( class, - &class_proven_this_tower_methods, - ), - )); + class_prefix, + None, + proven_this_methods_for_import(class, &class_proven_this_methods), + proven_this_methods_for_import( + class, + &class_proven_this_tower_methods, + ), + )); + } } } - } - // Issue #678 followup: V8-fallback imports. Native imports above - // wire `perry_fn___` extern symbols; V8 imports route - // through the runtime bridge instead. We populate BOTH - // `import_function_prefixes` (with a synthetic prefix so the - // codegen's `Some(source_prefix) = prefixes.get(name)` arm fires - // and the V8-specifier short-circuit inside it triggers) AND - // `import_function_v8_specifiers` (the actual specifier the bridge - // hands to `js_load_module`). The synthetic prefix never reaches - // a `perry_fn_...` symbol because every codegen site probes - // `import_function_v8_specifiers` first. - for import in &hir_module.imports { - if import.type_only || import.runtime_erased { - continue; - } - if import.module_kind != perry_hir::ModuleKind::Interpreted { - continue; - } - // The V8 bridge takes a specifier string and resolves it - // through deno_core's Node loader — bare specifiers like - // "ink" and absolute paths both work. Prefer the resolved - // canonical path (matches the `JsModule.specifier` key in - // `ctx.js_modules`) so the same module-handle cache hits - // across imports of the same package from different sites. - let specifier = import - .resolved_path - .clone() - .unwrap_or_else(|| import.source.clone()); - let synthetic_prefix = format!("__v8__{}", sanitize_name(&specifier)); - for spec in &import.specifiers { - match spec { - perry_hir::ImportSpecifier::Named { imported, local } => { - import_function_prefixes - .insert(local.clone(), synthetic_prefix.clone()); - import_function_v8_specifiers - .insert(local.clone(), specifier.clone()); - if local != imported { + // Issue #678 followup: V8-fallback imports. Native imports above + // wire `perry_fn___` extern symbols; V8 imports route + // through the runtime bridge instead. We populate BOTH + // `import_function_prefixes` (with a synthetic prefix so the + // codegen's `Some(source_prefix) = prefixes.get(name)` arm fires + // and the V8-specifier short-circuit inside it triggers) AND + // `import_function_v8_specifiers` (the actual specifier the bridge + // hands to `js_load_module`). The synthetic prefix never reaches + // a `perry_fn_...` symbol because every codegen site probes + // `import_function_v8_specifiers` first. + for import in &hir_module.imports { + if import.type_only || import.runtime_erased { + continue; + } + if import.module_kind != perry_hir::ModuleKind::Interpreted { + continue; + } + // The V8 bridge takes a specifier string and resolves it + // through deno_core's Node loader — bare specifiers like + // "ink" and absolute paths both work. Prefer the resolved + // canonical path (matches the `JsModule.specifier` key in + // `ctx.js_modules`) so the same module-handle cache hits + // across imports of the same package from different sites. + let specifier = import + .resolved_path + .clone() + .unwrap_or_else(|| import.source.clone()); + let synthetic_prefix = format!("__v8__{}", sanitize_name(&specifier)); + for spec in &import.specifiers { + match spec { + perry_hir::ImportSpecifier::Named { imported, local } => { + import_function_prefixes + .insert(local.clone(), synthetic_prefix.clone()); + import_function_v8_specifiers + .insert(local.clone(), specifier.clone()); + if local != imported { + import_function_prefixes + .insert(imported.clone(), synthetic_prefix.clone()); + import_function_v8_specifiers + .insert(imported.clone(), specifier.clone()); + // Issue #818 (Effect.succeed pattern) follow-up: + // when an aliased named-import (`import { Foo + // as Bar }`) of a V8 module is used as a + // static-method receiver (`Bar.method(...)`), + // the codegen's StaticMethodCall arm sees + // class_name = "Bar" — but the V8 namespace + // exposes the property under "Foo". Record the + // local→imported mapping in + // `import_function_origin_names` so the bridge + // call reaches the right namespace property. + // Without this, aliased Effect-shaped imports + // would look up a missing property and fall to + // undefined. + import_function_origin_names + .insert(local.clone(), imported.clone()); + } + } + perry_hir::ImportSpecifier::Default { local } => { import_function_prefixes - .insert(imported.clone(), synthetic_prefix.clone()); + .insert(local.clone(), synthetic_prefix.clone()); import_function_v8_specifiers - .insert(imported.clone(), specifier.clone()); - // Issue #818 (Effect.succeed pattern) follow-up: - // when an aliased named-import (`import { Foo - // as Bar }`) of a V8 module is used as a - // static-method receiver (`Bar.method(...)`), - // the codegen's StaticMethodCall arm sees - // class_name = "Bar" — but the V8 namespace - // exposes the property under "Foo". Record the - // local→imported mapping in - // `import_function_origin_names` so the bridge - // call reaches the right namespace property. - // Without this, aliased Effect-shaped imports - // would look up a missing property and fall to - // undefined. + .insert(local.clone(), specifier.clone()); + // #1195 — `import YAML from "yaml"` lands here. + // When the local name is used as a static-method + // receiver (`YAML.parse(...)`), the StaticMethodCall + // arm in expr/static_method.rs looks up + // `import_function_origin_names[class_name]` to + // pick the namespace property name, falling back + // to the local name. Without this insert, the + // bridge would ask V8 for `ns.YAML` (which doesn't + // exist on the proxy module's namespace; it + // re-exports the default under the literal + // "default" key). Record the local→"default" + // override so the bridge resolves the right + // namespace property. import_function_origin_names - .insert(local.clone(), imported.clone()); + .insert(local.clone(), "default".to_string()); + } + perry_hir::ImportSpecifier::Namespace { local } => { + // Namespace bindings (`import * as X from "ink"`) + // are already registered into `namespace_imports` + // by the pre-loop above. For pure-namespace usage + // with no companion `Named` import, the V8 module + // has no static export list to register members + // against — so we record `local → specifier` here. + // The codegen's StaticMethodCall arm and the + // namespace-member-call arm in `lower_call.rs` + // probe `namespace_v8_specifiers` and, on a hit, + // emit `js_call_v8_export(specifier, member, + // args, argc)` so `R.sum([1,2,3])` (`import * as + // R from "ramda"`) reaches V8 instead of falling + // to the `double_literal(0.0)` stub. Unblocks + // ramda / date-fns / jose / effect wildcard + // namespace usage. + namespace_v8_specifiers.insert(local.clone(), specifier.clone()); } - } - perry_hir::ImportSpecifier::Default { local } => { - import_function_prefixes - .insert(local.clone(), synthetic_prefix.clone()); - import_function_v8_specifiers - .insert(local.clone(), specifier.clone()); - // #1195 — `import YAML from "yaml"` lands here. - // When the local name is used as a static-method - // receiver (`YAML.parse(...)`), the StaticMethodCall - // arm in expr/static_method.rs looks up - // `import_function_origin_names[class_name]` to - // pick the namespace property name, falling back - // to the local name. Without this insert, the - // bridge would ask V8 for `ns.YAML` (which doesn't - // exist on the proxy module's namespace; it - // re-exports the default under the literal - // "default" key). Record the local→"default" - // override so the bridge resolves the right - // namespace property. - import_function_origin_names - .insert(local.clone(), "default".to_string()); - } - perry_hir::ImportSpecifier::Namespace { local } => { - // Namespace bindings (`import * as X from "ink"`) - // are already registered into `namespace_imports` - // by the pre-loop above. For pure-namespace usage - // with no companion `Named` import, the V8 module - // has no static export list to register members - // against — so we record `local → specifier` here. - // The codegen's StaticMethodCall arm and the - // namespace-member-call arm in `lower_call.rs` - // probe `namespace_v8_specifiers` and, on a hit, - // emit `js_call_v8_export(specifier, member, - // args, argc)` so `R.sum([1,2,3])` (`import * as - // R from "ramda"`) reaches V8 instead of falling - // to the `double_literal(0.0)` stub. Unblocks - // ramda / date-fns / jose / effect wildcard - // namespace usage. - namespace_v8_specifiers - .insert(local.clone(), specifier.clone()); } } } - } - // Issue #841: register named + namespace imports from the - // five recognized Node submodules — `node:timers/promises`, - // `node:readline/promises`, `node:stream/promises`, - // `node:stream/consumers`, `node:sys`. These don't resolve - // to anything perry-stdlib can back, but the runtime ships - // a `js_node_submodule_export_as_function` helper that - // returns a function singleton for each known export, plus - // `js_node_submodule_namespace` for namespace shapes. - // - // Without this registration the codegen's `ExternFuncRef` - // value-form catch-all fell to TAG_TRUE, so `typeof - // setTimeout` (from `node:timers/promises`) reported - // `"boolean"` instead of `"function"`. Namespaces were - // hard-errored at module-collection time pre-fix - // (`collect_modules.rs::known_node_submodule_key`); they - // now flow through and land here. - for import in &hir_module.imports { - if import.type_only || import.runtime_erased { - continue; - } - let submod_key = match self::collect_modules::known_node_submodule_key(&import.source) { - Some(k) => k.to_string(), - None => continue, - }; - for spec in &import.specifiers { - match spec { - perry_hir::ImportSpecifier::Named { imported, local } => { - // #1213: node:timers named imports (`import { - // setTimeout } from "node:timers"`) keep the global - // timer codegen fast-path (which handles the - // `setTimeout(fn, delay, ...args)` varargs form). - // Routing them through the submodule thunk here - // would drop varargs — only the `import * as` - // namespace shape uses the submodule. - if submod_key != "timers" { - // Register ONLY the local binding. For an - // aliased import (`import { setTimeout as ac5 } - // from "node:timers/promises"`) the in-scope - // name is `ac5`; the imported name `setTimeout` - // is NOT bound here — it still refers to the - // GLOBAL `setTimeout(callback, delay)`. A prior - // version also keyed the map by `imported` when - // `local != imported`, which made the bare - // global `setTimeout(fn, ms)` divert to the - // delay-first promises thunk and reject with - // `The "delay" argument must be of type number. - // Received function`. Keying only by `local` - // keeps the alias routed to the submodule export - // and leaves the unshadowed global intact. + // Issue #841: register named + namespace imports from the + // five recognized Node submodules — `node:timers/promises`, + // `node:readline/promises`, `node:stream/promises`, + // `node:stream/consumers`, `node:sys`. These don't resolve + // to anything perry-stdlib can back, but the runtime ships + // a `js_node_submodule_export_as_function` helper that + // returns a function singleton for each known export, plus + // `js_node_submodule_namespace` for namespace shapes. + // + // Without this registration the codegen's `ExternFuncRef` + // value-form catch-all fell to TAG_TRUE, so `typeof + // setTimeout` (from `node:timers/promises`) reported + // `"boolean"` instead of `"function"`. Namespaces were + // hard-errored at module-collection time pre-fix + // (`collect_modules.rs::known_node_submodule_key`); they + // now flow through and land here. + for import in &hir_module.imports { + if import.type_only || import.runtime_erased { + continue; + } + let submod_key = + match self::collect_modules::known_node_submodule_key(&import.source) { + Some(k) => k.to_string(), + None => continue, + }; + for spec in &import.specifiers { + match spec { + perry_hir::ImportSpecifier::Named { imported, local } => { + // #1213: node:timers named imports (`import { + // setTimeout } from "node:timers"`) keep the global + // timer codegen fast-path (which handles the + // `setTimeout(fn, delay, ...args)` varargs form). + // Routing them through the submodule thunk here + // would drop varargs — only the `import * as` + // namespace shape uses the submodule. + if submod_key != "timers" { + // Register ONLY the local binding. For an + // aliased import (`import { setTimeout as ac5 } + // from "node:timers/promises"`) the in-scope + // name is `ac5`; the imported name `setTimeout` + // is NOT bound here — it still refers to the + // GLOBAL `setTimeout(callback, delay)`. A prior + // version also keyed the map by `imported` when + // `local != imported`, which made the bare + // global `setTimeout(fn, ms)` divert to the + // delay-first promises thunk and reject with + // `The "delay" argument must be of type number. + // Received function`. Keying only by `local` + // keeps the alias routed to the submodule export + // and leaves the unshadowed global intact. + import_function_node_submodule.insert( + local.clone(), + (submod_key.clone(), imported.clone()), + ); + } + } + perry_hir::ImportSpecifier::Default { local } => { + // Default imports route to "default" — known Node + // submodules expose an object-valued default export + // that is distinct from the namespace object. import_function_node_submodule.insert( local.clone(), - (submod_key.clone(), imported.clone()), + (submod_key.clone(), "default".to_string()), ); } - } - perry_hir::ImportSpecifier::Default { local } => { - // Default imports route to "default" — known Node - // submodules expose an object-valued default export - // that is distinct from the namespace object. - import_function_node_submodule.insert( - local.clone(), - (submod_key.clone(), "default".to_string()), - ); - } - perry_hir::ImportSpecifier::Namespace { local } => { - namespace_node_submodules - .insert(local.clone(), submod_key.clone()); - // Already in `namespace_imports` via the - // pre-loop at L3441; nothing else to do. + perry_hir::ImportSpecifier::Namespace { local } => { + namespace_node_submodules.insert(local.clone(), submod_key.clone()); + // Already in `namespace_imports` via the + // pre-loop at L3441; nothing else to do. + } } } } - } - // Do not augment type-only interface consumers with every exported - // class in the program (the old issue #240 fallback). Dynamic method - // calls and method-as-value reads now resolve through the runtime's - // class-vtable registry; copying all class metadata here multiplied - // unrelated consumer IR and object size by the whole program. - - // Transitive class closure: pull in classes referenced by fields, - // declared call results, and parents of already-imported classes. - // Without the field side of this, a - // chain like `vm.viewport.scroll.scrollTop` (where vm is - // `EditorViewModel`, `viewport: ViewportManager`, `scroll: - // ScrollController`) breaks at the first hop because only - // `EditorViewModel` lives in `imported_classes` for this - // module — `receiver_class_name` can't walk through - // `viewport.scroll` because `ViewportManager` isn't in - // `class_table` and its field types are unknown. Closing - // over field types lets `PropertyGet` recursion resolve - // the receiver class at every step of the chain. - let mut visited_imports: std::collections::HashSet = - imported_classes.iter().map(|ic| ic.name.clone()).collect(); - // Issue #26 / #321: a class's `extends` parent must be resolved in - // the CHILD's own source module — same-named classes in different - // modules (effect's `Type` in SchemaAST.ts vs ParseResult.ts) are - // distinct. The by-NAME `visited_imports` dedup above would import - // only the first `Type` seen and skip the SchemaAST one, so - // SchemaAST's `OptionalType extends Type` chain loses its real - // parent's fields. Track parent additions by (path, name) identity - // so the correct-module parent is pulled in even when its bare - // name was already visited. Codegen's prefix-disambiguated parent - // resolver then picks the right one. - let mut visited_parent_paths: std::collections::HashSet<(String, String)> = - std::collections::HashSet::new(); - // Worklist of INDICES into `imported_classes` (not names): a name - // can map to several entries (same-named cross-module classes, - // refs #26), so we must process the exact entry we added, not the - // first by-name match. - let mut closure_worklist: Vec = (0..imported_classes.len()).collect(); - while let Some(idx) = closure_worklist.pop() { - if idx >= imported_classes.len() { - continue; - } - let field_types_clone = imported_classes[idx].field_types.clone(); - let method_return_types_clone: Vec = imported_classes[idx] - .method_return_types - .iter() - .chain(imported_classes[idx].static_method_return_types.iter()) - .chain(imported_classes[idx].getter_return_types.iter()) - .cloned() - .collect(); - let parent_name_clone = imported_classes[idx].parent_name.clone(); - let child_source_prefix = imported_classes[idx].source_prefix.clone(); - let child_src_path = native_module_paths_by_prefix.get(&child_source_prefix); - // Issue #485: include the class's parent in the transitive - // closure too. Without this, `import { Sub } from 'pkg'` where - // `Sub extends Base` (and Base lives in another file inside - // the same package) leaves Base unimported on this side, so - // codegen builds Sub's per-class shape with zero parent-field - // contribution. Sub instances allocate too few inline slots - // and the parent's cross-module ctor's `this.field = …` - // writes overflow the object header — `f.field` reads - // undefined on the importing side. - // - // `is_parent_ref` marks the entry that came from `extends` - // (vs a field or return-type reference): parent refs get - // path-aware resolution + (path,name) dedup so the - // correct-module parent is imported even past the bare-name - // dedup. Other refs keep the legacy by-name behavior because - // codegen's class dispatch table is still name-keyed. - let mut named_refs = std::collections::BTreeSet::new(); - for ty in field_types_clone.iter().chain(method_return_types_clone.iter()) { - collect_named_class_refs(ty, &mut named_refs); - } - let refs: Vec<(String, bool)> = named_refs - .into_iter() - .map(|name| (name, false)) - .chain(parent_name_clone.into_iter().map(|name| (name, true))) - .collect(); - for (ref_name, is_parent_ref) in refs { - // Resolve the type name in the declaring class's own - // module before falling back to the legacy global lookup. - // This includes erased `import type { Result as Local }` - // bindings, but only consumes their class metadata: it - // does not create a value binding or module-init edge. - let scoped_found = child_src_path.and_then(|child_path| { - let module = ctx.native_modules.get(child_path)?; - if let Some(class) = - module.classes.iter().find(|class| class.name == ref_name) - { - let canonical_path = class_canonical_path - .get(&(class as *const perry_hir::Class as usize)) - .cloned() - .unwrap_or_else(|| child_path.to_string_lossy().into_owned()); - return Some((canonical_path, class)); - } - module.imports.iter().find_map(|import| { - if import.module_kind != perry_hir::ModuleKind::NativeCompiled { - return None; - } - let resolved_path = import.resolved_path.as_ref()?; - import.specifiers.iter().find_map(|specifier| { - let (exported_name, local_name) = match specifier { - perry_hir::ImportSpecifier::Named { imported, local } => { - (imported.as_str(), local.as_str()) - } - perry_hir::ImportSpecifier::Default { local } => { - ("default", local.as_str()) - } - perry_hir::ImportSpecifier::Namespace { .. } => return None, - }; - if local_name != ref_name { - return None; - } - let origin_path = all_module_exports - .get(resolved_path) - .and_then(|exports| exports.get(exported_name)) - .cloned() - .unwrap_or_else(|| resolved_path.clone()); - let origin_name = all_module_export_origin_names - .get(resolved_path) - .and_then(|names| names.get(exported_name)) - .cloned() - .unwrap_or_else(|| exported_name.to_string()); - let class = exported_classes - .get(&(origin_path.clone(), origin_name.clone())) - .or_else(|| { - exported_classes - .get(&(origin_path.clone(), exported_name.to_string())) - }) - .or_else(|| { - exported_classes.get(&( - resolved_path.clone(), - exported_name.to_string(), - )) - })?; - let canonical_path = class_canonical_path - .get(&(*class as *const perry_hir::Class as usize)) - .cloned() - .unwrap_or(origin_path); - Some((canonical_path, *class)) - }) - }) - }); - // Issue #489: pick the canonical defining path for the - // parent class (where `class N { ... }` actually lives) - // rather than the first BTreeMap match by name (which - // can be a re-export barrel). Without this, drizzle's - // `MySqlPreparedQuery extends QueryPromise` chain pulls - // QueryPromise in under `drizzle-orm/index.js` (because - // `index.js` does `export * from "./query-promise.js"` - // and sorts before `query-promise.js`), and the dispatch - // table emits `perry_method___QueryPromise__then` - // — undefined symbol at link time. + // Do not augment type-only interface consumers with every exported + // class in the program (the old issue #240 fallback). Dynamic method + // calls and method-as-value reads now resolve through the runtime's + // class-vtable registry; copying all class metadata here multiplied + // unrelated consumer IR and object size by the whole program. + + // Transitive class closure: pull in classes referenced by fields, + // declared call results, and parents of already-imported classes. + // Without the field side of this, a + // chain like `vm.viewport.scroll.scrollTop` (where vm is + // `EditorViewModel`, `viewport: ViewportManager`, `scroll: + // ScrollController`) breaks at the first hop because only + // `EditorViewModel` lives in `imported_classes` for this + // module — `receiver_class_name` can't walk through + // `viewport.scroll` because `ViewportManager` isn't in + // `class_table` and its field types are unknown. Closing + // over field types lets `PropertyGet` recursion resolve + // the receiver class at every step of the chain. + let mut visited_imports: std::collections::HashSet = + imported_classes.iter().map(|ic| ic.name.clone()).collect(); + // Issue #26 / #321: a class's `extends` parent must be resolved in + // the CHILD's own source module — same-named classes in different + // modules (effect's `Type` in SchemaAST.ts vs ParseResult.ts) are + // distinct. The by-NAME `visited_imports` dedup above would import + // only the first `Type` seen and skip the SchemaAST one, so + // SchemaAST's `OptionalType extends Type` chain loses its real + // parent's fields. Track parent additions by (path, name) identity + // so the correct-module parent is pulled in even when its bare + // name was already visited. Codegen's prefix-disambiguated parent + // resolver then picks the right one. + let mut visited_parent_paths: std::collections::HashSet<(String, String)> = + std::collections::HashSet::new(); + // Worklist of INDICES into `imported_classes` (not names): a name + // can map to several entries (same-named cross-module classes, + // refs #26), so we must process the exact entry we added, not the + // first by-name match. + let mut closure_worklist: Vec = (0..imported_classes.len()).collect(); + while let Some(idx) = closure_worklist.pop() { + if idx >= imported_classes.len() { + continue; + } + let field_types_clone = imported_classes[idx].field_types.clone(); + let method_return_types_clone: Vec = imported_classes + [idx] + .method_return_types + .iter() + .chain(imported_classes[idx].static_method_return_types.iter()) + .chain(imported_classes[idx].getter_return_types.iter()) + .cloned() + .collect(); + let parent_name_clone = imported_classes[idx].parent_name.clone(); + let child_source_prefix = imported_classes[idx].source_prefix.clone(); + let child_src_path = native_module_paths_by_prefix.get(&child_source_prefix); + // Issue #485: include the class's parent in the transitive + // closure too. Without this, `import { Sub } from 'pkg'` where + // `Sub extends Base` (and Base lives in another file inside + // the same package) leaves Base unimported on this side, so + // codegen builds Sub's per-class shape with zero parent-field + // contribution. Sub instances allocate too few inline slots + // and the parent's cross-module ctor's `this.field = …` + // writes overflow the object header — `f.field` reads + // undefined on the importing side. // - // Issue #26: for a parent ref, prefer the same-named class - // in the CHILD's own source module before any global match. - let found = scoped_found.or_else(|| { - exported_classes - .iter() - .find(|((path, cname), class)| { - cname == &ref_name - && class_canonical_path - .get(&(**class as *const perry_hir::Class as usize)) - .map(|canonical| canonical == path) - .unwrap_or(true) - }) - .or_else(|| { - exported_classes - .iter() - .find(|((_, cname), _)| cname == &ref_name) - }) - .map(|((path, _), class)| { - // `exported_classes` deliberately carries alias - // entries stamped under barrel paths. Selecting - // one is valid for scope resolution, but symbols - // still live in the defining module. + // `is_parent_ref` marks the entry that came from `extends` + // (vs a field or return-type reference): parent refs get + // path-aware resolution + (path,name) dedup so the + // correct-module parent is imported even past the bare-name + // dedup. Other refs keep the legacy by-name behavior because + // codegen's class dispatch table is still name-keyed. + let mut named_refs = std::collections::BTreeSet::new(); + for ty in field_types_clone + .iter() + .chain(method_return_types_clone.iter()) + { + collect_named_class_refs(ty, &mut named_refs); + } + let refs: Vec<(String, bool)> = named_refs + .into_iter() + .map(|name| (name, false)) + .chain(parent_name_clone.into_iter().map(|name| (name, true))) + .collect(); + for (ref_name, is_parent_ref) in refs { + // Resolve the type name in the declaring class's own + // module before falling back to the legacy global lookup. + // This includes erased `import type { Result as Local }` + // bindings, but only consumes their class metadata: it + // does not create a value binding or module-init edge. + let scoped_found = child_src_path.and_then(|child_path| { + let module = ctx.native_modules.get(child_path)?; + if let Some(class) = + module.classes.iter().find(|class| class.name == ref_name) + { let canonical_path = class_canonical_path - .get(&(*class as *const perry_hir::Class as usize)) + .get(&(class as *const perry_hir::Class as usize)) .cloned() - .unwrap_or_else(|| path.clone()); - (canonical_path, *class) + .unwrap_or_else(|| child_path.to_string_lossy().into_owned()); + return Some((canonical_path, class)); + } + module.imports.iter().find_map(|import| { + if import.module_kind != perry_hir::ModuleKind::NativeCompiled { + return None; + } + let resolved_path = import.resolved_path.as_ref()?; + import.specifiers.iter().find_map(|specifier| { + let (exported_name, local_name) = match specifier { + perry_hir::ImportSpecifier::Named { imported, local } => { + (imported.as_str(), local.as_str()) + } + perry_hir::ImportSpecifier::Default { local } => { + ("default", local.as_str()) + } + perry_hir::ImportSpecifier::Namespace { .. } => { + return None + } + }; + if local_name != ref_name { + return None; + } + let origin_path = all_module_exports + .get(resolved_path) + .and_then(|exports| exports.get(exported_name)) + .cloned() + .unwrap_or_else(|| resolved_path.clone()); + let origin_name = all_module_export_origin_names + .get(resolved_path) + .and_then(|names| names.get(exported_name)) + .cloned() + .unwrap_or_else(|| exported_name.to_string()); + let class = exported_classes + .get(&(origin_path.clone(), origin_name.clone())) + .or_else(|| { + exported_classes.get(&( + origin_path.clone(), + exported_name.to_string(), + )) + }) + .or_else(|| { + exported_classes.get(&( + resolved_path.clone(), + exported_name.to_string(), + )) + })?; + let canonical_path = class_canonical_path + .get(&(*class as *const perry_hir::Class as usize)) + .cloned() + .unwrap_or(origin_path); + Some((canonical_path, *class)) + }) }) - }); - // Dedup: parent refs key on (resolved_path, name) so a - // distinct same-named parent in another module is still - // imported; all other refs key on name only (legacy). - if is_parent_ref { - if let Some((src_path, class)) = &found { - let source_prefix = - compute_module_prefix(src_path, &ctx.project_root); - let effective_name = if ref_name != class.name { - ref_name.as_str() + }); + // Issue #489: pick the canonical defining path for the + // parent class (where `class N { ... }` actually lives) + // rather than the first BTreeMap match by name (which + // can be a re-export barrel). Without this, drizzle's + // `MySqlPreparedQuery extends QueryPromise` chain pulls + // QueryPromise in under `drizzle-orm/index.js` (because + // `index.js` does `export * from "./query-promise.js"` + // and sorts before `query-promise.js`), and the dispatch + // table emits `perry_method___QueryPromise__then` + // — undefined symbol at link time. + // + // Issue #26: for a parent ref, prefer the same-named class + // in the CHILD's own source module before any global match. + let found = scoped_found.or_else(|| { + exported_classes + .iter() + .find(|((path, cname), class)| { + cname == &ref_name + && class_canonical_path + .get(&(**class as *const perry_hir::Class as usize)) + .map(|canonical| canonical == path) + .unwrap_or(true) + }) + .or_else(|| { + exported_classes + .iter() + .find(|((_, cname), _)| cname == &ref_name) + }) + .map(|((path, _), class)| { + // `exported_classes` deliberately carries alias + // entries stamped under barrel paths. Selecting + // one is valid for scope resolution, but symbols + // still live in the defining module. + let canonical_path = class_canonical_path + .get(&(*class as *const perry_hir::Class as usize)) + .cloned() + .unwrap_or_else(|| path.clone()); + (canonical_path, *class) + }) + }); + // Dedup: parent refs key on (resolved_path, name) so a + // distinct same-named parent in another module is still + // imported; all other refs key on name only (legacy). + if is_parent_ref { + if let Some((src_path, class)) = &found { + let source_prefix = + compute_module_prefix(src_path, &ctx.project_root); + let effective_name = if ref_name != class.name { + ref_name.as_str() + } else { + class.name.as_str() + }; + // The initial import walk may already contain this + // exact canonical class. A barrel-local child + // extending a re-exported parent must not append a + // second copy under the barrel path: the later + // duplicate would overwrite the correct ctor in + // codegen's name-keyed map (OpenTUI's index.node.js + // / chunk-node BoxRenderable shape). + if imported_classes.iter().any(|imported| { + imported.source_prefix == source_prefix + && imported.name == class.name + && imported.local_alias.as_deref().unwrap_or(&imported.name) + == effective_name + }) { + visited_parent_paths + .insert((src_path.clone(), ref_name.clone())); + continue; + } + if !visited_parent_paths + .insert((src_path.clone(), ref_name.clone())) + { + continue; + } + // Already have an entry under this name from a + // DIFFERENT module: still add this (path,name) + // variant so codegen can disambiguate, but skip + // re-pushing to the worklist by name below. } else { - class.name.as_str() - }; - // The initial import walk may already contain this - // exact canonical class. A barrel-local child - // extending a re-exported parent must not append a - // second copy under the barrel path: the later - // duplicate would overwrite the correct ctor in - // codegen's name-keyed map (OpenTUI's index.node.js - // / chunk-node BoxRenderable shape). - if imported_classes.iter().any(|imported| { - imported.source_prefix == source_prefix - && imported.name == class.name - && imported - .local_alias - .as_deref() - .unwrap_or(&imported.name) - == effective_name - }) { - visited_parent_paths - .insert((src_path.clone(), ref_name.clone())); - continue; - } - if !visited_parent_paths - .insert((src_path.clone(), ref_name.clone())) - { continue; } - // Already have an entry under this name from a - // DIFFERENT module: still add this (path,name) - // variant so codegen can disambiguate, but skip - // re-pushing to the worklist by name below. - } else { + } else if visited_imports.contains(&ref_name) { continue; } - } else if visited_imports.contains(&ref_name) { - continue; - } - if let Some((src_path, class)) = found { - let class_prefix = compute_module_prefix(&src_path, &ctx.project_root); - // Issue #485: when the child's `parent_name` doesn't - // match the source class's `class.name` (because the - // parent was imported via a rename — `import { Base - // as HBase } from './base.js'` or - // `export { Base as HBase }` on the source side), - // expose the stub under the alias the child knows. - // Without this, codegen's `imported_class_stubs` - // would register the parent under "Base" while the - // child's `extends_name` is "HBase", and the - // packed-keys / slot-index walker fails to traverse - // the chain. - let alias = if ref_name != class.name { - Some(ref_name.clone()) - } else { - None - }; - imported_classes.push(imported_class_from_hir( - class, - class_prefix, - alias, - proven_this_methods_for_import(class, &class_proven_this_methods), - proven_this_methods_for_import( + if let Some((src_path, class)) = found { + let class_prefix = compute_module_prefix(&src_path, &ctx.project_root); + // Issue #485: when the child's `parent_name` doesn't + // match the source class's `class.name` (because the + // parent was imported via a rename — `import { Base + // as HBase } from './base.js'` or + // `export { Base as HBase }` on the source side), + // expose the stub under the alias the child knows. + // Without this, codegen's `imported_class_stubs` + // would register the parent under "Base" while the + // child's `extends_name` is "HBase", and the + // packed-keys / slot-index walker fails to traverse + // the chain. + let alias = if ref_name != class.name { + Some(ref_name.clone()) + } else { + None + }; + imported_classes.push(imported_class_from_hir( class, - &class_proven_this_tower_methods, - ), - )); - visited_imports.insert(ref_name.clone()); - // Process the entry we just pushed (by index, so a - // same-named distinct-module class isn't skipped). Refs #26. - closure_worklist.push(imported_classes.len() - 1); + class_prefix, + alias, + proven_this_methods_for_import(class, &class_proven_this_methods), + proven_this_methods_for_import( + class, + &class_proven_this_tower_methods, + ), + )); + visited_imports.insert(ref_name.clone()); + // Process the entry we just pushed (by index, so a + // same-named distinct-module class isn't skipped). Refs #26. + closure_worklist.push(imported_classes.len() - 1); + } } } - } - // Type aliases from all modules - let type_alias_map: std::collections::HashMap = - all_type_aliases - .iter() - .map(|(k, v)| (k.clone(), v.clone())) - .collect(); + // Type aliases from all modules + let type_alias_map: std::collections::HashMap = + all_type_aliases + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(); - // Resolve the CLI's short target name (ios/android/etc.) to - // an LLVM triple. `None` falls through to the host default - // inside `compile_module`. - let resolved_triple = target - .as_deref() - .and_then(perry_codegen::resolve_target_triple); - // ── Feature plumbing ── - // Set all compile options so the codegen honors - // the same project configuration. Without this, the - // auto-optimize feature detection + linker flag - // construction can't see which modules the program - // actually uses and strips too much from libperry_stdlib.a. - let bundled_ext_vec: Vec<(String, String)> = if is_entry { - bundled_extensions - .iter() - .map(|(ext_path, _plugin_id)| { - let ext_prefix = - compute_module_prefix(&ext_path.to_string_lossy(), &ctx.project_root); - (ext_path.to_string_lossy().to_string(), ext_prefix) - }) - .collect() - } else { - Vec::new() - }; - let native_module_init_names_vec: Vec = if is_entry { - non_entry_module_names.clone() - } else { - Vec::new() - }; - let js_module_specifiers_vec: Vec = js_module_specifiers.clone(); - - let opts = perry_codegen::CompileOptions { - target: resolved_triple, - is_entry_module: is_entry, - non_entry_module_prefixes, - import_function_prefixes, - import_function_ffi_aliases, - import_function_origin_names, - import_function_v8_specifiers, - import_function_node_submodule, - namespace_node_submodules, - namespace_v8_specifiers, - namespace_member_prefixes, - namespace_member_origin_names, - emit_ir_only: bitcode_link, - verify_native_regions, - disable_buffer_fast_path, - namespace_imports, - namespace_member_nested: namespace_member_nested.into_iter().collect(), - imported_classes, - short_spread_method_candidates: std::sync::Arc::clone( - &short_spread_method_candidates, - ), - object_literal_method_candidates: std::sync::Arc::clone( - &object_literal_method_candidates, - ), - imported_enums, - imported_async_funcs: imported_async_set, - type_aliases: type_alias_map, - imported_func_param_counts: imported_param_counts, - imported_func_has_rest: imported_has_rest, - imported_func_synthetic_arguments: imported_synthetic_arguments, - imported_func_return_types: imported_return_types, - imported_vars, - - // Feature plumbing - output_type: args.output_type.clone(), - needs_stdlib: ctx.needs_stdlib, - needs_ui: ctx.needs_ui, - needs_geisterhand: ctx.needs_geisterhand, - geisterhand_port: ctx.geisterhand_port, - enabled_features: compiled_features.clone(), - native_module_init_names: native_module_init_names_vec, - js_module_specifiers: js_module_specifiers_vec, - bundled_extensions: bundled_ext_vec, - native_library_functions: ffi_functions.clone(), - i18n_table: i18n_snapshot.clone(), - fast_math: ctx.fast_math, - fp_contract_mode: ctx.fp_contract_mode, - app_metadata: perry_codegen::AppMetadata { - entry_source_path: if is_entry && args.output_type == "executable" { - Some(path.to_string_lossy().into_owned()) + // Resolve the CLI's short target name (ios/android/etc.) to + // an LLVM triple. `None` falls through to the host default + // inside `compile_module`. + let resolved_triple = target + .as_deref() + .and_then(perry_codegen::resolve_target_triple); + // ── Feature plumbing ── + // Set all compile options so the codegen honors + // the same project configuration. Without this, the + // auto-optimize feature detection + linker flag + // construction can't see which modules the program + // actually uses and strips too much from libperry_stdlib.a. + let bundled_ext_vec: Vec<(String, String)> = if is_entry { + bundled_extensions + .iter() + .map(|(ext_path, _plugin_id)| { + let ext_prefix = compute_module_prefix( + &ext_path.to_string_lossy(), + &ctx.project_root, + ); + (ext_path.to_string_lossy().to_string(), ext_prefix) + }) + .collect() + } else { + Vec::new() + }; + let native_module_init_names_vec: Vec = if is_entry { + non_entry_module_names.clone() + } else { + Vec::new() + }; + let js_module_specifiers_vec: Vec = js_module_specifiers.clone(); + + let opts = perry_codegen::CompileOptions { + target: resolved_triple, + is_entry_module: is_entry, + non_entry_module_prefixes, + import_function_prefixes, + import_function_ffi_aliases, + import_function_origin_names, + import_function_v8_specifiers, + import_function_node_submodule, + namespace_node_submodules, + namespace_v8_specifiers, + namespace_member_prefixes, + namespace_member_origin_names, + emit_ir_only: bitcode_link, + verify_native_regions, + disable_buffer_fast_path, + namespace_imports, + namespace_member_nested: namespace_member_nested.into_iter().collect(), + imported_classes, + constructor_param_counts: Default::default(), + short_spread_method_candidates: std::sync::Arc::clone( + &short_spread_method_candidates, + ), + object_literal_method_candidates: std::sync::Arc::clone( + &object_literal_method_candidates, + ), + imported_enums, + imported_async_funcs: imported_async_set, + type_aliases: type_alias_map, + imported_func_param_counts: imported_param_counts, + imported_func_has_rest: imported_has_rest, + imported_func_synthetic_arguments: imported_synthetic_arguments, + imported_func_return_types: imported_return_types, + imported_vars, + + // Feature plumbing + output_type: args.output_type.clone(), + needs_stdlib: ctx.needs_stdlib, + needs_ui: ctx.needs_ui, + needs_geisterhand: ctx.needs_geisterhand, + geisterhand_port: ctx.geisterhand_port, + enabled_features: compiled_features.clone(), + native_module_init_names: native_module_init_names_vec, + js_module_specifiers: js_module_specifiers_vec, + bundled_extensions: bundled_ext_vec, + native_library_functions: ffi_functions.clone(), + i18n_table: i18n_snapshot.clone(), + fast_math: ctx.fast_math, + fp_contract_mode: ctx.fp_contract_mode, + app_metadata: perry_codegen::AppMetadata { + entry_source_path: if is_entry && args.output_type == "executable" { + Some(path.to_string_lossy().into_owned()) + } else { + None + }, + ..ctx.app_metadata.clone() + }, + // Issue #100: namespace_entries empty unless this + // module is a dynamic-import target; the consumer-side + // dispatch map is empty unless this module performs + // dynamic imports. + namespace_entries: per_module_namespace_entries + .get(path) + .cloned() + .unwrap_or_default(), + dynamic_import_path_to_prefix: per_module_dyn_import_targets + .get(path) + .cloned() + .unwrap_or_default(), + nextjs_path_init_modules, + deferred_module_prefixes, + module_init_deps, + // Issue #842: signal side-effect-only dynamic-import + // targets to codegen so it still emits + // `@__perry_ns_` + populator. `dyn_target_paths` + // is the authoritative set built from every consumer's + // `import.is_dynamic` resolved paths; `namespace_entries` + // alone is insufficient because it's empty when the + // target has no `export` statements. + is_dynamic_import_target: dyn_target_paths.contains(path), + // #5247: source-location tracking for the dynamic call-dispatch + // throw path. Gated by `--debug-symbols` so the default build is + // unchanged (no source read, no per-call emission). When on, read + // the module's original source so codegen can map a Call's byte + // offset to a 1-based line. + debug_locations: args.debug_symbols, + // #5247 / #7036: source consulted to turn a node's `byte_offset` + // into a debug frame or opt-report snippet. For a CommonJS + // module the offsets are in WRAPPED-source + // coordinates (perry parsed the injected-IIFE text), so we hand + // codegen the WRAPPED source — counting newlines up to a wrapped + // offset against the original would be off by the preamble byte + // length. `debug_source_line_offset` (below) then converts the + // wrapped line back to the original line. Non-wrapped modules + // read the original from disk. Text reports need this source; + // JSON reports only need the offset already carried by HIR. + module_source: if args.debug_symbols + || opt_report_format == Some(OptReportFormat::Text) + { + match ctx.cjs_wrap_debug_sources.get(path) { + Some(w) => Some(w.wrapped_source.clone()), + None => std::fs::read_to_string(path).ok(), + } } else { None }, - ..ctx.app_metadata.clone() - }, - // Issue #100: namespace_entries empty unless this - // module is a dynamic-import target; the consumer-side - // dispatch map is empty unless this module performs - // dynamic imports. - namespace_entries: per_module_namespace_entries - .get(path) - .cloned() - .unwrap_or_default(), - dynamic_import_path_to_prefix: per_module_dyn_import_targets - .get(path) - .cloned() - .unwrap_or_default(), - nextjs_path_init_modules, - deferred_module_prefixes, - module_init_deps, - // Issue #842: signal side-effect-only dynamic-import - // targets to codegen so it still emits - // `@__perry_ns_` + populator. `dyn_target_paths` - // is the authoritative set built from every consumer's - // `import.is_dynamic` resolved paths; `namespace_entries` - // alone is insufficient because it's empty when the - // target has no `export` statements. - is_dynamic_import_target: dyn_target_paths.contains(path), - // #5247: source-location tracking for the dynamic call-dispatch - // throw path. Gated by `--debug-symbols` so the default build is - // unchanged (no source read, no per-call emission). When on, read - // the module's original source so codegen can map a Call's byte - // offset to a 1-based line. - debug_locations: args.debug_symbols, - // #5247 / #7036: source consulted to turn a node's `byte_offset` - // into a debug frame or opt-report snippet. For a CommonJS - // module the offsets are in WRAPPED-source - // coordinates (perry parsed the injected-IIFE text), so we hand - // codegen the WRAPPED source — counting newlines up to a wrapped - // offset against the original would be off by the preamble byte - // length. `debug_source_line_offset` (below) then converts the - // wrapped line back to the original line. Non-wrapped modules - // read the original from disk. Text reports need this source; - // JSON reports only need the offset already carried by HIR. - module_source: if args.debug_symbols - || opt_report_format == Some(OptReportFormat::Text) - { - match ctx.cjs_wrap_debug_sources.get(path) { - Some(w) => Some(w.wrapped_source.clone()), - None => std::fs::read_to_string(path).ok(), - } - } else { - None - }, - // #5247 (CJS-wrap coordinate skew): the number of newlines the - // injected wrapper prefix added before the original module body. - // Codegen subtracts this from the wrapped line number so the - // rendered location is in original-source coordinates. `0` for - // non-wrapped modules (and the entire default build). - debug_source_line_offset: if args.debug_symbols - || opt_report_format == Some(OptReportFormat::Text) - { - ctx.cjs_wrap_debug_sources - .get(path) - .map(|w| w.prefix_line_count) - .unwrap_or(0) - } else { - 0 - }, + // #5247 (CJS-wrap coordinate skew): the number of newlines the + // injected wrapper prefix added before the original module body. + // Codegen subtracts this from the wrapped line number so the + // rendered location is in original-source coordinates. `0` for + // non-wrapped modules (and the entire default build). + debug_source_line_offset: if args.debug_symbols + || opt_report_format == Some(OptReportFormat::Text) + { + ctx.cjs_wrap_debug_sources + .get(path) + .map(|w| w.prefix_line_count) + .unwrap_or(0) + } else { + 0 + }, + }; + Ok((path, hir_module, opts)) + }) + .collect() + }); + let mut prepared_modules = prepared_modules.map_err(|error| anyhow!(error))?; + perry_codegen::resolve_constructor_contracts(prepared_modules.iter_mut().map( + |(path, module, opts)| { + ( + compute_module_prefix(&path.to_string_lossy(), &ctx.project_root), + *module, + opts, + ) + }, + )); + let compile_results: Vec> = module_pool.install(|| { + prepared_modules.into_par_iter().map(|(path, hir_module, opts)| { + let _permit = + module_limiter.acquire(module_codegen_is_exclusive(path, hir_module)); + let _completion = ModuleCodegenCompletion { + completed: &codegen_modules_completed, + total: total_codegen_modules, + started: codegen_started, + enabled: codegen_progress_enabled, }; + // Compile this module to LLVM IR (or .ll text in bitcode-link mode). + // Linking builds return an artifact for the linker. `--no-link` + // writes each cold object in this worker as soon as it is ready so + // a large graph does not retain every object byte until all module + // jobs finish. + let codegen_index = codegen_modules_started.fetch_add(1, Ordering::Relaxed) + 1; + progress.record(ProgressSnapshot { + stage: "codegen", + module_path: Some(path), + module_name: Some(&hir_module.name), + visited: Some(codegen_index), + total: Some(total_codegen_modules), + collected: Some(total_codegen_modules), + ..Default::default() + }); // V2.2 + #686 object cache lookup. The key hashes every // codegen-affecting field of `opts` together with this // module's post-transform HIR fingerprint and the perry diff --git a/crates/perry/tests/source_graph_export_regressions/issue_10258.rs b/crates/perry/tests/source_graph_export_regressions/issue_10258.rs index e2c790d879..aef01b810f 100644 --- a/crates/perry/tests/source_graph_export_regressions/issue_10258.rs +++ b/crates/perry/tests/source_graph_export_regressions/issue_10258.rs @@ -1,10 +1,7 @@ -//! `new ImportedClass(args)` for an exported class with no own constructor whose -//! parent is a runtime value must forward the arguments (#10258). The defining -//! module synthesizes a fixed-arity forwarding constructor; the importer used to -//! declare it with zero parameters and dropped every argument. effect v4's -//! `PlatformError.SystemError extends Data.Error {}` has this shape. +//! Constructor contracts must agree across modules for every heritage form. +//! Expected stdout is captured from Bun, not inferred from Perry's output. -use super::{compile_and_run, write}; +use super::{compile_and_run_with_all_llvm_trace, write}; #[test] fn imported_default_ctor_with_runtime_parent_forwards_args() { @@ -12,44 +9,139 @@ fn imported_default_ctor_with_runtime_parent_forwards_args() { write( dir.path(), "core.ts", - "export const YieldableError = (function () { class YieldableError extends globalThis.Error {}; return YieldableError })()\n\ - export const Error = (function () {\n\ - \x20 return class Base extends YieldableError {\n\ - \x20 constructor(args?: any) { super(args?.message); if (args) Object.assign(this, args) }\n\ - \x20 }\n\ - })()\n\ - export const Plain = (function () { return class P { constructor(a?: any, b?: any, c?: any) { (this as any).sum = [a, b, c] } } })()\n", + r#"export const YieldableError = (function () { class YieldableError extends globalThis.Error {}; return YieldableError })() +const plainArgsSymbol = Symbol.for("effect/Data/Error/plainArgs") +export const Error = (function () { + return class Base extends YieldableError { + constructor(args?: any) { + super(args?.message, args?.cause ? { cause: args.cause } : undefined) + if (args) { Object.assign(this, args); Object.defineProperty(this, plainArgsSymbol, { value: args, enumerable: false }) } + } + } +})() +export const TaggedError = (tag: string) => { class Base extends Error { readonly _tag = tag }; return Base as any } +export const Plain = (function () { return class P { constructor(a?: any, b?: any, c?: any) { (this as any).sum = [a, b, c] } } })() +export class ImportedParent { + first: any + second: any + constructor(a: any, b: any) { this.first = a; this.second = b } +} +"#, + ); + write( + dir.path(), + "data.ts", + r#"import * as core from "./core" +export const Error = core.Error +export const TaggedError = core.TaggedError +export const Plain = core.Plain +export { ImportedParent as RealParent } from "./core" +"#, ); - write(dir.path(), "data.ts", "import * as core from \"./core\"\nexport const Error = core.Error\nexport const Plain = core.Plain\n"); write( dir.path(), "platform.ts", - "import * as Data from \"./data\"\n\ - export class Empty extends (Data.Error as any) {}\n\ - export class WithGetter extends (Data.Error as any) { get message() { return \"G:\" + (this as any)._tag } }\n\ - export class WithMethod extends (Data.Error as any) { describe() { return (this as any).module } }\n\ - export class Explicit extends (Data.Error as any) { constructor(a: any) { super(a) } }\n\ - export class ThreeArgs extends (Data.Plain as any) {}\n\ - export const makeLocal = (o: any) => new WithGetter(o)\n", + r#"import * as Data from "./data" +import { Error as NamedErr, RealParent as AliasedParent } from "./data" +export class Empty extends (Data.Error as any) {} +export class WithGetter extends (Data.Error as any) { get message() { return "G:" + (this as any)._tag } } +export class WithMethod extends (Data.Error as any) { describe() { return (this as any).module } } +export class Explicit extends (Data.Error as any) { constructor(a: any) { super(a) } } +export class ThreeArgs extends (Data.Plain as any) {} +export class MemberHeritage extends Data.Error {} +export class MemberHeritageGetter extends Data.Error { get message() { return "MH" } } +export class NamedHeritage extends NamedErr {} +class LocalParent { + first: any + second: any + constructor(a: any, b: any) { this.first = a; this.second = b } +} +class LocalMiddle extends LocalParent {} +export class LocalChild extends LocalMiddle {} +export { LocalChild as RenamedChild } +export class ImportedChild extends AliasedParent {} +export class MemberImportedChild extends Data.RealParent {} +export class PlatformError extends Data.TaggedError("PlatformError") { + constructor(reason: any) { super({ reason, cause: reason.cause }) } +} +export const makeLocal = (o: any) => new WithGetter(o) +export const makeMember = (o: any) => new MemberHeritage(o) +export const makeMemberGetter = (o: any) => new MemberHeritageGetter(o) +export const makeNamed = (o: any) => new NamedHeritage(o) +"#, ); write( dir.path(), "main.ts", - "import { Empty, WithGetter, WithMethod, Explicit, ThreeArgs, makeLocal } from \"./platform\"\n\ - import * as P from \"./platform\"\n\ - const o = () => ({ _tag: \"NotFound\", module: \"FS\" })\n\ - const show = (e: any) => [e._tag, e.module, e instanceof Error].join(\",\")\n\ - console.log(show(new Empty(o())), show(new WithGetter(o())), new WithGetter(o()).message)\n\ - console.log(show(new WithMethod(o())), new WithMethod(o()).describe(), show(new Explicit(o())))\n\ - console.log(show(new P.Empty(o())), show(makeLocal(o())), JSON.stringify((new ThreeArgs(1, 2, 3) as any).sum))\n\ - class Sub extends Empty {}\n\ - console.log(show(new Sub(o())))\n", - ); - assert_eq!( - compile_and_run(dir.path(), "main.ts"), - "NotFound,FS,true NotFound,FS,true G:NotFound\n\ - NotFound,FS,true FS NotFound,FS,true\n\ - NotFound,FS,true NotFound,FS,true [1,2,3]\n\ - NotFound,FS,true\n" + r#"import { Empty, WithGetter, WithMethod, Explicit, ThreeArgs, makeLocal, MemberHeritage, MemberHeritageGetter, NamedHeritage, LocalChild, ImportedChild, MemberImportedChild } from "./platform" +import { RenamedChild } from "./platform" +import * as P from "./platform" +import * as Data from "./data" +const o = () => ({ _tag: "NotFound", module: "FS" }) +const show = (e: any) => [e._tag, e.module, e instanceof Error].join(",") +const fields = (e: any) => JSON.stringify({ tag: e._tag, module: e.module, keys: Object.keys(e) }) +const pair = (e: any) => JSON.stringify([e.first, e.second]) +console.log(show(new Empty(o())), show(new WithGetter(o())), new WithGetter(o()).message) +console.log(show(new WithMethod(o())), new WithMethod(o()).describe(), show(new Explicit(o()))) +console.log(show(new P.Empty(o())), show(makeLocal(o())), JSON.stringify((new ThreeArgs(1, 2, 3) as any).sum)) +console.log("member", fields(new MemberHeritage(o()))) +console.log("getter", fields(new MemberHeritageGetter(o())), new MemberHeritageGetter(o()).message) +console.log("named", fields(new NamedHeritage(o()))) +console.log("namespace", fields(new P.MemberHeritage(o()))) +console.log("defining module", fields(P.makeMember(o())), fields(P.makeMemberGetter(o())), fields(P.makeNamed(o()))) +class LocalRuntime extends Data.Error {} +console.log("local runtime", fields(new LocalRuntime(o()))) +console.log("local parent", pair(new LocalChild("local", 2)), pair(new P.LocalChild("namespace", 22))) +console.log("imported parent", pair(new ImportedChild("imported", 3)), pair(new MemberImportedChild("member", 33))) +console.log("barrel", pair(new RenamedChild("renamed", 4))) +const wrapped: any = new P.PlatformError(new Empty({ ...o(), cause: new Error("c") })) +console.log("wrapped", JSON.stringify({ tag: wrapped._tag, reasonTag: wrapped.reason._tag, keys: Object.keys(wrapped), cause: wrapped.cause.message })) +class Sub extends Empty {} +class MemberSub extends MemberHeritage {} +class ResolvedSub extends ImportedChild {} +console.log(show(new Sub(o())), fields(new MemberSub(o())), pair(new ResolvedSub("sub", 5))) +"#, ); + let (stdout, ir) = compile_and_run_with_all_llvm_trace(dir.path(), "main.ts"); + assert_eq!(stdout, include_str!("issue_10258.stdout")); + + // Behavioral output alone cannot detect an over-declared signature on + // platforms that happen to ignore the surplus argument registers. + for (name, params) in [ + ("Empty", 8), + ("MemberHeritage", 8), + ("MemberHeritageGetter", 8), + ("NamedHeritage", 8), + ("ThreeArgs", 8), + ("LocalChild", 2), + ("ImportedChild", 2), + ("MemberImportedChild", 2), + ] { + let symbol = format!("__{name}_constructor("); + let signatures: Vec<_> = ir + .lines() + .filter(|line| { + (line.starts_with("define ") || line.starts_with("declare ")) + && line.contains(&symbol) + }) + .collect(); + assert!( + signatures.iter().any(|line| line.starts_with("define ")), + "missing definition: {symbol}" + ); + assert!( + signatures.iter().any(|line| line.starts_with("declare ")), + "missing import: {symbol}" + ); + for line in signatures { + let args = line + .split_once(&symbol) + .unwrap() + .1 + .split(')') + .next() + .unwrap(); + assert_eq!(args.matches("double").count(), params + 1, "{line}"); + } + } } diff --git a/crates/perry/tests/source_graph_export_regressions/issue_10258.stdout b/crates/perry/tests/source_graph_export_regressions/issue_10258.stdout new file mode 100644 index 0000000000..521f57de2a --- /dev/null +++ b/crates/perry/tests/source_graph_export_regressions/issue_10258.stdout @@ -0,0 +1,14 @@ +NotFound,FS,true NotFound,FS,true G:NotFound +NotFound,FS,true FS NotFound,FS,true +NotFound,FS,true NotFound,FS,true [1,2,3] +member {"tag":"NotFound","module":"FS","keys":["_tag","module"]} +getter {"tag":"NotFound","module":"FS","keys":["_tag","module"]} MH +named {"tag":"NotFound","module":"FS","keys":["_tag","module"]} +namespace {"tag":"NotFound","module":"FS","keys":["_tag","module"]} +defining module {"tag":"NotFound","module":"FS","keys":["_tag","module"]} {"tag":"NotFound","module":"FS","keys":["_tag","module"]} {"tag":"NotFound","module":"FS","keys":["_tag","module"]} +local runtime {"tag":"NotFound","module":"FS","keys":["_tag","module"]} +local parent ["local",2] ["namespace",22] +imported parent ["imported",3] ["member",33] +barrel ["renamed",4] +wrapped {"tag":"PlatformError","reasonTag":"NotFound","keys":["reason","_tag"],"cause":"c"} +NotFound,FS,true {"tag":"NotFound","module":"FS","keys":["_tag","module"]} ["sub",5] From 4b57df7dc4b92df11333827b53ae70c9b8ee0eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Mon, 14 Sep 2026 17:06:40 +0200 Subject: [PATCH 07/11] fix(compile): stream constructor contracts to bound memory --- .../10259-imported-default-ctor-arity.md | 10 +- changelog.d/10265-constructor-contracts.md | 13 + .../src/codegen/constructor_contracts.rs | 126 +- crates/perry-codegen/src/codegen/mod.rs | 2 +- crates/perry-codegen/src/lib.rs | 8 +- .../src/commands/compile/run_pipeline.rs | 4361 ++++++++--------- 6 files changed, 2228 insertions(+), 2292 deletions(-) create mode 100644 changelog.d/10265-constructor-contracts.md diff --git a/changelog.d/10259-imported-default-ctor-arity.md b/changelog.d/10259-imported-default-ctor-arity.md index 42a3efdfc0..1cc6dba602 100644 --- a/changelog.d/10259-imported-default-ctor-arity.md +++ b/changelog.d/10259-imported-default-ctor-arity.md @@ -1,9 +1 @@ -Fix imported default constructors losing arguments for every heritage form, including effect v4's `class SystemError extends Data.Error {}`, a named import of a runtime parent, and cast expressions (#10258; supersedes the partial fix in #10259). - -The defining module emitted an eight-argument forwarding constructor when it could not resolve the parent, while importing modules declared the same symbol with zero arguments. Prepare every module's imports before code generation, resolve constructor contracts in the defining module's scope, and copy the single result to both emitted constructors/runtime registration and imported-class metadata. Real local and imported parent constructors retain their exact arity; the existing standalone/auto-optimize fallback used by Next.js wall 51 remains available. Producer contracts and imported counts are included in object-cache keys. - -The four-module regression uses output captured from Bun and checks LLVM declarations against definitions, including two-parameter real parents, three runtime arguments, named/namespace imports, getters, aliases, and subclasses declared by consumers. This restores the error fields needed for OpenCode's `Effect.catchReason("PlatformError", "NotFound", …)` handling of missing optional configuration files (#10107). - -The tagged-error wrapper probe also exposed three constructor-chain details: default Error forwarding now preserves its options argument and non-enumerable cause, compiler capture slots stay hidden from reflection, and public fields of a dynamically derived class become own properties after its parent runs. The regression compares the wrapper's keys and cause with Bun as well. - -Local construction follows the runtime parent too: `new SystemError(...)` inside its defining module must not mistake the final `Error` component of `Data.Error` for the native Error constructor. This preserves the nested reason used by `catchReason`, as well as a consumer's locally declared `class MyError extends Data.Error {}`. +Fix `new ImportedClass(args)` for an exported class with no own constructor whose `extends` clause is a runtime value (for example effect v4's `class SystemError extends Data.Error {}`). The defining module synthesizes a forwarding constructor with a fixed parameter band because the parent's arity is unknown there, but the imported-class metadata counted only the class's own (absent) constructor and declared it with zero parameters, so the importing module called it with `this` alone and the parent constructor never saw the arguments. Importers now derive the arity from the same rule as the synthesized constructor. This unblocks OpenCode's config loading, where effect's file-not-found `PlatformError` lost its reason and turned a missing optional config file into a fatal error (#10107). diff --git a/changelog.d/10265-constructor-contracts.md b/changelog.d/10265-constructor-contracts.md new file mode 100644 index 0000000000..eb40585fdb --- /dev/null +++ b/changelog.d/10265-constructor-contracts.md @@ -0,0 +1,13 @@ +Fix imported default constructors losing arguments for every heritage form, including effect v4's `class SystemError extends Data.Error {}`, a named import of a runtime parent, and cast expressions (#10258; supersedes the partial fix in #10259). + +The defining module emitted an eight-argument forwarding constructor when it could not resolve the parent, while importing modules declared the same symbol with zero arguments. Resolve constructor contracts in the defining module's scope, and copy the single result to both emitted constructors/runtime registration and imported-class metadata. Real local and imported parent constructors retain their exact arity; the existing standalone/auto-optimize fallback used by Next.js wall 51 remains available. Producer contracts and imported counts are included in object-cache keys. + +The four-module regression uses output captured from Bun and checks LLVM declarations against definitions, including two-parameter real parents, three runtime arguments, named/namespace imports, getters, aliases, and subclasses declared by consumers. This restores the error fields needed for OpenCode's `Effect.catchReason("PlatformError", "NotFound", …)` handling of missing optional configuration files (#10107). + +The tagged-error wrapper probe also exposed three constructor-chain details: default Error forwarding now preserves its options argument and non-enumerable cause, compiler capture slots stay hidden from reflection, and public fields of a dynamically derived class become own properties after its parent runs. The regression compares the wrapper's keys and cause with Bun as well. + +Local construction follows the runtime parent too: `new SystemError(...)` inside its defining module must not mistake the final `Error` component of `Data.Error` for the native Error constructor. This preserves the nested reason used by `catchReason`, as well as a consumer's locally declared `class MyError extends Data.Error {}`. + +Bound contract resolution memory by streaming class-bearing modules into a compact `(module prefix, class name)` edge/count table, then consuming the edges into resolved arities. Temporary import metadata is dropped after each module, and full compile options (including graph-wide type aliases) are constructed only inside codegen worker permits. This removes the graph-wide options retention that exhausted memory compiling OpenCode in #10265. + +The full OpenCode v1.18.30 build on v0.5.1567 completes at 3 module jobs × 2 LLVM unit workers with a fresh lane cache: 27.36 GiB maximum RSS (`/usr/bin/time -v`, 28,686,112 KiB), 1h41m24s, and `COMPILE_RC=0`. The rebased purity pass selects 6,926 native modules and prunes 971 (7,897 candidates); the older coordinator runs selected 7,068 and pruned 829. The earlier 3×2 run was OOM-killed at a reported 49.7 GB anonymous RSS. All 58 source-graph tests, 2,038 codegen tests, 670 HIR tests, and the three Bun comparison probes pass. diff --git a/crates/perry-codegen/src/codegen/constructor_contracts.rs b/crates/perry-codegen/src/codegen/constructor_contracts.rs index a297d232c4..040df8de36 100644 --- a/crates/perry-codegen/src/codegen/constructor_contracts.rs +++ b/crates/perry-codegen/src/codegen/constructor_contracts.rs @@ -1,11 +1,11 @@ //! Resolve standalone constructor ABIs once in each defining module's scope. -//! The pipeline runs this after preparing every import route and before either -//! object-cache lookup or LLVM emission (#10258). +//! Collect only constructor edges, then resolve before object-cache lookup or +//! LLVM emission. Per-module import metadata can be dropped immediately (#10265). use std::collections::{BTreeMap, BTreeSet, HashMap}; use super::ctor_arity::{context_free_ctor_param_count, UNRESOLVED_PARENT_FWD_ARITY}; -use super::opts::CompileOptions; +use super::opts::{CompileOptions, ImportedClass}; type Symbol = (String, String); @@ -14,20 +14,28 @@ enum Contract { Parent(Symbol, usize), } -/// Populate both producer signatures and consumer declarations from one graph -/// of constructor contracts. Symbols use the canonical defining prefix/name; -/// local aliases and namespace keys only participate in scope lookup. -/// -/// Resolving imports first is essential: following a foreign class's bare -/// `extends_name` in the consumer can select an unrelated same-named parent. -/// A runtime heritage with no class binding keeps the existing 8-slot band; -/// a real parent constructor keeps its exact arity, including zero. -pub fn resolve_constructor_contracts<'a>( - modules: impl IntoIterator, -) { - let mut modules: Vec<_> = modules.into_iter().collect(); - let mut contracts = BTreeMap::new(); - for (prefix, module, opts) in &modules { +/// A compact graph of constructor edges in each defining module's scope. +/// No HIR, class bodies, or per-module compile options are retained. +#[derive(Default)] +pub struct ConstructorContracts { + contracts: BTreeMap, +} + +/// The only graph-wide constructor data needed during parallel codegen. +pub struct ResolvedConstructorContracts { + arities: BTreeMap, +} + +impl ConstructorContracts { + /// Record a module after resolving its import routes. Aliases and namespace + /// keys participate only in scope lookup; edges use canonical prefix/name. + /// The caller can immediately discard the module's temporary import metadata. + pub fn record( + &mut self, + prefix: &str, + module: &perry_hir::Module, + imported_classes: &[ImportedClass], + ) { let mut locals: HashMap<_, _> = module .classes .iter() @@ -39,7 +47,7 @@ pub fn resolve_constructor_contracts<'a>( } } let mut imports = HashMap::new(); - for imported in &opts.imported_classes { + for imported in imported_classes { imports.entry(imported.effective_name()).or_insert(imported); } for class in &module.classes { @@ -71,57 +79,67 @@ pub fn resolve_constructor_contracts<'a>( } contract }; - contracts.insert((prefix.clone(), class.name.clone()), contract); + self.contracts + .insert((prefix.to_owned(), class.name.clone()), contract); } } - fn resolve( - symbol: &Symbol, - contracts: &BTreeMap, - resolved: &mut BTreeMap, - visiting: &mut BTreeSet, - ) -> usize { - if let Some(count) = resolved.get(symbol) { - return *count; + /// Consume and drop the unresolved edges before any codegen options are built. + pub fn resolve(self) -> ResolvedConstructorContracts { + let mut resolved = BTreeMap::new(); + for symbol in self.contracts.keys() { + resolve(symbol, &self.contracts, &mut resolved, &mut BTreeSet::new()); } - if !visiting.insert(symbol.clone()) { - // Cyclic heritage has no constructor-bearing ancestor. Keep the - // standalone fallback and, crucially, the same ABI on every edge. - return UNRESOLVED_PARENT_FWD_ARITY; - } - let count = match &contracts[symbol] { - Contract::Params(count) => *count, - Contract::Parent(parent, fallback) => { - if contracts.contains_key(parent) { - resolve(parent, contracts, resolved, visiting) - } else { - // Synthetic/native capabilities have no HIR producer in - // this graph and already carry their declared signature. - *fallback - } - } - }; - visiting.remove(symbol); - resolved.insert(symbol.clone(), count); - count + ResolvedConstructorContracts { arities: resolved } } +} - let mut resolved = BTreeMap::new(); - for symbol in contracts.keys() { - resolve(symbol, &contracts, &mut resolved, &mut BTreeSet::new()); +fn resolve( + symbol: &Symbol, + contracts: &BTreeMap, + resolved: &mut BTreeMap, + visiting: &mut BTreeSet, +) -> usize { + if let Some(count) = resolved.get(symbol) { + return *count; + } + if !visiting.insert(symbol.clone()) { + // Cyclic heritage has no constructor-bearing ancestor. Keep the + // standalone fallback and, crucially, the same ABI on every edge. + return UNRESOLVED_PARENT_FWD_ARITY; } - for (prefix, module, opts) in &mut modules { + let count = match &contracts[symbol] { + Contract::Params(count) => *count, + Contract::Parent(parent, fallback) => { + if contracts.contains_key(parent) { + resolve(parent, contracts, resolved, visiting) + } else { + // Synthetic/native capabilities have no HIR producer in + // this graph and already carry their declared signature. + *fallback + } + } + }; + visiting.remove(symbol); + resolved.insert(symbol.clone(), count); + count +} + +impl ResolvedConstructorContracts { + /// Set producer and consumer signatures before object-cache hashing. + pub fn apply(&self, prefix: &str, module: &perry_hir::Module, opts: &mut CompileOptions) { opts.constructor_param_counts = module .classes .iter() .map(|class| { - let count = resolved[&(prefix.clone(), class.name.clone())]; + let count = self.arities[&(prefix.to_owned(), class.name.clone())]; (class.name.clone(), count) }) .collect(); for imported in &mut opts.imported_classes { - if let Some(count) = - resolved.get(&(imported.source_prefix.clone(), imported.name.clone())) + if let Some(count) = self + .arities + .get(&(imported.source_prefix.clone(), imported.name.clone())) { imported.constructor_param_count = *count; } diff --git a/crates/perry-codegen/src/codegen/mod.rs b/crates/perry-codegen/src/codegen/mod.rs index 5b77c5e805..a211a5782c 100644 --- a/crates/perry-codegen/src/codegen/mod.rs +++ b/crates/perry-codegen/src/codegen/mod.rs @@ -188,7 +188,7 @@ mod clone_suffix_tests; mod closure; mod closure_collect; mod constructor_contracts; -pub use constructor_contracts::resolve_constructor_contracts; +pub use constructor_contracts::{ConstructorContracts, ResolvedConstructorContracts}; mod ctor_arity; pub use ctor_arity::{context_free_ctor_param_count, UNRESOLVED_PARENT_FWD_ARITY}; #[cfg(test)] diff --git a/crates/perry-codegen/src/lib.rs b/crates/perry-codegen/src/lib.rs index 91ebfd8657..c8e5f33efa 100644 --- a/crates/perry-codegen/src/lib.rs +++ b/crates/perry-codegen/src/lib.rs @@ -76,11 +76,11 @@ pub mod unit_cache; pub use codegen::{ compile_module, context_free_ctor_param_count, namespace_member_class_key, - namespace_member_func_key, namespace_member_var_key, resolve_constructor_contracts, - resolve_target_triple, short_spread_method_capabilities, user_function_symbol, AppMetadata, - CompileOptions, ExportedObjectLiteralCapability, FpContractMode, ImportedClass, + namespace_member_func_key, namespace_member_var_key, resolve_target_triple, + short_spread_method_capabilities, user_function_symbol, AppMetadata, CompileOptions, + ConstructorContracts, ExportedObjectLiteralCapability, FpContractMode, ImportedClass, ImportedObjectLiteral, ImportedObjectLiteralMethod, NamespaceEntry, NamespaceEntryKind, - ObjectLiteralMethodCandidate, ShortSpreadMethodCandidate, + ObjectLiteralMethodCandidate, ResolvedConstructorContracts, ShortSpreadMethodCandidate, }; pub use collectors::CjsPreambleCensus; // #9843: the segment-view for-of matcher's counter. Exported so the diff --git a/crates/perry/src/commands/compile/run_pipeline.rs b/crates/perry/src/commands/compile/run_pipeline.rs index 211fbef1a9..f751ace6dc 100644 --- a/crates/perry/src/commands/compile/run_pipeline.rs +++ b/crates/perry/src/commands/compile/run_pipeline.rs @@ -3133,86 +3133,87 @@ pub fn run_with_parse_cache( .build() .map_err(|error| anyhow!("failed to create module codegen pool: {error}"))?; let module_limiter = ModuleCodegenLimiter::new(module_jobs); - // Prepare the complete import graph before resolving constructor contracts. - // A consumer must use the defining module's context, even through barrels. - let prepared_modules: Result, String> = module_pool.install(|| { - ctx.native_modules - .par_iter() - .map(|(path, hir_module)| { - let is_entry = path == &entry_path; - // Compute the prefix list of non-entry modules so the - // entry main can call each `__init` in order. - // The prefix derivation must match what - // `perry_codegen::compile_module` does internally - // (sanitize(hir.name)) so the symbols match. LLVM IR - // identifiers cannot start with a digit, so prefix with - // `_` if the first character would be one (handles module - // names like `05_fibonacci.ts`). - let sanitize_name = |s: &str| -> String { - let mut out: String = s - .chars() - .map(|c| { - if c.is_ascii_alphanumeric() || c == '_' { - c - } else { - '_' - } - }) - .collect(); - if out - .chars() - .next() - .map(|c| c.is_ascii_digit()) - .unwrap_or(false) - { - out.insert(0, '_'); + // Reuse the exact import-route preparation in both passes. The contract + // pass releases each module's metadata before visiting the next module; + // codegen builds complete options only while holding a worker permit. + let prepare_module = |path: &PathBuf, + hir_module: &perry_hir::Module, + contracts_only: bool| + -> Result { + let is_entry = path == &entry_path; + // Compute the prefix list of non-entry modules so the + // entry main can call each `__init` in order. + // The prefix derivation must match what + // `perry_codegen::compile_module` does internally + // (sanitize(hir.name)) so the symbols match. LLVM IR + // identifiers cannot start with a digit, so prefix with + // `_` if the first character would be one (handles module + // names like `05_fibonacci.ts`). + let sanitize_name = |s: &str| -> String { + let mut out: String = s + .chars() + .map(|c| { + if c.is_ascii_alphanumeric() || c == '_' { + c + } else { + '_' } - out - }; - // CRITICAL: iterate `non_entry_module_names` (topologically - // sorted above) rather than `ctx.native_modules` — the latter - // is a `BTreeMap` and iterates in alphabetical - // path order, which silently reverses the dependency order - // for any project whose leaf modules sort after their - // dependents (e.g. `types/registry.ts` sorting after - // `connection.ts`). When that happens, a top-level - // `registerDefaultCodecs()` call in register-defaults.ts - // runs BEFORE types/registry.ts's init has set up the - // `REGISTRY_OIDS` global — the push-site writes to a stale - // (0.0-initialized) global while the read-site later loads - // from the real one. Symptom: registry appears empty to - // every later consumer even though primitives like - // `let registered = false` look shared (they only need - // storage, not init-order). Fixes GH #32. - let non_entry_module_prefixes: Vec = if is_entry { - non_entry_module_names - .iter() - .map(|name| sanitize_name(name)) - .collect() - } else { - Vec::new() - }; - // Issue #753: every module receives the program-wide set of - // Deferred module prefixes. The entry main filters these - // out of its eager init call sequence; non-entry modules - // ignore it. Empty when no module in the program is - // Deferred (i.e. no dynamic `import()` sites). - let deferred_module_prefixes: std::collections::HashSet = ctx - .native_modules - .iter() - .filter(|(_, m)| m.init_kind == perry_hir::ModuleInitKind::Deferred) - .map(|(_, m)| sanitize_name(&m.name)) - .collect(); - // Next.js wall 54 (part 2): `(absolute_path, prefix)` for every - // `.next/server/**` runtime module so the entry's `main` can record - // its `__init` address by path (`js_register_path_init`). Only the - // entry emits these; the runtime `require(absolutePath)` shim then - // triggers the matching module's lazy init on first load. - let nextjs_path_init_modules: Vec<(String, String)> = if is_entry { - ctx.native_modules - .iter() - .filter(|(p, module)| { - module.init_kind == perry_hir::ModuleInitKind::Deferred + }) + .collect(); + if out + .chars() + .next() + .map(|c| c.is_ascii_digit()) + .unwrap_or(false) + { + out.insert(0, '_'); + } + out + }; + // CRITICAL: iterate `non_entry_module_names` (topologically + // sorted above) rather than `ctx.native_modules` — the latter + // is a `BTreeMap` and iterates in alphabetical + // path order, which silently reverses the dependency order + // for any project whose leaf modules sort after their + // dependents (e.g. `types/registry.ts` sorting after + // `connection.ts`). When that happens, a top-level + // `registerDefaultCodecs()` call in register-defaults.ts + // runs BEFORE types/registry.ts's init has set up the + // `REGISTRY_OIDS` global — the push-site writes to a stale + // (0.0-initialized) global while the read-site later loads + // from the real one. Symptom: registry appears empty to + // every later consumer even though primitives like + // `let registered = false` look shared (they only need + // storage, not init-order). Fixes GH #32. + let non_entry_module_prefixes: Vec = if is_entry { + non_entry_module_names + .iter() + .map(|name| sanitize_name(name)) + .collect() + } else { + Vec::new() + }; + // Issue #753: every module receives the program-wide set of + // Deferred module prefixes. The entry main filters these + // out of its eager init call sequence; non-entry modules + // ignore it. Empty when no module in the program is + // Deferred (i.e. no dynamic `import()` sites). + let deferred_module_prefixes: std::collections::HashSet = ctx + .native_modules + .iter() + .filter(|(_, m)| m.init_kind == perry_hir::ModuleInitKind::Deferred) + .map(|(_, m)| sanitize_name(&m.name)) + .collect(); + // Next.js wall 54 (part 2): `(absolute_path, prefix)` for every + // `.next/server/**` runtime module so the entry's `main` can record + // its `__init` address by path (`js_register_path_init`). Only the + // entry emits these; the runtime `require(absolutePath)` shim then + // triggers the matching module's lazy init on first load. + let nextjs_path_init_modules: Vec<(String, String)> = if is_entry { + ctx.native_modules + .iter() + .filter(|(p, module)| { + module.init_kind == perry_hir::ModuleInitKind::Deferred || self::collect_modules::is_nextjs_runtime_module(p) // A `perry.compilePackages` module may be reachable // ONLY through a runtime-computed require (Next's @@ -3224,322 +3225,470 @@ pub fn run_with_parse_cache( .compile_package_dirs .iter() .any(|dir| p.starts_with(dir)) - }) - .map(|(p, m)| (p.to_string_lossy().into_owned(), sanitize_name(&m.name))) - .collect() - } else { - Vec::new() - }; - // Issue #753: prefixes of this module's static-import + - // re-export source modules (non-entry only — the entry's - // body is in `main`, not a `__init`). The wrapper at - // `__init` calls each dep's `__init` before - // dispatching to `__init_body`; this transitively - // initializes any Deferred dep reached only through this - // module's re-export chain. For Eager modules the calls - // short-circuit on the idempotent guard's first-write - // check (one load + cmp + cond_br each). - let module_init_deps: Vec = if is_entry { - Vec::new() - } else { - let mut deps: Vec = Vec::new(); - let mut seen: std::collections::HashSet = - std::collections::HashSet::new(); - let entry_prefix = ctx - .native_modules - .get(&entry_path) - .map(|m| sanitize_name(&m.name)); - let push_dep = |deps: &mut Vec, - seen: &mut std::collections::HashSet, - prefix: String| { - if Some(&prefix) == entry_prefix.as_ref() { - return; - } - if seen.insert(prefix.clone()) { - deps.push(prefix); - } - }; - for import in &hir_module.imports { - // `is_deferred_require`: a function-local `require('S')` - // (lazy in Node). S must NOT chain into this module's init - // — it inits only when the require shim is actually called. - if import.is_dynamic - || import.type_only - || import.runtime_erased - || import.is_deferred_require - { - continue; - } - if let Some(resolved) = &import.resolved_path { - let resolved_path = PathBuf::from(resolved); - if let Some(src_mod) = ctx.native_modules.get(&resolved_path) { - push_dep(&mut deps, &mut seen, sanitize_name(&src_mod.name)); - } - } - } - for export in &hir_module.exports { - let src = match export { - perry_hir::Export::ExportAll { source } => Some(source.clone()), - perry_hir::Export::ReExport { source, .. } => Some(source.clone()), - perry_hir::Export::NamespaceReExport { source, .. } => { - Some(source.clone()) - } - perry_hir::Export::Named { .. } => None, - }; - if let Some(src) = src { - if let Some((resolved_path, _)) = - resolve_import_with_context(&src, path, &ctx) - { - if let Some(src_mod) = ctx.native_modules.get(&resolved_path) { - push_dep(&mut deps, &mut seen, sanitize_name(&src_mod.name)); - } - } - } - } - // Drop init-call back-edges (#6463). `topo_sort_non_entry_modules` - // breaks import cycles at the back-edge and the eager main - // sequence runs inits in that order — but the wrapper's nested - // dep-init calls re-derive the order dynamically at runtime. - // When the cycle member the sort placed FIRST runs, its broken - // edge to the member placed second pulled that module's BODY in - // early, before this module's own body had populated anything. - // Effect's web.ts died on this: find-my-way-ts - // internal/router.ts has `import * as Router from "../index.js"` - // used only in type positions (no `type` keyword, so it is a - // value edge), forming a cycle index ⇄ internal. The sort - // correctly placed internal first — matching node's ESM - // evaluation order from the entry — but internal's wrapper then - // called index's init, whose body copied - // `export const make = internal.make` while internal's global - // was still undefined. `FindMyWay.make` stayed undefined - // forever: "TypeError: value is not a function" at - // Layer.launch. Keeping only forward edges (dep positioned - // before this module) is exactly ESM's behavior of skipping a - // module already on the evaluation stack. A dep missing from - // the position map keeps its edge (conservative). - let init_pos: std::collections::HashMap = non_entry_module_names - .iter() - .enumerate() - .map(|(i, name)| (sanitize_name(name), i)) - .collect(); - if let Some(&self_pos) = init_pos.get(&sanitize_name(&hir_module.name)) { - deps.retain(|dep| init_pos.get(dep).map_or(true, |&p| p < self_pos)); + }) + .map(|(p, m)| (p.to_string_lossy().into_owned(), sanitize_name(&m.name))) + .collect() + } else { + Vec::new() + }; + // Issue #753: prefixes of this module's static-import + + // re-export source modules (non-entry only — the entry's + // body is in `main`, not a `__init`). The wrapper at + // `__init` calls each dep's `__init` before + // dispatching to `__init_body`; this transitively + // initializes any Deferred dep reached only through this + // module's re-export chain. For Eager modules the calls + // short-circuit on the idempotent guard's first-write + // check (one load + cmp + cond_br each). + let module_init_deps: Vec = if is_entry { + Vec::new() + } else { + let mut deps: Vec = Vec::new(); + let mut seen: std::collections::HashSet = std::collections::HashSet::new(); + let entry_prefix = ctx + .native_modules + .get(&entry_path) + .map(|m| sanitize_name(&m.name)); + let push_dep = |deps: &mut Vec, + seen: &mut std::collections::HashSet, + prefix: String| { + if Some(&prefix) == entry_prefix.as_ref() { + return; + } + if seen.insert(prefix.clone()) { + deps.push(prefix); + } + }; + for import in &hir_module.imports { + // `is_deferred_require`: a function-local `require('S')` + // (lazy in Node). S must NOT chain into this module's init + // — it inits only when the require shim is actually called. + if import.is_dynamic + || import.type_only + || import.runtime_erased + || import.is_deferred_require + { + continue; + } + if let Some(resolved) = &import.resolved_path { + let resolved_path = PathBuf::from(resolved); + if let Some(src_mod) = ctx.native_modules.get(&resolved_path) { + push_dep(&mut deps, &mut seen, sanitize_name(&src_mod.name)); } - deps + } + } + for export in &hir_module.exports { + let src = match export { + perry_hir::Export::ExportAll { source } => Some(source.clone()), + perry_hir::Export::ReExport { source, .. } => Some(source.clone()), + perry_hir::Export::NamespaceReExport { source, .. } => Some(source.clone()), + perry_hir::Export::Named { .. } => None, }; - // Build import → source-prefix table for cross-module - // ExternFuncRef calls. For each Named import in this - // module, look up the source module's HIR by resolved - // path and capture its name. The LLVM codegen uses this - // to generate `perry_fn___`. - let mut import_function_prefixes: std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #5621: ergonomic camelCase binding → snake_case - // `js__*` FFI symbol. A `perry.nativeLibrary` package may - // expose spec-faithful camelCase exports (`requestAdapter`) - // over its manifest symbols (`js_webgpu_request_adapter`). When - // a specifier matches a manifest function via the standard - // `js__` ⇒ camelCase derivation (rather than a - // byte-for-byte name match), we skip the wrapper registration - // below AND record the alias here so the call site - // (`lower_call`) rewrites the binding to its manifest symbol. - let mut import_function_ffi_aliases: std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #678: parallel to `import_function_prefixes`. When the - // import traverses a re-export rename (`export { default as render - // } from './render.js'`), the consumer sees `render` but the - // origin module emits the symbol with its own export name - // (`default`). This map captures the consumer-name → origin-name - // override so every `perry_fn___` construction site - // can pick the right suffix. Absent entries (the common case) - // mean no rename — the consumer name is the origin name. - let mut import_function_origin_names: std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #678 followup: imports landing in `ModuleKind::Interpreted` - // (V8 fallback). The codegen probes this map BEFORE - // `perry_fn___` symbol formation and routes hits - // through `js_call_v8_export(specifier, name, args, argc)`. - // Pre-fix, V8-backed imports were silently dropped from - // `import_function_prefixes`, so the consumer's call - // emitted a bare `call double @` against an - // undefined symbol — every `import { render } from "ink"` - // (or similar where the package fell back to V8) failed at - // link time with `Undefined symbols: _perry_fn_..._render`. - let mut import_function_v8_specifiers: std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #841: named-import → (submodule_key, exported_name) - // for the five recognized Node submodules with no perry-stdlib - // backing. Populated by a dedicated pass below; consumed by - // codegen's `Expr::ExternFuncRef` value-form catch-all. - let mut import_function_node_submodule: std::collections::HashMap< - String, - (String, String), - > = std::collections::HashMap::new(); - // Issue #841 companion: local-namespace → submodule_key for - // `import * as ns from "node:"`. - let mut namespace_node_submodules: std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #678 followup (namespace branch): local-namespace → - // V8 module specifier for `import * as ns from ""`. - // Populated in the V8-imports pass below at the same site that - // would otherwise no-op on `ImportSpecifier::Namespace`. Used - // by codegen's StaticMethodCall / namespace-member-call - // lowering to route `ns.member(args)` through - // `js_call_v8_export` when nothing else seeded - // `import_function_prefixes` for the member. - let mut namespace_v8_specifiers: std::collections::HashMap = - std::collections::HashMap::new(); - // Issue #680: per-namespace member resolution. Disambiguates - // `random.make` vs `tracer.make` when multiple namespaces - // export the same member name. Keyed by `(namespace_local, - // member_name)` → `source_prefix`. - let mut namespace_member_prefixes: std::collections::HashMap< - (String, String), - String, - > = std::collections::HashMap::new(); - // Issue #5924 (companion to #680/#678): per-namespace origin-name - // resolution. `import_function_origin_names` is flat (keyed by - // bare member name), so when two namespaces imported into the - // same file both have a member with the same name and only ONE - // of them is a re-export rename, the rename's origin-name - // override clobbers the other namespace's (correct, unrenamed) - // suffix. Keyed by `(namespace_local, member_name)` → - // `origin_name`, mirroring `namespace_member_prefixes`. - let mut namespace_member_origin_names: std::collections::HashMap< - (String, String), - String, - > = std::collections::HashMap::new(); - let mut namespace_imports: Vec = Vec::new(); - // #7189: members of a namespace whose value is ITSELF a module - // namespace, from `export * as ns from "./m.ts"` in the imported - // module. They resolve to `@__perry_ns_` rather than to a - // `perry_fn___` symbol, because no such symbol exists — - // the member is a whole module, not a binding in one. - let mut namespace_member_nested: std::collections::HashSet<(String, String)> = - std::collections::HashSet::new(); - let mut imported_classes: Vec = Vec::new(); - let mut imported_enums: Vec<(String, Vec<(String, perry_hir::EnumValue)>)> = - Vec::new(); - let mut imported_async_set: std::collections::HashSet = - std::collections::HashSet::new(); - let mut imported_param_counts: std::collections::HashMap = - std::collections::HashMap::new(); - let mut imported_return_types: std::collections::HashMap< - String, - perry_hir::types::Type, - > = std::collections::HashMap::new(); - // Issue #608 — set of imported function names whose source-side - // signature has a trailing `...rest` parameter. Built alongside - // `imported_param_counts` from the source module's - // `exported_func_has_rest` table; consulted by the cross-module - // call site in `lower_call.rs` to bundle trailing args into a - // single rest array. Sparse set (only `true` entries stored). - let mut imported_has_rest: std::collections::HashSet = - std::collections::HashSet::new(); - // #1816: imported functions whose trailing param is the synthesized - // `arguments` rest — the cross-module call must bundle ALL args into - // it, not just trailing. Built alongside `imported_has_rest`. - let mut imported_synthetic_arguments: std::collections::HashSet = - std::collections::HashSet::new(); - let mut imported_vars: std::collections::HashSet = - std::collections::HashSet::new(); - - // Issue #629: register namespace imports BEFORE the main - // resolution loop so unresolved-source bindings still flow - // to the codegen's `namespace_imports` set. Without this, - // the early `continue` for unresolved imports below means - // `import * as fsp from "node:fs/promises"` (when - // fs/promises has no perry-stdlib backing) leaves `fsp` - // off the namespace list — the catch-all in - // `Expr::ExternFuncRef` then returns TAG_TRUE and - // `typeof fsp === "boolean"`. Registering here lets the - // catch-all route through `js_unresolved_namespace_stub` - // (typeof "object", missing properties → undefined). - // - // Issue #684: skip WHOLE-DECL type-only imports - // (`import type * as X from "..."`). They're erased at - // runtime — the local binding never appears in any - // value-position expression, so registering it as a - // namespace would only widen the per-namespace member - // map below. Per-specifier type-only (`import { type Foo, - // bar }`) is still handled because the same import has - // value specifiers; the whole-decl flag is the one that - // makes the entire import a no-op. - for import in &hir_module.imports { - if import.type_only || import.runtime_erased { - continue; - } - for spec in &import.specifiers { - if let perry_hir::ImportSpecifier::Namespace { local } = spec { - if !namespace_imports.contains(local) { - namespace_imports.push(local.clone()); - } + if let Some(src) = src { + if let Some((resolved_path, _)) = resolve_import_with_context(&src, path, &ctx) + { + if let Some(src_mod) = ctx.native_modules.get(&resolved_path) { + push_dep(&mut deps, &mut seen, sanitize_name(&src_mod.name)); } } } + } + // Drop init-call back-edges (#6463). `topo_sort_non_entry_modules` + // breaks import cycles at the back-edge and the eager main + // sequence runs inits in that order — but the wrapper's nested + // dep-init calls re-derive the order dynamically at runtime. + // When the cycle member the sort placed FIRST runs, its broken + // edge to the member placed second pulled that module's BODY in + // early, before this module's own body had populated anything. + // Effect's web.ts died on this: find-my-way-ts + // internal/router.ts has `import * as Router from "../index.js"` + // used only in type positions (no `type` keyword, so it is a + // value edge), forming a cycle index ⇄ internal. The sort + // correctly placed internal first — matching node's ESM + // evaluation order from the entry — but internal's wrapper then + // called index's init, whose body copied + // `export const make = internal.make` while internal's global + // was still undefined. `FindMyWay.make` stayed undefined + // forever: "TypeError: value is not a function" at + // Layer.launch. Keeping only forward edges (dep positioned + // before this module) is exactly ESM's behavior of skipping a + // module already on the evaluation stack. A dep missing from + // the position map keeps its edge (conservative). + let init_pos: std::collections::HashMap = non_entry_module_names + .iter() + .enumerate() + .map(|(i, name)| (sanitize_name(name), i)) + .collect(); + if let Some(&self_pos) = init_pos.get(&sanitize_name(&hir_module.name)) { + deps.retain(|dep| init_pos.get(dep).map_or(true, |&p| p < self_pos)); + } + deps + }; + // Build import → source-prefix table for cross-module + // ExternFuncRef calls. For each Named import in this + // module, look up the source module's HIR by resolved + // path and capture its name. The LLVM codegen uses this + // to generate `perry_fn___`. + let mut import_function_prefixes: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #5621: ergonomic camelCase binding → snake_case + // `js__*` FFI symbol. A `perry.nativeLibrary` package may + // expose spec-faithful camelCase exports (`requestAdapter`) + // over its manifest symbols (`js_webgpu_request_adapter`). When + // a specifier matches a manifest function via the standard + // `js__` ⇒ camelCase derivation (rather than a + // byte-for-byte name match), we skip the wrapper registration + // below AND record the alias here so the call site + // (`lower_call`) rewrites the binding to its manifest symbol. + let mut import_function_ffi_aliases: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #678: parallel to `import_function_prefixes`. When the + // import traverses a re-export rename (`export { default as render + // } from './render.js'`), the consumer sees `render` but the + // origin module emits the symbol with its own export name + // (`default`). This map captures the consumer-name → origin-name + // override so every `perry_fn___` construction site + // can pick the right suffix. Absent entries (the common case) + // mean no rename — the consumer name is the origin name. + let mut import_function_origin_names: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #678 followup: imports landing in `ModuleKind::Interpreted` + // (V8 fallback). The codegen probes this map BEFORE + // `perry_fn___` symbol formation and routes hits + // through `js_call_v8_export(specifier, name, args, argc)`. + // Pre-fix, V8-backed imports were silently dropped from + // `import_function_prefixes`, so the consumer's call + // emitted a bare `call double @` against an + // undefined symbol — every `import { render } from "ink"` + // (or similar where the package fell back to V8) failed at + // link time with `Undefined symbols: _perry_fn_..._render`. + let mut import_function_v8_specifiers: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #841: named-import → (submodule_key, exported_name) + // for the five recognized Node submodules with no perry-stdlib + // backing. Populated by a dedicated pass below; consumed by + // codegen's `Expr::ExternFuncRef` value-form catch-all. + let mut import_function_node_submodule: std::collections::HashMap< + String, + (String, String), + > = std::collections::HashMap::new(); + // Issue #841 companion: local-namespace → submodule_key for + // `import * as ns from "node:"`. + let mut namespace_node_submodules: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #678 followup (namespace branch): local-namespace → + // V8 module specifier for `import * as ns from ""`. + // Populated in the V8-imports pass below at the same site that + // would otherwise no-op on `ImportSpecifier::Namespace`. Used + // by codegen's StaticMethodCall / namespace-member-call + // lowering to route `ns.member(args)` through + // `js_call_v8_export` when nothing else seeded + // `import_function_prefixes` for the member. + let mut namespace_v8_specifiers: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #680: per-namespace member resolution. Disambiguates + // `random.make` vs `tracer.make` when multiple namespaces + // export the same member name. Keyed by `(namespace_local, + // member_name)` → `source_prefix`. + let mut namespace_member_prefixes: std::collections::HashMap<(String, String), String> = + std::collections::HashMap::new(); + // Issue #5924 (companion to #680/#678): per-namespace origin-name + // resolution. `import_function_origin_names` is flat (keyed by + // bare member name), so when two namespaces imported into the + // same file both have a member with the same name and only ONE + // of them is a re-export rename, the rename's origin-name + // override clobbers the other namespace's (correct, unrenamed) + // suffix. Keyed by `(namespace_local, member_name)` → + // `origin_name`, mirroring `namespace_member_prefixes`. + let mut namespace_member_origin_names: std::collections::HashMap<(String, String), String> = + std::collections::HashMap::new(); + let mut namespace_imports: Vec = Vec::new(); + // #7189: members of a namespace whose value is ITSELF a module + // namespace, from `export * as ns from "./m.ts"` in the imported + // module. They resolve to `@__perry_ns_` rather than to a + // `perry_fn___` symbol, because no such symbol exists — + // the member is a whole module, not a binding in one. + let mut namespace_member_nested: std::collections::HashSet<(String, String)> = + std::collections::HashSet::new(); + let mut imported_classes: Vec = Vec::new(); + let mut imported_enums: Vec<(String, Vec<(String, perry_hir::EnumValue)>)> = Vec::new(); + let mut imported_async_set: std::collections::HashSet = + std::collections::HashSet::new(); + let mut imported_param_counts: std::collections::HashMap = + std::collections::HashMap::new(); + let mut imported_return_types: std::collections::HashMap = + std::collections::HashMap::new(); + // Issue #608 — set of imported function names whose source-side + // signature has a trailing `...rest` parameter. Built alongside + // `imported_param_counts` from the source module's + // `exported_func_has_rest` table; consulted by the cross-module + // call site in `lower_call.rs` to bundle trailing args into a + // single rest array. Sparse set (only `true` entries stored). + let mut imported_has_rest: std::collections::HashSet = + std::collections::HashSet::new(); + // #1816: imported functions whose trailing param is the synthesized + // `arguments` rest — the cross-module call must bundle ALL args into + // it, not just trailing. Built alongside `imported_has_rest`. + let mut imported_synthetic_arguments: std::collections::HashSet = + std::collections::HashSet::new(); + let mut imported_vars: std::collections::HashSet = std::collections::HashSet::new(); + + // Issue #629: register namespace imports BEFORE the main + // resolution loop so unresolved-source bindings still flow + // to the codegen's `namespace_imports` set. Without this, + // the early `continue` for unresolved imports below means + // `import * as fsp from "node:fs/promises"` (when + // fs/promises has no perry-stdlib backing) leaves `fsp` + // off the namespace list — the catch-all in + // `Expr::ExternFuncRef` then returns TAG_TRUE and + // `typeof fsp === "boolean"`. Registering here lets the + // catch-all route through `js_unresolved_namespace_stub` + // (typeof "object", missing properties → undefined). + // + // Issue #684: skip WHOLE-DECL type-only imports + // (`import type * as X from "..."`). They're erased at + // runtime — the local binding never appears in any + // value-position expression, so registering it as a + // namespace would only widen the per-namespace member + // map below. Per-specifier type-only (`import { type Foo, + // bar }`) is still handled because the same import has + // value specifiers; the whole-decl flag is the one that + // makes the entire import a no-op. + for import in &hir_module.imports { + if import.type_only || import.runtime_erased { + continue; + } + for spec in &import.specifiers { + if let perry_hir::ImportSpecifier::Namespace { local } = spec { + if !namespace_imports.contains(local) { + namespace_imports.push(local.clone()); + } + } + } + } - for import in &hir_module.imports { - if import.module_kind != perry_hir::ModuleKind::NativeCompiled { + for import in &hir_module.imports { + if import.module_kind != perry_hir::ModuleKind::NativeCompiled { + continue; + } + let resolved_path = match &import.resolved_path { + Some(p) => p, + None => continue, + }; + let resolved_path_str = resolved_path.clone(); + let source_module = ctx + .native_modules + .iter() + .find(|(p, _)| p.to_string_lossy() == *resolved_path) + .map(|(_, m)| m); + let source_prefix = match &source_module { + Some(m) => sanitize_name(&m.name), + None => continue, + }; + // A whole-declaration `import type` contributes no runtime + // binding or init edge (#684), but a named class annotation + // may still carry useful producer-authored field metadata. + // Attach only that exact class when its defining module is + // already present in the value-reachable graph. Do not touch + // function/namespace maps, imported vars, native libraries, + // or module-init dependencies: those were the collision and + // phantom-load hazards #684 removed. + if import.type_only || import.runtime_erased { + for spec in &import.specifiers { + let perry_hir::ImportSpecifier::Named { imported, local } = spec else { continue; - } - let resolved_path = match &import.resolved_path { - Some(p) => p, - None => continue, }; - let resolved_path_str = resolved_path.clone(); - let source_module = ctx - .native_modules - .iter() - .find(|(p, _)| p.to_string_lossy() == *resolved_path) - .map(|(_, m)| m); - let source_prefix = match &source_module { - Some(m) => sanitize_name(&m.name), - None => continue, + let key = (resolved_path_str.clone(), imported.clone()); + let Some(class) = exported_classes.get(&key) else { + continue; }; - // A whole-declaration `import type` contributes no runtime - // binding or init edge (#684), but a named class annotation - // may still carry useful producer-authored field metadata. - // Attach only that exact class when its defining module is - // already present in the value-reachable graph. Do not touch - // function/namespace maps, imported vars, native libraries, - // or module-init dependencies: those were the collision and - // phantom-load hazards #684 removed. - if import.type_only || import.runtime_erased { - for spec in &import.specifiers { - let perry_hir::ImportSpecifier::Named { imported, local } = spec else { - continue; - }; - let key = (resolved_path_str.clone(), imported.clone()); - let Some(class) = exported_classes.get(&key) else { - continue; - }; - let origin_path = all_module_exports + let origin_path = all_module_exports + .get(&resolved_path_str) + .and_then(|exports| exports.get(imported)) + .cloned() + .unwrap_or_else(|| resolved_path_str.clone()); + let effective_prefix = if origin_path != resolved_path_str { + compute_module_prefix(&origin_path, &ctx.project_root) + } else { + source_prefix.clone() + }; + let class_prefix = canonical_class_source_prefix( + class, + &class_canonical_path, + &ctx.project_root, + &effective_prefix, + ); + let local_alias = (local != &class.name).then(|| local.clone()); + let duplicate = imported_classes.iter().any(|existing| { + existing.name == class.name + && existing.local_alias.as_ref() == local_alias.as_ref() + && existing.source_prefix == class_prefix + }); + if !duplicate { + imported_classes.push(imported_class_from_hir( + class, + class_prefix, + local_alias, + proven_this_methods_for_import(class, &class_proven_this_methods), + proven_this_methods_for_import(class, &class_proven_this_tower_methods), + )); + } + } + continue; + } + // PerryTS/storekit#1: when the import source is a package that + // declares `perry.nativeLibrary` (e.g. `@perryts/storekit`), + // its `.ts` source is a wrapper holding ambient `export + // declare function` signatures — the real implementation lives + // in the linked static library. There is no Perry wrapper + // symbol `perry_fn___` for the source to emit, so + // registering the FFI specifier in `import_function_prefixes` + // would route the caller through an undefined wrapper and + // fail at link time. The per-specifier skip below lets + // `lower_call.rs` fall through to the FFI-manifest path + // (consults `ctx.ffi_signatures`, emits the call against the + // FFI symbol declared in `package.json :: perry.nativeLibrary. + // functions` plus a matching `declare external`). + let native_library_for_import = ctx + .native_libraries + .iter() + .find(|nl| nl.module == import.source); + + for spec in &import.specifiers { + // Handle namespace imports (import * as X). + // + // Issue #4872: a DEFAULT import of a compiled module that + // has NO `default` export gets the same treatment. The + // CJS wrap lowers every `require('X')` to `import _req_N + // from 'X'`; when X resolves to an ESM barrel with only + // named exports (rxjs's src/index.ts, uid's index.mjs) or + // to a type-only interface surface with no exports at all + // (nestjs dist `*.interface.js`), there is no + // `perry_fn___default` symbol for the consumer to + // bind — the old fall-through registered the local as a + // callable function import and the link died on + // `__perry_wrap_perry_fn___default`. Node's + // `require(esm)` semantics hand back the module namespace + // object, so route the local through the namespace + // machinery: member reads resolve per-export to origin + // symbols, and a whole-value read materializes the + // namespace object (empty for zero-export modules). + let namespace_like_local: Option<&String> = match spec { + perry_hir::ImportSpecifier::Namespace { local } => Some(local), + perry_hir::ImportSpecifier::Default { local } + if !all_module_exports + .get(&resolved_path_str) + .is_some_and(|exports| exports.contains_key("default")) => + { + Some(local) + } + _ => None, + }; + if let Some(local) = namespace_like_local { + namespace_imports.push(local.clone()); + // Issue #6586: a namespace import of a CommonJS module + // whose `module.exports` value is itself the export + // (`module.exports = function equal(){}`, no + // `__esModule` marker) is TypeScript's + // esModuleInterop=false interop — `import * as equal + // from "fast-deep-equal"` binds `equal` to the whole + // `require()` result (the default export), so a DIRECT + // call `equal(a, b)` is a call OF that value. ajv's + // `lib/compile/resolve.ts` does exactly this for + // `fast-deep-equal` and `json-schema-traverse`, and + // fast-json-stringify pulls ajv in. The CJS wrap emits + // the value under the module's `default` symbol, but the + // namespace binding had no `import_function_prefixes` + // entry, so the direct call fell through to a bare + // `equal` extern and the link died with + // `Undefined symbols: "_equal"`. Wire the whole-value + // binding to the `default` export exactly like a Default + // specifier does below (member reads `ns.foo` are keyed + // per-namespace via `namespace_member_prefixes` and are + // unaffected). Only genuine namespace imports of a module + // that actually HAS a `default` export qualify — the + // #4872 default-import-of-a-named-only-barrel case that + // also lands here has no `default` and is skipped. + if matches!(spec, perry_hir::ImportSpecifier::Namespace { .. }) { + if let Some(default_origin_path) = all_module_exports + .get(&resolved_path_str) + .and_then(|exports| exports.get("default")) + .cloned() + { + let default_prefix = + compute_module_prefix(&default_origin_path, &ctx.project_root); + let default_suffix = all_module_export_origin_names .get(&resolved_path_str) - .and_then(|exports| exports.get(imported)) + .and_then(|m| m.get("default")) .cloned() - .unwrap_or_else(|| resolved_path_str.clone()); - let effective_prefix = if origin_path != resolved_path_str { - compute_module_prefix(&origin_path, &ctx.project_root) - } else { - source_prefix.clone() - }; - let class_prefix = canonical_class_source_prefix( - class, - &class_canonical_path, - &ctx.project_root, - &effective_prefix, - ); - let local_alias = (local != &class.name).then(|| local.clone()); - let duplicate = imported_classes.iter().any(|existing| { - existing.name == class.name - && existing.local_alias.as_ref() == local_alias.as_ref() - && existing.source_prefix == class_prefix - }); - if !duplicate { + .unwrap_or_else(|| "default".to_string()); + import_function_prefixes + .entry(local.clone()) + .or_insert(default_prefix.clone()); + import_function_origin_names + .entry(local.clone()) + .or_insert(default_suffix.clone()); + // The metadata maps are keyed by + // (declaring-path, exported-name); the default + // is declared at `default_origin_path` under + // `default_suffix` (== "default" unless a + // re-export renamed it). + let key = (default_origin_path.clone(), default_suffix); + // A CJS `module.exports = ` becomes a + // var-shaped default: a value binding emitted as + // a zero-arg getter. A direct call must fetch the + // closure via that getter and THEN invoke it with + // the args (`js_closure_callN`), so mark the local + // as an imported var — otherwise the call site + // treats the getter's return value AS the call + // result and `equal(1, 1)` yields the function + // itself instead of `true`. Mirrors the + // Default-import var classification below. + if exported_var_names.contains(&key) + || exported_var_names + .contains(&(resolved_path_str.clone(), "default".to_string())) + { + imported_vars.insert(local.clone()); + } + // A non-var-shaped default — a `module.exports = + // function foo(){}` static-function or a + // `module.exports = class Foo{}` — is called / + // instantiated through the direct + // `perry_fn___default` symbol, so it needs + // the same arity / rest / synthetic-arguments / + // return-type / async / class / enum metadata the + // Default specifier propagates below. Without it a + // rest-param default mis-bundles its trailing args + // and a class default has no ImportedClass entry + // (so `new ns()` can't resolve). Key everything by + // the namespace LOCAL, the name the consumer's + // ExternFuncRef carries. + if let Some(¶m_count) = exported_func_param_counts.get(&key) { + imported_param_counts.insert(local.clone(), param_count); + } + if exported_func_has_rest.get(&key).copied().unwrap_or(false) { + imported_has_rest.insert(local.clone()); + } + if exported_func_synthetic_arguments.contains(&key) { + imported_synthetic_arguments.insert(local.clone()); + } + if let Some(return_type) = exported_func_return_types.get(&key) { + imported_return_types.insert(local.clone(), return_type.clone()); + } + if exported_async_funcs.contains(&key) { + imported_async_set.insert(local.clone()); + } + if let Some(class) = exported_classes.get(&key) { + let class_prefix = canonical_class_source_prefix( + class, + &class_canonical_path, + &ctx.project_root, + &default_prefix, + ); imported_classes.push(imported_class_from_hir( class, class_prefix, - local_alias, + Some(local.clone()), proven_this_methods_for_import( class, &class_proven_this_methods, @@ -3550,1129 +3699,182 @@ pub fn run_with_parse_cache( ), )); } + if let Some(members) = exported_enums.get(&key) { + imported_enums.push((local.clone(), members.clone())); + } } - continue; } - // PerryTS/storekit#1: when the import source is a package that - // declares `perry.nativeLibrary` (e.g. `@perryts/storekit`), - // its `.ts` source is a wrapper holding ambient `export - // declare function` signatures — the real implementation lives - // in the linked static library. There is no Perry wrapper - // symbol `perry_fn___` for the source to emit, so - // registering the FFI specifier in `import_function_prefixes` - // would route the caller through an undefined wrapper and - // fail at link time. The per-specifier skip below lets - // `lower_call.rs` fall through to the FFI-manifest path - // (consults `ctx.ffi_signatures`, emits the call against the - // FFI symbol declared in `package.json :: perry.nativeLibrary. - // functions` plus a matching `declare external`). - let native_library_for_import = ctx - .native_libraries - .iter() - .find(|nl| nl.module == import.source); - - for spec in &import.specifiers { - // Handle namespace imports (import * as X). - // - // Issue #4872: a DEFAULT import of a compiled module that - // has NO `default` export gets the same treatment. The - // CJS wrap lowers every `require('X')` to `import _req_N - // from 'X'`; when X resolves to an ESM barrel with only - // named exports (rxjs's src/index.ts, uid's index.mjs) or - // to a type-only interface surface with no exports at all - // (nestjs dist `*.interface.js`), there is no - // `perry_fn___default` symbol for the consumer to - // bind — the old fall-through registered the local as a - // callable function import and the link died on - // `__perry_wrap_perry_fn___default`. Node's - // `require(esm)` semantics hand back the module namespace - // object, so route the local through the namespace - // machinery: member reads resolve per-export to origin - // symbols, and a whole-value read materializes the - // namespace object (empty for zero-export modules). - let namespace_like_local: Option<&String> = match spec { - perry_hir::ImportSpecifier::Namespace { local } => Some(local), - perry_hir::ImportSpecifier::Default { local } - if !all_module_exports - .get(&resolved_path_str) - .is_some_and(|exports| exports.contains_key("default")) => - { - Some(local) - } - _ => None, - }; - if let Some(local) = namespace_like_local { - namespace_imports.push(local.clone()); - // Issue #6586: a namespace import of a CommonJS module - // whose `module.exports` value is itself the export - // (`module.exports = function equal(){}`, no - // `__esModule` marker) is TypeScript's - // esModuleInterop=false interop — `import * as equal - // from "fast-deep-equal"` binds `equal` to the whole - // `require()` result (the default export), so a DIRECT - // call `equal(a, b)` is a call OF that value. ajv's - // `lib/compile/resolve.ts` does exactly this for - // `fast-deep-equal` and `json-schema-traverse`, and - // fast-json-stringify pulls ajv in. The CJS wrap emits - // the value under the module's `default` symbol, but the - // namespace binding had no `import_function_prefixes` - // entry, so the direct call fell through to a bare - // `equal` extern and the link died with - // `Undefined symbols: "_equal"`. Wire the whole-value - // binding to the `default` export exactly like a Default - // specifier does below (member reads `ns.foo` are keyed - // per-namespace via `namespace_member_prefixes` and are - // unaffected). Only genuine namespace imports of a module - // that actually HAS a `default` export qualify — the - // #4872 default-import-of-a-named-only-barrel case that - // also lands here has no `default` and is skipped. - if matches!(spec, perry_hir::ImportSpecifier::Namespace { .. }) { - if let Some(default_origin_path) = all_module_exports - .get(&resolved_path_str) - .and_then(|exports| exports.get("default")) - .cloned() - { - let default_prefix = compute_module_prefix( - &default_origin_path, - &ctx.project_root, - ); - let default_suffix = all_module_export_origin_names - .get(&resolved_path_str) - .and_then(|m| m.get("default")) - .cloned() - .unwrap_or_else(|| "default".to_string()); - import_function_prefixes - .entry(local.clone()) - .or_insert(default_prefix.clone()); + // Register all exports from the source module + if let Some(exports) = all_module_exports.get(&resolved_path_str) { + for (export_name, origin_path) in exports { + let origin_prefix = + compute_module_prefix(origin_path, &ctx.project_root); + // Issue #5927: namespace members are a + // best-effort fallback in the flat + // `import_function_prefixes` map — the + // authoritative lookup for genuine + // namespace-member accesses is the + // per-namespace `namespace_member_prefixes` + // map populated unconditionally below. Use + // `or_insert` (never overwrite) so a PLAIN + // named import of the same bare name (which + // has NO other resolution path — a bare + // call has no namespace to scope against) + // always wins the flat map, regardless of + // which import statement is processed + // first. Pre-fix, `import { omit } from + // "remeda"` in the same file as `import { + // Context } from "effect"` (where + // effect's Context.ts also exports `omit`) + // meant whichever import was LATER in + // source order silently overwrote the + // other's flat-map entry — opencode's + // `provider.ts` has `Context` imported + // after `omit`, so `omit(...)` (a bare + // remeda call) resolved against + // `Context.ts`'s prefix instead of + // remeda's chunk. + import_function_prefixes + .entry(export_name.clone()) + .or_insert_with(|| origin_prefix.clone()); + // Issue #678: surface origin-name overrides + // for namespace-imported members too. A + // member reached via a re-export rename + // (`export { default as foo }`) needs the + // codegen to call `perry_fn___default` + // when the consumer writes `ns.foo()`. + let resolved_origin_name = all_module_export_origin_names + .get(&resolved_path_str) + .and_then(|m| m.get(export_name)) + .cloned(); + if let Some(ref origin_name) = resolved_origin_name { + if origin_name != export_name { + // Issue #5927: same `or_insert` + // rationale as `import_function_prefixes` + // above — never let a namespace + // member's origin-name rename + // overwrite a plain import's entry. import_function_origin_names - .entry(local.clone()) - .or_insert(default_suffix.clone()); - // The metadata maps are keyed by - // (declaring-path, exported-name); the default - // is declared at `default_origin_path` under - // `default_suffix` (== "default" unless a - // re-export renamed it). - let key = (default_origin_path.clone(), default_suffix); - // A CJS `module.exports = ` becomes a - // var-shaped default: a value binding emitted as - // a zero-arg getter. A direct call must fetch the - // closure via that getter and THEN invoke it with - // the args (`js_closure_callN`), so mark the local - // as an imported var — otherwise the call site - // treats the getter's return value AS the call - // result and `equal(1, 1)` yields the function - // itself instead of `true`. Mirrors the - // Default-import var classification below. - if exported_var_names.contains(&key) - || exported_var_names.contains(&( - resolved_path_str.clone(), - "default".to_string(), - )) - { - imported_vars.insert(local.clone()); - } - // A non-var-shaped default — a `module.exports = - // function foo(){}` static-function or a - // `module.exports = class Foo{}` — is called / - // instantiated through the direct - // `perry_fn___default` symbol, so it needs - // the same arity / rest / synthetic-arguments / - // return-type / async / class / enum metadata the - // Default specifier propagates below. Without it a - // rest-param default mis-bundles its trailing args - // and a class default has no ImportedClass entry - // (so `new ns()` can't resolve). Key everything by - // the namespace LOCAL, the name the consumer's - // ExternFuncRef carries. - if let Some(¶m_count) = exported_func_param_counts.get(&key) - { - imported_param_counts.insert(local.clone(), param_count); - } - if exported_func_has_rest.get(&key).copied().unwrap_or(false) { - imported_has_rest.insert(local.clone()); - } - if exported_func_synthetic_arguments.contains(&key) { - imported_synthetic_arguments.insert(local.clone()); - } - if let Some(return_type) = exported_func_return_types.get(&key) - { - imported_return_types - .insert(local.clone(), return_type.clone()); - } - if exported_async_funcs.contains(&key) { - imported_async_set.insert(local.clone()); - } - if let Some(class) = exported_classes.get(&key) { - let class_prefix = canonical_class_source_prefix( - class, - &class_canonical_path, - &ctx.project_root, - &default_prefix, - ); - imported_classes.push(imported_class_from_hir( - class, - class_prefix, - Some(local.clone()), - proven_this_methods_for_import( - class, - &class_proven_this_methods, - ), - proven_this_methods_for_import( - class, - &class_proven_this_tower_methods, - ), - )); - } - if let Some(members) = exported_enums.get(&key) { - imported_enums.push((local.clone(), members.clone())); - } - } - } - // Register all exports from the source module - if let Some(exports) = all_module_exports.get(&resolved_path_str) { - for (export_name, origin_path) in exports { - let origin_prefix = - compute_module_prefix(origin_path, &ctx.project_root); - // Issue #5927: namespace members are a - // best-effort fallback in the flat - // `import_function_prefixes` map — the - // authoritative lookup for genuine - // namespace-member accesses is the - // per-namespace `namespace_member_prefixes` - // map populated unconditionally below. Use - // `or_insert` (never overwrite) so a PLAIN - // named import of the same bare name (which - // has NO other resolution path — a bare - // call has no namespace to scope against) - // always wins the flat map, regardless of - // which import statement is processed - // first. Pre-fix, `import { omit } from - // "remeda"` in the same file as `import { - // Context } from "effect"` (where - // effect's Context.ts also exports `omit`) - // meant whichever import was LATER in - // source order silently overwrote the - // other's flat-map entry — opencode's - // `provider.ts` has `Context` imported - // after `omit`, so `omit(...)` (a bare - // remeda call) resolved against - // `Context.ts`'s prefix instead of - // remeda's chunk. - import_function_prefixes .entry(export_name.clone()) - .or_insert_with(|| origin_prefix.clone()); - // Issue #678: surface origin-name overrides - // for namespace-imported members too. A - // member reached via a re-export rename - // (`export { default as foo }`) needs the - // codegen to call `perry_fn___default` - // when the consumer writes `ns.foo()`. - let resolved_origin_name = all_module_export_origin_names - .get(&resolved_path_str) - .and_then(|m| m.get(export_name)) - .cloned(); - if let Some(ref origin_name) = resolved_origin_name { - if origin_name != export_name { - // Issue #5927: same `or_insert` - // rationale as `import_function_prefixes` - // above — never let a namespace - // member's origin-name rename - // overwrite a plain import's entry. - import_function_origin_names - .entry(export_name.clone()) - .or_insert_with(|| origin_name.clone()); - } - } - // Issue #5924: unconditionally register every - // member under the per-namespace key — - // mirrors `namespace_member_prefixes` below, - // which is also populated for every export, - // not just renamed ones. A *sparse* map here - // (only renamed members) would still force a - // fallback to the flat - // `import_function_origin_names` for - // unrenamed members, and that flat entry may - // belong to a DIFFERENT namespace imported - // into the same file. Storing every member's - // resolved suffix (renamed or not) lets the - // consumer treat a namespace hit as - // authoritative and never fall through. - namespace_member_origin_names.insert( - (local.clone(), export_name.clone()), - resolved_origin_name - .clone() - .unwrap_or_else(|| export_name.clone()), - ); - // Issue #680: also register under the - // per-namespace key so `random.make` and - // `tracer.make` can be disambiguated. - namespace_member_prefixes.insert( - (local.clone(), export_name.clone()), - origin_prefix.clone(), - ); - - let key = (origin_path.clone(), export_name.clone()); - let scoped_func_key = perry_codegen::namespace_member_func_key( - local, - export_name, - ); - if let Some(¶m_count) = exported_func_param_counts.get(&key) - { - imported_param_counts - .insert(export_name.clone(), param_count); - imported_param_counts - .insert(scoped_func_key.clone(), param_count); - } - if exported_func_has_rest.get(&key).copied().unwrap_or(false) { - imported_has_rest.insert(export_name.clone()); - imported_has_rest.insert(scoped_func_key.clone()); - } - if exported_func_synthetic_arguments.contains(&key) { - imported_synthetic_arguments.insert(export_name.clone()); - imported_synthetic_arguments.insert(scoped_func_key); - } - // Issue #636: namespace-imported vars must - // route through the zero-arg getter at - // call sites (`ns.fn(args)` where `fn` is a - // `let`/`const` binding holding a closure - // — the canonical `export const make = (s) - // => ...` shape). Without this, the codegen - // falls through to the direct-call path - // which treats the getter's return value - // as the call result instead of invoking - // the closure with `args`. Mirrors the - // named-import branch at the var-detection - // arm below. The key is namespace-qualified: - // a flat `make` entry lets one namespace's - // variable export misclassify another - // namespace's declared function as a getter. - // - // Issue #4841: when the namespace member is a - // re-export of a CJS submodule's `default` - // (`import sfy from './sfy'; export { sfy }`, - // where `./sfy` is `module.exports = function`), - // the origin module records the var under its - // "default" suffix — NOT the consumer-visible - // member name. Probe both keys (mirrors the - // named-import arm) so the var-vs-function - // classification fires; otherwise `ns.sfy` takes - // the function path and wraps the default getter - // in a singleton closure, so `ns.sfy(args)` - // RETURNS the function value instead of being it - // (Stripe's `qs.stringify(...)` returned the qs - // function ⇒ `.replace is not a function`). - let origin_key_under_origin_name = resolved_origin_name - .as_ref() - .map(|n| (origin_path.clone(), n.clone())); - if exported_var_names.contains(&key) - || origin_key_under_origin_name - .as_ref() - .map(|k| exported_var_names.contains(k)) - .unwrap_or(false) - { - imported_vars.insert( - perry_codegen::namespace_member_var_key( - local, - export_name, - ), - ); - } - // #9285: re-export renames keep the class - // metadata under its origin name (`Child`), not - // the namespace-visible alias (`PublicChild`). - // The var path above already consults this - // origin key; class registration must do the - // same or `new ns.PublicChild(arg)` falls - // through to a function wrapper and never runs - // the class constructor. - let imported_class = exported_classes.get(&key).or_else(|| { - origin_key_under_origin_name - .as_ref() - .and_then(|origin_key| exported_classes.get(origin_key)) - }); - if let Some(class) = imported_class { - let class_prefix = canonical_class_source_prefix( - class, - &class_canonical_path, - &ctx.project_root, - &origin_prefix, - ); - let local_alias = if export_name == &class.name { - None - } else { - Some(export_name.clone()) - }; - let mut imported_class = imported_class_from_hir( - class, - class_prefix, - local_alias, - proven_this_methods_for_import( - class, - &class_proven_this_methods, - ), - proven_this_methods_for_import( - class, - &class_proven_this_tower_methods, - ), - ); - // A namespace member is reachable only as - // `local.export_name`; it is not a lexical - // binding named `export_name`. Keeping that - // ownership explicit prevents same-named - // classes from replacing direct imports. - imported_class.namespace = Some(local.clone()); - imported_classes.push(imported_class); - } - if let Some(members) = exported_enums.get(&key) { - imported_enums.push((export_name.clone(), members.clone())); - } - } - } - // Namespace aliases also participate in - // `all_module_exports`, so repeat this after the - // ordinary walk and let the TARGET prefix win over the - // declaring barrel's prefix. - if let Some(nested) = namespace_reexport_targets.get(&resolved_path_str) - { - for (alias, target_path) in nested { - let target_prefix = compute_module_prefix( - &target_path.to_string_lossy(), - &ctx.project_root, - ); - namespace_member_prefixes - .insert((local.clone(), alias.clone()), target_prefix); - namespace_member_nested.insert((local.clone(), alias.clone())); - } - } - if source_module.is_some_and(|module| is_wrapped_cjs(module)) { - let default_prefix = - compute_module_prefix(&resolved_path_str, &ctx.project_root); - let default_is_var = all_module_exports - .get(&resolved_path_str) - .and_then(|exports| exports.get("default")) - .is_some_and(|origin_path| { - let origin_name = all_module_export_origin_names - .get(&resolved_path_str) - .and_then(|names| names.get("default")) - .cloned() - .unwrap_or_else(|| "default".to_string()); - exported_var_names - .contains(&(origin_path.clone(), origin_name)) - }) - || exported_var_names.contains(&( - resolved_path_str.clone(), - "default".to_string(), - )); - // CJS namespace exotic objects expose both names - // as aliases of the evaluated exports object. The - // per-namespace origin map makes `module.exports` - // call the existing `default` getter rather than a - // nonexistent dotted symbol. - for member in ["default", "module.exports"] { - namespace_member_prefixes.insert( - (local.clone(), member.to_string()), - default_prefix.clone(), - ); - namespace_member_origin_names.insert( - (local.clone(), member.to_string()), - "default".to_string(), - ); - import_function_prefixes - .entry(member.to_string()) - .or_insert_with(|| default_prefix.clone()); - import_function_origin_names - .entry(member.to_string()) - .or_insert_with(|| "default".to_string()); - if member == "module.exports" || default_is_var { - imported_vars.insert( - perry_codegen::namespace_member_var_key(local, member), - ); - } - } - } - continue; - } - - let (local_name, exported_name) = match spec { - perry_hir::ImportSpecifier::Named { imported, local } => { - (local.clone(), imported.clone()) - } - perry_hir::ImportSpecifier::Default { local } => { - (local.clone(), "default".to_string()) - } - perry_hir::ImportSpecifier::Namespace { .. } => unreachable!(), - }; - - // PerryTS/storekit#1 + #5621: skip the wrapper-fn - // registration when this specifier names an FFI function - // declared in the source package's - // `perry.nativeLibrary.functions` manifest. The source - // `.ts` is ambient and has no Perry wrapper for the linker - // to resolve, so the FFI-manifest path in `lower_call.rs` - // must win. Two binding conventions route here: - // 1. Exact match — the binding name IS the symbol - // (`js_storekit_load_products`, raw ambient style). - // 2. Ergonomic camelCase (#5621) — the binding - // (`requestAdapter`) is the `js__` ⇒ - // camelCase derivation of the symbol. Record the alias - // (keyed by the *local* binding, since call sites see - // the local name) so the call site rewrites it; exact - // matches need no alias. - if let Some(nl) = native_library_for_import { - let exact_symbol = nl - .functions - .iter() - .find(|f| f.name == exported_name) - .map(|f| f.name.clone()); - // Issue #6715: a REAL module export wins over a derived - // ergonomic alias. The `js__` ⇒ camelCase - // routing (#5621) is a convenience for packages whose - // `.ts` only holds ambient `export declare function` - // signatures (no body) — those are skipped at lowering - // (`module_decl.rs`: `body.is_none()`), so they never - // enter `all_module_exports`. But the documented wrapper - // convention (native-extensions.md) is an ambient - // `declare function js__speak(...)` PLUS a real - // `export async function speak(...)` that transforms args - // and calls the FFI symbol. When such a wrapper's name - // collides with a manifest symbol's derived alias - // (`js_speech_speak` → `speak`), the alias must NOT - // shadow it — the import binds to the wrapper, which the - // module emits a `perry_fn___speak` symbol for and - // the fall-through named-import path registers below. - // Only genuine, implemented value exports land here, so - // ambient-declare-only packages keep the #5621 routing. - let has_genuine_module_export = all_module_exports - .get(&resolved_path_str) - .is_some_and(|exports| exports.contains_key(&exported_name)); - // Collect ALL ergonomic matches so an ambiguous manifest - // (two symbols deriving the same camelCase binding) is - // rejected rather than silently bound to the first. - let ergonomic_matches: Vec = - if exact_symbol.is_some() || has_genuine_module_export { - Vec::new() - } else { - nl.functions - .iter() - .filter(|f| { - ergonomic_export_alias(&nl.module, &f.name).as_deref() - == Some(exported_name.as_str()) - }) - .map(|f| f.name.clone()) - .collect() - }; - if ergonomic_matches.len() > 1 { - return Err(format!( - "native library `{}` has ambiguous ergonomic exports for \ - `{}`: the manifest symbols {:?} all derive the same \ - camelCase binding. Rename the symbols so each derives a \ - distinct binding, or import one by its raw `js_*` name.", - nl.module, exported_name, ergonomic_matches - )); - } - let matched_symbol = - exact_symbol.or_else(|| ergonomic_matches.into_iter().next()); - if let Some(symbol) = matched_symbol { - // No alias needed when the binding already IS the - // symbol (raw exact-match, unaliased). - if symbol != local_name { - import_function_ffi_aliases.insert(local_name.clone(), symbol); + .or_insert_with(|| origin_name.clone()); } - continue; } - } + // Issue #5924: unconditionally register every + // member under the per-namespace key — + // mirrors `namespace_member_prefixes` below, + // which is also populated for every export, + // not just renamed ones. A *sparse* map here + // (only renamed members) would still force a + // fallback to the flat + // `import_function_origin_names` for + // unrenamed members, and that flat entry may + // belong to a DIFFERENT namespace imported + // into the same file. Storing every member's + // resolved suffix (renamed or not) lets the + // consumer treat a namespace hit as + // authoritative and never fall through. + namespace_member_origin_names.insert( + (local.clone(), export_name.clone()), + resolved_origin_name + .clone() + .unwrap_or_else(|| export_name.clone()), + ); + // Issue #680: also register under the + // per-namespace key so `random.make` and + // `tracer.make` can be disambiguated. + namespace_member_prefixes.insert( + (local.clone(), export_name.clone()), + origin_prefix.clone(), + ); - // Issue #5916: the `NamespaceReExport` we are about to scan - // for may not sit in the module we import from — it can be - // one or more `export { X } from "src"` hops upstream. A - // barrel that does - // export { Token } from "./selfns" // ReExport - // where `selfns.ts` declares - // export * as Token from "./selfns" // NamespaceReExport - // exposes `Token` as a NAMESPACE, but the scan below only - // looked at the barrel's own exports, saw a plain `ReExport`, - // and fell through to the ordinary value path. `Token.estimate(…)` - // then lowered to a `StaticMethodCall` referencing - // `__perry_wrap_perry_fn___Token` — a closure wrapper - // no module emits, so the link failed outright. (A ReExport of - // an ordinary function/const across the same hop links fine; - // it is specifically a NAMESPACE-valued binding that needs the - // namespace routing.) - // - // Walk the re-export chain first so the scan runs against the - // module that actually DECLARES the namespace, under the name - // it declares it with. When no hop applies (the overwhelmingly - // common case) this leaves the scan target exactly where it was, - // so behaviour is unchanged. - let mut ns_scan_hir = source_module; - let mut ns_scan_path = resolved_path_str.clone(); - let mut ns_scan_name = exported_name.clone(); - for _ in 0..MAX_REEXPORT_HOPS { - let Some(hir) = ns_scan_hir else { break }; - // Already the declaring module — nothing to follow. - if hir.exports.iter().any(|e| { - matches!( - e, - perry_hir::Export::NamespaceReExport { name, .. } - if *name == ns_scan_name - ) - }) { - break; + let key = (origin_path.clone(), export_name.clone()); + let scoped_func_key = + perry_codegen::namespace_member_func_key(local, export_name); + if let Some(¶m_count) = exported_func_param_counts.get(&key) { + imported_param_counts.insert(export_name.clone(), param_count); + imported_param_counts.insert(scoped_func_key.clone(), param_count); } - // Follow either an explicit named re-export or an - // `export *` barrel whose target owns this name. The - // latter is how Effect and OpenCode expose namespace - // values through public entry points. - let named_hop = hir.exports.iter().find_map(|e| match e { - perry_hir::Export::ReExport { - source, - imported, - exported, - } if *exported == ns_scan_name => { - Some((source.clone(), imported.clone())) - } - _ => None, - }); - let export_all_hop = || { - hir.exports.iter().find_map(|e| { - let perry_hir::Export::ExportAll { source } = e else { - return None; - }; - let (target_path, _) = resolve_import_with_context( - source, - std::path::Path::new(&ns_scan_path), - &ctx, - )?; - let target = target_path.to_string_lossy().to_string(); - all_module_exports - .get(&target) - .is_some_and(|exports| exports.contains_key(&ns_scan_name)) - .then(|| (source.clone(), ns_scan_name.clone())) - }) - }; - let Some((hop_src, hop_imported)) = named_hop.or_else(export_all_hop) - else { - break; - }; - let Some((hop_path, _)) = resolve_import_with_context( - &hop_src, - std::path::Path::new(&ns_scan_path), - &ctx, - ) else { - break; - }; - let Some(hop_hir) = ctx.native_modules.get(&hop_path) else { - break; - }; - ns_scan_path = hop_path.to_string_lossy().to_string(); - ns_scan_hir = Some(hop_hir); - ns_scan_name = hop_imported; - } - - // Issue #310: when the source module re-exports the - // imported name as a namespace (`export * as Foo from - // "./Foo"`), the local binding behaves identically to - // `import * as Foo from "pkg/Foo"` — `Foo.member` should - // dispatch through the namespace path. Detect this by - // looking at the source module's HIR exports for a - // `NamespaceReExport` whose name matches the imported - // name, then route the local through `namespace_imports` - // + register the namespace target's full export surface. - let mut handled_as_namespace_reexport = false; - if let Some(src_hir) = ns_scan_hir { - for export in &src_hir.exports { - if let perry_hir::Export::NamespaceReExport { - source: ns_src, - name, - } = export - { - if name != &ns_scan_name { - continue; - } - // Native namespace targets (for example - // `export * as NodeWS from "ws"`) have no HIR - // module and no `@__perry_ns_ws` global. The - // declaring module emits a zero-arg namespace - // getter; classify this named import as a var so - // consumer code calls that getter. - if perry_hir::NATIVE_MODULES - .contains(&ns_src.strip_prefix("node:").unwrap_or(ns_src)) - { - let declaring_prefix = - compute_module_prefix(&ns_scan_path, &ctx.project_root); - import_function_prefixes - .insert(local_name.clone(), declaring_prefix); - if local_name != ns_scan_name { - import_function_origin_names - .insert(local_name.clone(), ns_scan_name.clone()); - } - imported_vars.insert(local_name.clone()); - handled_as_namespace_reexport = true; - break; - } - let importer = std::path::Path::new(&ns_scan_path); - let Some((ns_target, _)) = - resolve_import_with_context(ns_src, importer, &ctx) - else { - break; - }; - let ns_target_str = ns_target.to_string_lossy().to_string(); - let Some(target_exports) = - all_module_exports.get(&ns_target_str) - else { - break; - }; - namespace_imports.push(local_name.clone()); - for (export_name, origin_path) in target_exports { - let origin_prefix = - compute_module_prefix(origin_path, &ctx.project_root); - // Issue #5927: `or_insert` — see the - // matching rationale on the - // `namespace_like_local` branch above. - // A namespace member is a best-effort - // fallback in this flat map; a PLAIN - // named import of the same bare name - // has no other resolution path and - // must always win, regardless of - // import-statement order. - import_function_prefixes - .entry(export_name.clone()) - .or_insert_with(|| origin_prefix.clone()); - // Issue #5922 (companion to #680): also - // register under the per-namespace key so - // `Context.foo` and `Option.foo` resolve to - // their own sources even when two - // namespace-reexport targets imported into - // the same file happen to export a member - // with the same bare name. Without this, - // codegen's `expr/static_method.rs` (plus - // `namespace_call.rs` / `property_get.rs` - // for lowercase-receiver call/read forms) - // fall through to the flat - // `import_function_prefixes`, which the - // last-registered namespace silently wins. - namespace_member_prefixes.insert( - (local_name.clone(), export_name.clone()), - origin_prefix.clone(), - ); - // Issue #678: surface origin-name overrides - // for the NamespaceReExport branch too. - let resolved_origin_name = all_module_export_origin_names - .get(&ns_target_str) - .and_then(|m| m.get(export_name)) - .cloned(); - if let Some(ref origin_name) = resolved_origin_name { - if origin_name != export_name { - // Issue #5927: `or_insert` — see - // the matching rationale above. - import_function_origin_names - .entry(export_name.clone()) - .or_insert_with(|| origin_name.clone()); - } - } - // Issue #5924: unconditionally register - // every member under the per-namespace - // key, mirroring `namespace_member_prefixes` - // above (populated for every export, not - // just renamed ones). Found via a - // real-world `sst/opencode` compile: - // `import { Effect, Layer, Context, - // Schema, Types } from "effect"` - // processes all five namespace-reexport - // targets into this file's shared maps. - // When an EARLIER-processed namespace - // (e.g. `Effect`) re-exports a member - // under a rename (e.g. `Service`), the - // flat `import_function_origin_names` - // entry it leaves behind clobbers a - // LATER-processed namespace's (e.g. - // `Context`'s) *unrenamed* member of the - // same name — `Context.Service` resolved - // to the wrong symbol suffix and linking - // failed with an undefined - // `perry_fn_..._Context_ts__< - // wrong-suffix>` symbol. A *sparse* - // per-namespace map (only renamed - // members) doesn't fully fix this: an - // unrenamed member with no entry here - // would still fall back to the - // (possibly contaminated) flat map, so - // every member gets an entry — the - // resolved origin name when renamed, - // else the export name itself. - namespace_member_origin_names.insert( - (local_name.clone(), export_name.clone()), - resolved_origin_name - .clone() - .unwrap_or_else(|| export_name.clone()), - ); - - let key = (origin_path.clone(), export_name.clone()); - let scoped_func_key = - perry_codegen::namespace_member_func_key( - &local_name, - export_name, - ); - if let Some(¶m_count) = - exported_func_param_counts.get(&key) - { - imported_param_counts - .insert(export_name.clone(), param_count); - imported_param_counts - .insert(scoped_func_key.clone(), param_count); - } - if exported_func_has_rest - .get(&key) - .copied() - .unwrap_or(false) - { - imported_has_rest.insert(export_name.clone()); - imported_has_rest.insert(scoped_func_key.clone()); - } - if exported_func_synthetic_arguments.contains(&key) { - imported_synthetic_arguments - .insert(export_name.clone()); - imported_synthetic_arguments.insert(scoped_func_key); - } - // Issue #321: NamespaceReExport members - // that are var-shaped exports (the - // canonical `export const succeed = (v) => - // ...` shape in effect/Effect.ts and - // co-equivalent re-export hubs) must land - // in `imported_vars` under a namespace- - // qualified key so the codegen's - // StaticMethodCall and namespace-member - // call sites route through the zero-arg - // getter + `js_closure_callN`. Without - // this, `import { Effect } from "effect"; - // Effect.succeed(42)` emitted a 1-arg - // direct call against the 0-arg getter - // — the source returned the closure - // pointer unchanged and `typeof - // Effect.succeed(42)` was `"function"`, - // and `runSync(program)` then threw - // `Cannot read properties of undefined` - // on `program._tag`. Mirrors the - // `Namespace { local }` branch above. - let origin_key_under_origin_name = resolved_origin_name - .as_ref() - .map(|name| (origin_path.clone(), name.clone())); - if exported_var_names.contains(&key) - || origin_key_under_origin_name - .as_ref() - .map(|key| exported_var_names.contains(key)) - .unwrap_or(false) - { - imported_vars.insert( - perry_codegen::namespace_member_var_key( - &local_name, - export_name, - ), - ); - } - // #9285: a renamed class re-export is - // indexed under its origin name, while this - // namespace exposes `export_name`. Resolve - // through the same origin key used for the - // var classification above so the scoped - // ImportedClass retains both identities. - let imported_class = - exported_classes.get(&key).or_else(|| { - origin_key_under_origin_name.as_ref().and_then( - |origin_key| exported_classes.get(origin_key), - ) - }); - if let Some(class) = imported_class { - let class_prefix = canonical_class_source_prefix( - class, - &class_canonical_path, - &ctx.project_root, - &origin_prefix, - ); - let local_alias = if export_name == &class.name { - None - } else { - Some(export_name.clone()) - }; - let mut imported_class = imported_class_from_hir( - class, - class_prefix, - local_alias, - proven_this_methods_for_import( - class, - &class_proven_this_methods, - ), - proven_this_methods_for_import( - class, - &class_proven_this_tower_methods, - ), - ); - imported_class.namespace = Some(local_name.clone()); - imported_classes.push(imported_class); - } - if let Some(members) = exported_enums.get(&key) { - imported_enums - .push((export_name.clone(), members.clone())); - } - } - // A named namespace re-export can itself expose - // nested namespace aliases (Zod's `z.core`, - // `z.locales`, `z.iso`, and `z.coerce` shape). - // Mark those members explicitly and overwrite - // the declaring-barrel prefixes registered by - // the ordinary export walk above with the - // namespace TARGET prefixes. - if let Some(nested) = - namespace_reexport_targets.get(&ns_target_str) - { - for (alias, target_path) in nested { - let target_prefix = compute_module_prefix( - &target_path.to_string_lossy(), - &ctx.project_root, - ); - namespace_member_prefixes.insert( - (local_name.clone(), alias.clone()), - target_prefix, - ); - namespace_member_nested - .insert((local_name.clone(), alias.clone())); - } - } - handled_as_namespace_reexport = true; - break; - } + if exported_func_has_rest.get(&key).copied().unwrap_or(false) { + imported_has_rest.insert(export_name.clone()); + imported_has_rest.insert(scoped_func_key.clone()); } - } - if handled_as_namespace_reexport { - continue; - } - - let key = (resolved_path_str.clone(), exported_name.clone()); - - // Resolve the ORIGIN path of `exported_name` by following - // re-exports. `index.js`'s `export { pgTable } from "./table.js"` - // means the immediate import resolves to index.js but the - // actual `Let pgTable = (...) => ...` lives in table.js. The - // `exported_var_names` set is keyed by the ORIGIN path, so - // looking up `(index.js, "pgTable")` misses; we need to walk - // the re-export chain to find table.js. Refs #420. - let origin_path: String = - if let Some(exports) = all_module_exports.get(&resolved_path_str) { - if let Some(p) = exports.get(&exported_name) { - p.clone() - } else { - resolved_path_str.clone() - } - } else { - resolved_path_str.clone() - }; - let origin_key = (origin_path.clone(), exported_name.clone()); - - // Resolve effective prefix (follow re-exports) - let effective_prefix = if origin_path != resolved_path_str { - compute_module_prefix(&origin_path, &ctx.project_root) - } else { - source_prefix.clone() - }; - - // Issue #: only key by `exported_name` in the - // no-rename case (`local_name == exported_name`), where - // the HIR's `ExternFuncRef` genuinely carries that - // string. In the aliased case (#35/#321 above: - // `ExternFuncRef` carries the LOCAL name, unique per - // import site), inserting under `exported_name` too is - // not just redundant — `exported_name` is whatever the - // ORIGIN module happens to call it, so it can collide - // with an unrelated LOCAL alias elsewhere in the same - // file. Concrete repro: `import { a as n, c as a } from - // "./x"; import { a as t } from "./y"` — the second - // specifier's exported name "a" overwrote the first - // import's *local* alias "a" (from `c as a`), silently - // repointing `ExternFuncRef { name: "a" }` at module y - // instead of x. Only inserting the ALIASED case under - // `local_name` (never also under `exported_name`) keeps - // every key in this map unique per file — local names - // can't collide with each other (each `let`/import - // binding needs a distinct identifier), but exported - // names from different source modules can and do. - if local_name == exported_name { - import_function_prefixes - .insert(exported_name.clone(), effective_prefix.clone()); - } else { - import_function_prefixes - .insert(local_name.clone(), effective_prefix.clone()); - } - - // Issue #678: if the import chain renames through a - // re-export (`export { default as render } from - // './render.js'`), the symbol in the origin module - // is `perry_fn___default`, not - // `perry_fn___render`. Surface the deeper - // origin name via `import_function_origin_names` so - // the codegen can pick the right suffix when forming - // the extern symbol. The map is sparse — entries are - // only inserted when origin_name != exported_name. - let resolved_origin_name = all_module_export_origin_names - .get(&resolved_path_str) - .and_then(|m| m.get(&exported_name)) - .cloned(); - if let Some(ref origin_name) = resolved_origin_name { - if origin_name != &exported_name { - // Key by the same rule as `import_function_prefixes` - // above: the LOCAL name for an aliased import, the - // exported name otherwise — the HIR's `ExternFuncRef` - // carries exactly that string. Also inserting an - // aliased import under its EXPORTED name poisons any - // same-file binding that happens to share it: - // `import { XML } from "a"` + `import { XML as C } - // from "b"` (where b's barrel does `export { default - // as XML }`) rewrote a's `XML` suffix to `default` - // and the link failed on `perry_fn___default` - // (the fast-xml-parser × is-unsafe graph). - if local_name == exported_name { - import_function_origin_names - .insert(exported_name.clone(), origin_name.clone()); - } else { - import_function_origin_names - .insert(local_name.clone(), origin_name.clone()); - } + if exported_func_synthetic_arguments.contains(&key) { + imported_synthetic_arguments.insert(export_name.clone()); + imported_synthetic_arguments.insert(scoped_func_key); } - } - - // Issue #35 (#321): companion to the HIR-side change in - // `module_decl.rs` (Named specifier now registers - // `(local, local)`, so an ALIASED named import's - // `ExternFuncRef` carries the unique LOCAL name). The - // origin module still emits its symbol under the EXPORTED - // name, so map `local → exported_name` (or the deeper - // re-export origin name when one applies) here so codegen - // forms `perry_fn___` rather than - // `perry_fn___`. Mirrors the #901 Default-import - // override below. Only needed when `local != exported` - // (the alias case); the no-alias case carries the export - // name verbatim. Skip if the re-export-rename block above - // already inserted a (deeper) override for this local. - if matches!(spec, perry_hir::ImportSpecifier::Named { .. }) - && local_name != exported_name - && !import_function_origin_names.contains_key(&local_name) - { - import_function_origin_names - .insert(local_name.clone(), exported_name.clone()); - } - - // Issue #901: companion to the HIR-side change at - // `crates/perry-hir/src/lower.rs`'s Default specifier - // (which now registers `(local, local)` instead of - // `(local, "default")`). The HIR's `ExternFuncRef` now - // carries the LOCAL name (unique per import site), so - // `import_function_prefixes.get(local)` resolves to the - // right source module. But the symbol the codegen emits - // must still be `perry_fn___default` (or whatever - // origin-name the source actually exports default as), - // not `perry_fn___` — the source module emits - // its default-export symbol under the literal "default" - // suffix. Insert the local→"default" override (or the - // resolved origin name, when a re-export renamed it) so - // every `perry_fn___` construction site - // probing `import_function_origin_names` picks the right - // suffix. Pre-fix two same-file default imports of - // different modules collided on the "default" key and - // pino's `SORTING_ORDER.ASC` threw because `_req_9` - // (`./lib/constants`) and `_req_10` (`./lib/tools`) both - // resolved to `./lib/tools`. Pairs with the HIR change; - // both must land for the resolution to be correct. - if matches!(spec, perry_hir::ImportSpecifier::Default { .. }) { - let suffix = resolved_origin_name - .clone() - .unwrap_or_else(|| exported_name.clone()); - import_function_origin_names.insert(local_name.clone(), suffix); - } - - // Imported variables (not functions) — ExternFuncRef-as-value - // should call the getter, not wrap as closure. Look up by the - // ORIGIN path (where the `Let X = ...` actually lives), not - // the immediate import path. Without this, re-exports through - // `index.js` barrel files (drizzle's `pg-core/index.js`, - // hono's adapter index files, etc.) silently fall through to - // the direct-call path which treats the zero-arg getter's - // return value AS the call result — pgTable("users", cols) - // returned the closure handle (typeof === "function") with no - // pgTable body actually invoked. - // - // Issue #678 followup: when a re-export rename routes - // the import through `export default `, the origin - // module's `exported_objects` carries the synthetic - // "default" entry (the only thing exported at that - // shape) — not the consumer-visible name. Probe both - // keys so the var-vs-function classification fires - // even when re-export renaming is in play. - let origin_key_under_origin_name = resolved_origin_name - .as_ref() - .map(|n| (origin_path.clone(), n.clone())); - let source_exports_object = exported_var_names - .contains(&(resolved_path_str.clone(), exported_name.clone())); - if source_exports_object - || exported_var_names.contains(&origin_key) - || origin_key_under_origin_name + // Issue #636: namespace-imported vars must + // route through the zero-arg getter at + // call sites (`ns.fn(args)` where `fn` is a + // `let`/`const` binding holding a closure + // — the canonical `export const make = (s) + // => ...` shape). Without this, the codegen + // falls through to the direct-call path + // which treats the getter's return value + // as the call result instead of invoking + // the closure with `args`. Mirrors the + // named-import branch at the var-detection + // arm below. The key is namespace-qualified: + // a flat `make` entry lets one namespace's + // variable export misclassify another + // namespace's declared function as a getter. + // + // Issue #4841: when the namespace member is a + // re-export of a CJS submodule's `default` + // (`import sfy from './sfy'; export { sfy }`, + // where `./sfy` is `module.exports = function`), + // the origin module records the var under its + // "default" suffix — NOT the consumer-visible + // member name. Probe both keys (mirrors the + // named-import arm) so the var-vs-function + // classification fires; otherwise `ns.sfy` takes + // the function path and wraps the default getter + // in a singleton closure, so `ns.sfy(args)` + // RETURNS the function value instead of being it + // (Stripe's `qs.stringify(...)` returned the qs + // function ⇒ `.replace is not a function`). + let origin_key_under_origin_name = resolved_origin_name .as_ref() - .map(|k| exported_var_names.contains(k)) - .unwrap_or(false) - { - imported_vars.insert(exported_name.clone()); - if local_name != exported_name { - imported_vars.insert(local_name.clone()); - } - - let origin_export_name = resolved_origin_name - .clone() - .unwrap_or_else(|| exported_name.clone()); - if let Some(capability) = exported_object_literals - .get(&(origin_path.clone(), origin_export_name.clone())) + .map(|n| (origin_path.clone(), n.clone())); + if exported_var_names.contains(&key) + || origin_key_under_origin_name + .as_ref() + .map(|k| exported_var_names.contains(k)) + .unwrap_or(false) { - imported_classes.push(imported_object_literal_from_capability( - capability, - effective_prefix.clone(), - origin_export_name, - local_name.clone(), + imported_vars.insert(perry_codegen::namespace_member_var_key( + local, + export_name, )); } - } - - // Imported classes - if let Some(class) = exported_classes.get(&key) { - let class_prefix = canonical_class_source_prefix( - class, - &class_canonical_path, - &ctx.project_root, - &effective_prefix, - ); - // Issue #665: when the user wrote `import X from "pkg"` - // and `pkg`'s default export is a class, the importer - // still registers `exported_name="default"` into - // `import_function_prefixes` above. Codegen's wrapper- - // emission loop iterates that map and — for any name - // NOT in `imported_class_names` — emits a function - // wrapper that calls `perry_fn___default`, which - // the source module never defines (the source only has - // a `_Child_constructor` symbol). That declares an - // unresolved extern and the link step errors with - // `Undefined symbols: ___perry_wrap_perry_fn___default`. - // Push a SECOND ImportedClass entry whose `local_alias` - // is the exported_name (`"default"` for default imports, - // or the original-name for `{ Foo as Bar }`-style - // renames). codegen's `imported_class_names` builder - // adds both `ic.name` and `ic.local_alias`, so the - // exported_name lands in the set and the wrapper- - // emission loop takes the `is_class` no-op-stub branch - // instead of declaring a phantom function. The second - // entry also registers `class_ids[exported_name]`, - // letting consumer-side `Expr::ExternFuncRef { name: - // exported_name }` resolve to the class-id NaN-box. - if local_name != exported_name { - imported_classes.push(imported_class_from_hir( + // #9285: re-export renames keep the class + // metadata under its origin name (`Child`), not + // the namespace-visible alias (`PublicChild`). + // The var path above already consults this + // origin key; class registration must do the + // same or `new ns.PublicChild(arg)` falls + // through to a function wrapper and never runs + // the class constructor. + let imported_class = exported_classes.get(&key).or_else(|| { + origin_key_under_origin_name + .as_ref() + .and_then(|origin_key| exported_classes.get(origin_key)) + }); + if let Some(class) = imported_class { + let class_prefix = canonical_class_source_prefix( class, - class_prefix.clone(), - Some(exported_name.clone()), + &class_canonical_path, + &ctx.project_root, + &origin_prefix, + ); + let local_alias = if export_name == &class.name { + None + } else { + Some(export_name.clone()) + }; + let mut imported_class = imported_class_from_hir( + class, + class_prefix, + local_alias, proven_this_methods_for_import( class, &class_proven_this_methods, @@ -4681,83 +3883,467 @@ pub fn run_with_parse_cache( class, &class_proven_this_tower_methods, ), - )); + ); + // A namespace member is reachable only as + // `local.export_name`; it is not a lexical + // binding named `export_name`. Keeping that + // ownership explicit prevents same-named + // classes from replacing direct imports. + imported_class.namespace = Some(local.clone()); + imported_classes.push(imported_class); } - imported_classes.push(imported_class_from_hir( - class, - class_prefix, - if local_name != class.name { - Some(local_name.clone()) - } else { - None - }, - proven_this_methods_for_import(class, &class_proven_this_methods), - proven_this_methods_for_import( - class, - &class_proven_this_tower_methods, - ), - )); - } - - // Imported param counts - if let Some(¶m_count) = exported_func_param_counts.get(&key) { - imported_param_counts.insert(exported_name.clone(), param_count); - if local_name != exported_name { - imported_param_counts.insert(local_name.clone(), param_count); + if let Some(members) = exported_enums.get(&key) { + imported_enums.push((export_name.clone(), members.clone())); } } - - // Issue #608 — propagate has_rest alongside the param - // count so the cross-module call site can pack the - // trailing args into a rest array. - if exported_func_has_rest.get(&key).copied().unwrap_or(false) { - imported_has_rest.insert(exported_name.clone()); - if local_name != exported_name { - imported_has_rest.insert(local_name.clone()); - } + } + // Namespace aliases also participate in + // `all_module_exports`, so repeat this after the + // ordinary walk and let the TARGET prefix win over the + // declaring barrel's prefix. + if let Some(nested) = namespace_reexport_targets.get(&resolved_path_str) { + for (alias, target_path) in nested { + let target_prefix = compute_module_prefix( + &target_path.to_string_lossy(), + &ctx.project_root, + ); + namespace_member_prefixes + .insert((local.clone(), alias.clone()), target_prefix); + namespace_member_nested.insert((local.clone(), alias.clone())); } - if exported_func_synthetic_arguments.contains(&key) { - imported_synthetic_arguments.insert(exported_name.clone()); - if local_name != exported_name { - imported_synthetic_arguments.insert(local_name.clone()); + } + if source_module.is_some_and(|module| is_wrapped_cjs(module)) { + let default_prefix = + compute_module_prefix(&resolved_path_str, &ctx.project_root); + let default_is_var = all_module_exports + .get(&resolved_path_str) + .and_then(|exports| exports.get("default")) + .is_some_and(|origin_path| { + let origin_name = all_module_export_origin_names + .get(&resolved_path_str) + .and_then(|names| names.get("default")) + .cloned() + .unwrap_or_else(|| "default".to_string()); + exported_var_names.contains(&(origin_path.clone(), origin_name)) + }) + || exported_var_names + .contains(&(resolved_path_str.clone(), "default".to_string())); + // CJS namespace exotic objects expose both names + // as aliases of the evaluated exports object. The + // per-namespace origin map makes `module.exports` + // call the existing `default` getter rather than a + // nonexistent dotted symbol. + for member in ["default", "module.exports"] { + namespace_member_prefixes.insert( + (local.clone(), member.to_string()), + default_prefix.clone(), + ); + namespace_member_origin_names + .insert((local.clone(), member.to_string()), "default".to_string()); + import_function_prefixes + .entry(member.to_string()) + .or_insert_with(|| default_prefix.clone()); + import_function_origin_names + .entry(member.to_string()) + .or_insert_with(|| "default".to_string()); + if member == "module.exports" || default_is_var { + imported_vars + .insert(perry_codegen::namespace_member_var_key(local, member)); } } + } + continue; + } + + let (local_name, exported_name) = match spec { + perry_hir::ImportSpecifier::Named { imported, local } => { + (local.clone(), imported.clone()) + } + perry_hir::ImportSpecifier::Default { local } => { + (local.clone(), "default".to_string()) + } + perry_hir::ImportSpecifier::Namespace { .. } => unreachable!(), + }; - // Imported return types - if let Some(return_type) = exported_func_return_types.get(&key) { - imported_return_types.insert(local_name.clone(), return_type.clone()); + // PerryTS/storekit#1 + #5621: skip the wrapper-fn + // registration when this specifier names an FFI function + // declared in the source package's + // `perry.nativeLibrary.functions` manifest. The source + // `.ts` is ambient and has no Perry wrapper for the linker + // to resolve, so the FFI-manifest path in `lower_call.rs` + // must win. Two binding conventions route here: + // 1. Exact match — the binding name IS the symbol + // (`js_storekit_load_products`, raw ambient style). + // 2. Ergonomic camelCase (#5621) — the binding + // (`requestAdapter`) is the `js__` ⇒ + // camelCase derivation of the symbol. Record the alias + // (keyed by the *local* binding, since call sites see + // the local name) so the call site rewrites it; exact + // matches need no alias. + if let Some(nl) = native_library_for_import { + let exact_symbol = nl + .functions + .iter() + .find(|f| f.name == exported_name) + .map(|f| f.name.clone()); + // Issue #6715: a REAL module export wins over a derived + // ergonomic alias. The `js__` ⇒ camelCase + // routing (#5621) is a convenience for packages whose + // `.ts` only holds ambient `export declare function` + // signatures (no body) — those are skipped at lowering + // (`module_decl.rs`: `body.is_none()`), so they never + // enter `all_module_exports`. But the documented wrapper + // convention (native-extensions.md) is an ambient + // `declare function js__speak(...)` PLUS a real + // `export async function speak(...)` that transforms args + // and calls the FFI symbol. When such a wrapper's name + // collides with a manifest symbol's derived alias + // (`js_speech_speak` → `speak`), the alias must NOT + // shadow it — the import binds to the wrapper, which the + // module emits a `perry_fn___speak` symbol for and + // the fall-through named-import path registers below. + // Only genuine, implemented value exports land here, so + // ambient-declare-only packages keep the #5621 routing. + let has_genuine_module_export = all_module_exports + .get(&resolved_path_str) + .is_some_and(|exports| exports.contains_key(&exported_name)); + // Collect ALL ergonomic matches so an ambiguous manifest + // (two symbols deriving the same camelCase binding) is + // rejected rather than silently bound to the first. + let ergonomic_matches: Vec = + if exact_symbol.is_some() || has_genuine_module_export { + Vec::new() + } else { + nl.functions + .iter() + .filter(|f| { + ergonomic_export_alias(&nl.module, &f.name).as_deref() + == Some(exported_name.as_str()) + }) + .map(|f| f.name.clone()) + .collect() + }; + if ergonomic_matches.len() > 1 { + return Err(format!( + "native library `{}` has ambiguous ergonomic exports for \ + `{}`: the manifest symbols {:?} all derive the same \ + camelCase binding. Rename the symbols so each derives a \ + distinct binding, or import one by its raw `js_*` name.", + nl.module, exported_name, ergonomic_matches + )); + } + let matched_symbol = + exact_symbol.or_else(|| ergonomic_matches.into_iter().next()); + if let Some(symbol) = matched_symbol { + // No alias needed when the binding already IS the + // symbol (raw exact-match, unaliased). + if symbol != local_name { + import_function_ffi_aliases.insert(local_name.clone(), symbol); } + continue; + } + } + + // Issue #5916: the `NamespaceReExport` we are about to scan + // for may not sit in the module we import from — it can be + // one or more `export { X } from "src"` hops upstream. A + // barrel that does + // export { Token } from "./selfns" // ReExport + // where `selfns.ts` declares + // export * as Token from "./selfns" // NamespaceReExport + // exposes `Token` as a NAMESPACE, but the scan below only + // looked at the barrel's own exports, saw a plain `ReExport`, + // and fell through to the ordinary value path. `Token.estimate(…)` + // then lowered to a `StaticMethodCall` referencing + // `__perry_wrap_perry_fn___Token` — a closure wrapper + // no module emits, so the link failed outright. (A ReExport of + // an ordinary function/const across the same hop links fine; + // it is specifically a NAMESPACE-valued binding that needs the + // namespace routing.) + // + // Walk the re-export chain first so the scan runs against the + // module that actually DECLARES the namespace, under the name + // it declares it with. When no hop applies (the overwhelmingly + // common case) this leaves the scan target exactly where it was, + // so behaviour is unchanged. + let mut ns_scan_hir = source_module; + let mut ns_scan_path = resolved_path_str.clone(); + let mut ns_scan_name = exported_name.clone(); + for _ in 0..MAX_REEXPORT_HOPS { + let Some(hir) = ns_scan_hir else { break }; + // Already the declaring module — nothing to follow. + if hir.exports.iter().any(|e| { + matches!( + e, + perry_hir::Export::NamespaceReExport { name, .. } + if *name == ns_scan_name + ) + }) { + break; + } + // Follow either an explicit named re-export or an + // `export *` barrel whose target owns this name. The + // latter is how Effect and OpenCode expose namespace + // values through public entry points. + let named_hop = hir.exports.iter().find_map(|e| match e { + perry_hir::Export::ReExport { + source, + imported, + exported, + } if *exported == ns_scan_name => Some((source.clone(), imported.clone())), + _ => None, + }); + let export_all_hop = || { + hir.exports.iter().find_map(|e| { + let perry_hir::Export::ExportAll { source } = e else { + return None; + }; + let (target_path, _) = resolve_import_with_context( + source, + std::path::Path::new(&ns_scan_path), + &ctx, + )?; + let target = target_path.to_string_lossy().to_string(); + all_module_exports + .get(&target) + .is_some_and(|exports| exports.contains_key(&ns_scan_name)) + .then(|| (source.clone(), ns_scan_name.clone())) + }) + }; + let Some((hop_src, hop_imported)) = named_hop.or_else(export_all_hop) else { + break; + }; + let Some((hop_path, _)) = resolve_import_with_context( + &hop_src, + std::path::Path::new(&ns_scan_path), + &ctx, + ) else { + break; + }; + let Some(hop_hir) = ctx.native_modules.get(&hop_path) else { + break; + }; + ns_scan_path = hop_path.to_string_lossy().to_string(); + ns_scan_hir = Some(hop_hir); + ns_scan_name = hop_imported; + } - // #7170 R2: cross-module return-shape provenance. Resolve - // the same exact origin path/name the call-symbol plumbing - // above uses, then install both halves atomically: - // - // * LOCAL ExternFuncRef name -> returned shape, and - // * the source class's field metadata in imported_classes. - // - // The producer pre-pass exports anonymous record shapes - // only. Their names content-address the complete field - // shape, so a same-named local class is the same layout; - // named user classes remain fail-closed in this increment. - let return_shape_origin_name = resolved_origin_name - .as_ref() - .unwrap_or(&exported_name) - .clone(); - let return_shape_key = (origin_path.clone(), return_shape_origin_name); - if let Some(class) = exported_return_shapes.get(&return_shape_key).copied() + // Issue #310: when the source module re-exports the + // imported name as a namespace (`export * as Foo from + // "./Foo"`), the local binding behaves identically to + // `import * as Foo from "pkg/Foo"` — `Foo.member` should + // dispatch through the namespace path. Detect this by + // looking at the source module's HIR exports for a + // `NamespaceReExport` whose name matches the imported + // name, then route the local through `namespace_imports` + // + register the namespace target's full export surface. + let mut handled_as_namespace_reexport = false; + if let Some(src_hir) = ns_scan_hir { + for export in &src_hir.exports { + if let perry_hir::Export::NamespaceReExport { + source: ns_src, + name, + } = export { - let imported_index = match imported_classes - .iter() - .position(|imported| imported.name == class.name) + if name != &ns_scan_name { + continue; + } + // Native namespace targets (for example + // `export * as NodeWS from "ws"`) have no HIR + // module and no `@__perry_ns_ws` global. The + // declaring module emits a zero-arg namespace + // getter; classify this named import as a var so + // consumer code calls that getter. + if perry_hir::NATIVE_MODULES + .contains(&ns_src.strip_prefix("node:").unwrap_or(ns_src)) { - Some(index) => index, - None => { - let class_prefix = - compute_module_prefix(&origin_path, &ctx.project_root); - imported_classes.push(imported_class_from_hir( + let declaring_prefix = + compute_module_prefix(&ns_scan_path, &ctx.project_root); + import_function_prefixes + .insert(local_name.clone(), declaring_prefix); + if local_name != ns_scan_name { + import_function_origin_names + .insert(local_name.clone(), ns_scan_name.clone()); + } + imported_vars.insert(local_name.clone()); + handled_as_namespace_reexport = true; + break; + } + let importer = std::path::Path::new(&ns_scan_path); + let Some((ns_target, _)) = + resolve_import_with_context(ns_src, importer, &ctx) + else { + break; + }; + let ns_target_str = ns_target.to_string_lossy().to_string(); + let Some(target_exports) = all_module_exports.get(&ns_target_str) + else { + break; + }; + namespace_imports.push(local_name.clone()); + for (export_name, origin_path) in target_exports { + let origin_prefix = + compute_module_prefix(origin_path, &ctx.project_root); + // Issue #5927: `or_insert` — see the + // matching rationale on the + // `namespace_like_local` branch above. + // A namespace member is a best-effort + // fallback in this flat map; a PLAIN + // named import of the same bare name + // has no other resolution path and + // must always win, regardless of + // import-statement order. + import_function_prefixes + .entry(export_name.clone()) + .or_insert_with(|| origin_prefix.clone()); + // Issue #5922 (companion to #680): also + // register under the per-namespace key so + // `Context.foo` and `Option.foo` resolve to + // their own sources even when two + // namespace-reexport targets imported into + // the same file happen to export a member + // with the same bare name. Without this, + // codegen's `expr/static_method.rs` (plus + // `namespace_call.rs` / `property_get.rs` + // for lowercase-receiver call/read forms) + // fall through to the flat + // `import_function_prefixes`, which the + // last-registered namespace silently wins. + namespace_member_prefixes.insert( + (local_name.clone(), export_name.clone()), + origin_prefix.clone(), + ); + // Issue #678: surface origin-name overrides + // for the NamespaceReExport branch too. + let resolved_origin_name = all_module_export_origin_names + .get(&ns_target_str) + .and_then(|m| m.get(export_name)) + .cloned(); + if let Some(ref origin_name) = resolved_origin_name { + if origin_name != export_name { + // Issue #5927: `or_insert` — see + // the matching rationale above. + import_function_origin_names + .entry(export_name.clone()) + .or_insert_with(|| origin_name.clone()); + } + } + // Issue #5924: unconditionally register + // every member under the per-namespace + // key, mirroring `namespace_member_prefixes` + // above (populated for every export, not + // just renamed ones). Found via a + // real-world `sst/opencode` compile: + // `import { Effect, Layer, Context, + // Schema, Types } from "effect"` + // processes all five namespace-reexport + // targets into this file's shared maps. + // When an EARLIER-processed namespace + // (e.g. `Effect`) re-exports a member + // under a rename (e.g. `Service`), the + // flat `import_function_origin_names` + // entry it leaves behind clobbers a + // LATER-processed namespace's (e.g. + // `Context`'s) *unrenamed* member of the + // same name — `Context.Service` resolved + // to the wrong symbol suffix and linking + // failed with an undefined + // `perry_fn_..._Context_ts__< + // wrong-suffix>` symbol. A *sparse* + // per-namespace map (only renamed + // members) doesn't fully fix this: an + // unrenamed member with no entry here + // would still fall back to the + // (possibly contaminated) flat map, so + // every member gets an entry — the + // resolved origin name when renamed, + // else the export name itself. + namespace_member_origin_names.insert( + (local_name.clone(), export_name.clone()), + resolved_origin_name + .clone() + .unwrap_or_else(|| export_name.clone()), + ); + + let key = (origin_path.clone(), export_name.clone()); + let scoped_func_key = perry_codegen::namespace_member_func_key( + &local_name, + export_name, + ); + if let Some(¶m_count) = exported_func_param_counts.get(&key) { + imported_param_counts.insert(export_name.clone(), param_count); + imported_param_counts + .insert(scoped_func_key.clone(), param_count); + } + if exported_func_has_rest.get(&key).copied().unwrap_or(false) { + imported_has_rest.insert(export_name.clone()); + imported_has_rest.insert(scoped_func_key.clone()); + } + if exported_func_synthetic_arguments.contains(&key) { + imported_synthetic_arguments.insert(export_name.clone()); + imported_synthetic_arguments.insert(scoped_func_key); + } + // Issue #321: NamespaceReExport members + // that are var-shaped exports (the + // canonical `export const succeed = (v) => + // ...` shape in effect/Effect.ts and + // co-equivalent re-export hubs) must land + // in `imported_vars` under a namespace- + // qualified key so the codegen's + // StaticMethodCall and namespace-member + // call sites route through the zero-arg + // getter + `js_closure_callN`. Without + // this, `import { Effect } from "effect"; + // Effect.succeed(42)` emitted a 1-arg + // direct call against the 0-arg getter + // — the source returned the closure + // pointer unchanged and `typeof + // Effect.succeed(42)` was `"function"`, + // and `runSync(program)` then threw + // `Cannot read properties of undefined` + // on `program._tag`. Mirrors the + // `Namespace { local }` branch above. + let origin_key_under_origin_name = resolved_origin_name + .as_ref() + .map(|name| (origin_path.clone(), name.clone())); + if exported_var_names.contains(&key) + || origin_key_under_origin_name + .as_ref() + .map(|key| exported_var_names.contains(key)) + .unwrap_or(false) + { + imported_vars.insert(perry_codegen::namespace_member_var_key( + &local_name, + export_name, + )); + } + // #9285: a renamed class re-export is + // indexed under its origin name, while this + // namespace exposes `export_name`. Resolve + // through the same origin key used for the + // var classification above so the scoped + // ImportedClass retains both identities. + let imported_class = exported_classes.get(&key).or_else(|| { + origin_key_under_origin_name + .as_ref() + .and_then(|origin_key| exported_classes.get(origin_key)) + }); + if let Some(class) = imported_class { + let class_prefix = canonical_class_source_prefix( + class, + &class_canonical_path, + &ctx.project_root, + &origin_prefix, + ); + let local_alias = if export_name == &class.name { + None + } else { + Some(export_name.clone()) + }; + let mut imported_class = imported_class_from_hir( class, class_prefix, - None, + local_alias, proven_this_methods_for_import( class, &class_proven_this_methods, @@ -4766,89 +4352,337 @@ pub fn run_with_parse_cache( class, &class_proven_this_tower_methods, ), - )); - imported_classes.len() - 1 + ); + imported_class.namespace = Some(local_name.clone()); + imported_classes.push(imported_class); + } + if let Some(members) = exported_enums.get(&key) { + imported_enums.push((export_name.clone(), members.clone())); + } + } + // A named namespace re-export can itself expose + // nested namespace aliases (Zod's `z.core`, + // `z.locales`, `z.iso`, and `z.coerce` shape). + // Mark those members explicitly and overwrite + // the declaring-barrel prefixes registered by + // the ordinary export walk above with the + // namespace TARGET prefixes. + if let Some(nested) = namespace_reexport_targets.get(&ns_target_str) { + for (alias, target_path) in nested { + let target_prefix = compute_module_prefix( + &target_path.to_string_lossy(), + &ctx.project_root, + ); + namespace_member_prefixes + .insert((local_name.clone(), alias.clone()), target_prefix); + namespace_member_nested + .insert((local_name.clone(), alias.clone())); } - }; - let imported = &mut imported_classes[imported_index]; - if !imported.return_shape_imports.contains(&local_name) { - imported.return_shape_imports.push(local_name.clone()); } + handled_as_namespace_reexport = true; + break; + } + } + } + if handled_as_namespace_reexport { + continue; + } + + let key = (resolved_path_str.clone(), exported_name.clone()); + + // Resolve the ORIGIN path of `exported_name` by following + // re-exports. `index.js`'s `export { pgTable } from "./table.js"` + // means the immediate import resolves to index.js but the + // actual `Let pgTable = (...) => ...` lives in table.js. The + // `exported_var_names` set is keyed by the ORIGIN path, so + // looking up `(index.js, "pgTable")` misses; we need to walk + // the re-export chain to find table.js. Refs #420. + let origin_path: String = + if let Some(exports) = all_module_exports.get(&resolved_path_str) { + if let Some(p) = exports.get(&exported_name) { + p.clone() + } else { + resolved_path_str.clone() + } + } else { + resolved_path_str.clone() + }; + let origin_key = (origin_path.clone(), exported_name.clone()); + + // Resolve effective prefix (follow re-exports) + let effective_prefix = if origin_path != resolved_path_str { + compute_module_prefix(&origin_path, &ctx.project_root) + } else { + source_prefix.clone() + }; + + // Issue #: only key by `exported_name` in the + // no-rename case (`local_name == exported_name`), where + // the HIR's `ExternFuncRef` genuinely carries that + // string. In the aliased case (#35/#321 above: + // `ExternFuncRef` carries the LOCAL name, unique per + // import site), inserting under `exported_name` too is + // not just redundant — `exported_name` is whatever the + // ORIGIN module happens to call it, so it can collide + // with an unrelated LOCAL alias elsewhere in the same + // file. Concrete repro: `import { a as n, c as a } from + // "./x"; import { a as t } from "./y"` — the second + // specifier's exported name "a" overwrote the first + // import's *local* alias "a" (from `c as a`), silently + // repointing `ExternFuncRef { name: "a" }` at module y + // instead of x. Only inserting the ALIASED case under + // `local_name` (never also under `exported_name`) keeps + // every key in this map unique per file — local names + // can't collide with each other (each `let`/import + // binding needs a distinct identifier), but exported + // names from different source modules can and do. + if local_name == exported_name { + import_function_prefixes + .insert(exported_name.clone(), effective_prefix.clone()); + } else { + import_function_prefixes.insert(local_name.clone(), effective_prefix.clone()); + } + + // Issue #678: if the import chain renames through a + // re-export (`export { default as render } from + // './render.js'`), the symbol in the origin module + // is `perry_fn___default`, not + // `perry_fn___render`. Surface the deeper + // origin name via `import_function_origin_names` so + // the codegen can pick the right suffix when forming + // the extern symbol. The map is sparse — entries are + // only inserted when origin_name != exported_name. + let resolved_origin_name = all_module_export_origin_names + .get(&resolved_path_str) + .and_then(|m| m.get(&exported_name)) + .cloned(); + if let Some(ref origin_name) = resolved_origin_name { + if origin_name != &exported_name { + // Key by the same rule as `import_function_prefixes` + // above: the LOCAL name for an aliased import, the + // exported name otherwise — the HIR's `ExternFuncRef` + // carries exactly that string. Also inserting an + // aliased import under its EXPORTED name poisons any + // same-file binding that happens to share it: + // `import { XML } from "a"` + `import { XML as C } + // from "b"` (where b's barrel does `export { default + // as XML }`) rewrote a's `XML` suffix to `default` + // and the link failed on `perry_fn___default` + // (the fast-xml-parser × is-unsafe graph). + if local_name == exported_name { + import_function_origin_names + .insert(exported_name.clone(), origin_name.clone()); + } else { + import_function_origin_names + .insert(local_name.clone(), origin_name.clone()); } + } + } - // Imported async functions - if exported_async_funcs.contains(&key) { - imported_async_set.insert(local_name.clone()); - if local_name != exported_name { - imported_async_set.insert(exported_name.clone()); - } - } + // Issue #35 (#321): companion to the HIR-side change in + // `module_decl.rs` (Named specifier now registers + // `(local, local)`, so an ALIASED named import's + // `ExternFuncRef` carries the unique LOCAL name). The + // origin module still emits its symbol under the EXPORTED + // name, so map `local → exported_name` (or the deeper + // re-export origin name when one applies) here so codegen + // forms `perry_fn___` rather than + // `perry_fn___`. Mirrors the #901 Default-import + // override below. Only needed when `local != exported` + // (the alias case); the no-alias case carries the export + // name verbatim. Skip if the re-export-rename block above + // already inserted a (deeper) override for this local. + if matches!(spec, perry_hir::ImportSpecifier::Named { .. }) + && local_name != exported_name + && !import_function_origin_names.contains_key(&local_name) + { + import_function_origin_names.insert(local_name.clone(), exported_name.clone()); + } - // Imported enums - if let Some(members) = exported_enums.get(&key) { - imported_enums.push((local_name.clone(), members.clone())); - } + // Issue #901: companion to the HIR-side change at + // `crates/perry-hir/src/lower.rs`'s Default specifier + // (which now registers `(local, local)` instead of + // `(local, "default")`). The HIR's `ExternFuncRef` now + // carries the LOCAL name (unique per import site), so + // `import_function_prefixes.get(local)` resolves to the + // right source module. But the symbol the codegen emits + // must still be `perry_fn___default` (or whatever + // origin-name the source actually exports default as), + // not `perry_fn___` — the source module emits + // its default-export symbol under the literal "default" + // suffix. Insert the local→"default" override (or the + // resolved origin name, when a re-export renamed it) so + // every `perry_fn___` construction site + // probing `import_function_origin_names` picks the right + // suffix. Pre-fix two same-file default imports of + // different modules collided on the "default" key and + // pino's `SORTING_ORDER.ASC` threw because `_req_9` + // (`./lib/constants`) and `_req_10` (`./lib/tools`) both + // resolved to `./lib/tools`. Pairs with the HIR change; + // both must land for the resolution to be correct. + if matches!(spec, perry_hir::ImportSpecifier::Default { .. }) { + let suffix = resolved_origin_name + .clone() + .unwrap_or_else(|| exported_name.clone()); + import_function_origin_names.insert(local_name.clone(), suffix); + } + + // Imported variables (not functions) — ExternFuncRef-as-value + // should call the getter, not wrap as closure. Look up by the + // ORIGIN path (where the `Let X = ...` actually lives), not + // the immediate import path. Without this, re-exports through + // `index.js` barrel files (drizzle's `pg-core/index.js`, + // hono's adapter index files, etc.) silently fall through to + // the direct-call path which treats the zero-arg getter's + // return value AS the call result — pgTable("users", cols) + // returned the closure handle (typeof === "function") with no + // pgTable body actually invoked. + // + // Issue #678 followup: when a re-export rename routes + // the import through `export default `, the origin + // module's `exported_objects` carries the synthetic + // "default" entry (the only thing exported at that + // shape) — not the consumer-visible name. Probe both + // keys so the var-vs-function classification fires + // even when re-export renaming is in play. + let origin_key_under_origin_name = resolved_origin_name + .as_ref() + .map(|n| (origin_path.clone(), n.clone())); + let source_exports_object = exported_var_names + .contains(&(resolved_path_str.clone(), exported_name.clone())); + if source_exports_object + || exported_var_names.contains(&origin_key) + || origin_key_under_origin_name + .as_ref() + .map(|k| exported_var_names.contains(k)) + .unwrap_or(false) + { + imported_vars.insert(exported_name.clone()); + if local_name != exported_name { + imported_vars.insert(local_name.clone()); } - // Named imports only bring in explicitly-imported symbols, so - // a class that leaks out of the source module as the return - // type of an imported *function* (e.g. `import { makeThing }` - // where `makeThing(): Promise`) leaves `Thing` invisible - // to this module's dispatch tables. `t.doWork(...)` then can't - // find `("Thing", "doWork")` in `ctx.methods` and falls through - // to `js_native_call_method`, which returns the receiver's - // ObjectHeader as a stub. Closes #83. - // - // Mirror the namespace-import behavior: for every - // native-compiled module we import from (and every module that - // module transitively re-exports from), enumerate every class - // defined in that module and register it for dispatch, even - // when the class name wasn't in the specifier list. Local - // classes with the same name take precedence in - // `compile_module` (the `class_table.contains_key` check), so - // this doesn't clobber anything. - // - // We iterate `ctx.native_modules` directly — NOT the - // `exported_classes` BTreeMap. `exported_classes` gets alias - // entries stamped under every re-exporter's path (the - // `Export::ReExport` / `Export::ExportAll` propagation loop - // above), so iterating it would hand us the class keyed by - // `index.ts` when it was actually compiled under - // `pool.ts`. Using each module's own `hir.classes` Vec guarantees - // `src_path` is the TRUE defining module, so the mangled - // `perry_method_____` symbol - // matches what that module actually emitted (otherwise the - // linker fails with "undefined symbol - // _perry_method_src_index_ts__Pool__query" when Pool was - // compiled under src_pool_ts). - let mut origin_paths: std::collections::HashSet = - std::collections::HashSet::new(); - origin_paths.insert(resolved_path_str.clone()); - if let Some(exports) = all_module_exports.get(&resolved_path_str) { - for origin_path in exports.values() { - origin_paths.insert(origin_path.clone()); - } + let origin_export_name = resolved_origin_name + .clone() + .unwrap_or_else(|| exported_name.clone()); + if let Some(capability) = exported_object_literals + .get(&(origin_path.clone(), origin_export_name.clone())) + { + imported_classes.push(imported_object_literal_from_capability( + capability, + effective_prefix.clone(), + origin_export_name, + local_name.clone(), + )); } - for (src_pathbuf, src_hir) in &ctx.native_modules { - let src_path = src_pathbuf.to_string_lossy().to_string(); - if !origin_paths.contains(&src_path) { - continue; - } - for class in &src_hir.classes { - if !class.is_exported { - continue; - } - // Dedup across multiple import statements: the same class - // may be transitively reachable from several imports, and - // the same-class-twice case would produce duplicate - // `@perry_class_keys___` globals in IR. - // Same-name local classes win via `compile_module`'s - // class_table check, so this filter is strictly about - // cross-module twinning. - if imported_classes.iter().any(|c| c.name == class.name) { - continue; - } - let class_prefix = compute_module_prefix(&src_path, &ctx.project_root); + } + + // Imported classes + if let Some(class) = exported_classes.get(&key) { + let class_prefix = canonical_class_source_prefix( + class, + &class_canonical_path, + &ctx.project_root, + &effective_prefix, + ); + // Issue #665: when the user wrote `import X from "pkg"` + // and `pkg`'s default export is a class, the importer + // still registers `exported_name="default"` into + // `import_function_prefixes` above. Codegen's wrapper- + // emission loop iterates that map and — for any name + // NOT in `imported_class_names` — emits a function + // wrapper that calls `perry_fn___default`, which + // the source module never defines (the source only has + // a `_Child_constructor` symbol). That declares an + // unresolved extern and the link step errors with + // `Undefined symbols: ___perry_wrap_perry_fn___default`. + // Push a SECOND ImportedClass entry whose `local_alias` + // is the exported_name (`"default"` for default imports, + // or the original-name for `{ Foo as Bar }`-style + // renames). codegen's `imported_class_names` builder + // adds both `ic.name` and `ic.local_alias`, so the + // exported_name lands in the set and the wrapper- + // emission loop takes the `is_class` no-op-stub branch + // instead of declaring a phantom function. The second + // entry also registers `class_ids[exported_name]`, + // letting consumer-side `Expr::ExternFuncRef { name: + // exported_name }` resolve to the class-id NaN-box. + if local_name != exported_name { + imported_classes.push(imported_class_from_hir( + class, + class_prefix.clone(), + Some(exported_name.clone()), + proven_this_methods_for_import(class, &class_proven_this_methods), + proven_this_methods_for_import(class, &class_proven_this_tower_methods), + )); + } + imported_classes.push(imported_class_from_hir( + class, + class_prefix, + if local_name != class.name { + Some(local_name.clone()) + } else { + None + }, + proven_this_methods_for_import(class, &class_proven_this_methods), + proven_this_methods_for_import(class, &class_proven_this_tower_methods), + )); + } + + // Imported param counts + if let Some(¶m_count) = exported_func_param_counts.get(&key) { + imported_param_counts.insert(exported_name.clone(), param_count); + if local_name != exported_name { + imported_param_counts.insert(local_name.clone(), param_count); + } + } + + // Issue #608 — propagate has_rest alongside the param + // count so the cross-module call site can pack the + // trailing args into a rest array. + if exported_func_has_rest.get(&key).copied().unwrap_or(false) { + imported_has_rest.insert(exported_name.clone()); + if local_name != exported_name { + imported_has_rest.insert(local_name.clone()); + } + } + if exported_func_synthetic_arguments.contains(&key) { + imported_synthetic_arguments.insert(exported_name.clone()); + if local_name != exported_name { + imported_synthetic_arguments.insert(local_name.clone()); + } + } + + // Imported return types + if let Some(return_type) = exported_func_return_types.get(&key) { + imported_return_types.insert(local_name.clone(), return_type.clone()); + } + + // #7170 R2: cross-module return-shape provenance. Resolve + // the same exact origin path/name the call-symbol plumbing + // above uses, then install both halves atomically: + // + // * LOCAL ExternFuncRef name -> returned shape, and + // * the source class's field metadata in imported_classes. + // + // The producer pre-pass exports anonymous record shapes + // only. Their names content-address the complete field + // shape, so a same-named local class is the same layout; + // named user classes remain fail-closed in this increment. + let return_shape_origin_name = resolved_origin_name + .as_ref() + .unwrap_or(&exported_name) + .clone(); + let return_shape_key = (origin_path.clone(), return_shape_origin_name); + if let Some(class) = exported_return_shapes.get(&return_shape_key).copied() { + let imported_index = match imported_classes + .iter() + .position(|imported| imported.name == class.name) + { + Some(index) => index, + None => { + let class_prefix = + compute_module_prefix(&origin_path, &ctx.project_root); imported_classes.push(imported_class_from_hir( class, class_prefix, @@ -4859,632 +4693,705 @@ pub fn run_with_parse_cache( &class_proven_this_tower_methods, ), )); + imported_classes.len() - 1 } + }; + let imported = &mut imported_classes[imported_index]; + if !imported.return_shape_imports.contains(&local_name) { + imported.return_shape_imports.push(local_name.clone()); } } - // Issue #678 followup: V8-fallback imports. Native imports above - // wire `perry_fn___` extern symbols; V8 imports route - // through the runtime bridge instead. We populate BOTH - // `import_function_prefixes` (with a synthetic prefix so the - // codegen's `Some(source_prefix) = prefixes.get(name)` arm fires - // and the V8-specifier short-circuit inside it triggers) AND - // `import_function_v8_specifiers` (the actual specifier the bridge - // hands to `js_load_module`). The synthetic prefix never reaches - // a `perry_fn_...` symbol because every codegen site probes - // `import_function_v8_specifiers` first. - for import in &hir_module.imports { - if import.type_only || import.runtime_erased { + // Imported async functions + if exported_async_funcs.contains(&key) { + imported_async_set.insert(local_name.clone()); + if local_name != exported_name { + imported_async_set.insert(exported_name.clone()); + } + } + + // Imported enums + if let Some(members) = exported_enums.get(&key) { + imported_enums.push((local_name.clone(), members.clone())); + } + } + + // Named imports only bring in explicitly-imported symbols, so + // a class that leaks out of the source module as the return + // type of an imported *function* (e.g. `import { makeThing }` + // where `makeThing(): Promise`) leaves `Thing` invisible + // to this module's dispatch tables. `t.doWork(...)` then can't + // find `("Thing", "doWork")` in `ctx.methods` and falls through + // to `js_native_call_method`, which returns the receiver's + // ObjectHeader as a stub. Closes #83. + // + // Mirror the namespace-import behavior: for every + // native-compiled module we import from (and every module that + // module transitively re-exports from), enumerate every class + // defined in that module and register it for dispatch, even + // when the class name wasn't in the specifier list. Local + // classes with the same name take precedence in + // `compile_module` (the `class_table.contains_key` check), so + // this doesn't clobber anything. + // + // We iterate `ctx.native_modules` directly — NOT the + // `exported_classes` BTreeMap. `exported_classes` gets alias + // entries stamped under every re-exporter's path (the + // `Export::ReExport` / `Export::ExportAll` propagation loop + // above), so iterating it would hand us the class keyed by + // `index.ts` when it was actually compiled under + // `pool.ts`. Using each module's own `hir.classes` Vec guarantees + // `src_path` is the TRUE defining module, so the mangled + // `perry_method_____` symbol + // matches what that module actually emitted (otherwise the + // linker fails with "undefined symbol + // _perry_method_src_index_ts__Pool__query" when Pool was + // compiled under src_pool_ts). + let mut origin_paths: std::collections::HashSet = + std::collections::HashSet::new(); + origin_paths.insert(resolved_path_str.clone()); + if let Some(exports) = all_module_exports.get(&resolved_path_str) { + for origin_path in exports.values() { + origin_paths.insert(origin_path.clone()); + } + } + for (src_pathbuf, src_hir) in &ctx.native_modules { + let src_path = src_pathbuf.to_string_lossy().to_string(); + if !origin_paths.contains(&src_path) { + continue; + } + for class in &src_hir.classes { + if !class.is_exported { continue; } - if import.module_kind != perry_hir::ModuleKind::Interpreted { + // Dedup across multiple import statements: the same class + // may be transitively reachable from several imports, and + // the same-class-twice case would produce duplicate + // `@perry_class_keys___` globals in IR. + // Same-name local classes win via `compile_module`'s + // class_table check, so this filter is strictly about + // cross-module twinning. + if imported_classes.iter().any(|c| c.name == class.name) { continue; } - // The V8 bridge takes a specifier string and resolves it - // through deno_core's Node loader — bare specifiers like - // "ink" and absolute paths both work. Prefer the resolved - // canonical path (matches the `JsModule.specifier` key in - // `ctx.js_modules`) so the same module-handle cache hits - // across imports of the same package from different sites. - let specifier = import - .resolved_path - .clone() - .unwrap_or_else(|| import.source.clone()); - let synthetic_prefix = format!("__v8__{}", sanitize_name(&specifier)); - for spec in &import.specifiers { - match spec { - perry_hir::ImportSpecifier::Named { imported, local } => { - import_function_prefixes - .insert(local.clone(), synthetic_prefix.clone()); - import_function_v8_specifiers - .insert(local.clone(), specifier.clone()); - if local != imported { - import_function_prefixes - .insert(imported.clone(), synthetic_prefix.clone()); - import_function_v8_specifiers - .insert(imported.clone(), specifier.clone()); - // Issue #818 (Effect.succeed pattern) follow-up: - // when an aliased named-import (`import { Foo - // as Bar }`) of a V8 module is used as a - // static-method receiver (`Bar.method(...)`), - // the codegen's StaticMethodCall arm sees - // class_name = "Bar" — but the V8 namespace - // exposes the property under "Foo". Record the - // local→imported mapping in - // `import_function_origin_names` so the bridge - // call reaches the right namespace property. - // Without this, aliased Effect-shaped imports - // would look up a missing property and fall to - // undefined. - import_function_origin_names - .insert(local.clone(), imported.clone()); - } - } - perry_hir::ImportSpecifier::Default { local } => { - import_function_prefixes - .insert(local.clone(), synthetic_prefix.clone()); - import_function_v8_specifiers - .insert(local.clone(), specifier.clone()); - // #1195 — `import YAML from "yaml"` lands here. - // When the local name is used as a static-method - // receiver (`YAML.parse(...)`), the StaticMethodCall - // arm in expr/static_method.rs looks up - // `import_function_origin_names[class_name]` to - // pick the namespace property name, falling back - // to the local name. Without this insert, the - // bridge would ask V8 for `ns.YAML` (which doesn't - // exist on the proxy module's namespace; it - // re-exports the default under the literal - // "default" key). Record the local→"default" - // override so the bridge resolves the right - // namespace property. - import_function_origin_names - .insert(local.clone(), "default".to_string()); - } - perry_hir::ImportSpecifier::Namespace { local } => { - // Namespace bindings (`import * as X from "ink"`) - // are already registered into `namespace_imports` - // by the pre-loop above. For pure-namespace usage - // with no companion `Named` import, the V8 module - // has no static export list to register members - // against — so we record `local → specifier` here. - // The codegen's StaticMethodCall arm and the - // namespace-member-call arm in `lower_call.rs` - // probe `namespace_v8_specifiers` and, on a hit, - // emit `js_call_v8_export(specifier, member, - // args, argc)` so `R.sum([1,2,3])` (`import * as - // R from "ramda"`) reaches V8 instead of falling - // to the `double_literal(0.0)` stub. Unblocks - // ramda / date-fns / jose / effect wildcard - // namespace usage. - namespace_v8_specifiers.insert(local.clone(), specifier.clone()); - } + let class_prefix = compute_module_prefix(&src_path, &ctx.project_root); + imported_classes.push(imported_class_from_hir( + class, + class_prefix, + None, + proven_this_methods_for_import(class, &class_proven_this_methods), + proven_this_methods_for_import(class, &class_proven_this_tower_methods), + )); + } + } + } + + // Issue #678 followup: V8-fallback imports. Native imports above + // wire `perry_fn___` extern symbols; V8 imports route + // through the runtime bridge instead. We populate BOTH + // `import_function_prefixes` (with a synthetic prefix so the + // codegen's `Some(source_prefix) = prefixes.get(name)` arm fires + // and the V8-specifier short-circuit inside it triggers) AND + // `import_function_v8_specifiers` (the actual specifier the bridge + // hands to `js_load_module`). The synthetic prefix never reaches + // a `perry_fn_...` symbol because every codegen site probes + // `import_function_v8_specifiers` first. + for import in &hir_module.imports { + if import.type_only || import.runtime_erased { + continue; + } + if import.module_kind != perry_hir::ModuleKind::Interpreted { + continue; + } + // The V8 bridge takes a specifier string and resolves it + // through deno_core's Node loader — bare specifiers like + // "ink" and absolute paths both work. Prefer the resolved + // canonical path (matches the `JsModule.specifier` key in + // `ctx.js_modules`) so the same module-handle cache hits + // across imports of the same package from different sites. + let specifier = import + .resolved_path + .clone() + .unwrap_or_else(|| import.source.clone()); + let synthetic_prefix = format!("__v8__{}", sanitize_name(&specifier)); + for spec in &import.specifiers { + match spec { + perry_hir::ImportSpecifier::Named { imported, local } => { + import_function_prefixes.insert(local.clone(), synthetic_prefix.clone()); + import_function_v8_specifiers.insert(local.clone(), specifier.clone()); + if local != imported { + import_function_prefixes + .insert(imported.clone(), synthetic_prefix.clone()); + import_function_v8_specifiers + .insert(imported.clone(), specifier.clone()); + // Issue #818 (Effect.succeed pattern) follow-up: + // when an aliased named-import (`import { Foo + // as Bar }`) of a V8 module is used as a + // static-method receiver (`Bar.method(...)`), + // the codegen's StaticMethodCall arm sees + // class_name = "Bar" — but the V8 namespace + // exposes the property under "Foo". Record the + // local→imported mapping in + // `import_function_origin_names` so the bridge + // call reaches the right namespace property. + // Without this, aliased Effect-shaped imports + // would look up a missing property and fall to + // undefined. + import_function_origin_names.insert(local.clone(), imported.clone()); } } + perry_hir::ImportSpecifier::Default { local } => { + import_function_prefixes.insert(local.clone(), synthetic_prefix.clone()); + import_function_v8_specifiers.insert(local.clone(), specifier.clone()); + // #1195 — `import YAML from "yaml"` lands here. + // When the local name is used as a static-method + // receiver (`YAML.parse(...)`), the StaticMethodCall + // arm in expr/static_method.rs looks up + // `import_function_origin_names[class_name]` to + // pick the namespace property name, falling back + // to the local name. Without this insert, the + // bridge would ask V8 for `ns.YAML` (which doesn't + // exist on the proxy module's namespace; it + // re-exports the default under the literal + // "default" key). Record the local→"default" + // override so the bridge resolves the right + // namespace property. + import_function_origin_names.insert(local.clone(), "default".to_string()); + } + perry_hir::ImportSpecifier::Namespace { local } => { + // Namespace bindings (`import * as X from "ink"`) + // are already registered into `namespace_imports` + // by the pre-loop above. For pure-namespace usage + // with no companion `Named` import, the V8 module + // has no static export list to register members + // against — so we record `local → specifier` here. + // The codegen's StaticMethodCall arm and the + // namespace-member-call arm in `lower_call.rs` + // probe `namespace_v8_specifiers` and, on a hit, + // emit `js_call_v8_export(specifier, member, + // args, argc)` so `R.sum([1,2,3])` (`import * as + // R from "ramda"`) reaches V8 instead of falling + // to the `double_literal(0.0)` stub. Unblocks + // ramda / date-fns / jose / effect wildcard + // namespace usage. + namespace_v8_specifiers.insert(local.clone(), specifier.clone()); + } } + } + } - // Issue #841: register named + namespace imports from the - // five recognized Node submodules — `node:timers/promises`, - // `node:readline/promises`, `node:stream/promises`, - // `node:stream/consumers`, `node:sys`. These don't resolve - // to anything perry-stdlib can back, but the runtime ships - // a `js_node_submodule_export_as_function` helper that - // returns a function singleton for each known export, plus - // `js_node_submodule_namespace` for namespace shapes. - // - // Without this registration the codegen's `ExternFuncRef` - // value-form catch-all fell to TAG_TRUE, so `typeof - // setTimeout` (from `node:timers/promises`) reported - // `"boolean"` instead of `"function"`. Namespaces were - // hard-errored at module-collection time pre-fix - // (`collect_modules.rs::known_node_submodule_key`); they - // now flow through and land here. - for import in &hir_module.imports { - if import.type_only || import.runtime_erased { - continue; - } - let submod_key = - match self::collect_modules::known_node_submodule_key(&import.source) { - Some(k) => k.to_string(), - None => continue, - }; - for spec in &import.specifiers { - match spec { - perry_hir::ImportSpecifier::Named { imported, local } => { - // #1213: node:timers named imports (`import { - // setTimeout } from "node:timers"`) keep the global - // timer codegen fast-path (which handles the - // `setTimeout(fn, delay, ...args)` varargs form). - // Routing them through the submodule thunk here - // would drop varargs — only the `import * as` - // namespace shape uses the submodule. - if submod_key != "timers" { - // Register ONLY the local binding. For an - // aliased import (`import { setTimeout as ac5 } - // from "node:timers/promises"`) the in-scope - // name is `ac5`; the imported name `setTimeout` - // is NOT bound here — it still refers to the - // GLOBAL `setTimeout(callback, delay)`. A prior - // version also keyed the map by `imported` when - // `local != imported`, which made the bare - // global `setTimeout(fn, ms)` divert to the - // delay-first promises thunk and reject with - // `The "delay" argument must be of type number. - // Received function`. Keying only by `local` - // keeps the alias routed to the submodule export - // and leaves the unshadowed global intact. - import_function_node_submodule.insert( - local.clone(), - (submod_key.clone(), imported.clone()), - ); - } - } - perry_hir::ImportSpecifier::Default { local } => { - // Default imports route to "default" — known Node - // submodules expose an object-valued default export - // that is distinct from the namespace object. - import_function_node_submodule.insert( - local.clone(), - (submod_key.clone(), "default".to_string()), - ); - } - perry_hir::ImportSpecifier::Namespace { local } => { - namespace_node_submodules.insert(local.clone(), submod_key.clone()); - // Already in `namespace_imports` via the - // pre-loop at L3441; nothing else to do. - } + // Issue #841: register named + namespace imports from the + // five recognized Node submodules — `node:timers/promises`, + // `node:readline/promises`, `node:stream/promises`, + // `node:stream/consumers`, `node:sys`. These don't resolve + // to anything perry-stdlib can back, but the runtime ships + // a `js_node_submodule_export_as_function` helper that + // returns a function singleton for each known export, plus + // `js_node_submodule_namespace` for namespace shapes. + // + // Without this registration the codegen's `ExternFuncRef` + // value-form catch-all fell to TAG_TRUE, so `typeof + // setTimeout` (from `node:timers/promises`) reported + // `"boolean"` instead of `"function"`. Namespaces were + // hard-errored at module-collection time pre-fix + // (`collect_modules.rs::known_node_submodule_key`); they + // now flow through and land here. + for import in &hir_module.imports { + if import.type_only || import.runtime_erased { + continue; + } + let submod_key = match self::collect_modules::known_node_submodule_key(&import.source) { + Some(k) => k.to_string(), + None => continue, + }; + for spec in &import.specifiers { + match spec { + perry_hir::ImportSpecifier::Named { imported, local } => { + // #1213: node:timers named imports (`import { + // setTimeout } from "node:timers"`) keep the global + // timer codegen fast-path (which handles the + // `setTimeout(fn, delay, ...args)` varargs form). + // Routing them through the submodule thunk here + // would drop varargs — only the `import * as` + // namespace shape uses the submodule. + if submod_key != "timers" { + // Register ONLY the local binding. For an + // aliased import (`import { setTimeout as ac5 } + // from "node:timers/promises"`) the in-scope + // name is `ac5`; the imported name `setTimeout` + // is NOT bound here — it still refers to the + // GLOBAL `setTimeout(callback, delay)`. A prior + // version also keyed the map by `imported` when + // `local != imported`, which made the bare + // global `setTimeout(fn, ms)` divert to the + // delay-first promises thunk and reject with + // `The "delay" argument must be of type number. + // Received function`. Keying only by `local` + // keeps the alias routed to the submodule export + // and leaves the unshadowed global intact. + import_function_node_submodule + .insert(local.clone(), (submod_key.clone(), imported.clone())); } } + perry_hir::ImportSpecifier::Default { local } => { + // Default imports route to "default" — known Node + // submodules expose an object-valued default export + // that is distinct from the namespace object. + import_function_node_submodule + .insert(local.clone(), (submod_key.clone(), "default".to_string())); + } + perry_hir::ImportSpecifier::Namespace { local } => { + namespace_node_submodules.insert(local.clone(), submod_key.clone()); + // Already in `namespace_imports` via the + // pre-loop at L3441; nothing else to do. + } } + } + } - // Do not augment type-only interface consumers with every exported - // class in the program (the old issue #240 fallback). Dynamic method - // calls and method-as-value reads now resolve through the runtime's - // class-vtable registry; copying all class metadata here multiplied - // unrelated consumer IR and object size by the whole program. - - // Transitive class closure: pull in classes referenced by fields, - // declared call results, and parents of already-imported classes. - // Without the field side of this, a - // chain like `vm.viewport.scroll.scrollTop` (where vm is - // `EditorViewModel`, `viewport: ViewportManager`, `scroll: - // ScrollController`) breaks at the first hop because only - // `EditorViewModel` lives in `imported_classes` for this - // module — `receiver_class_name` can't walk through - // `viewport.scroll` because `ViewportManager` isn't in - // `class_table` and its field types are unknown. Closing - // over field types lets `PropertyGet` recursion resolve - // the receiver class at every step of the chain. - let mut visited_imports: std::collections::HashSet = - imported_classes.iter().map(|ic| ic.name.clone()).collect(); - // Issue #26 / #321: a class's `extends` parent must be resolved in - // the CHILD's own source module — same-named classes in different - // modules (effect's `Type` in SchemaAST.ts vs ParseResult.ts) are - // distinct. The by-NAME `visited_imports` dedup above would import - // only the first `Type` seen and skip the SchemaAST one, so - // SchemaAST's `OptionalType extends Type` chain loses its real - // parent's fields. Track parent additions by (path, name) identity - // so the correct-module parent is pulled in even when its bare - // name was already visited. Codegen's prefix-disambiguated parent - // resolver then picks the right one. - let mut visited_parent_paths: std::collections::HashSet<(String, String)> = - std::collections::HashSet::new(); - // Worklist of INDICES into `imported_classes` (not names): a name - // can map to several entries (same-named cross-module classes, - // refs #26), so we must process the exact entry we added, not the - // first by-name match. - let mut closure_worklist: Vec = (0..imported_classes.len()).collect(); - while let Some(idx) = closure_worklist.pop() { - if idx >= imported_classes.len() { - continue; - } - let field_types_clone = imported_classes[idx].field_types.clone(); - let method_return_types_clone: Vec = imported_classes - [idx] - .method_return_types - .iter() - .chain(imported_classes[idx].static_method_return_types.iter()) - .chain(imported_classes[idx].getter_return_types.iter()) - .cloned() - .collect(); - let parent_name_clone = imported_classes[idx].parent_name.clone(); - let child_source_prefix = imported_classes[idx].source_prefix.clone(); - let child_src_path = native_module_paths_by_prefix.get(&child_source_prefix); - // Issue #485: include the class's parent in the transitive - // closure too. Without this, `import { Sub } from 'pkg'` where - // `Sub extends Base` (and Base lives in another file inside - // the same package) leaves Base unimported on this side, so - // codegen builds Sub's per-class shape with zero parent-field - // contribution. Sub instances allocate too few inline slots - // and the parent's cross-module ctor's `this.field = …` - // writes overflow the object header — `f.field` reads - // undefined on the importing side. - // - // `is_parent_ref` marks the entry that came from `extends` - // (vs a field or return-type reference): parent refs get - // path-aware resolution + (path,name) dedup so the - // correct-module parent is imported even past the bare-name - // dedup. Other refs keep the legacy by-name behavior because - // codegen's class dispatch table is still name-keyed. - let mut named_refs = std::collections::BTreeSet::new(); - for ty in field_types_clone - .iter() - .chain(method_return_types_clone.iter()) + // Do not augment type-only interface consumers with every exported + // class in the program (the old issue #240 fallback). Dynamic method + // calls and method-as-value reads now resolve through the runtime's + // class-vtable registry; copying all class metadata here multiplied + // unrelated consumer IR and object size by the whole program. + + // Transitive class closure: pull in classes referenced by fields, + // declared call results, and parents of already-imported classes. + // Without the field side of this, a + // chain like `vm.viewport.scroll.scrollTop` (where vm is + // `EditorViewModel`, `viewport: ViewportManager`, `scroll: + // ScrollController`) breaks at the first hop because only + // `EditorViewModel` lives in `imported_classes` for this + // module — `receiver_class_name` can't walk through + // `viewport.scroll` because `ViewportManager` isn't in + // `class_table` and its field types are unknown. Closing + // over field types lets `PropertyGet` recursion resolve + // the receiver class at every step of the chain. + let mut visited_imports: std::collections::HashSet = + imported_classes.iter().map(|ic| ic.name.clone()).collect(); + // Issue #26 / #321: a class's `extends` parent must be resolved in + // the CHILD's own source module — same-named classes in different + // modules (effect's `Type` in SchemaAST.ts vs ParseResult.ts) are + // distinct. The by-NAME `visited_imports` dedup above would import + // only the first `Type` seen and skip the SchemaAST one, so + // SchemaAST's `OptionalType extends Type` chain loses its real + // parent's fields. Track parent additions by (path, name) identity + // so the correct-module parent is pulled in even when its bare + // name was already visited. Codegen's prefix-disambiguated parent + // resolver then picks the right one. + let mut visited_parent_paths: std::collections::HashSet<(String, String)> = + std::collections::HashSet::new(); + // Worklist of INDICES into `imported_classes` (not names): a name + // can map to several entries (same-named cross-module classes, + // refs #26), so we must process the exact entry we added, not the + // first by-name match. + let mut closure_worklist: Vec = (0..imported_classes.len()).collect(); + while let Some(idx) = closure_worklist.pop() { + if idx >= imported_classes.len() { + continue; + } + let field_types_clone = imported_classes[idx].field_types.clone(); + let method_return_types_clone: Vec = imported_classes[idx] + .method_return_types + .iter() + .chain(imported_classes[idx].static_method_return_types.iter()) + .chain(imported_classes[idx].getter_return_types.iter()) + .cloned() + .collect(); + let parent_name_clone = imported_classes[idx].parent_name.clone(); + let child_source_prefix = imported_classes[idx].source_prefix.clone(); + let child_src_path = native_module_paths_by_prefix.get(&child_source_prefix); + // Issue #485: include the class's parent in the transitive + // closure too. Without this, `import { Sub } from 'pkg'` where + // `Sub extends Base` (and Base lives in another file inside + // the same package) leaves Base unimported on this side, so + // codegen builds Sub's per-class shape with zero parent-field + // contribution. Sub instances allocate too few inline slots + // and the parent's cross-module ctor's `this.field = …` + // writes overflow the object header — `f.field` reads + // undefined on the importing side. + // + // `is_parent_ref` marks the entry that came from `extends` + // (vs a field or return-type reference): parent refs get + // path-aware resolution + (path,name) dedup so the + // correct-module parent is imported even past the bare-name + // dedup. Other refs keep the legacy by-name behavior because + // codegen's class dispatch table is still name-keyed. + let mut named_refs = std::collections::BTreeSet::new(); + for ty in field_types_clone + .iter() + .chain(method_return_types_clone.iter()) + { + collect_named_class_refs(ty, &mut named_refs); + } + let refs: Vec<(String, bool)> = named_refs + .into_iter() + .map(|name| (name, false)) + .chain(parent_name_clone.into_iter().map(|name| (name, true))) + .collect(); + for (ref_name, is_parent_ref) in refs { + // Resolve the type name in the declaring class's own + // module before falling back to the legacy global lookup. + // This includes erased `import type { Result as Local }` + // bindings, but only consumes their class metadata: it + // does not create a value binding or module-init edge. + let scoped_found = child_src_path.and_then(|child_path| { + let module = ctx.native_modules.get(child_path)?; + if let Some(class) = module.classes.iter().find(|class| class.name == ref_name) { - collect_named_class_refs(ty, &mut named_refs); + let canonical_path = class_canonical_path + .get(&(class as *const perry_hir::Class as usize)) + .cloned() + .unwrap_or_else(|| child_path.to_string_lossy().into_owned()); + return Some((canonical_path, class)); } - let refs: Vec<(String, bool)> = named_refs - .into_iter() - .map(|name| (name, false)) - .chain(parent_name_clone.into_iter().map(|name| (name, true))) - .collect(); - for (ref_name, is_parent_ref) in refs { - // Resolve the type name in the declaring class's own - // module before falling back to the legacy global lookup. - // This includes erased `import type { Result as Local }` - // bindings, but only consumes their class metadata: it - // does not create a value binding or module-init edge. - let scoped_found = child_src_path.and_then(|child_path| { - let module = ctx.native_modules.get(child_path)?; - if let Some(class) = - module.classes.iter().find(|class| class.name == ref_name) - { - let canonical_path = class_canonical_path - .get(&(class as *const perry_hir::Class as usize)) - .cloned() - .unwrap_or_else(|| child_path.to_string_lossy().into_owned()); - return Some((canonical_path, class)); - } - module.imports.iter().find_map(|import| { - if import.module_kind != perry_hir::ModuleKind::NativeCompiled { - return None; + module.imports.iter().find_map(|import| { + if import.module_kind != perry_hir::ModuleKind::NativeCompiled { + return None; + } + let resolved_path = import.resolved_path.as_ref()?; + import.specifiers.iter().find_map(|specifier| { + let (exported_name, local_name) = match specifier { + perry_hir::ImportSpecifier::Named { imported, local } => { + (imported.as_str(), local.as_str()) } - let resolved_path = import.resolved_path.as_ref()?; - import.specifiers.iter().find_map(|specifier| { - let (exported_name, local_name) = match specifier { - perry_hir::ImportSpecifier::Named { imported, local } => { - (imported.as_str(), local.as_str()) - } - perry_hir::ImportSpecifier::Default { local } => { - ("default", local.as_str()) - } - perry_hir::ImportSpecifier::Namespace { .. } => { - return None - } - }; - if local_name != ref_name { - return None; - } - let origin_path = all_module_exports - .get(resolved_path) - .and_then(|exports| exports.get(exported_name)) - .cloned() - .unwrap_or_else(|| resolved_path.clone()); - let origin_name = all_module_export_origin_names - .get(resolved_path) - .and_then(|names| names.get(exported_name)) - .cloned() - .unwrap_or_else(|| exported_name.to_string()); - let class = exported_classes - .get(&(origin_path.clone(), origin_name.clone())) - .or_else(|| { - exported_classes.get(&( - origin_path.clone(), - exported_name.to_string(), - )) - }) - .or_else(|| { - exported_classes.get(&( - resolved_path.clone(), - exported_name.to_string(), - )) - })?; - let canonical_path = class_canonical_path - .get(&(*class as *const perry_hir::Class as usize)) - .cloned() - .unwrap_or(origin_path); - Some((canonical_path, *class)) - }) - }) - }); - // Issue #489: pick the canonical defining path for the - // parent class (where `class N { ... }` actually lives) - // rather than the first BTreeMap match by name (which - // can be a re-export barrel). Without this, drizzle's - // `MySqlPreparedQuery extends QueryPromise` chain pulls - // QueryPromise in under `drizzle-orm/index.js` (because - // `index.js` does `export * from "./query-promise.js"` - // and sorts before `query-promise.js`), and the dispatch - // table emits `perry_method___QueryPromise__then` - // — undefined symbol at link time. - // - // Issue #26: for a parent ref, prefer the same-named class - // in the CHILD's own source module before any global match. - let found = scoped_found.or_else(|| { - exported_classes - .iter() - .find(|((path, cname), class)| { - cname == &ref_name - && class_canonical_path - .get(&(**class as *const perry_hir::Class as usize)) - .map(|canonical| canonical == path) - .unwrap_or(true) - }) + perry_hir::ImportSpecifier::Default { local } => { + ("default", local.as_str()) + } + perry_hir::ImportSpecifier::Namespace { .. } => return None, + }; + if local_name != ref_name { + return None; + } + let origin_path = all_module_exports + .get(resolved_path) + .and_then(|exports| exports.get(exported_name)) + .cloned() + .unwrap_or_else(|| resolved_path.clone()); + let origin_name = all_module_export_origin_names + .get(resolved_path) + .and_then(|names| names.get(exported_name)) + .cloned() + .unwrap_or_else(|| exported_name.to_string()); + let class = exported_classes + .get(&(origin_path.clone(), origin_name.clone())) .or_else(|| { exported_classes - .iter() - .find(|((_, cname), _)| cname == &ref_name) - }) - .map(|((path, _), class)| { - // `exported_classes` deliberately carries alias - // entries stamped under barrel paths. Selecting - // one is valid for scope resolution, but symbols - // still live in the defining module. - let canonical_path = class_canonical_path - .get(&(*class as *const perry_hir::Class as usize)) - .cloned() - .unwrap_or_else(|| path.clone()); - (canonical_path, *class) + .get(&(origin_path.clone(), exported_name.to_string())) }) - }); - // Dedup: parent refs key on (resolved_path, name) so a - // distinct same-named parent in another module is still - // imported; all other refs key on name only (legacy). - if is_parent_ref { - if let Some((src_path, class)) = &found { - let source_prefix = - compute_module_prefix(src_path, &ctx.project_root); - let effective_name = if ref_name != class.name { - ref_name.as_str() - } else { - class.name.as_str() - }; - // The initial import walk may already contain this - // exact canonical class. A barrel-local child - // extending a re-exported parent must not append a - // second copy under the barrel path: the later - // duplicate would overwrite the correct ctor in - // codegen's name-keyed map (OpenTUI's index.node.js - // / chunk-node BoxRenderable shape). - if imported_classes.iter().any(|imported| { - imported.source_prefix == source_prefix - && imported.name == class.name - && imported.local_alias.as_deref().unwrap_or(&imported.name) - == effective_name - }) { - visited_parent_paths - .insert((src_path.clone(), ref_name.clone())); - continue; - } - if !visited_parent_paths - .insert((src_path.clone(), ref_name.clone())) - { - continue; - } - // Already have an entry under this name from a - // DIFFERENT module: still add this (path,name) - // variant so codegen can disambiguate, but skip - // re-pushing to the worklist by name below. - } else { - continue; - } - } else if visited_imports.contains(&ref_name) { + .or_else(|| { + exported_classes + .get(&(resolved_path.clone(), exported_name.to_string())) + })?; + let canonical_path = class_canonical_path + .get(&(*class as *const perry_hir::Class as usize)) + .cloned() + .unwrap_or(origin_path); + Some((canonical_path, *class)) + }) + }) + }); + // Issue #489: pick the canonical defining path for the + // parent class (where `class N { ... }` actually lives) + // rather than the first BTreeMap match by name (which + // can be a re-export barrel). Without this, drizzle's + // `MySqlPreparedQuery extends QueryPromise` chain pulls + // QueryPromise in under `drizzle-orm/index.js` (because + // `index.js` does `export * from "./query-promise.js"` + // and sorts before `query-promise.js`), and the dispatch + // table emits `perry_method___QueryPromise__then` + // — undefined symbol at link time. + // + // Issue #26: for a parent ref, prefer the same-named class + // in the CHILD's own source module before any global match. + let found = scoped_found.or_else(|| { + exported_classes + .iter() + .find(|((path, cname), class)| { + cname == &ref_name + && class_canonical_path + .get(&(**class as *const perry_hir::Class as usize)) + .map(|canonical| canonical == path) + .unwrap_or(true) + }) + .or_else(|| { + exported_classes + .iter() + .find(|((_, cname), _)| cname == &ref_name) + }) + .map(|((path, _), class)| { + // `exported_classes` deliberately carries alias + // entries stamped under barrel paths. Selecting + // one is valid for scope resolution, but symbols + // still live in the defining module. + let canonical_path = class_canonical_path + .get(&(*class as *const perry_hir::Class as usize)) + .cloned() + .unwrap_or_else(|| path.clone()); + (canonical_path, *class) + }) + }); + // Dedup: parent refs key on (resolved_path, name) so a + // distinct same-named parent in another module is still + // imported; all other refs key on name only (legacy). + if is_parent_ref { + if let Some((src_path, class)) = &found { + let source_prefix = compute_module_prefix(src_path, &ctx.project_root); + let effective_name = if ref_name != class.name { + ref_name.as_str() + } else { + class.name.as_str() + }; + // The initial import walk may already contain this + // exact canonical class. A barrel-local child + // extending a re-exported parent must not append a + // second copy under the barrel path: the later + // duplicate would overwrite the correct ctor in + // codegen's name-keyed map (OpenTUI's index.node.js + // / chunk-node BoxRenderable shape). + if imported_classes.iter().any(|imported| { + imported.source_prefix == source_prefix + && imported.name == class.name + && imported.local_alias.as_deref().unwrap_or(&imported.name) + == effective_name + }) { + visited_parent_paths.insert((src_path.clone(), ref_name.clone())); continue; } - if let Some((src_path, class)) = found { - let class_prefix = compute_module_prefix(&src_path, &ctx.project_root); - // Issue #485: when the child's `parent_name` doesn't - // match the source class's `class.name` (because the - // parent was imported via a rename — `import { Base - // as HBase } from './base.js'` or - // `export { Base as HBase }` on the source side), - // expose the stub under the alias the child knows. - // Without this, codegen's `imported_class_stubs` - // would register the parent under "Base" while the - // child's `extends_name` is "HBase", and the - // packed-keys / slot-index walker fails to traverse - // the chain. - let alias = if ref_name != class.name { - Some(ref_name.clone()) - } else { - None - }; - imported_classes.push(imported_class_from_hir( - class, - class_prefix, - alias, - proven_this_methods_for_import(class, &class_proven_this_methods), - proven_this_methods_for_import( - class, - &class_proven_this_tower_methods, - ), - )); - visited_imports.insert(ref_name.clone()); - // Process the entry we just pushed (by index, so a - // same-named distinct-module class isn't skipped). Refs #26. - closure_worklist.push(imported_classes.len() - 1); + if !visited_parent_paths.insert((src_path.clone(), ref_name.clone())) { + continue; } + // Already have an entry under this name from a + // DIFFERENT module: still add this (path,name) + // variant so codegen can disambiguate, but skip + // re-pushing to the worklist by name below. + } else { + continue; } + } else if visited_imports.contains(&ref_name) { + continue; } - - // Type aliases from all modules - let type_alias_map: std::collections::HashMap = - all_type_aliases - .iter() - .map(|(k, v)| (k.clone(), v.clone())) - .collect(); - - // Resolve the CLI's short target name (ios/android/etc.) to - // an LLVM triple. `None` falls through to the host default - // inside `compile_module`. - let resolved_triple = target - .as_deref() - .and_then(perry_codegen::resolve_target_triple); - // ── Feature plumbing ── - // Set all compile options so the codegen honors - // the same project configuration. Without this, the - // auto-optimize feature detection + linker flag - // construction can't see which modules the program - // actually uses and strips too much from libperry_stdlib.a. - let bundled_ext_vec: Vec<(String, String)> = if is_entry { - bundled_extensions - .iter() - .map(|(ext_path, _plugin_id)| { - let ext_prefix = compute_module_prefix( - &ext_path.to_string_lossy(), - &ctx.project_root, - ); - (ext_path.to_string_lossy().to_string(), ext_prefix) - }) - .collect() - } else { - Vec::new() - }; - let native_module_init_names_vec: Vec = if is_entry { - non_entry_module_names.clone() - } else { - Vec::new() - }; - let js_module_specifiers_vec: Vec = js_module_specifiers.clone(); - - let opts = perry_codegen::CompileOptions { - target: resolved_triple, - is_entry_module: is_entry, - non_entry_module_prefixes, - import_function_prefixes, - import_function_ffi_aliases, - import_function_origin_names, - import_function_v8_specifiers, - import_function_node_submodule, - namespace_node_submodules, - namespace_v8_specifiers, - namespace_member_prefixes, - namespace_member_origin_names, - emit_ir_only: bitcode_link, - verify_native_regions, - disable_buffer_fast_path, - namespace_imports, - namespace_member_nested: namespace_member_nested.into_iter().collect(), - imported_classes, - constructor_param_counts: Default::default(), - short_spread_method_candidates: std::sync::Arc::clone( - &short_spread_method_candidates, - ), - object_literal_method_candidates: std::sync::Arc::clone( - &object_literal_method_candidates, - ), - imported_enums, - imported_async_funcs: imported_async_set, - type_aliases: type_alias_map, - imported_func_param_counts: imported_param_counts, - imported_func_has_rest: imported_has_rest, - imported_func_synthetic_arguments: imported_synthetic_arguments, - imported_func_return_types: imported_return_types, - imported_vars, - - // Feature plumbing - output_type: args.output_type.clone(), - needs_stdlib: ctx.needs_stdlib, - needs_ui: ctx.needs_ui, - needs_geisterhand: ctx.needs_geisterhand, - geisterhand_port: ctx.geisterhand_port, - enabled_features: compiled_features.clone(), - native_module_init_names: native_module_init_names_vec, - js_module_specifiers: js_module_specifiers_vec, - bundled_extensions: bundled_ext_vec, - native_library_functions: ffi_functions.clone(), - i18n_table: i18n_snapshot.clone(), - fast_math: ctx.fast_math, - fp_contract_mode: ctx.fp_contract_mode, - app_metadata: perry_codegen::AppMetadata { - entry_source_path: if is_entry && args.output_type == "executable" { - Some(path.to_string_lossy().into_owned()) - } else { - None - }, - ..ctx.app_metadata.clone() - }, - // Issue #100: namespace_entries empty unless this - // module is a dynamic-import target; the consumer-side - // dispatch map is empty unless this module performs - // dynamic imports. - namespace_entries: per_module_namespace_entries - .get(path) - .cloned() - .unwrap_or_default(), - dynamic_import_path_to_prefix: per_module_dyn_import_targets - .get(path) - .cloned() - .unwrap_or_default(), - nextjs_path_init_modules, - deferred_module_prefixes, - module_init_deps, - // Issue #842: signal side-effect-only dynamic-import - // targets to codegen so it still emits - // `@__perry_ns_` + populator. `dyn_target_paths` - // is the authoritative set built from every consumer's - // `import.is_dynamic` resolved paths; `namespace_entries` - // alone is insufficient because it's empty when the - // target has no `export` statements. - is_dynamic_import_target: dyn_target_paths.contains(path), - // #5247: source-location tracking for the dynamic call-dispatch - // throw path. Gated by `--debug-symbols` so the default build is - // unchanged (no source read, no per-call emission). When on, read - // the module's original source so codegen can map a Call's byte - // offset to a 1-based line. - debug_locations: args.debug_symbols, - // #5247 / #7036: source consulted to turn a node's `byte_offset` - // into a debug frame or opt-report snippet. For a CommonJS - // module the offsets are in WRAPPED-source - // coordinates (perry parsed the injected-IIFE text), so we hand - // codegen the WRAPPED source — counting newlines up to a wrapped - // offset against the original would be off by the preamble byte - // length. `debug_source_line_offset` (below) then converts the - // wrapped line back to the original line. Non-wrapped modules - // read the original from disk. Text reports need this source; - // JSON reports only need the offset already carried by HIR. - module_source: if args.debug_symbols - || opt_report_format == Some(OptReportFormat::Text) - { - match ctx.cjs_wrap_debug_sources.get(path) { - Some(w) => Some(w.wrapped_source.clone()), - None => std::fs::read_to_string(path).ok(), - } + if let Some((src_path, class)) = found { + let class_prefix = compute_module_prefix(&src_path, &ctx.project_root); + // Issue #485: when the child's `parent_name` doesn't + // match the source class's `class.name` (because the + // parent was imported via a rename — `import { Base + // as HBase } from './base.js'` or + // `export { Base as HBase }` on the source side), + // expose the stub under the alias the child knows. + // Without this, codegen's `imported_class_stubs` + // would register the parent under "Base" while the + // child's `extends_name` is "HBase", and the + // packed-keys / slot-index walker fails to traverse + // the chain. + let alias = if ref_name != class.name { + Some(ref_name.clone()) } else { None - }, - // #5247 (CJS-wrap coordinate skew): the number of newlines the - // injected wrapper prefix added before the original module body. - // Codegen subtracts this from the wrapped line number so the - // rendered location is in original-source coordinates. `0` for - // non-wrapped modules (and the entire default build). - debug_source_line_offset: if args.debug_symbols - || opt_report_format == Some(OptReportFormat::Text) - { - ctx.cjs_wrap_debug_sources - .get(path) - .map(|w| w.prefix_line_count) - .unwrap_or(0) - } else { - 0 - }, - }; - Ok((path, hir_module, opts)) - }) - .collect() - }); - let mut prepared_modules = prepared_modules.map_err(|error| anyhow!(error))?; - perry_codegen::resolve_constructor_contracts(prepared_modules.iter_mut().map( - |(path, module, opts)| { - ( - compute_module_prefix(&path.to_string_lossy(), &ctx.project_root), - *module, - opts, - ) - }, - )); + }; + imported_classes.push(imported_class_from_hir( + class, + class_prefix, + alias, + proven_this_methods_for_import(class, &class_proven_this_methods), + proven_this_methods_for_import(class, &class_proven_this_tower_methods), + )); + visited_imports.insert(ref_name.clone()); + // Process the entry we just pushed (by index, so a + // same-named distinct-module class isn't skipped). Refs #26. + closure_worklist.push(imported_classes.len() - 1); + } + } + } + + if contracts_only { + return Ok(perry_codegen::CompileOptions { + imported_classes, + ..Default::default() + }); + } + + // Type aliases from all modules + let type_alias_map: std::collections::HashMap = + all_type_aliases + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(); + + // Resolve the CLI's short target name (ios/android/etc.) to + // an LLVM triple. `None` falls through to the host default + // inside `compile_module`. + let resolved_triple = target + .as_deref() + .and_then(perry_codegen::resolve_target_triple); + // ── Feature plumbing ── + // Set all compile options so the codegen honors + // the same project configuration. Without this, the + // auto-optimize feature detection + linker flag + // construction can't see which modules the program + // actually uses and strips too much from libperry_stdlib.a. + let bundled_ext_vec: Vec<(String, String)> = if is_entry { + bundled_extensions + .iter() + .map(|(ext_path, _plugin_id)| { + let ext_prefix = + compute_module_prefix(&ext_path.to_string_lossy(), &ctx.project_root); + (ext_path.to_string_lossy().to_string(), ext_prefix) + }) + .collect() + } else { + Vec::new() + }; + let native_module_init_names_vec: Vec = if is_entry { + non_entry_module_names.clone() + } else { + Vec::new() + }; + let js_module_specifiers_vec: Vec = js_module_specifiers.clone(); + + let opts = perry_codegen::CompileOptions { + target: resolved_triple, + is_entry_module: is_entry, + non_entry_module_prefixes, + import_function_prefixes, + import_function_ffi_aliases, + import_function_origin_names, + import_function_v8_specifiers, + import_function_node_submodule, + namespace_node_submodules, + namespace_v8_specifiers, + namespace_member_prefixes, + namespace_member_origin_names, + emit_ir_only: bitcode_link, + verify_native_regions, + disable_buffer_fast_path, + namespace_imports, + namespace_member_nested: namespace_member_nested.into_iter().collect(), + imported_classes, + constructor_param_counts: Default::default(), + short_spread_method_candidates: std::sync::Arc::clone(&short_spread_method_candidates), + object_literal_method_candidates: std::sync::Arc::clone( + &object_literal_method_candidates, + ), + imported_enums, + imported_async_funcs: imported_async_set, + type_aliases: type_alias_map, + imported_func_param_counts: imported_param_counts, + imported_func_has_rest: imported_has_rest, + imported_func_synthetic_arguments: imported_synthetic_arguments, + imported_func_return_types: imported_return_types, + imported_vars, + + // Feature plumbing + output_type: args.output_type.clone(), + needs_stdlib: ctx.needs_stdlib, + needs_ui: ctx.needs_ui, + needs_geisterhand: ctx.needs_geisterhand, + geisterhand_port: ctx.geisterhand_port, + enabled_features: compiled_features.clone(), + native_module_init_names: native_module_init_names_vec, + js_module_specifiers: js_module_specifiers_vec, + bundled_extensions: bundled_ext_vec, + native_library_functions: ffi_functions.clone(), + i18n_table: i18n_snapshot.clone(), + fast_math: ctx.fast_math, + fp_contract_mode: ctx.fp_contract_mode, + app_metadata: perry_codegen::AppMetadata { + entry_source_path: if is_entry && args.output_type == "executable" { + Some(path.to_string_lossy().into_owned()) + } else { + None + }, + ..ctx.app_metadata.clone() + }, + // Issue #100: namespace_entries empty unless this + // module is a dynamic-import target; the consumer-side + // dispatch map is empty unless this module performs + // dynamic imports. + namespace_entries: per_module_namespace_entries + .get(path) + .cloned() + .unwrap_or_default(), + dynamic_import_path_to_prefix: per_module_dyn_import_targets + .get(path) + .cloned() + .unwrap_or_default(), + nextjs_path_init_modules, + deferred_module_prefixes, + module_init_deps, + // Issue #842: signal side-effect-only dynamic-import + // targets to codegen so it still emits + // `@__perry_ns_` + populator. `dyn_target_paths` + // is the authoritative set built from every consumer's + // `import.is_dynamic` resolved paths; `namespace_entries` + // alone is insufficient because it's empty when the + // target has no `export` statements. + is_dynamic_import_target: dyn_target_paths.contains(path), + // #5247: source-location tracking for the dynamic call-dispatch + // throw path. Gated by `--debug-symbols` so the default build is + // unchanged (no source read, no per-call emission). When on, read + // the module's original source so codegen can map a Call's byte + // offset to a 1-based line. + debug_locations: args.debug_symbols, + // #5247 / #7036: source consulted to turn a node's `byte_offset` + // into a debug frame or opt-report snippet. For a CommonJS + // module the offsets are in WRAPPED-source + // coordinates (perry parsed the injected-IIFE text), so we hand + // codegen the WRAPPED source — counting newlines up to a wrapped + // offset against the original would be off by the preamble byte + // length. `debug_source_line_offset` (below) then converts the + // wrapped line back to the original line. Non-wrapped modules + // read the original from disk. Text reports need this source; + // JSON reports only need the offset already carried by HIR. + module_source: if args.debug_symbols || opt_report_format == Some(OptReportFormat::Text) + { + match ctx.cjs_wrap_debug_sources.get(path) { + Some(w) => Some(w.wrapped_source.clone()), + None => std::fs::read_to_string(path).ok(), + } + } else { + None + }, + // #5247 (CJS-wrap coordinate skew): the number of newlines the + // injected wrapper prefix added before the original module body. + // Codegen subtracts this from the wrapped line number so the + // rendered location is in original-source coordinates. `0` for + // non-wrapped modules (and the entire default build). + debug_source_line_offset: if args.debug_symbols + || opt_report_format == Some(OptReportFormat::Text) + { + ctx.cjs_wrap_debug_sources + .get(path) + .map(|w| w.prefix_line_count) + .unwrap_or(0) + } else { + 0 + }, + }; + Ok(opts) + }; + // Retain one compact edge/count per class, never every module's options. + // Classless modules and context-free constructors need no import prepass. + let mut constructor_contracts = perry_codegen::ConstructorContracts::default(); + for (path, module) in &ctx.native_modules { + if module.classes.is_empty() { + continue; + } + let prefix = compute_module_prefix(&path.to_string_lossy(), &ctx.project_root); + if module + .classes + .iter() + .all(|class| perry_codegen::context_free_ctor_param_count(class).is_some()) + { + constructor_contracts.record(&prefix, module, &[]); + } else { + let opts = prepare_module(path, module, true).map_err(|error| anyhow!(error))?; + constructor_contracts.record(&prefix, module, &opts.imported_classes); + } + } + let constructor_contracts = constructor_contracts.resolve(); let compile_results: Vec> = module_pool.install(|| { - prepared_modules.into_par_iter().map(|(path, hir_module, opts)| { + ctx.native_modules.par_iter().map(|(path, hir_module)| { let _permit = module_limiter.acquire(module_codegen_is_exclusive(path, hir_module)); let _completion = ModuleCodegenCompletion { @@ -5508,6 +5415,12 @@ pub fn run_with_parse_cache( collected: Some(total_codegen_modules), ..Default::default() }); + let mut opts = prepare_module(path, hir_module, false)?; + constructor_contracts.apply( + &compute_module_prefix(&path.to_string_lossy(), &ctx.project_root), + hir_module, + &mut opts, + ); // V2.2 + #686 object cache lookup. The key hashes every // codegen-affecting field of `opts` together with this // module's post-transform HIR fingerprint and the perry From 4b3711c78e7687072e03235d889d6ccd6123ab7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Mon, 14 Sep 2026 16:36:56 +0200 Subject: [PATCH 08/11] fix(runtime): reload array descriptor owners after allocating probes --- crates/perry-runtime/src/array/named_props.rs | 1 + .../src/gc/tests/array_named_props.rs | 34 +++++++++- .../src/gc/tests/rooted_define_property.rs | 64 +++++++++++++++++++ .../src/object/array_object_ops.rs | 24 +++---- 4 files changed, 105 insertions(+), 18 deletions(-) diff --git a/crates/perry-runtime/src/array/named_props.rs b/crates/perry-runtime/src/array/named_props.rs index 8797b9ee2e..1e228c0478 100644 --- a/crates/perry-runtime/src/array/named_props.rs +++ b/crates/perry-runtime/src/array/named_props.rs @@ -117,6 +117,7 @@ impl InlineKeySet { /// the same way: a `regex-engine`-off build has no caller. #[cfg(feature = "regex-engine")] #[inline] + #[cfg(feature = "regex-engine")] const fn header_word(self) -> u64 { let n = self.keys().len() as u64; INT32_TAG | (self as u64) | (((1u64 << n) - 1) << 8) diff --git a/crates/perry-runtime/src/gc/tests/array_named_props.rs b/crates/perry-runtime/src/gc/tests/array_named_props.rs index 88a7364a86..08e829f226 100644 --- a/crates/perry-runtime/src/gc/tests/array_named_props.rs +++ b/crates/perry-runtime/src/gc/tests/array_named_props.rs @@ -1,6 +1,6 @@ //! #10166 (brief 4): an array's named properties live in a pairs array that //! its reserved front slot points at (`array/named_props.rs`). There is no -//! address-keyed table any more, so the death story is the ordinary one — a +//! address-keyed table for reserved arrays, so their death story is ordinary — a //! dead array's pairs die with it — and the value edge is a real child edge of //! the array: `gc/layout_slot_visit.rs` emits the reserved slot as a fixed //! child slot, and `store_pairs_pointer` is the one barriered store into it. @@ -76,7 +76,7 @@ fn test_array_named_property_value_survives_full_gc_through_its_live_owner() { } #[test] -fn test_array_named_dead_owner_cannot_leak_property_across_exact_eden_reuse() { +fn test_array_named_dead_owner_cannot_leak_property_across_eden_page_reuse() { let _guard = CopyingNurseryTestGuard::new(0); let _side_tables = ArraySideTableTestGuard::new(); register_array_side_table_scanners(); @@ -332,3 +332,33 @@ fn test_full_array_live_move_rekeys_owner_and_rewrites_object_value() { old_owner )); } + +#[test] +fn test_full_array_dead_owner_cannot_leak_property_across_exact_eden_reuse() { + let _guard = CopyingNurseryTestGuard::new(0); + let _side_tables = ArraySideTableTestGuard::new(); + register_array_side_table_scanners(); + crate::arena::arena_reset_all_blocks_to_zero(); + + let dead = unsafe { alloc_nursery_test_array() }; + let dead = unsafe { + set_array_named_property(dead, "inherited", f64::from_bits(crate::value::TAG_TRUE)) + }; + let dead_addr = dead as usize; + assert!(crate::array::test_full_array_named_property_owner_exists( + dead_addr + )); + let _ = gc_collect_minor(); + let replacement = unsafe { alloc_nursery_test_array() }; + assert_eq!( + replacement as usize, dead_addr, + "test premise: the Eden reset must reuse the exact fallback owner address" + ); + assert!(!crate::array::test_full_array_named_property_owner_exists( + dead_addr + )); + assert!( + unsafe { crate::array::array_named_property_get_by_name(replacement, "inherited") } + .is_none() + ); +} diff --git a/crates/perry-runtime/src/gc/tests/rooted_define_property.rs b/crates/perry-runtime/src/gc/tests/rooted_define_property.rs index a29f0363af..c0fadf48f1 100644 --- a/crates/perry-runtime/src/gc/tests/rooted_define_property.rs +++ b/crates/perry-runtime/src/gc/tests/rooted_define_property.rs @@ -251,3 +251,67 @@ fn desc_view_field_values_are_rooted() { assert_string_bytes(string_ptr_of(after_value), b"desc_view_payload"); } } + +extern "C" fn moving_writable_getter(_closure: *const crate::closure::ClosureHeader) -> f64 { + let trace = collect_minor_trace(GcTriggerKind::Direct); + GETTER_COPIED_OBJECTS.with(|c| c.set(c.get() + trace.copying_nursery.copied_objects)); + f64::from_bits(crate::value::TAG_TRUE) +} + +#[test] +fn array_named_property_attributes_follow_a_move_in_the_final_descriptor_probe() { + let _guard = CopyingNurseryTestGuard::new(0); + let _trigger_guard = GcTriggerThresholdTestGuard::suppress_automatic_triggers(); + register_handle_scanner(); + GETTER_COPIED_OBJECTS.with(|c| c.set(0)); + unsafe { + let scope = RuntimeHandleScope::new(); + let target = scope.root_raw_mut_ptr(crate::array::js_array_alloc(0)); + let key = scope.root_nanbox_f64(string_value("tag")); + let bag = scope.root_nanbox_f64(object_value(crate::object::js_object_alloc(0, 0))); + let inner = scope.root_nanbox_f64(object_value(crate::object::js_object_alloc(0, 0))); + let getter = crate::closure::js_closure_alloc(moving_writable_getter as *const u8, 0); + let get_key = crate::string::js_string_from_bytes(b"get".as_ptr(), 3); + crate::object::js_object_set_field_by_name( + addr_of(inner.get_nanbox_f64()) as *mut crate::object::ObjectHeader, + get_key, + f64::from_bits(ptr_bits(getter as usize)), + ); + crate::object::js_object_define_property( + bag.get_nanbox_f64(), + string_value("writable"), + inner.get_nanbox_f64(), + ); + let value_key = crate::string::js_string_from_bytes(b"value".as_ptr(), 5); + crate::object::js_object_set_field_by_name( + addr_of(bag.get_nanbox_f64()) as *mut crate::object::ObjectHeader, + value_key, + 42.0, + ); + let before = target.get_raw_mut_ptr::() as usize; + let applied = crate::object::define_array_property( + target.get_raw_mut_ptr::().cast(), + f64::from_bits(ptr_bits(before)), + string_ptr_of(key.get_nanbox_f64()), + Some("tag"), + bag.get_nanbox_f64(), + ); + assert_eq!(applied, Some(true)); + assert!(GETTER_COPIED_OBJECTS.with(|c| c.get()) > 0); + let live = target.get_raw_mut_ptr::(); + assert_ne!( + live as usize, before, + "the writable getter must move the receiver" + ); + assert_eq!( + crate::array::array_named_property_get_by_name(live, "tag"), + Some(42.0) + ); + let attrs = crate::object::descriptor_state::get_property_attrs(live as usize, "tag") + .expect("the attributes must be filed under the current array address"); + assert!(attrs.writable()); + assert!(!attrs.enumerable()); + assert!(!attrs.configurable()); + assert!(crate::object::descriptor_state::get_property_attrs(before, "tag").is_none()); + } +} diff --git a/crates/perry-runtime/src/object/array_object_ops.rs b/crates/perry-runtime/src/object/array_object_ops.rs index 3550e98460..961ed3c944 100644 --- a/crates/perry-runtime/src/object/array_object_ops.rs +++ b/crates/perry-runtime/src/object/array_object_ops.rs @@ -871,26 +871,18 @@ pub(crate) unsafe fn define_array_property( // Write the value: an explicit `value` wins; a NEW property with no value // defaults to `undefined`; a redefine that omits `value` keeps the current. - // The first named property on a full array grows it (`named_props.rs`), - // so the attributes below are keyed by the RETURNED live head — an entry - // recorded under the old address would sit on a forwarding stub that - // `transfer_descriptor_owner` already migrated away from. - let live = if has_value { - crate::array::array_named_property_set(arr, key_str, value) + // Setting a new property can allocate its pairs array and relocate the + // receiver. The descriptor-field reads below can collect again, so reload + // the rooted receiver only after every probe has finished. + if has_value { + crate::array::array_named_property_set(arr, key_str, value); } else if !exists { crate::array::array_named_property_set( arr, key_str, f64::from_bits(crate::value::TAG_UNDEFINED), - ) - } else { - arr - }; - let owner = if live.is_null() { - obj as usize - } else { - live as usize - }; + ); + } let writable = read_bool(b"writable").unwrap_or_else(|| cur_attrs.map(|a| a.writable()).unwrap_or(false)); @@ -899,7 +891,7 @@ pub(crate) unsafe fn define_array_property( let configurable = read_bool(b"configurable") .unwrap_or_else(|| cur_attrs.map(|a| a.configurable()).unwrap_or(false)); set_property_attrs( - owner, + current_arr() as usize, key_name.to_string(), PropertyAttrs::new(writable, enumerable, configurable), ); From a9ab14436f9b9a3952c19a341ee75ecbecd5c395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Mon, 14 Sep 2026 16:49:35 +0200 Subject: [PATCH 09/11] test(gc): scope array handle reads in the moving descriptor witness --- .../src/gc/tests/rooted_define_property.rs | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/crates/perry-runtime/src/gc/tests/rooted_define_property.rs b/crates/perry-runtime/src/gc/tests/rooted_define_property.rs index c0fadf48f1..7bdd253754 100644 --- a/crates/perry-runtime/src/gc/tests/rooted_define_property.rs +++ b/crates/perry-runtime/src/gc/tests/rooted_define_property.rs @@ -288,30 +288,35 @@ fn array_named_property_attributes_follow_a_move_in_the_final_descriptor_probe() value_key, 42.0, ); - let before = target.get_raw_mut_ptr::() as usize; - let applied = crate::object::define_array_property( - target.get_raw_mut_ptr::().cast(), - f64::from_bits(ptr_bits(before)), - string_ptr_of(key.get_nanbox_f64()), - Some("tag"), - bag.get_nanbox_f64(), - ); + // Keep only an observation address across the move; never dereference it. + let before = target.with_mut_ptr(|ptr: *mut crate::array::ArrayHeader| ptr as usize); + let applied = target.with_mut_ptr(|ptr: *mut crate::array::ArrayHeader| { + // This runtime entry roots its receiver before probing the descriptor. + crate::object::define_array_property( + ptr.cast(), + f64::from_bits(ptr_bits(ptr as usize)), + string_ptr_of(key.get_nanbox_f64()), + Some("tag"), + bag.get_nanbox_f64(), + ) + }); assert_eq!(applied, Some(true)); assert!(GETTER_COPIED_OBJECTS.with(|c| c.get()) > 0); - let live = target.get_raw_mut_ptr::(); - assert_ne!( - live as usize, before, - "the writable getter must move the receiver" - ); - assert_eq!( - crate::array::array_named_property_get_by_name(live, "tag"), - Some(42.0) - ); - let attrs = crate::object::descriptor_state::get_property_attrs(live as usize, "tag") - .expect("the attributes must be filed under the current array address"); - assert!(attrs.writable()); - assert!(!attrs.enumerable()); - assert!(!attrs.configurable()); + target.with_mut_ptr(|live: *mut crate::array::ArrayHeader| { + assert_ne!( + live as usize, before, + "the writable getter must move the receiver" + ); + assert_eq!( + crate::array::array_named_property_get_by_name(live, "tag"), + Some(42.0) + ); + let attrs = crate::object::descriptor_state::get_property_attrs(live as usize, "tag") + .expect("the attributes must be filed under the current array address"); + assert!(attrs.writable()); + assert!(!attrs.enumerable()); + assert!(!attrs.configurable()); + }); assert!(crate::object::descriptor_state::get_property_attrs(before, "tag").is_none()); } } From 2a8e318a8eec3d37a56631cd2c128666622610a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Mon, 14 Sep 2026 17:08:38 +0200 Subject: [PATCH 10/11] fix(runtime): preserve array descriptor owner identity across growth aliases --- .../perry-runtime/src/object/array_object_ops.rs | 7 ++++++- .../test_gap_array_named_descriptor_forwarding.ts | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test-files/test_gap_array_named_descriptor_forwarding.ts diff --git a/crates/perry-runtime/src/object/array_object_ops.rs b/crates/perry-runtime/src/object/array_object_ops.rs index 961ed3c944..98d7e4fa95 100644 --- a/crates/perry-runtime/src/object/array_object_ops.rs +++ b/crates/perry-runtime/src/object/array_object_ops.rs @@ -890,8 +890,13 @@ pub(crate) unsafe fn define_array_property( .unwrap_or_else(|| cur_attrs.map(|a| a.enumerable()).unwrap_or(false)); let configurable = read_bool(b"configurable") .unwrap_or_else(|| cur_attrs.map(|a| a.configurable()).unwrap_or(false)); + // Named descriptor readers use the caller's owner identity, which can be + // a pre-growth forwarding alias. Preserve that identity while reloading + // the handle after every allocating probe: GC moves update the handle, + // whereas resolving array growth here alone would strand the attributes + // from getOwnPropertyDescriptor's existing lookup. set_property_attrs( - current_arr() as usize, + current_obj() as usize, key_name.to_string(), PropertyAttrs::new(writable, enumerable, configurable), ); diff --git a/test-files/test_gap_array_named_descriptor_forwarding.ts b/test-files/test_gap_array_named_descriptor_forwarding.ts new file mode 100644 index 0000000000..3318b63370 --- /dev/null +++ b/test-files/test_gap_array_named_descriptor_forwarding.ts @@ -0,0 +1,15 @@ +// A literal's variable can retain a forwarding alias after push grows it. +// Descriptor writes and reflection must agree on that receiver's owner key. +const values: any = [1, 2]; +values.tag = 5; +values.push(3); +Object.defineProperty(values, "fixed", { + value: 11, writable: false, enumerable: true, configurable: false, +}); +const descriptor: any = Object.getOwnPropertyDescriptor(values, "fixed"); +if (!descriptor || descriptor.value !== 11 || descriptor.writable !== false || + descriptor.enumerable !== true || descriptor.configurable !== false) { + throw new Error("named descriptor attributes lost through a growth alias"); +} +console.log("forwarded-named-descriptor", values.fixed, descriptor.writable, + descriptor.enumerable, descriptor.configurable, values.length, values.tag); From 84fa0c4a363d42beb2a05df9346ed7f1ca977e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Mon, 14 Sep 2026 17:33:06 +0200 Subject: [PATCH 11/11] chore: release merge train 192 as v0.5.1570 --- CLAUDE.md | 2 +- Cargo.lock | 162 +++++++++--------- Cargo.toml | 2 +- crates/perry-runtime/src/array/named_props.rs | 1 - 4 files changed, 83 insertions(+), 84 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 488b0be1f6..379b015f73 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Perry is a native TypeScript compiler written in Rust that compiles TypeScript source code directly to native executables. It uses SWC for TypeScript parsing and LLVM for code generation. -**Current Version:** 0.5.1569 +**Current Version:** 0.5.1570 ## TypeScript Parity Status diff --git a/Cargo.lock b/Cargo.lock index d7ddf5f312..d2a41f5a52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5583,7 +5583,7 @@ checksum = "1542e48011813fbdf3c075da4a4ed53ee93c816eef62e36eb5064a6fd2be10a5" [[package]] name = "perry" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "base64 0.22.1", @@ -5647,7 +5647,7 @@ dependencies = [ [[package]] name = "perry-api-manifest" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-dispatch", "serde", @@ -5655,7 +5655,7 @@ dependencies = [ [[package]] name = "perry-audio-miniaudio" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "cc", "libc", @@ -5664,7 +5664,7 @@ dependencies = [ [[package]] name = "perry-codegen" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "aho-corasick", "anyhow", @@ -5681,7 +5681,7 @@ dependencies = [ [[package]] name = "perry-codegen-arkts" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "perry-hir", @@ -5689,7 +5689,7 @@ dependencies = [ [[package]] name = "perry-codegen-glance" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "perry-hir", @@ -5697,7 +5697,7 @@ dependencies = [ [[package]] name = "perry-codegen-js" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "perry-dispatch", @@ -5706,7 +5706,7 @@ dependencies = [ [[package]] name = "perry-codegen-swiftui" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "perry-hir", @@ -5714,7 +5714,7 @@ dependencies = [ [[package]] name = "perry-codegen-wasm" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "base64 0.22.1", @@ -5726,7 +5726,7 @@ dependencies = [ [[package]] name = "perry-codegen-wear-tiles" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "perry-hir", @@ -5734,7 +5734,7 @@ dependencies = [ [[package]] name = "perry-container-compose" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "async-trait", "clap", @@ -5758,14 +5758,14 @@ dependencies = [ [[package]] name = "perry-container-e2e" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", ] [[package]] name = "perry-diagnostics" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "serde", "serde_json", @@ -5773,7 +5773,7 @@ dependencies = [ [[package]] name = "perry-dispatch" -version = "0.5.1569" +version = "0.5.1570" [[package]] name = "perry-doc-fixture-my-bindings" @@ -5784,7 +5784,7 @@ dependencies = [ [[package]] name = "perry-doc-tests" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "clap", @@ -5799,7 +5799,7 @@ dependencies = [ [[package]] name = "perry-ext-ads" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "block2", "objc2", @@ -5809,7 +5809,7 @@ dependencies = [ [[package]] name = "perry-ext-argon2" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "argon2", "perry-ffi", @@ -5818,7 +5818,7 @@ dependencies = [ [[package]] name = "perry-ext-axios" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "reqwest", @@ -5827,7 +5827,7 @@ dependencies = [ [[package]] name = "perry-ext-bcrypt" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "bcrypt", "perry-ffi", @@ -5835,7 +5835,7 @@ dependencies = [ [[package]] name = "perry-ext-better-sqlite3" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "rusqlite", @@ -5843,7 +5843,7 @@ dependencies = [ [[package]] name = "perry-ext-cheerio" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "scraper", @@ -5851,7 +5851,7 @@ dependencies = [ [[package]] name = "perry-ext-commander" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "perry-runtime", @@ -5859,7 +5859,7 @@ dependencies = [ [[package]] name = "perry-ext-cron" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "chrono", "cron", @@ -5869,7 +5869,7 @@ dependencies = [ [[package]] name = "perry-ext-dayjs" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "chrono", "perry-ffi", @@ -5877,7 +5877,7 @@ dependencies = [ [[package]] name = "perry-ext-decimal" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "rust_decimal", @@ -5885,7 +5885,7 @@ dependencies = [ [[package]] name = "perry-ext-dotenv" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "serde_json", @@ -5893,7 +5893,7 @@ dependencies = [ [[package]] name = "perry-ext-ethers" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "rand 0.10.2", @@ -5901,7 +5901,7 @@ dependencies = [ [[package]] name = "perry-ext-events" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "perry-runtime", @@ -5909,14 +5909,14 @@ dependencies = [ [[package]] name = "perry-ext-exponential-backoff" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", ] [[package]] name = "perry-ext-fastify" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "bytes", "http-body-util", @@ -5933,7 +5933,7 @@ dependencies = [ [[package]] name = "perry-ext-fetch" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "bytes", "lazy_static", @@ -5946,7 +5946,7 @@ dependencies = [ [[package]] name = "perry-ext-http" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "bytes", @@ -5978,7 +5978,7 @@ dependencies = [ [[package]] name = "perry-ext-ioredis" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "lazy_static", "perry-ffi", @@ -5988,7 +5988,7 @@ dependencies = [ [[package]] name = "perry-ext-jsonwebtoken" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "jsonwebtoken", @@ -5999,7 +5999,7 @@ dependencies = [ [[package]] name = "perry-ext-lru-cache" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "lru", "perry-ffi", @@ -6008,7 +6008,7 @@ dependencies = [ [[package]] name = "perry-ext-moment" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "chrono", "perry-ffi", @@ -6016,7 +6016,7 @@ dependencies = [ [[package]] name = "perry-ext-mongodb" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "bson", "futures-util", @@ -6028,7 +6028,7 @@ dependencies = [ [[package]] name = "perry-ext-mysql2" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "chrono", "perry-ffi", @@ -6040,7 +6040,7 @@ dependencies = [ [[package]] name = "perry-ext-nanoid" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "nanoid", "perry-ffi", @@ -6049,7 +6049,7 @@ dependencies = [ [[package]] name = "perry-ext-net" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "bytes", "perry-ffi", @@ -6064,7 +6064,7 @@ dependencies = [ [[package]] name = "perry-ext-node-forge" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "const-oid 0.10.2", "der 0.8.1", @@ -6083,7 +6083,7 @@ dependencies = [ [[package]] name = "perry-ext-nodemailer" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "lettre", "perry-ffi", @@ -6093,7 +6093,7 @@ dependencies = [ [[package]] name = "perry-ext-parcel-watcher" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "notify", "perry-ffi", @@ -6105,7 +6105,7 @@ dependencies = [ [[package]] name = "perry-ext-pdf" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "printpdf", @@ -6113,7 +6113,7 @@ dependencies = [ [[package]] name = "perry-ext-pg" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "sqlx", @@ -6122,7 +6122,7 @@ dependencies = [ [[package]] name = "perry-ext-qs" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "perry-runtime", @@ -6131,7 +6131,7 @@ dependencies = [ [[package]] name = "perry-ext-ratelimit" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "governor", "perry-ffi", @@ -6139,7 +6139,7 @@ dependencies = [ [[package]] name = "perry-ext-sharp" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "fast_image_resize", "image", @@ -6150,7 +6150,7 @@ dependencies = [ [[package]] name = "perry-ext-streams" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "lazy_static", "perry-ffi", @@ -6159,7 +6159,7 @@ dependencies = [ [[package]] name = "perry-ext-typescript" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "perry-ffi", @@ -6179,7 +6179,7 @@ dependencies = [ [[package]] name = "perry-ext-undici" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "perry-runtime", @@ -6188,7 +6188,7 @@ dependencies = [ [[package]] name = "perry-ext-uuid" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "uuid", @@ -6196,7 +6196,7 @@ dependencies = [ [[package]] name = "perry-ext-validator" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-ffi", "perry-validation", @@ -6205,7 +6205,7 @@ dependencies = [ [[package]] name = "perry-ext-ws" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "futures-util", "lazy_static", @@ -6218,7 +6218,7 @@ dependencies = [ [[package]] name = "perry-ext-zlib" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "brotli", "flate2", @@ -6228,7 +6228,7 @@ dependencies = [ [[package]] name = "perry-ffi" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "dashmap 6.2.1", "once_cell", @@ -6238,7 +6238,7 @@ dependencies = [ [[package]] name = "perry-hir" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "perry-api-manifest", @@ -6258,11 +6258,11 @@ dependencies = [ [[package]] name = "perry-native-registration" -version = "0.5.1569" +version = "0.5.1570" [[package]] name = "perry-parser" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "perry-diagnostics", @@ -6275,7 +6275,7 @@ dependencies = [ [[package]] name = "perry-perex" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perex", "regex", @@ -6283,7 +6283,7 @@ dependencies = [ [[package]] name = "perry-runtime" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "ahash", "base64 0.22.1", @@ -6341,14 +6341,14 @@ dependencies = [ [[package]] name = "perry-runtime-static" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-runtime", ] [[package]] name = "perry-stdlib" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "aes 0.8.4", "aes 0.9.1", @@ -6437,21 +6437,21 @@ dependencies = [ [[package]] name = "perry-stdlib-static" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-stdlib", ] [[package]] name = "perry-transform" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "perry-hir", ] [[package]] name = "perry-ui" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "dirs", "perry-ffi", @@ -6461,7 +6461,7 @@ dependencies = [ [[package]] name = "perry-ui-android" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "jni", @@ -6476,7 +6476,7 @@ dependencies = [ [[package]] name = "perry-ui-geisterhand" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "rand 0.10.2", "serde", @@ -6486,7 +6486,7 @@ dependencies = [ [[package]] name = "perry-ui-gtk4" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "cairo-rs 0.22.9", @@ -6509,7 +6509,7 @@ dependencies = [ [[package]] name = "perry-ui-ios" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "block2", @@ -6526,7 +6526,7 @@ dependencies = [ [[package]] name = "perry-ui-macos" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "block2", @@ -6543,7 +6543,7 @@ dependencies = [ [[package]] name = "perry-ui-model" -version = "0.5.1569" +version = "0.5.1570" [[package]] name = "perry-ui-test" @@ -6554,11 +6554,11 @@ dependencies = [ [[package]] name = "perry-ui-testkit" -version = "0.5.1569" +version = "0.5.1570" [[package]] name = "perry-ui-tvos" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "block2", @@ -6575,7 +6575,7 @@ dependencies = [ [[package]] name = "perry-ui-visionos" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "block2", @@ -6592,7 +6592,7 @@ dependencies = [ [[package]] name = "perry-ui-watchos" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "block2", "libc", @@ -6606,7 +6606,7 @@ dependencies = [ [[package]] name = "perry-ui-windows" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "libc", @@ -6625,7 +6625,7 @@ dependencies = [ [[package]] name = "perry-ui-windows-winui" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "base64 0.22.1", "libc", @@ -6638,7 +6638,7 @@ dependencies = [ [[package]] name = "perry-updater" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "anyhow", "base64 0.22.1", @@ -6653,7 +6653,7 @@ dependencies = [ [[package]] name = "perry-validation" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "idna", "regex", @@ -6663,7 +6663,7 @@ dependencies = [ [[package]] name = "perry-wasm-host" -version = "0.5.1569" +version = "0.5.1570" dependencies = [ "wasmi", ] diff --git a/Cargo.toml b/Cargo.toml index 0fc54e3c34..8d2a6ab121 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -338,7 +338,7 @@ codegen-units = 1 codegen-units = 1 [workspace.package] -version = "0.5.1569" +version = "0.5.1570" edition = "2021" license = "MIT" repository = "https://github.com/PerryTS/perry" diff --git a/crates/perry-runtime/src/array/named_props.rs b/crates/perry-runtime/src/array/named_props.rs index 1e228c0478..8797b9ee2e 100644 --- a/crates/perry-runtime/src/array/named_props.rs +++ b/crates/perry-runtime/src/array/named_props.rs @@ -117,7 +117,6 @@ impl InlineKeySet { /// the same way: a `regex-engine`-off build has no caller. #[cfg(feature = "regex-engine")] #[inline] - #[cfg(feature = "regex-engine")] const fn header_word(self) -> u64 { let n = self.keys().len() as u64; INT32_TAG | (self as u64) | (((1u64 << n) - 1) << 8)