diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 1e2123ec49b..f420a7e664d 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -593,6 +593,7 @@ "addr2line_0.25.1": "{\"dependencies\":[{\"name\":\"alloc\",\"optional\":true,\"package\":\"rustc-std-workspace-alloc\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"backtrace\",\"req\":\"^0.3.13\"},{\"features\":[\"wrap_help\"],\"name\":\"clap\",\"optional\":true,\"req\":\"^4.3.21\"},{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"cpp_demangle\",\"optional\":true,\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7.0\"},{\"default_features\":false,\"name\":\"fallible-iterator\",\"optional\":true,\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"findshlibs\",\"req\":\"^0.10\"},{\"default_features\":false,\"features\":[\"read\"],\"name\":\"gimli\",\"req\":\"^0.32.0\"},{\"kind\":\"dev\",\"name\":\"libtest-mimic\",\"req\":\"^0.8.1\"},{\"name\":\"memmap2\",\"optional\":true,\"req\":\"^0.9.4\"},{\"default_features\":false,\"features\":[\"read\",\"compression\"],\"name\":\"object\",\"optional\":true,\"req\":\"^0.37.0\"},{\"name\":\"rustc-demangle\",\"optional\":true,\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"smallvec\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"typed-arena\",\"optional\":true,\"req\":\"^2\"}],\"features\":{\"all\":[\"bin\",\"wasm\"],\"bin\":[\"loader\",\"rustc-demangle\",\"cpp_demangle\",\"fallible-iterator\",\"smallvec\",\"dep:clap\"],\"cargo-all\":[],\"default\":[\"rustc-demangle\",\"cpp_demangle\",\"loader\",\"fallible-iterator\",\"smallvec\"],\"loader\":[\"std\",\"dep:object\",\"dep:memmap2\",\"dep:typed-arena\"],\"rustc-dep-of-std\":[\"core\",\"alloc\",\"gimli/rustc-dep-of-std\"],\"std\":[\"gimli/std\"],\"wasm\":[\"object/wasm\"]}}", "adler2_2.0.1": "{\"dependencies\":[{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"}],\"features\":{\"default\":[\"std\"],\"rustc-dep-of-std\":[\"core\"],\"std\":[]}}", "aead_0.5.2": "{\"dependencies\":[{\"default_features\":false,\"name\":\"arrayvec\",\"optional\":true,\"req\":\"^0.7\"},{\"name\":\"blobby\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"bytes\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"crypto-common\",\"req\":\"^0.1.4\"},{\"default_features\":false,\"name\":\"generic-array\",\"req\":\"^0.14\"},{\"default_features\":false,\"name\":\"heapless\",\"optional\":true,\"req\":\"^0.7\"}],\"features\":{\"alloc\":[],\"default\":[\"rand_core\"],\"dev\":[\"blobby\"],\"getrandom\":[\"crypto-common/getrandom\",\"rand_core\"],\"rand_core\":[\"crypto-common/rand_core\"],\"std\":[\"alloc\",\"crypto-common/std\"],\"stream\":[]}}", + "aes-gcm_0.10.3": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aead\",\"req\":\"^0.5\"},{\"default_features\":false,\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"aead\",\"req\":\"^0.5\"},{\"name\":\"aes\",\"optional\":true,\"req\":\"^0.8\"},{\"name\":\"cipher\",\"req\":\"^0.4\"},{\"name\":\"ctr\",\"req\":\"^0.9\"},{\"default_features\":false,\"name\":\"ghash\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"alloc\":[\"aead/alloc\"],\"arrayvec\":[\"aead/arrayvec\"],\"default\":[\"aes\",\"alloc\",\"getrandom\"],\"getrandom\":[\"aead/getrandom\",\"rand_core\"],\"heapless\":[\"aead/heapless\"],\"rand_core\":[\"aead/rand_core\"],\"std\":[\"aead/std\",\"alloc\"],\"stream\":[\"aead/stream\"]}}", "aes_0.8.4": "{\"dependencies\":[{\"name\":\"cfg-if\",\"req\":\"^1\"},{\"name\":\"cipher\",\"req\":\"^0.4.2\"},{\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"cipher\",\"req\":\"^0.4.2\"},{\"name\":\"cpufeatures\",\"req\":\"^0.2\",\"target\":\"cfg(any(target_arch = \\\"aarch64\\\", target_arch = \\\"x86_64\\\", target_arch = \\\"x86\\\"))\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"aarch64\"],\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1.5.6\",\"target\":\"cfg(all(aes_armv8, target_arch = \\\"aarch64\\\"))\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1.6.0\",\"target\":\"cfg(not(all(aes_armv8, target_arch = \\\"aarch64\\\")))\"}],\"features\":{\"hazmat\":[]}}", "age-core_0.11.0": "{\"dependencies\":[{\"name\":\"base64\",\"req\":\"^0.21\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"chacha20poly1305\",\"req\":\"^0.10\"},{\"name\":\"cookie-factory\",\"req\":\"^0.3.1\"},{\"name\":\"hkdf\",\"req\":\"^0.12\"},{\"name\":\"io_tee\",\"req\":\"^0.1.1\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"nom\",\"req\":\"^7\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"secrecy\",\"req\":\"^0.10\"},{\"name\":\"sha2\",\"req\":\"^0.10\"},{\"name\":\"tempfile\",\"optional\":true,\"req\":\"^3.2.0\"}],\"features\":{\"plugin\":[\"tempfile\"],\"unstable\":[]}}", "age_0.11.2": "{\"dependencies\":[{\"name\":\"aes\",\"optional\":true,\"req\":\"^0.8\"},{\"name\":\"aes-gcm\",\"optional\":true,\"req\":\"^0.10\"},{\"name\":\"age-core\",\"req\":\"^0.11.0\"},{\"name\":\"base64\",\"req\":\"^0.21\"},{\"name\":\"bcrypt-pbkdf\",\"optional\":true,\"req\":\"^0.10\"},{\"name\":\"bech32\",\"req\":\"^0.9\"},{\"name\":\"cbc\",\"optional\":true,\"req\":\"^0.1\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"chacha20poly1305\",\"req\":\"^0.10\"},{\"features\":[\"alloc\"],\"name\":\"cipher\",\"optional\":true,\"req\":\"^0.4.3\"},{\"default_features\":false,\"name\":\"console\",\"optional\":true,\"req\":\"^0.15\"},{\"name\":\"cookie-factory\",\"req\":\"^0.3.1\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"criterion-cycles-per-byte\",\"req\":\"^0.6\",\"target\":\"cfg(any(target_arch = \\\"x86\\\", target_arch = \\\"x86_64\\\"))\"},{\"name\":\"ctr\",\"optional\":true,\"req\":\"^0.9\"},{\"name\":\"curve25519-dalek\",\"optional\":true,\"req\":\"^4\"},{\"name\":\"futures\",\"optional\":true,\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"futures-test\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4\"},{\"name\":\"hmac\",\"req\":\"^0.12\"},{\"features\":[\"fluent-system\"],\"name\":\"i18n-embed\",\"req\":\"^0.15\"},{\"features\":[\"fluent-system\",\"desktop-requester\"],\"kind\":\"dev\",\"name\":\"i18n-embed\",\"req\":\"^0.15\"},{\"name\":\"i18n-embed-fl\",\"req\":\"^0.9\"},{\"name\":\"is-terminal\",\"optional\":true,\"req\":\"^0.4\"},{\"name\":\"lazy_static\",\"req\":\"^1\"},{\"name\":\"memchr\",\"optional\":true,\"req\":\"^2.5\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"nom\",\"req\":\"^7\"},{\"name\":\"num-traits\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"pin-project\",\"req\":\"^1\"},{\"name\":\"pinentry\",\"optional\":true,\"req\":\"^0.6\"},{\"features\":[\"criterion\",\"flamegraph\"],\"kind\":\"dev\",\"name\":\"pprof\",\"req\":\"^0.13\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"rpassword\",\"optional\":true,\"req\":\"^7\"},{\"default_features\":false,\"name\":\"rsa\",\"optional\":true,\"req\":\"^0.9\"},{\"name\":\"rust-embed\",\"req\":\"^8\"},{\"default_features\":false,\"name\":\"scrypt\",\"req\":\"^0.11\"},{\"name\":\"sha2\",\"req\":\"^0.10\"},{\"name\":\"subtle\",\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"test-case\",\"req\":\"^3\"},{\"features\":[\"macros\",\"rt-multi-thread\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"Window\",\"Performance\"],\"name\":\"web-sys\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"which\",\"optional\":true,\"req\":\"^4\",\"target\":\"cfg(any(unix, windows))\"},{\"name\":\"wsl\",\"optional\":true,\"req\":\"^0.1\",\"target\":\"cfg(any(unix, windows))\"},{\"features\":[\"static_secrets\"],\"name\":\"x25519-dalek\",\"req\":\"^2\"},{\"name\":\"zeroize\",\"req\":\"^1\"}],\"features\":{\"armor\":[],\"async\":[\"futures\",\"memchr\"],\"cli-common\":[\"console\",\"is-terminal\",\"pinentry\",\"rpassword\"],\"default\":[],\"plugin\":[\"age-core/plugin\",\"which\",\"wsl\"],\"ssh\":[\"aes\",\"aes-gcm\",\"bcrypt-pbkdf\",\"cbc\",\"cipher\",\"ctr\",\"curve25519-dalek\",\"num-traits\",\"rsa\"],\"unstable\":[\"age-core/unstable\"]}}", @@ -620,8 +621,10 @@ "arrayvec_0.7.6": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.4\"},{\"default_features\":false,\"name\":\"borsh\",\"optional\":true,\"req\":\"^1.2.0\"},{\"kind\":\"dev\",\"name\":\"matches\",\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_test\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1.4\"}],\"features\":{\"default\":[\"std\"],\"std\":[]}}", "ascii-canvas_3.0.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"diff\",\"req\":\"^0.1\"},{\"name\":\"term\",\"req\":\"^0.7\"}],\"features\":{}}", "ascii_1.1.0": "{\"dependencies\":[{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.25\"},{\"name\":\"serde_test\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"std\":[\"alloc\"]}}", + "asn1-rs-derive_0.5.1": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2.0\"},{\"name\":\"synstructure\",\"req\":\"^0.13\"}],\"features\":{}}", "asn1-rs-derive_0.6.0": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2.0\"},{\"name\":\"synstructure\",\"req\":\"^0.13\"}],\"features\":{}}", "asn1-rs-impl_0.2.0": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"name\":\"syn\",\"req\":\"^2.0\"}],\"features\":{}}", + "asn1-rs_0.6.2": "{\"dependencies\":[{\"name\":\"asn1-rs-derive\",\"req\":\"^0.5\"},{\"name\":\"asn1-rs-impl\",\"req\":\"^0.2\"},{\"name\":\"bitvec\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"colored\",\"optional\":true,\"req\":\"^2.0\"},{\"kind\":\"dev\",\"name\":\"colored\",\"req\":\"^2.0\"},{\"name\":\"cookie-factory\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"displaydoc\",\"req\":\"^0.2.2\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"nom\",\"req\":\"^7.0\"},{\"name\":\"num-bigint\",\"optional\":true,\"req\":\"^0.4\"},{\"name\":\"num-traits\",\"req\":\"^0.2.14\"},{\"kind\":\"dev\",\"name\":\"pem\",\"req\":\"^3.0\"},{\"name\":\"rusticata-macros\",\"req\":\"^4.0\"},{\"name\":\"thiserror\",\"req\":\"^1.0.25\"},{\"features\":[\"macros\",\"parsing\",\"formatting\"],\"name\":\"time\",\"optional\":true,\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0\"}],\"features\":{\"bigint\":[\"num-bigint\"],\"bits\":[\"bitvec\"],\"datetime\":[\"time\"],\"debug\":[\"colored\"],\"default\":[\"std\"],\"serialize\":[\"cookie-factory\"],\"std\":[],\"trace\":[\"debug\"]}}", "asn1-rs_0.7.1": "{\"dependencies\":[{\"name\":\"asn1-rs-derive\",\"req\":\"^0.6\"},{\"name\":\"asn1-rs-impl\",\"req\":\"^0.2\"},{\"name\":\"bitvec\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"colored\",\"optional\":true,\"req\":\"^3.0\"},{\"kind\":\"dev\",\"name\":\"colored\",\"req\":\"^3.0\"},{\"name\":\"cookie-factory\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"displaydoc\",\"req\":\"^0.2.2\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"nom\",\"req\":\"^7.0\"},{\"name\":\"num-bigint\",\"optional\":true,\"req\":\"^0.4\"},{\"name\":\"num-traits\",\"req\":\"^0.2.14\"},{\"kind\":\"dev\",\"name\":\"pem\",\"req\":\"^3.0\"},{\"name\":\"rusticata-macros\",\"req\":\"^4.0\"},{\"name\":\"thiserror\",\"req\":\"^2.0.0\"},{\"features\":[\"macros\",\"parsing\",\"formatting\"],\"name\":\"time\",\"optional\":true,\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0\"}],\"features\":{\"bigint\":[\"num-bigint\"],\"bits\":[\"bitvec\"],\"datetime\":[\"time\"],\"debug\":[\"std\",\"colored\"],\"default\":[\"std\"],\"serialize\":[\"cookie-factory\"],\"std\":[],\"trace\":[\"debug\"]}}", "assert-json-diff_2.0.2": "{\"dependencies\":[{\"name\":\"serde\",\"req\":\"^1\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1\"},{\"name\":\"serde_json\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"version-sync\",\"req\":\"^0.8\"}],\"features\":{}}", "assert_cmd_2.1.2": "{\"dependencies\":[{\"name\":\"anstream\",\"optional\":true,\"req\":\"^0.6.7\"},{\"name\":\"anstyle\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"automod\",\"req\":\"^1.0.14\"},{\"name\":\"bstr\",\"req\":\"^1.0.1\"},{\"kind\":\"dev\",\"name\":\"escargot\",\"req\":\"^0.5\"},{\"name\":\"libc\",\"req\":\"^0.2.137\",\"target\":\"cfg(any())\"},{\"default_features\":false,\"features\":[\"diff\"],\"name\":\"predicates\",\"req\":\"^3.0.1\"},{\"name\":\"predicates-core\",\"req\":\"^1.0.6\"},{\"name\":\"predicates-tree\",\"req\":\"^1.0.1\"},{\"name\":\"wait-timeout\",\"req\":\"^0.2.0\"}],\"features\":{\"color\":[\"dep:anstream\",\"predicates/color\"],\"color-auto\":[\"color\"]}}", @@ -648,6 +651,7 @@ "axum-core_0.5.6": "{\"dependencies\":[{\"name\":\"bytes\",\"req\":\"^1.2\"},{\"name\":\"futures-core\",\"req\":\"^0.3\"},{\"name\":\"http\",\"req\":\"^1.0.0\"},{\"name\":\"http-body\",\"req\":\"^1.0.0\"},{\"name\":\"http-body-util\",\"req\":\"^0.1.0\"},{\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^1.0.0\"},{\"name\":\"mime\",\"req\":\"^0.3.16\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.7\"},{\"name\":\"sync_wrapper\",\"req\":\"^1.0.0\"},{\"features\":[\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.25.0\"},{\"features\":[\"limit\"],\"name\":\"tower-http\",\"optional\":true,\"req\":\"^0.6.0\"},{\"features\":[\"limit\"],\"kind\":\"dev\",\"name\":\"tower-http\",\"req\":\"^0.6.0\"},{\"name\":\"tower-layer\",\"req\":\"^0.3\"},{\"name\":\"tower-service\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.37\"}],\"features\":{\"__private_docs\":[\"dep:tower-http\"],\"tracing\":[\"dep:tracing\"]}}", "axum_0.8.8": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"anyhow\",\"req\":\"^1.0\"},{\"name\":\"axum-core\",\"req\":\"^0.5.5\"},{\"name\":\"axum-macros\",\"optional\":true,\"req\":\"^0.5.0\"},{\"name\":\"base64\",\"optional\":true,\"req\":\"^0.22.1\"},{\"name\":\"bytes\",\"req\":\"^1.0\"},{\"name\":\"form_urlencoded\",\"optional\":true,\"req\":\"^1.1.0\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"futures-util\",\"req\":\"^0.3\"},{\"name\":\"http\",\"req\":\"^1.0.0\"},{\"name\":\"http-body\",\"req\":\"^1.0.0\"},{\"name\":\"http-body-util\",\"req\":\"^0.1.0\"},{\"name\":\"hyper\",\"optional\":true,\"req\":\"^1.1.0\"},{\"features\":[\"client\"],\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^1.1.0\"},{\"features\":[\"tokio\",\"server\",\"service\"],\"name\":\"hyper-util\",\"optional\":true,\"req\":\"^0.1.3\"},{\"name\":\"itoa\",\"req\":\"^1.0.5\"},{\"name\":\"matchit\",\"req\":\"=0.8.4\"},{\"name\":\"memchr\",\"req\":\"^2.4.1\"},{\"name\":\"mime\",\"req\":\"^0.3.16\"},{\"name\":\"multer\",\"optional\":true,\"req\":\"^3.0.0\"},{\"name\":\"percent-encoding\",\"req\":\"^2.1\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.7\"},{\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"quickcheck_macros\",\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"json\",\"stream\",\"multipart\"],\"name\":\"reqwest\",\"optional\":true,\"req\":\"^0.12\"},{\"default_features\":false,\"features\":[\"json\",\"stream\",\"multipart\"],\"kind\":\"dev\",\"name\":\"reqwest\",\"req\":\"^0.12\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.211\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.221\"},{\"name\":\"serde_core\",\"req\":\"^1.0.221\"},{\"features\":[\"raw_value\"],\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1.0\"},{\"features\":[\"raw_value\"],\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"serde_path_to_error\",\"optional\":true,\"req\":\"^0.1.8\"},{\"name\":\"serde_urlencoded\",\"optional\":true,\"req\":\"^0.7\"},{\"name\":\"sha1\",\"optional\":true,\"req\":\"^0.10\"},{\"name\":\"sync_wrapper\",\"req\":\"^1.0.0\"},{\"features\":[\"serde-human-readable\"],\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3\"},{\"features\":[\"time\"],\"name\":\"tokio\",\"optional\":true,\"package\":\"tokio\",\"req\":\"^1.44\"},{\"features\":[\"macros\",\"rt\",\"rt-multi-thread\",\"net\",\"test-util\"],\"kind\":\"dev\",\"name\":\"tokio\",\"package\":\"tokio\",\"req\":\"^1.44.2\"},{\"kind\":\"dev\",\"name\":\"tokio-stream\",\"req\":\"^0.1\"},{\"name\":\"tokio-tungstenite\",\"optional\":true,\"req\":\"^0.28.0\"},{\"kind\":\"dev\",\"name\":\"tokio-tungstenite\",\"req\":\"^0.28.0\"},{\"default_features\":false,\"features\":[\"util\"],\"name\":\"tower\",\"req\":\"^0.5.2\"},{\"features\":[\"util\",\"timeout\",\"limit\",\"load-shed\",\"steer\",\"filter\"],\"kind\":\"dev\",\"name\":\"tower\",\"package\":\"tower\",\"req\":\"^0.5.2\"},{\"features\":[\"add-extension\",\"auth\",\"catch-panic\",\"compression-br\",\"compression-deflate\",\"compression-gzip\",\"cors\",\"decompression-br\",\"decompression-deflate\",\"decompression-gzip\",\"follow-redirect\",\"fs\",\"limit\",\"map-request-body\",\"map-response-body\",\"metrics\",\"normalize-path\",\"propagate-header\",\"redirect\",\"request-id\",\"sensitive-headers\",\"set-header\",\"set-status\",\"timeout\",\"trace\",\"util\",\"validate-request\"],\"name\":\"tower-http\",\"optional\":true,\"req\":\"^0.6.0\"},{\"features\":[\"add-extension\",\"auth\",\"catch-panic\",\"compression-br\",\"compression-deflate\",\"compression-gzip\",\"cors\",\"decompression-br\",\"decompression-deflate\",\"decompression-gzip\",\"follow-redirect\",\"fs\",\"limit\",\"map-request-body\",\"map-response-body\",\"metrics\",\"normalize-path\",\"propagate-header\",\"redirect\",\"request-id\",\"sensitive-headers\",\"set-header\",\"set-status\",\"timeout\",\"trace\",\"util\",\"validate-request\"],\"kind\":\"dev\",\"name\":\"tower-http\",\"req\":\"^0.6.0\"},{\"name\":\"tower-layer\",\"req\":\"^0.3.2\"},{\"name\":\"tower-service\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"tracing\",\"req\":\"^0.1\"},{\"features\":[\"json\"],\"kind\":\"dev\",\"name\":\"tracing-subscriber\",\"req\":\"^0.3\"},{\"features\":[\"serde\",\"v4\"],\"kind\":\"dev\",\"name\":\"uuid\",\"req\":\"^1.0\"}],\"features\":{\"__private\":[\"tokio\",\"http1\",\"dep:reqwest\"],\"__private_docs\":[\"axum-core/__private_docs\",\"tower/full\",\"dep:serde\",\"dep:tower-http\"],\"default\":[\"form\",\"http1\",\"json\",\"matched-path\",\"original-uri\",\"query\",\"tokio\",\"tower-log\",\"tracing\"],\"form\":[\"dep:form_urlencoded\",\"dep:serde_urlencoded\",\"dep:serde_path_to_error\"],\"http1\":[\"dep:hyper\",\"hyper?/http1\",\"hyper-util?/http1\"],\"http2\":[\"dep:hyper\",\"hyper?/http2\",\"hyper-util?/http2\"],\"json\":[\"dep:serde_json\",\"dep:serde_path_to_error\"],\"macros\":[\"dep:axum-macros\"],\"matched-path\":[],\"multipart\":[\"dep:multer\"],\"original-uri\":[],\"query\":[\"dep:form_urlencoded\",\"dep:serde_urlencoded\",\"dep:serde_path_to_error\"],\"tokio\":[\"dep:hyper-util\",\"dep:tokio\",\"tokio/net\",\"tokio/rt\",\"tower/make\",\"tokio/macros\"],\"tower-log\":[\"tower/log\"],\"tracing\":[\"dep:tracing\",\"axum-core/tracing\"],\"ws\":[\"dep:hyper\",\"tokio\",\"dep:tokio-tungstenite\",\"dep:sha1\",\"dep:base64\"]}}", "backtrace_0.3.76": "{\"dependencies\":[{\"default_features\":false,\"name\":\"addr2line\",\"req\":\"^0.25.0\",\"target\":\"cfg(not(all(windows, target_env = \\\"msvc\\\", not(target_vendor = \\\"uwp\\\"))))\"},{\"name\":\"cfg-if\",\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"cpp_demangle\",\"optional\":true,\"req\":\"^0.5.0\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.156\",\"target\":\"cfg(not(all(windows, target_env = \\\"msvc\\\", not(target_vendor = \\\"uwp\\\"))))\"},{\"kind\":\"dev\",\"name\":\"libloading\",\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"miniz_oxide\",\"req\":\"^0.8\",\"target\":\"cfg(not(all(windows, target_env = \\\"msvc\\\", not(target_vendor = \\\"uwp\\\"))))\"},{\"default_features\":false,\"features\":[\"read_core\",\"elf\",\"macho\",\"pe\",\"xcoff\",\"unaligned\",\"archive\"],\"name\":\"object\",\"req\":\"^0.37.0\",\"target\":\"cfg(not(all(windows, target_env = \\\"msvc\\\", not(target_vendor = \\\"uwp\\\"))))\"},{\"name\":\"rustc-demangle\",\"req\":\"^0.1.24\"},{\"default_features\":false,\"name\":\"ruzstd\",\"optional\":true,\"req\":\"^0.8.1\",\"target\":\"cfg(not(all(windows, target_env = \\\"msvc\\\", not(target_vendor = \\\"uwp\\\"))))\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"windows-link\",\"req\":\"^0.2\",\"target\":\"cfg(any(windows, target_os = \\\"cygwin\\\"))\"}],\"features\":{\"coresymbolication\":[],\"dbghelp\":[],\"default\":[\"std\"],\"dl_iterate_phdr\":[],\"dladdr\":[],\"kernel32\":[],\"libunwind\":[],\"ruzstd\":[\"dep:ruzstd\"],\"serialize-serde\":[\"serde\"],\"std\":[],\"unix-backtrace\":[]}}", + "base16ct_0.2.0": "{\"dependencies\":[],\"features\":{\"alloc\":[],\"std\":[\"alloc\"]}}", "base64_0.21.7": "{\"dependencies\":[{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^3.2.25\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.4.0\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"^1\"},{\"features\":[\"small_rng\"],\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.5\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.13.0\"},{\"kind\":\"dev\",\"name\":\"rstest_reuse\",\"req\":\"^0.6.0\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"strum\",\"req\":\"^0.25\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"std\":[\"alloc\"]}}", "base64_0.22.1": "{\"dependencies\":[{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^3.2.25\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.4.0\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"^1\"},{\"features\":[\"small_rng\"],\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.5\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.13.0\"},{\"kind\":\"dev\",\"name\":\"rstest_reuse\",\"req\":\"^0.6.0\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"strum\",\"req\":\"^0.25\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"std\":[\"alloc\"]}}", "base64ct_1.8.3": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"base64\",\"req\":\"^0.22\"},{\"default_features\":false,\"features\":[\"std\"],\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1.6\"}],\"features\":{\"alloc\":[],\"std\":[\"alloc\"]}}", @@ -669,6 +673,8 @@ "borsh_1.6.0": "{\"dependencies\":[{\"name\":\"ascii\",\"optional\":true,\"req\":\"^1.1\"},{\"name\":\"borsh-derive\",\"optional\":true,\"req\":\"~1.6.0\"},{\"name\":\"bson\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"bytes\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"build\",\"name\":\"cfg_aliases\",\"req\":\"^0.2.1\"},{\"name\":\"hashbrown\",\"optional\":true,\"req\":\">=0.11, <0.16.0\"},{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"insta\",\"req\":\"^1.29.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1\"}],\"features\":{\"de_strict_order\":[],\"default\":[\"std\"],\"derive\":[\"borsh-derive\"],\"rc\":[],\"std\":[],\"unstable__schema\":[\"derive\",\"borsh-derive/schema\"]}}", "bstr_1.12.1": "{\"dependencies\":[{\"default_features\":false,\"name\":\"memchr\",\"req\":\"^2.7.1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"dfa-search\"],\"name\":\"regex-automata\",\"optional\":true,\"req\":\"^0.4.1\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.85\"},{\"kind\":\"dev\",\"name\":\"ucd-parse\",\"req\":\"^0.1.3\"},{\"kind\":\"dev\",\"name\":\"unicode-segmentation\",\"req\":\"^1.2.1\"}],\"features\":{\"alloc\":[\"memchr/alloc\",\"serde?/alloc\"],\"default\":[\"std\",\"unicode\"],\"serde\":[\"dep:serde\"],\"std\":[\"alloc\",\"memchr/std\",\"serde?/std\"],\"unicode\":[\"dep:regex-automata\"]}}", "bumpalo_3.19.1": "{\"dependencies\":[{\"default_features\":false,\"name\":\"allocator-api2\",\"optional\":true,\"req\":\"^0.2.8\"},{\"kind\":\"dev\",\"name\":\"blink-alloc\",\"req\":\"=0.4.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3.6\"},{\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0.3\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.5\"},{\"kind\":\"dev\",\"name\":\"rayon\",\"req\":\"=1.10.0\"},{\"kind\":\"dev\",\"name\":\"rayon-core\",\"req\":\"=1.12.1\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.171\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.197\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.115\"}],\"features\":{\"allocator_api\":[],\"bench_allocator_api\":[\"allocator_api\",\"blink-alloc/nightly\"],\"boxed\":[],\"collections\":[],\"default\":[],\"serde\":[\"dep:serde\"],\"std\":[]}}", + "bytecheck_0.8.2": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bytecheck_derive\",\"req\":\"=0.8.2\"},{\"default_features\":false,\"name\":\"ptr_meta\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"rancor\",\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"simdutf8\",\"optional\":true,\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"uuid-1\",\"optional\":true,\"package\":\"uuid\",\"req\":\"^1\"}],\"features\":{\"default\":[\"simdutf8\"]}}", + "bytecheck_derive_0.8.2": "{\"dependencies\":[{\"default_features\":false,\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"quote\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"clone-impls\",\"derive\",\"full\",\"parsing\",\"printing\",\"proc-macro\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}", "bytemuck_1.25.0": "{\"dependencies\":[{\"name\":\"bytemuck_derive\",\"optional\":true,\"req\":\"^1.10.2\"},{\"name\":\"rustversion\",\"optional\":true,\"req\":\"^1.0.22\"}],\"features\":{\"aarch64_simd\":[],\"align_offset\":[],\"alloc_uninit\":[],\"avx512_simd\":[],\"const_zeroed\":[],\"derive\":[\"bytemuck_derive\"],\"extern_crate_alloc\":[],\"extern_crate_std\":[\"extern_crate_alloc\"],\"impl_core_error\":[],\"latest_stable_rust\":[\"aarch64_simd\",\"avx512_simd\",\"align_offset\",\"alloc_uninit\",\"const_zeroed\",\"derive\",\"impl_core_error\",\"min_const_generics\",\"must_cast\",\"must_cast_extra\",\"pod_saturating\",\"track_caller\",\"transparentwrapper_extra\",\"wasm_simd\",\"zeroable_atomics\",\"zeroable_maybe_uninit\",\"zeroable_unwind_fn\"],\"min_const_generics\":[],\"must_cast\":[],\"must_cast_extra\":[\"must_cast\"],\"nightly_docs\":[],\"nightly_float\":[],\"nightly_portable_simd\":[\"rustversion\"],\"nightly_stdsimd\":[],\"pod_saturating\":[],\"track_caller\":[],\"transparentwrapper_extra\":[],\"unsound_ptr_pod_impl\":[],\"wasm_simd\":[],\"zeroable_atomics\":[],\"zeroable_maybe_uninit\":[],\"zeroable_unwind_fn\":[]}}", "byteorder-lite_0.1.0": "{\"dependencies\":[{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^0.9.2\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.7\"}],\"features\":{\"default\":[\"std\"],\"std\":[]}}", "byteorder_1.5.0": "{\"dependencies\":[{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^0.9.2\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.7\"}],\"features\":{\"default\":[\"std\"],\"i128\":[],\"std\":[]}}", @@ -688,6 +694,7 @@ "cbc_0.1.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"aes\",\"req\":\"^0.8\"},{\"name\":\"cipher\",\"req\":\"^0.4.2\"},{\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"cipher\",\"req\":\"^0.4.2\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3.3\"}],\"features\":{\"alloc\":[\"cipher/alloc\"],\"block-padding\":[\"cipher/block-padding\"],\"default\":[\"block-padding\"],\"std\":[\"cipher/std\",\"alloc\"],\"zeroize\":[\"cipher/zeroize\"]}}", "cc_1.2.55": "{\"dependencies\":[{\"name\":\"find-msvc-tools\",\"req\":\"^0.1.9\"},{\"default_features\":false,\"name\":\"jobserver\",\"optional\":true,\"req\":\"^0.1.30\"},{\"default_features\":false,\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.62\",\"target\":\"cfg(unix)\"},{\"name\":\"shlex\",\"req\":\"^1.3.0\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3\"}],\"features\":{\"jobserver\":[],\"parallel\":[\"dep:libc\",\"dep:jobserver\"]}}", "cc_1.2.56": "{\"dependencies\":[{\"name\":\"find-msvc-tools\",\"req\":\"^0.1.9\"},{\"default_features\":false,\"name\":\"jobserver\",\"optional\":true,\"req\":\"^0.1.30\"},{\"default_features\":false,\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.62\",\"target\":\"cfg(unix)\"},{\"name\":\"shlex\",\"req\":\"^1.3.0\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3\"}],\"features\":{\"jobserver\":[],\"parallel\":[\"dep:libc\",\"dep:jobserver\"]}}", + "ccm_0.5.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aead\",\"req\":\"^0.5\"},{\"default_features\":false,\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"aead\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"aes\",\"req\":\"^0.8.1\"},{\"default_features\":false,\"name\":\"cipher\",\"req\":\"^0.4.3\"},{\"default_features\":false,\"name\":\"ctr\",\"req\":\"^0.9.1\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3.4\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2\"}],\"features\":{\"alloc\":[\"aead/alloc\"],\"default\":[\"alloc\",\"getrandom\"],\"getrandom\":[\"aead/getrandom\"],\"heapless\":[\"aead/heapless\"],\"std\":[\"aead/std\",\"alloc\"],\"stream\":[\"aead/stream\"]}}", "cesu8_1.1.0": "{\"dependencies\":[],\"features\":{\"unstable\":[]}}", "cexpr_0.6.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"clang-sys\",\"req\":\">=0.13.0, <0.29.0\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"nom\",\"req\":\"^7\"}],\"features\":{}}", "cfg-if_1.0.4": "{\"dependencies\":[{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"}],\"features\":{\"rustc-dep-of-std\":[\"core\"]}}", @@ -745,12 +752,14 @@ "crossbeam-utils_0.8.21": "{\"dependencies\":[{\"name\":\"loom\",\"optional\":true,\"req\":\"^0.7.1\",\"target\":\"cfg(crossbeam_loom)\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"}],\"features\":{\"default\":[\"std\"],\"nightly\":[],\"std\":[]}}", "crossterm_winapi_0.9.1": "{\"dependencies\":[{\"features\":[\"winbase\",\"consoleapi\",\"processenv\",\"handleapi\",\"synchapi\",\"impl-default\"],\"name\":\"winapi\",\"req\":\"^0.3.8\",\"target\":\"cfg(windows)\"}],\"features\":{}}", "crunchy_0.2.4": "{\"dependencies\":[],\"features\":{\"default\":[\"limit_128\"],\"limit_1024\":[],\"limit_128\":[],\"limit_2048\":[],\"limit_256\":[],\"limit_512\":[],\"limit_64\":[],\"std\":[]}}", + "crypto-bigint_0.5.5": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1\"},{\"features\":[\"html_reports\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"default_features\":false,\"name\":\"der\",\"optional\":true,\"req\":\"^0.7\"},{\"name\":\"generic-array\",\"optional\":true,\"req\":\"^0.14\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"num-bigint\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"num-integer\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"num-traits\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"rand_chacha\",\"req\":\"^0.3\"},{\"name\":\"rand_core\",\"optional\":true,\"req\":\"^0.6.4\"},{\"features\":[\"std\"],\"kind\":\"dev\",\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"default_features\":false,\"name\":\"rlp\",\"optional\":true,\"req\":\"^0.5\"},{\"default_features\":false,\"name\":\"serdect\",\"optional\":true,\"req\":\"^0.2\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2.4\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"alloc\":[\"serdect?/alloc\"],\"default\":[\"rand\"],\"extra-sizes\":[],\"rand\":[\"rand_core/std\"],\"serde\":[\"dep:serdect\"]}}", "crypto-common_0.1.7": "{\"dependencies\":[{\"features\":[\"more_lengths\"],\"name\":\"generic-array\",\"req\":\"=0.14.7\"},{\"name\":\"rand_core\",\"optional\":true,\"req\":\"^0.6\"},{\"name\":\"typenum\",\"req\":\"^1.14\"}],\"features\":{\"getrandom\":[\"rand_core/getrandom\"],\"std\":[]}}", "csv-core_0.1.13": "{\"dependencies\":[{\"default_features\":false,\"kind\":\"dev\",\"name\":\"arrayvec\",\"req\":\"^0.5\"},{\"default_features\":false,\"name\":\"memchr\",\"req\":\"^2\"}],\"features\":{\"default\":[],\"libc\":[\"memchr/libc\"]}}", "csv_1.4.0": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"alloc\",\"serde\"],\"kind\":\"dev\",\"name\":\"bstr\",\"req\":\"^1.7.0\"},{\"name\":\"csv-core\",\"req\":\"^0.1.11\"},{\"name\":\"itoa\",\"req\":\"^1\"},{\"name\":\"ryu\",\"req\":\"^1\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.221\"},{\"name\":\"serde_core\",\"req\":\"^1.0.221\"}],\"features\":{}}", "ctor-proc-macro_0.0.7": "{\"dependencies\":[],\"features\":{\"default\":[]}}", "ctor_0.1.26": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"libc-print\",\"req\":\"^0.1.20\"},{\"name\":\"quote\",\"req\":\"^1.0.20\"},{\"default_features\":false,\"features\":[\"full\",\"parsing\",\"printing\",\"proc-macro\"],\"name\":\"syn\",\"req\":\"^1.0.98\"}],\"features\":{}}", "ctor_0.6.3": "{\"dependencies\":[{\"name\":\"ctor-proc-macro\",\"optional\":true,\"req\":\"=0.0.7\"},{\"default_features\":false,\"name\":\"dtor\",\"optional\":true,\"req\":\"^0.1.0\"},{\"kind\":\"dev\",\"name\":\"libc-print\",\"req\":\"^0.1.20\"}],\"features\":{\"__no_warn_on_missing_unsafe\":[\"dtor?/__no_warn_on_missing_unsafe\"],\"default\":[\"dtor\",\"proc_macro\",\"__no_warn_on_missing_unsafe\"],\"dtor\":[\"dep:dtor\"],\"proc_macro\":[\"dep:ctor-proc-macro\",\"dtor?/proc_macro\"],\"used_linker\":[\"dtor?/used_linker\"]}}", + "ctr_0.9.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"aes\",\"req\":\"^0.8\"},{\"name\":\"cipher\",\"req\":\"^0.4.2\"},{\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"cipher\",\"req\":\"^0.4.2\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3.3\"},{\"kind\":\"dev\",\"name\":\"kuznyechik\",\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"magma\",\"req\":\"^0.8\"}],\"features\":{\"alloc\":[\"cipher/alloc\"],\"block-padding\":[\"cipher/block-padding\"],\"std\":[\"cipher/std\",\"alloc\"],\"zeroize\":[\"cipher/zeroize\"]}}", "curve25519-dalek-derive_0.1.1": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1.0.66\"},{\"name\":\"quote\",\"req\":\"^1.0.31\"},{\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2.0.27\"}],\"features\":{}}", "curve25519-dalek_4.1.3": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1\"},{\"name\":\"cfg-if\",\"req\":\"^1\"},{\"name\":\"cpufeatures\",\"req\":\"^0.2.6\",\"target\":\"cfg(target_arch = \\\"x86_64\\\")\"},{\"features\":[\"html_reports\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"name\":\"curve25519-dalek-derive\",\"req\":\"^0.1\",\"target\":\"cfg(all(not(curve25519_dalek_backend = \\\"fiat\\\"), not(curve25519_dalek_backend = \\\"serial\\\"), target_arch = \\\"x86_64\\\"))\"},{\"default_features\":false,\"name\":\"digest\",\"optional\":true,\"req\":\"^0.10\"},{\"default_features\":false,\"name\":\"ff\",\"optional\":true,\"req\":\"^0.13\"},{\"default_features\":false,\"name\":\"fiat-crypto\",\"req\":\"^0.2.1\",\"target\":\"cfg(curve25519_dalek_backend = \\\"fiat\\\")\"},{\"default_features\":false,\"name\":\"group\",\"optional\":true,\"req\":\"^0.13\"},{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4.2\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"rand_core\",\"optional\":true,\"req\":\"^0.6.4\"},{\"default_features\":false,\"features\":[\"getrandom\"],\"kind\":\"dev\",\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"kind\":\"build\",\"name\":\"rustc_version\",\"req\":\"^0.4.0\"},{\"default_features\":false,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"sha2\",\"req\":\"^0.10\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2.3.0\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"alloc\":[\"zeroize?/alloc\"],\"default\":[\"alloc\",\"precomputed-tables\",\"zeroize\"],\"group\":[\"dep:group\",\"rand_core\"],\"group-bits\":[\"group\",\"ff/bits\"],\"legacy_compatibility\":[],\"precomputed-tables\":[]}}", "darling_0.20.11": "{\"dependencies\":[{\"name\":\"darling_core\",\"req\":\"=0.20.11\"},{\"name\":\"darling_macro\",\"req\":\"=0.20.11\"},{\"kind\":\"dev\",\"name\":\"proc-macro2\",\"req\":\"^1.0.86\"},{\"kind\":\"dev\",\"name\":\"quote\",\"req\":\"^1.0.18\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0.9\",\"target\":\"cfg(compiletests)\"},{\"kind\":\"dev\",\"name\":\"syn\",\"req\":\"^2.0.15\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.89\",\"target\":\"cfg(compiletests)\"}],\"features\":{\"default\":[\"suggestions\"],\"diagnostics\":[\"darling_core/diagnostics\"],\"suggestions\":[\"darling_core/suggestions\"]}}", @@ -772,6 +781,7 @@ "debugserver-types_0.5.0": "{\"dependencies\":[{\"name\":\"schemafy\",\"req\":\"^0.5.0\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"}],\"features\":{}}", "deflate64_0.1.10": "{\"dependencies\":[{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"bytemuck\",\"req\":\"^1.13.1\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1.2.0\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.7.1\"}],\"features\":{}}", "der-parser_10.0.0": "{\"dependencies\":[{\"name\":\"asn1-rs\",\"req\":\"^0.7\"},{\"name\":\"bitvec\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"cookie-factory\",\"optional\":true,\"req\":\"^0.3.0\"},{\"default_features\":false,\"name\":\"displaydoc\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"name\":\"nom\",\"req\":\"^7.0\"},{\"name\":\"num-bigint\",\"optional\":true,\"req\":\"^0.4\"},{\"name\":\"num-traits\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"pretty_assertions\",\"req\":\"^1.0\"},{\"name\":\"rusticata-macros\",\"req\":\"^4.0\"},{\"kind\":\"dev\",\"name\":\"test-case\",\"req\":\"^3.0\"}],\"features\":{\"as_bitvec\":[\"bitvec\"],\"bigint\":[\"num-bigint\"],\"default\":[\"std\"],\"serialize\":[\"std\",\"cookie-factory\"],\"std\":[],\"unstable\":[]}}", + "der-parser_9.0.0": "{\"dependencies\":[{\"name\":\"asn1-rs\",\"req\":\"^0.6\"},{\"name\":\"cookie-factory\",\"optional\":true,\"req\":\"^0.3.0\"},{\"default_features\":false,\"name\":\"displaydoc\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"name\":\"nom\",\"req\":\"^7.0\"},{\"name\":\"num-bigint\",\"optional\":true,\"req\":\"^0.4\"},{\"name\":\"num-traits\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"pretty_assertions\",\"req\":\"^1.0\"},{\"name\":\"rusticata-macros\",\"req\":\"^4.0\"},{\"kind\":\"dev\",\"name\":\"test-case\",\"req\":\"^3.0\"}],\"features\":{\"bigint\":[\"num-bigint\"],\"default\":[\"std\"],\"serialize\":[\"std\",\"cookie-factory\"],\"std\":[],\"unstable\":[]}}", "der_0.7.10": "{\"dependencies\":[{\"features\":[\"derive\"],\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1.3\"},{\"default_features\":false,\"name\":\"bytes\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"const-oid\",\"optional\":true,\"req\":\"^0.9.2\"},{\"name\":\"der_derive\",\"optional\":true,\"req\":\"^0.7.2\"},{\"name\":\"flagset\",\"optional\":true,\"req\":\"^0.4.3\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4.1\"},{\"features\":[\"alloc\"],\"name\":\"pem-rfc7468\",\"optional\":true,\"req\":\"^0.7\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"time\",\"optional\":true,\"req\":\"^0.3.4\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1.5\"}],\"features\":{\"alloc\":[\"zeroize?/alloc\"],\"arbitrary\":[\"dep:arbitrary\",\"const-oid?/arbitrary\",\"std\"],\"bytes\":[\"dep:bytes\",\"alloc\"],\"derive\":[\"dep:der_derive\"],\"oid\":[\"dep:const-oid\"],\"pem\":[\"dep:pem-rfc7468\",\"alloc\",\"zeroize\"],\"real\":[],\"std\":[\"alloc\"]}}", "deranged_0.5.5": "{\"dependencies\":[{\"name\":\"deranged-macros\",\"optional\":true,\"req\":\"=0.3.0\"},{\"default_features\":false,\"name\":\"num-traits\",\"optional\":true,\"req\":\"^0.2.15\"},{\"default_features\":false,\"name\":\"powerfmt\",\"optional\":true,\"req\":\"^0.2.0\"},{\"default_features\":false,\"name\":\"quickcheck\",\"optional\":true,\"req\":\"^1.0.3\"},{\"default_features\":false,\"name\":\"rand08\",\"optional\":true,\"package\":\"rand\",\"req\":\"^0.8.4\"},{\"kind\":\"dev\",\"name\":\"rand08\",\"package\":\"rand\",\"req\":\"^0.8.4\"},{\"default_features\":false,\"name\":\"rand09\",\"optional\":true,\"package\":\"rand\",\"req\":\"^0.9.0\"},{\"kind\":\"dev\",\"name\":\"rand09\",\"package\":\"rand\",\"req\":\"^0.9.0\"},{\"default_features\":false,\"name\":\"serde_core\",\"optional\":true,\"req\":\"^1.0.220\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.86\"}],\"features\":{\"alloc\":[],\"default\":[],\"macros\":[\"dep:deranged-macros\"],\"num\":[\"dep:num-traits\"],\"powerfmt\":[\"dep:powerfmt\"],\"quickcheck\":[\"dep:quickcheck\",\"alloc\"],\"rand\":[\"rand08\",\"rand09\"],\"rand08\":[\"dep:rand08\"],\"rand09\":[\"dep:rand09\"],\"serde\":[\"dep:serde_core\"]}}", "derivative_2.2.0": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"features\":[\"visit\",\"extra-traits\"],\"name\":\"syn\",\"req\":\"^1.0.3\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.18, < 1.0.23\"}],\"features\":{\"use_core\":[]}}", @@ -797,6 +807,7 @@ "displaydoc_0.2.5": "{\"dependencies\":[{\"default_features\":false,\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"pretty_assertions\",\"req\":\"^0.6.1\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"static_assertions\",\"req\":\"^1.1\"},{\"name\":\"syn\",\"req\":\"^2.0\"},{\"kind\":\"dev\",\"name\":\"thiserror\",\"req\":\"^1.0.24\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0\"}],\"features\":{\"default\":[\"std\"],\"std\":[]}}", "dotenvy_0.15.7": "{\"dependencies\":[{\"name\":\"clap\",\"optional\":true,\"req\":\"^3.2\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"^1.16.0\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.3.0\"}],\"features\":{\"cli\":[\"clap\"]}}", "downcast-rs_1.2.1": "{\"dependencies\":[],\"features\":{\"default\":[\"std\"],\"std\":[]}}", + "dtls_0.17.1": "{\"dependencies\":[{\"name\":\"aes\",\"req\":\"^0.8\"},{\"name\":\"aes-gcm\",\"req\":\"^0.10\"},{\"name\":\"async-trait\",\"req\":\"^0.1\"},{\"name\":\"bytecheck\",\"req\":\"^0.8\"},{\"name\":\"byteorder\",\"req\":\"^1\"},{\"features\":[\"block-padding\",\"alloc\"],\"name\":\"cbc\",\"req\":\"^0.1\"},{\"name\":\"ccm\",\"req\":\"^0.5\"},{\"name\":\"chacha20poly1305\",\"req\":\"^0.10.1\"},{\"name\":\"der-parser\",\"req\":\"^9.0\"},{\"name\":\"hmac\",\"req\":\"^0.12\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"features\":[\"default\",\"ecdh\",\"ecdsa\"],\"name\":\"p256\",\"req\":\"^0.13\"},{\"name\":\"p384\",\"req\":\"^0.13\"},{\"name\":\"pem\",\"optional\":true,\"req\":\"^3\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"name\":\"rcgen\",\"req\":\"^0.13\"},{\"name\":\"ring\",\"req\":\"^0.17.14\"},{\"name\":\"rkyv\",\"req\":\"^0.8\"},{\"default_features\":false,\"features\":[\"std\",\"ring\"],\"name\":\"rustls\",\"req\":\"^0.23.27\"},{\"features\":[\"std\"],\"name\":\"sec1\",\"req\":\"^0.7\"},{\"name\":\"sha1\",\"req\":\"^0.10\"},{\"name\":\"sha2\",\"req\":\"^0.10\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"default_features\":false,\"features\":[\"conn\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"},{\"features\":[\"static_secrets\"],\"name\":\"x25519-dalek\",\"req\":\"^2\"},{\"name\":\"x509-parser\",\"req\":\"^0.16\"}],\"features\":{\"pem\":[\"dep:pem\"]}}", "dtor-proc-macro_0.0.6": "{\"dependencies\":[],\"features\":{\"default\":[]}}", "dtor_0.1.1": "{\"dependencies\":[{\"name\":\"dtor-proc-macro\",\"optional\":true,\"req\":\"=0.0.6\"},{\"kind\":\"dev\",\"name\":\"libc-print\",\"req\":\"^0.1.20\"}],\"features\":{\"__no_warn_on_missing_unsafe\":[],\"default\":[\"proc_macro\",\"__no_warn_on_missing_unsafe\"],\"proc_macro\":[\"dep:dtor-proc-macro\"],\"used_linker\":[]}}", "dunce_1.0.5": "{\"dependencies\":[],\"features\":{}}", @@ -807,7 +818,9 @@ "dylint_linting_5.0.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"assert_cmd\",\"req\":\"^2.0\"},{\"name\":\"cargo_metadata\",\"req\":\"^0.23\"},{\"features\":[\"config\"],\"name\":\"dylint_internal\",\"req\":\"=5.0.0\"},{\"name\":\"paste\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rustc_version\",\"req\":\"^0.4\"},{\"name\":\"rustversion\",\"req\":\"^1.0\"},{\"name\":\"serde\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.23\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"name\":\"toml\",\"req\":\"^0.9\"},{\"kind\":\"build\",\"name\":\"toml\",\"req\":\"^0.9\"}],\"features\":{\"constituent\":[]}}", "dylint_testing_5.0.0": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0\"},{\"name\":\"cargo_metadata\",\"req\":\"^0.23\"},{\"name\":\"compiletest_rs\",\"req\":\"^0.11\"},{\"name\":\"dylint\",\"req\":\"=5.0.0\"},{\"name\":\"dylint_internal\",\"req\":\"=5.0.0\"},{\"name\":\"env_logger\",\"req\":\"^0.11\"},{\"name\":\"once_cell\",\"req\":\"^1.21\"},{\"name\":\"regex\",\"req\":\"^1.11\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"tempfile\",\"req\":\"^3.23\"}],\"features\":{\"default\":[],\"deny_warnings\":[]}}", "dyn-clone_1.0.20": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.66\"}],\"features\":{}}", + "ecdsa_0.16.9": "{\"dependencies\":[{\"name\":\"der\",\"optional\":true,\"req\":\"^0.7\"},{\"default_features\":false,\"features\":[\"oid\"],\"name\":\"digest\",\"optional\":true,\"req\":\"^0.10.7\"},{\"default_features\":false,\"features\":[\"digest\",\"sec1\"],\"name\":\"elliptic-curve\",\"req\":\"^0.13.6\"},{\"default_features\":false,\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"elliptic-curve\",\"req\":\"^0.13\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"name\":\"rfc6979\",\"optional\":true,\"req\":\"^0.4\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"serdect\",\"optional\":true,\"req\":\"^0.2\"},{\"default_features\":false,\"features\":[\"oid\"],\"name\":\"sha2\",\"optional\":true,\"req\":\"^0.10\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"sha2\",\"req\":\"^0.10\"},{\"default_features\":false,\"features\":[\"rand_core\"],\"name\":\"signature\",\"req\":\"^2.0, <2.3\"},{\"default_features\":false,\"name\":\"spki\",\"optional\":true,\"req\":\"^0.7.2\"}],\"features\":{\"alloc\":[\"elliptic-curve/alloc\",\"signature/alloc\",\"spki/alloc\"],\"arithmetic\":[\"elliptic-curve/arithmetic\"],\"default\":[\"digest\"],\"dev\":[\"arithmetic\",\"digest\",\"elliptic-curve/dev\",\"hazmat\"],\"digest\":[\"dep:digest\",\"signature/digest\"],\"hazmat\":[],\"pem\":[\"elliptic-curve/pem\",\"pkcs8\"],\"pkcs8\":[\"digest\",\"elliptic-curve/pkcs8\",\"der\"],\"serde\":[\"elliptic-curve/serde\",\"serdect\"],\"signing\":[\"arithmetic\",\"digest\",\"hazmat\",\"rfc6979\"],\"std\":[\"alloc\",\"elliptic-curve/std\",\"signature/std\"],\"verifying\":[\"arithmetic\",\"digest\",\"hazmat\"]}}", "either_1.15.0": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"alloc\",\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.95\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.0\"}],\"features\":{\"default\":[\"std\"],\"std\":[],\"use_std\":[\"std\"]}}", + "elliptic-curve_0.13.8": "{\"dependencies\":[{\"name\":\"base16ct\",\"req\":\"^0.2\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"base64ct\",\"optional\":true,\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"rand_core\",\"generic-array\",\"zeroize\"],\"name\":\"crypto-bigint\",\"req\":\"^0.5\"},{\"name\":\"digest\",\"optional\":true,\"req\":\"^0.10\"},{\"default_features\":false,\"name\":\"ff\",\"optional\":true,\"req\":\"^0.13\"},{\"default_features\":false,\"features\":[\"zeroize\"],\"name\":\"generic-array\",\"req\":\"^0.14.6\"},{\"default_features\":false,\"name\":\"group\",\"optional\":true,\"req\":\"^0.13\"},{\"name\":\"hex-literal\",\"optional\":true,\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"default_features\":false,\"name\":\"hkdf\",\"optional\":true,\"req\":\"^0.12.1\"},{\"features\":[\"alloc\"],\"name\":\"pem-rfc7468\",\"optional\":true,\"req\":\"^0.7\"},{\"default_features\":false,\"name\":\"pkcs8\",\"optional\":true,\"req\":\"^0.10.2\"},{\"default_features\":false,\"name\":\"rand_core\",\"req\":\"^0.6.4\"},{\"features\":[\"subtle\",\"zeroize\"],\"name\":\"sec1\",\"optional\":true,\"req\":\"^0.7.1\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1.0.47\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"serdect\",\"optional\":true,\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"sha2\",\"req\":\"^0.10\"},{\"kind\":\"dev\",\"name\":\"sha3\",\"req\":\"^0.10\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2\"},{\"default_features\":false,\"name\":\"tap\",\"optional\":true,\"req\":\"^1.0.1\"},{\"default_features\":false,\"name\":\"zeroize\",\"req\":\"^1.7\"}],\"features\":{\"alloc\":[\"base16ct/alloc\",\"ff?/alloc\",\"group?/alloc\",\"pkcs8?/alloc\",\"sec1?/alloc\",\"zeroize/alloc\"],\"arithmetic\":[\"group\"],\"bits\":[\"arithmetic\",\"ff/bits\",\"dep:tap\"],\"default\":[\"arithmetic\"],\"dev\":[\"arithmetic\",\"dep:hex-literal\",\"pem\",\"pkcs8\"],\"ecdh\":[\"arithmetic\",\"digest\",\"dep:hkdf\"],\"group\":[\"dep:group\",\"ff\"],\"hash2curve\":[\"arithmetic\",\"digest\"],\"hazmat\":[],\"jwk\":[\"dep:base64ct\",\"dep:serde_json\",\"alloc\",\"serde\",\"zeroize/alloc\"],\"pem\":[\"dep:pem-rfc7468\",\"alloc\",\"arithmetic\",\"pkcs8\",\"sec1/pem\"],\"pkcs8\":[\"dep:pkcs8\",\"sec1\"],\"serde\":[\"dep:serdect\",\"alloc\",\"pkcs8\",\"sec1/serde\"],\"std\":[\"alloc\",\"rand_core/std\",\"pkcs8?/std\",\"sec1?/std\"],\"voprf\":[\"digest\"]}}", "ena_0.14.3": "{\"dependencies\":[{\"name\":\"dogged\",\"optional\":true,\"req\":\"^0.2.0\"},{\"name\":\"log\",\"req\":\"^0.4\"}],\"features\":{\"bench\":[],\"persistent\":[\"dogged\"]}}", "encode_unicode_1.0.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"ascii\",\"optional\":true,\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1.0\",\"target\":\"cfg(unix)\"},{\"features\":[\"https-native\"],\"kind\":\"dev\",\"name\":\"minreq\",\"req\":\"^2.6\"}],\"features\":{\"default\":[\"std\"],\"std\":[]}}", "encoding_rs_0.8.35": "{\"dependencies\":[{\"name\":\"any_all_workaround\",\"optional\":true,\"req\":\"^0.1.0\"},{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1.0\"},{\"name\":\"cfg-if\",\"req\":\"^1.0\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"}],\"features\":{\"alloc\":[],\"default\":[\"alloc\"],\"fast-big5-hanzi-encode\":[],\"fast-gb-hanzi-encode\":[],\"fast-hangul-encode\":[],\"fast-hanja-encode\":[],\"fast-kanji-encode\":[],\"fast-legacy-encode\":[\"fast-hangul-encode\",\"fast-hanja-encode\",\"fast-kanji-encode\",\"fast-gb-hanzi-encode\",\"fast-big5-hanzi-encode\"],\"less-slow-big5-hanzi-encode\":[],\"less-slow-gb-hanzi-encode\":[],\"less-slow-kanji-encode\":[],\"simd-accel\":[\"any_all_workaround\"]}}", @@ -835,6 +848,7 @@ "fax_derive_0.2.0": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"name\":\"syn\",\"req\":\"^2.0\"}],\"features\":{}}", "fd-lock_4.0.4": "{\"dependencies\":[{\"name\":\"cfg-if\",\"req\":\"^1.0.0\"},{\"features\":[\"fs\"],\"name\":\"rustix\",\"req\":\"^1.0.0\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.0.8\"},{\"features\":[\"Win32_Foundation\",\"Win32_Storage_FileSystem\",\"Win32_System_IO\"],\"name\":\"windows-sys\",\"req\":\">=0.52.0, <0.60.0\",\"target\":\"cfg(windows)\"}],\"features\":{}}", "fdeflate_0.3.7": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"miniz_oxide\",\"req\":\"^0.7.1\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.5\"},{\"name\":\"simd-adler32\",\"req\":\"^0.3.4\"}],\"features\":{}}", + "ff_0.13.1": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bitvec\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"blake2b_simd\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"byteorder\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"ff_derive\",\"optional\":true,\"req\":\"^0.13.1\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"default_features\":false,\"features\":[\"i128\"],\"name\":\"subtle\",\"req\":\"^2.2.1\"}],\"features\":{\"alloc\":[],\"bits\":[\"bitvec\"],\"default\":[\"bits\",\"std\"],\"derive\":[\"byteorder\",\"ff_derive\"],\"derive_bits\":[\"bits\",\"ff_derive/bits\"],\"std\":[\"alloc\"]}}", "fiat-crypto_0.2.9": "{\"dependencies\":[],\"features\":{\"default\":[\"std\"],\"std\":[]}}", "filedescriptor_0.8.3": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2\"},{\"name\":\"thiserror\",\"req\":\"^1.0\"},{\"features\":[\"winuser\",\"handleapi\",\"fileapi\",\"namedpipeapi\",\"processthreadsapi\",\"winsock2\",\"processenv\"],\"name\":\"winapi\",\"req\":\"^0.3\",\"target\":\"cfg(windows)\"}],\"features\":{}}", "filetime_0.2.27": "{\"dependencies\":[{\"name\":\"cfg-if\",\"req\":\"^1.0.0\"},{\"name\":\"libc\",\"req\":\"^0.2.27\",\"target\":\"cfg(unix)\"},{\"name\":\"libredox\",\"req\":\"^0.1.0\",\"target\":\"cfg(target_os = \\\"redox\\\")\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3\"}],\"features\":{}}", @@ -880,6 +894,7 @@ "getrandom_0.2.17": "{\"dependencies\":[{\"name\":\"cfg-if\",\"req\":\"^1\"},{\"name\":\"compiler_builtins\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0\"},{\"name\":\"js-sys\",\"optional\":true,\"req\":\"^0.3\",\"target\":\"cfg(all(any(target_arch = \\\"wasm32\\\", target_arch = \\\"wasm64\\\"), target_os = \\\"unknown\\\"))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(unix)\"},{\"default_features\":false,\"name\":\"wasi\",\"req\":\"^0.11\",\"target\":\"cfg(target_os = \\\"wasi\\\")\"},{\"default_features\":false,\"name\":\"wasm-bindgen\",\"optional\":true,\"req\":\"^0.2.62\",\"target\":\"cfg(all(any(target_arch = \\\"wasm32\\\", target_arch = \\\"wasm64\\\"), target_os = \\\"unknown\\\"))\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3.18\",\"target\":\"cfg(all(any(target_arch = \\\"wasm32\\\", target_arch = \\\"wasm64\\\"), target_os = \\\"unknown\\\"))\"}],\"features\":{\"custom\":[],\"js\":[\"wasm-bindgen\",\"js-sys\"],\"linux_disable_fallback\":[],\"rdrand\":[],\"rustc-dep-of-std\":[\"compiler_builtins\",\"core\",\"libc/rustc-dep-of-std\",\"wasi/rustc-dep-of-std\"],\"std\":[],\"test-in-browser\":[]}}", "getrandom_0.3.4": "{\"dependencies\":[{\"name\":\"cfg-if\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"js-sys\",\"optional\":true,\"req\":\"^0.3.77\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", any(target_os = \\\"unknown\\\", target_os = \\\"none\\\"), target_feature = \\\"atomics\\\"))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), not(any(all(target_os = \\\"linux\\\", target_env = \\\"\\\"), getrandom_backend = \\\"custom\\\", getrandom_backend = \\\"linux_raw\\\", getrandom_backend = \\\"rdrand\\\", getrandom_backend = \\\"rndr\\\"))))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(any(target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"hurd\\\", target_os = \\\"illumos\\\", target_os = \\\"cygwin\\\", all(target_os = \\\"horizon\\\", target_arch = \\\"arm\\\")))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(any(target_os = \\\"haiku\\\", target_os = \\\"redox\\\", target_os = \\\"nto\\\", target_os = \\\"aix\\\"))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(any(target_os = \\\"ios\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\", target_os = \\\"tvos\\\"))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(any(target_os = \\\"macos\\\", target_os = \\\"openbsd\\\", target_os = \\\"vita\\\", target_os = \\\"emscripten\\\"))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(target_os = \\\"netbsd\\\")\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(target_os = \\\"solaris\\\")\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(target_os = \\\"vxworks\\\")\"},{\"default_features\":false,\"name\":\"r-efi\",\"req\":\"^5.1\",\"target\":\"cfg(all(target_os = \\\"uefi\\\", getrandom_backend = \\\"efi_rng\\\"))\"},{\"default_features\":false,\"name\":\"wasip2\",\"req\":\"^1\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"wasi\\\", target_env = \\\"p2\\\"))\"},{\"default_features\":false,\"name\":\"wasm-bindgen\",\"optional\":true,\"req\":\"^0.2.98\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", any(target_os = \\\"unknown\\\", target_os = \\\"none\\\")))\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", any(target_os = \\\"unknown\\\", target_os = \\\"none\\\")))\"}],\"features\":{\"std\":[],\"wasm_js\":[\"dep:wasm-bindgen\",\"dep:js-sys\"]}}", "getrandom_0.4.2": "{\"dependencies\":[{\"name\":\"cfg-if\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"js-sys\",\"optional\":true,\"req\":\"^0.3.77\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", any(target_os = \\\"unknown\\\", target_os = \\\"none\\\"), target_feature = \\\"atomics\\\"))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(all(any(target_os = \\\"linux\\\", target_os = \\\"android\\\"), not(any(all(target_os = \\\"linux\\\", target_env = \\\"\\\"), getrandom_backend = \\\"custom\\\", getrandom_backend = \\\"linux_raw\\\", getrandom_backend = \\\"rdrand\\\", getrandom_backend = \\\"rndr\\\"))))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(any(target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"hurd\\\", target_os = \\\"illumos\\\", target_os = \\\"cygwin\\\", all(target_os = \\\"horizon\\\", target_arch = \\\"arm\\\")))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(any(target_os = \\\"haiku\\\", target_os = \\\"redox\\\", target_os = \\\"nto\\\", target_os = \\\"aix\\\"))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(any(target_os = \\\"ios\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\", target_os = \\\"tvos\\\"))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(any(target_os = \\\"macos\\\", target_os = \\\"openbsd\\\", target_os = \\\"vita\\\", target_os = \\\"emscripten\\\"))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(target_os = \\\"netbsd\\\")\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(target_os = \\\"solaris\\\")\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.154\",\"target\":\"cfg(target_os = \\\"vxworks\\\")\"},{\"default_features\":false,\"name\":\"r-efi\",\"req\":\"^6\",\"target\":\"cfg(all(target_os = \\\"uefi\\\", getrandom_backend = \\\"efi_rng\\\"))\"},{\"name\":\"rand_core\",\"optional\":true,\"req\":\"^0.10.0\"},{\"default_features\":false,\"name\":\"wasip2\",\"req\":\"^1\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"wasi\\\", target_env = \\\"p2\\\"))\"},{\"name\":\"wasip3\",\"req\":\"^0.4\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"wasi\\\", target_env = \\\"p3\\\"))\"},{\"default_features\":false,\"name\":\"wasm-bindgen\",\"optional\":true,\"req\":\"^0.2.98\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", any(target_os = \\\"unknown\\\", target_os = \\\"none\\\")))\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", any(target_os = \\\"unknown\\\", target_os = \\\"none\\\")))\"}],\"features\":{\"std\":[],\"sys_rng\":[\"dep:rand_core\"],\"wasm_js\":[\"dep:wasm-bindgen\",\"dep:js-sys\"]}}", + "ghash_0.5.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3\"},{\"name\":\"opaque-debug\",\"req\":\"^0.3\"},{\"name\":\"polyval\",\"req\":\"^0.6.2\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"std\":[\"polyval/std\"]}}", "gif_0.14.1": "{\"dependencies\":[{\"name\":\"color_quant\",\"optional\":true,\"req\":\"^1.1\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7.0\"},{\"kind\":\"dev\",\"name\":\"glob\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"png\",\"req\":\"^0.18.0\"},{\"kind\":\"dev\",\"name\":\"rayon\",\"req\":\"^1.10.0\"},{\"name\":\"weezl\",\"req\":\"^0.1.10\"}],\"features\":{\"color_quant\":[\"dep:color_quant\"],\"default\":[\"raii_no_panic\",\"std\",\"color_quant\"],\"raii_no_panic\":[],\"std\":[]}}", "gimli_0.32.3": "{\"dependencies\":[{\"name\":\"alloc\",\"optional\":true,\"package\":\"rustc-std-workspace-alloc\",\"req\":\"^1.0.0\"},{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"default_features\":false,\"name\":\"fallible-iterator\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^2.0.0\"},{\"default_features\":false,\"name\":\"stable_deref_trait\",\"optional\":true,\"req\":\"^1.1.0\"},{\"kind\":\"dev\",\"name\":\"test-assembler\",\"req\":\"^0.1.3\"}],\"features\":{\"default\":[\"read-all\",\"write\"],\"endian-reader\":[\"read\",\"dep:stable_deref_trait\"],\"fallible-iterator\":[\"dep:fallible-iterator\"],\"read\":[\"read-core\"],\"read-all\":[\"read\",\"std\",\"fallible-iterator\",\"endian-reader\"],\"read-core\":[],\"rustc-dep-of-std\":[\"dep:core\",\"dep:alloc\"],\"std\":[\"fallible-iterator?/std\",\"stable_deref_trait?/std\"],\"write\":[\"dep:indexmap\"]}}", "git+https://github.com/dzbarsky/rules_rust?rev=b56cbaa8465e74127f1ea216f813cd377295ad81#b56cbaa8465e74127f1ea216f813cd377295ad81_runfiles": "{\"dependencies\":[],\"features\":{},\"strip_prefix\":\"\"}", @@ -893,6 +908,7 @@ "git2_0.20.4": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2.1.0\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^4.4.13\"},{\"name\":\"libc\",\"req\":\"^0.2\"},{\"name\":\"libgit2-sys\",\"req\":\"^0.18.3\"},{\"name\":\"log\",\"req\":\"^0.4.8\"},{\"name\":\"openssl-probe\",\"optional\":true,\"req\":\"^0.1\",\"target\":\"cfg(all(unix, not(target_os = \\\"macos\\\")))\"},{\"name\":\"openssl-sys\",\"optional\":true,\"req\":\"^0.9.45\",\"target\":\"cfg(all(unix, not(target_os = \\\"macos\\\")))\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.1.0\"},{\"features\":[\"formatting\"],\"kind\":\"dev\",\"name\":\"time\",\"req\":\"^0.3.37\"},{\"name\":\"url\",\"req\":\"^2.5.4\"}],\"features\":{\"default\":[\"ssh\",\"https\"],\"https\":[\"libgit2-sys/https\",\"openssl-sys\",\"openssl-probe\"],\"ssh\":[\"libgit2-sys/ssh\"],\"unstable\":[],\"vendored-libgit2\":[\"libgit2-sys/vendored\"],\"vendored-openssl\":[\"openssl-sys/vendored\",\"libgit2-sys/vendored-openssl\"],\"zlib-ng-compat\":[\"libgit2-sys/zlib-ng-compat\"]}}", "glob_0.3.3": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"tempdir\",\"req\":\"^0.3\"}],\"features\":{}}", "globset_0.4.18": "{\"dependencies\":[{\"name\":\"aho-corasick\",\"req\":\"^1.1.1\"},{\"features\":[\"derive\"],\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1.3.2\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"bstr\",\"req\":\"^1.6.2\"},{\"kind\":\"dev\",\"name\":\"glob\",\"req\":\"^0.3.1\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.20\"},{\"default_features\":false,\"features\":[\"std\",\"perf\",\"syntax\",\"meta\",\"nfa\",\"hybrid\"],\"name\":\"regex-automata\",\"req\":\"^0.4.0\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"regex-syntax\",\"req\":\"^0.8.0\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.188\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.107\"}],\"features\":{\"arbitrary\":[\"dep:arbitrary\"],\"default\":[\"log\"],\"serde1\":[\"serde\"],\"simd-accel\":[]}}", + "group_0.13.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"ff\",\"req\":\"^0.13\"},{\"name\":\"memuse\",\"optional\":true,\"req\":\"^0.2\"},{\"default_features\":false,\"name\":\"rand\",\"optional\":true,\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"name\":\"rand_xorshift\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2.2.1\"}],\"features\":{\"alloc\":[],\"default\":[\"alloc\"],\"tests\":[\"alloc\",\"rand\",\"rand_xorshift\"],\"wnaf-memuse\":[\"alloc\",\"memuse\"]}}", "gzip-header_1.0.0": "{\"dependencies\":[{\"name\":\"crc32fast\",\"req\":\"^1.2.1\"}],\"features\":{}}", "h2_0.4.13": "{\"dependencies\":[{\"name\":\"atomic-waker\",\"req\":\"^1.0.0\"},{\"name\":\"bytes\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10\"},{\"name\":\"fnv\",\"req\":\"^1.0.5\"},{\"default_features\":false,\"name\":\"futures-core\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"futures-sink\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4.3\"},{\"name\":\"http\",\"req\":\"^1\"},{\"features\":[\"std\"],\"name\":\"indexmap\",\"req\":\"^2\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0.3\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.4\"},{\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.0\"},{\"name\":\"slab\",\"req\":\"^0.4.2\"},{\"features\":[\"io-util\"],\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"rt-multi-thread\",\"macros\",\"sync\",\"net\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tokio-rustls\",\"req\":\"^0.26\"},{\"features\":[\"codec\",\"io\"],\"name\":\"tokio-util\",\"req\":\"^0.7.1\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"req\":\"^0.1.35\"},{\"kind\":\"dev\",\"name\":\"walkdir\",\"req\":\"^2.3.2\"},{\"kind\":\"dev\",\"name\":\"webpki-roots\",\"req\":\"^1\"}],\"features\":{\"stream\":[],\"unstable\":[]}}", "half_2.7.1": "{\"dependencies\":[{\"features\":[\"derive\"],\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1.4.1\"},{\"default_features\":false,\"features\":[\"derive\"],\"name\":\"bytemuck\",\"optional\":true,\"req\":\"^1.4.1\"},{\"name\":\"cfg-if\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"name\":\"crunchy\",\"req\":\"^0.2.2\",\"target\":\"cfg(target_arch = \\\"spirv\\\")\"},{\"kind\":\"dev\",\"name\":\"crunchy\",\"req\":\"^0.2.2\"},{\"default_features\":false,\"features\":[\"libm\"],\"name\":\"num-traits\",\"optional\":true,\"req\":\"^0.2.16\"},{\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"quickcheck_macros\",\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"thread_rng\"],\"name\":\"rand\",\"optional\":true,\"req\":\"^0.9.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9.0\"},{\"default_features\":false,\"name\":\"rand_distr\",\"optional\":true,\"req\":\"^0.5.0\"},{\"name\":\"rkyv\",\"optional\":true,\"req\":\"^0.8.0\"},{\"default_features\":false,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"derive\",\"simd\"],\"name\":\"zerocopy\",\"req\":\"^0.8.26\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"nightly\":[],\"rand_distr\":[\"dep:rand\",\"dep:rand_distr\"],\"std\":[\"alloc\"],\"use-intrinsics\":[],\"zerocopy\":[]}}", @@ -923,7 +939,7 @@ "hyper-rustls_0.27.7": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"cfg-if\",\"req\":\"^1\"},{\"name\":\"http\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"http-body-util\",\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"hyper\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"client-legacy\",\"tokio\"],\"name\":\"hyper-util\",\"req\":\"^0.1\"},{\"default_features\":false,\"features\":[\"server-auto\"],\"kind\":\"dev\",\"name\":\"hyper-util\",\"req\":\"^0.1\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.4\"},{\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"rustls\",\"req\":\"^0.23\"},{\"default_features\":false,\"features\":[\"tls12\"],\"kind\":\"dev\",\"name\":\"rustls\",\"req\":\"^0.23\"},{\"name\":\"rustls-native-certs\",\"optional\":true,\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"rustls-pemfile\",\"req\":\"^2\"},{\"name\":\"rustls-platform-verifier\",\"optional\":true,\"req\":\"^0.6\"},{\"name\":\"tokio\",\"req\":\"^1.0\"},{\"features\":[\"io-std\",\"macros\",\"net\",\"rt-multi-thread\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"tokio-rustls\",\"req\":\"^0.26\"},{\"name\":\"tower-service\",\"req\":\"^0.3\"},{\"name\":\"webpki-roots\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"aws-lc-rs\":[\"rustls/aws_lc_rs\"],\"default\":[\"native-tokio\",\"http1\",\"tls12\",\"logging\",\"aws-lc-rs\"],\"fips\":[\"aws-lc-rs\",\"rustls/fips\"],\"http1\":[\"hyper-util/http1\"],\"http2\":[\"hyper-util/http2\"],\"logging\":[\"log\",\"tokio-rustls/logging\",\"rustls/logging\"],\"native-tokio\":[\"rustls-native-certs\"],\"ring\":[\"rustls/ring\"],\"tls12\":[\"tokio-rustls/tls12\",\"rustls/tls12\"],\"webpki-tokio\":[\"webpki-roots\"]}}", "hyper-timeout_0.5.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"http-body-util\",\"req\":\"^0.1\"},{\"name\":\"hyper\",\"req\":\"^1.1\"},{\"features\":[\"http1\"],\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^1.1\"},{\"kind\":\"dev\",\"name\":\"hyper-tls\",\"req\":\"^0.6\"},{\"features\":[\"client-legacy\",\"http1\"],\"name\":\"hyper-util\",\"req\":\"^0.1.10\"},{\"features\":[\"client-legacy\",\"http1\",\"server\",\"server-graceful\"],\"kind\":\"dev\",\"name\":\"hyper-util\",\"req\":\"^0.1.10\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2\"},{\"name\":\"tokio\",\"req\":\"^1.35\"},{\"features\":[\"io-std\",\"io-util\",\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.35\"},{\"name\":\"tower-service\",\"req\":\"^0.3\"}],\"features\":{}}", "hyper-tls_0.6.0": "{\"dependencies\":[{\"name\":\"bytes\",\"req\":\"^1\"},{\"name\":\"http-body-util\",\"req\":\"^0.1.0\"},{\"name\":\"hyper\",\"req\":\"^1\"},{\"features\":[\"client-legacy\",\"tokio\"],\"name\":\"hyper-util\",\"req\":\"^0.1.0\"},{\"features\":[\"http1\"],\"kind\":\"dev\",\"name\":\"hyper-util\",\"req\":\"^0.1.0\"},{\"name\":\"native-tls\",\"req\":\"^0.2.1\"},{\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"io-std\",\"macros\",\"io-util\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0.0\"},{\"name\":\"tokio-native-tls\",\"req\":\"^0.3\"},{\"name\":\"tower-service\",\"req\":\"^0.3\"}],\"features\":{\"alpn\":[\"native-tls/alpn\"],\"vendored\":[\"native-tls/vendored\"]}}", - "hyper-util_0.1.20": "{\"dependencies\":[{\"name\":\"base64\",\"optional\":true,\"req\":\"^0.22\"},{\"name\":\"bytes\",\"req\":\"^1.7.1\"},{\"kind\":\"dev\",\"name\":\"bytes\",\"req\":\"^1\"},{\"name\":\"futures-channel\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3.16\"},{\"default_features\":false,\"features\":[\"alloc\"],\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3.16\"},{\"name\":\"http\",\"req\":\"^1.0\"},{\"name\":\"http-body\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"http-body-util\",\"req\":\"^0.1.0\"},{\"name\":\"hyper\",\"req\":\"^1.8.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^1.4.0\"},{\"name\":\"ipnet\",\"optional\":true,\"req\":\"^2.9\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"percent-encoding\",\"optional\":true,\"req\":\"^2.3\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.4\"},{\"kind\":\"dev\",\"name\":\"pnet_datalink\",\"req\":\"^0.35.0\",\"target\":\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"macos\\\"))\"},{\"kind\":\"dev\",\"name\":\"pretty_env_logger\",\"req\":\"^0.5\"},{\"features\":[\"all\"],\"name\":\"socket2\",\"optional\":true,\"req\":\">=0.5.9, <0.7\"},{\"name\":\"system-configuration\",\"optional\":true,\"req\":\"^0.7\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"default_features\":false,\"name\":\"tokio\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"macros\",\"test-util\",\"signal\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"name\":\"tower-layer\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"tower-service\",\"optional\":true,\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"tower-test\",\"req\":\"^0.4\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"windows-registry\",\"optional\":true,\"req\":\">=0.3, <0.7\",\"target\":\"cfg(windows)\"}],\"features\":{\"__internal_happy_eyeballs_tests\":[],\"client\":[\"hyper/client\",\"tokio/net\",\"dep:tracing\",\"dep:futures-channel\",\"dep:tower-service\"],\"client-legacy\":[\"client\",\"dep:socket2\",\"tokio/sync\",\"dep:libc\",\"dep:futures-util\"],\"client-pool\":[\"client\",\"dep:futures-util\",\"dep:tower-layer\"],\"client-proxy\":[\"client\",\"dep:base64\",\"dep:ipnet\",\"dep:percent-encoding\"],\"client-proxy-system\":[\"dep:system-configuration\",\"dep:windows-registry\"],\"default\":[],\"full\":[\"client\",\"client-legacy\",\"client-pool\",\"client-proxy\",\"client-proxy-system\",\"server\",\"server-auto\",\"server-graceful\",\"service\",\"http1\",\"http2\",\"tokio\",\"tracing\"],\"http1\":[\"hyper/http1\"],\"http2\":[\"hyper/http2\"],\"server\":[\"hyper/server\"],\"server-auto\":[\"server\",\"http1\",\"http2\"],\"server-graceful\":[\"server\",\"tokio/sync\"],\"service\":[\"dep:tower-service\"],\"tokio\":[\"dep:tokio\",\"tokio/rt\",\"tokio/time\"],\"tracing\":[\"dep:tracing\"]}}", + "hyper-util_0.1.19": "{\"dependencies\":[{\"name\":\"base64\",\"optional\":true,\"req\":\"^0.22\"},{\"name\":\"bytes\",\"req\":\"^1.7.1\"},{\"kind\":\"dev\",\"name\":\"bytes\",\"req\":\"^1\"},{\"name\":\"futures-channel\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"futures-core\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3.16\"},{\"default_features\":false,\"features\":[\"alloc\"],\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3.16\"},{\"name\":\"http\",\"req\":\"^1.0\"},{\"name\":\"http-body\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"http-body-util\",\"req\":\"^0.1.0\"},{\"name\":\"hyper\",\"req\":\"^1.8.0\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^1.4.0\"},{\"name\":\"ipnet\",\"optional\":true,\"req\":\"^2.9\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"percent-encoding\",\"optional\":true,\"req\":\"^2.3\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.4\"},{\"kind\":\"dev\",\"name\":\"pnet_datalink\",\"req\":\"^0.35.0\",\"target\":\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"macos\\\"))\"},{\"kind\":\"dev\",\"name\":\"pretty_env_logger\",\"req\":\"^0.5\"},{\"features\":[\"all\"],\"name\":\"socket2\",\"optional\":true,\"req\":\">=0.5.9, <0.7\"},{\"name\":\"system-configuration\",\"optional\":true,\"req\":\">=0.5, <0.7\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"default_features\":false,\"name\":\"tokio\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"macros\",\"test-util\",\"signal\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"name\":\"tower-layer\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"tower-service\",\"optional\":true,\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"tower-test\",\"req\":\"^0.4\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"windows-registry\",\"optional\":true,\"req\":\">=0.3, <0.7\",\"target\":\"cfg(windows)\"}],\"features\":{\"__internal_happy_eyeballs_tests\":[],\"client\":[\"hyper/client\",\"tokio/net\",\"dep:tracing\",\"dep:futures-channel\",\"dep:tower-service\"],\"client-legacy\":[\"client\",\"dep:socket2\",\"tokio/sync\",\"dep:libc\",\"dep:futures-util\"],\"client-pool\":[\"client\",\"dep:futures-util\",\"dep:tower-layer\"],\"client-proxy\":[\"client\",\"dep:base64\",\"dep:ipnet\",\"dep:percent-encoding\"],\"client-proxy-system\":[\"dep:system-configuration\",\"dep:windows-registry\"],\"default\":[],\"full\":[\"client\",\"client-legacy\",\"client-pool\",\"client-proxy\",\"client-proxy-system\",\"server\",\"server-auto\",\"server-graceful\",\"service\",\"http1\",\"http2\",\"tokio\",\"tracing\"],\"http1\":[\"hyper/http1\"],\"http2\":[\"hyper/http2\"],\"server\":[\"hyper/server\"],\"server-auto\":[\"server\",\"http1\",\"http2\"],\"server-graceful\":[\"server\",\"tokio/sync\"],\"service\":[\"dep:tower-service\"],\"tokio\":[\"dep:tokio\",\"tokio/rt\",\"tokio/time\"],\"tracing\":[\"dep:tracing\"]}}", "hyper_1.8.1": "{\"dependencies\":[{\"name\":\"atomic-waker\",\"optional\":true,\"req\":\"^1.1.2\"},{\"name\":\"bytes\",\"req\":\"^1.2\"},{\"kind\":\"dev\",\"name\":\"form_urlencoded\",\"req\":\"^1\"},{\"name\":\"futures-channel\",\"optional\":true,\"req\":\"^0.3\"},{\"features\":[\"sink\"],\"kind\":\"dev\",\"name\":\"futures-channel\",\"req\":\"^0.3\"},{\"name\":\"futures-core\",\"optional\":true,\"req\":\"^0.3.31\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"alloc\",\"sink\"],\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3\"},{\"name\":\"h2\",\"optional\":true,\"req\":\"^0.4.2\"},{\"name\":\"http\",\"req\":\"^1\"},{\"name\":\"http-body\",\"req\":\"^1\"},{\"name\":\"http-body-util\",\"optional\":true,\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"http-body-util\",\"req\":\"^0.1\"},{\"name\":\"httparse\",\"optional\":true,\"req\":\"^1.9\"},{\"name\":\"httpdate\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"itoa\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"pin-project-lite\",\"optional\":true,\"req\":\"^0.2.4\"},{\"kind\":\"dev\",\"name\":\"pin-project-lite\",\"req\":\"^0.2.4\"},{\"name\":\"pin-utils\",\"optional\":true,\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"pretty_env_logger\",\"req\":\"^0.5\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"features\":[\"const_generics\",\"const_new\"],\"name\":\"smallvec\",\"optional\":true,\"req\":\"^1.12\"},{\"kind\":\"dev\",\"name\":\"spmc\",\"req\":\"^0.3\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"fs\",\"macros\",\"net\",\"io-std\",\"io-util\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\",\"test-util\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"tokio-util\",\"req\":\"^0.7.10\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"want\",\"optional\":true,\"req\":\"^0.3\"}],\"features\":{\"capi\":[],\"client\":[\"dep:want\",\"dep:pin-project-lite\",\"dep:smallvec\"],\"default\":[],\"ffi\":[\"dep:http-body-util\",\"dep:futures-util\"],\"full\":[\"client\",\"http1\",\"http2\",\"server\"],\"http1\":[\"dep:atomic-waker\",\"dep:futures-channel\",\"dep:futures-core\",\"dep:httparse\",\"dep:itoa\",\"dep:pin-utils\"],\"http2\":[\"dep:futures-channel\",\"dep:futures-core\",\"dep:h2\"],\"nightly\":[],\"server\":[\"dep:httpdate\",\"dep:pin-project-lite\",\"dep:smallvec\"],\"tracing\":[\"dep:tracing\"]}}", "i18n-config_0.4.8": "{\"dependencies\":[{\"name\":\"basic-toml\",\"req\":\"^0.1\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_derive\",\"req\":\"^1.0\"},{\"name\":\"thiserror\",\"req\":\"^1.0\"},{\"features\":[\"serde\"],\"name\":\"unic-langid\",\"req\":\"^0.9\"}],\"features\":{}}", "i18n-embed-fl_0.9.4": "{\"dependencies\":[{\"name\":\"dashmap\",\"optional\":true,\"req\":\"^6.0\"},{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11\"},{\"name\":\"find-crate\",\"req\":\"^0.6\"},{\"name\":\"fluent\",\"req\":\"^0.16\"},{\"name\":\"fluent-syntax\",\"req\":\"^0.11\"},{\"name\":\"i18n-config\",\"req\":\"^0.4.7\"},{\"features\":[\"fluent-system\",\"filesystem-assets\"],\"name\":\"i18n-embed\",\"req\":\"^0.15.4\"},{\"kind\":\"dev\",\"name\":\"pretty_assertions\",\"req\":\"^1.4\"},{\"name\":\"proc-macro-error2\",\"req\":\"^2.0.1\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rust-embed\",\"req\":\"^8.0\"},{\"name\":\"strsim\",\"req\":\"^0.11\"},{\"features\":[\"derive\",\"proc-macro\",\"parsing\",\"printing\",\"extra-traits\",\"full\"],\"name\":\"syn\",\"req\":\"^2.0\"},{\"name\":\"unic-langid\",\"req\":\"^0.9\"}],\"features\":{\"dashmap\":[\"dep:dashmap\"]}}", @@ -964,6 +980,7 @@ "inout_0.1.4": "{\"dependencies\":[{\"name\":\"block-padding\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"generic-array\",\"req\":\"^0.14\"}],\"features\":{\"std\":[\"block-padding/std\"]}}", "insta_1.46.3": "{\"dependencies\":[{\"features\":[\"derive\",\"env\"],\"name\":\"clap\",\"optional\":true,\"req\":\"^4.1\"},{\"default_features\":false,\"name\":\"console\",\"optional\":true,\"req\":\"^0.15.4\"},{\"name\":\"csv\",\"optional\":true,\"req\":\"^1.1.6\"},{\"name\":\"globset\",\"optional\":true,\"req\":\"^0.4.6\"},{\"name\":\"once_cell\",\"req\":\"^1.20.2\"},{\"name\":\"pest\",\"optional\":true,\"req\":\"^2.1.3\"},{\"name\":\"pest_derive\",\"optional\":true,\"req\":\"^2.1.0\"},{\"default_features\":false,\"features\":[\"std\",\"unicode\"],\"name\":\"regex\",\"optional\":true,\"req\":\"^1.6.0\"},{\"name\":\"ron\",\"optional\":true,\"req\":\"^0.12.0\"},{\"kind\":\"dev\",\"name\":\"rustc_version\",\"req\":\"^0.4.0\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.117\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.117\"},{\"features\":[\"inline\"],\"name\":\"similar\",\"req\":\"^2.1.0\"},{\"kind\":\"dev\",\"name\":\"similar-asserts\",\"req\":\"^1.4.2\"},{\"name\":\"tempfile\",\"req\":\"^3\"},{\"features\":[\"serde\",\"parse\",\"display\"],\"name\":\"toml_edit\",\"optional\":true,\"req\":\"^0.23.0\"},{\"name\":\"toml_writer\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"walkdir\",\"optional\":true,\"req\":\"^2.3.1\"}],\"features\":{\"_cargo_insta_internal\":[\"clap\"],\"colors\":[\"console\"],\"csv\":[\"dep:csv\",\"serde\"],\"default\":[\"colors\"],\"filters\":[\"regex\"],\"glob\":[\"walkdir\",\"globset\"],\"json\":[\"serde\"],\"redactions\":[\"pest\",\"pest_derive\",\"serde\"],\"ron\":[\"dep:ron\",\"serde\"],\"toml\":[\"dep:toml_edit\",\"dep:toml_writer\",\"serde\"],\"yaml\":[\"serde\"]}}", "instability_0.3.11": "{\"dependencies\":[{\"name\":\"darling\",\"req\":\"^0.23\"},{\"name\":\"indoc\",\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"pretty_assertions\",\"req\":\"^1.4\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0.86\"},{\"name\":\"quote\",\"req\":\"^1.0.25\"},{\"features\":[\"derive\",\"full\"],\"name\":\"syn\",\"req\":\"^2.0.15\"}],\"features\":{}}", + "interceptor_0.17.1": "{\"dependencies\":[{\"name\":\"async-trait\",\"req\":\"^0.1\"},{\"name\":\"bytes\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4.28\"},{\"name\":\"futures\",\"req\":\"^0.3\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"name\":\"rtcp\",\"req\":\"^0.17.1\"},{\"name\":\"rtp\",\"req\":\"^0.17.1\"},{\"name\":\"srtp\",\"package\":\"webrtc-srtp\",\"req\":\"^0.17.1\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"default_features\":false,\"features\":[\"marshal\",\"sync\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"},{\"name\":\"waitgroup\",\"req\":\"^0.1\"}],\"features\":{}}", "intl-memoizer_0.5.3": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"fluent-langneg\",\"req\":\"^0.13\"},{\"kind\":\"dev\",\"name\":\"intl_pluralrules\",\"req\":\"^7.0\"},{\"name\":\"type-map\",\"req\":\"^0.5\"},{\"name\":\"unic-langid\",\"req\":\"^0.9\"}],\"features\":{}}", "intl_pluralrules_7.0.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"},{\"name\":\"unic-langid\",\"req\":\"^0.9\"},{\"features\":[\"macros\"],\"kind\":\"dev\",\"name\":\"unic-langid\",\"req\":\"^0.9\"}],\"features\":{}}", "inventory_0.3.21": "{\"dependencies\":[{\"name\":\"rustversion\",\"req\":\"^1.0\",\"target\":\"cfg(target_family = \\\"wasm\\\")\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.89\"}],\"features\":{}}", @@ -1038,6 +1055,7 @@ "memchr_2.7.6": "{\"dependencies\":[{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.20\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0.3\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"libc\":[],\"logging\":[\"dep:log\"],\"rustc-dep-of-std\":[\"core\"],\"std\":[\"alloc\"],\"use_std\":[\"std\"]}}", "memchr_2.8.0": "{\"dependencies\":[{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.20\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0.3\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"libc\":[],\"logging\":[\"dep:log\"],\"rustc-dep-of-std\":[\"core\"],\"std\":[\"alloc\"],\"use_std\":[\"std\"]}}", "memoffset_0.6.5": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"autocfg\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\"}],\"features\":{\"default\":[],\"unstable_const\":[]}}", + "memoffset_0.7.1": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"autocfg\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\"}],\"features\":{\"default\":[],\"unstable_const\":[]}}", "memoffset_0.9.1": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"autocfg\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\"}],\"features\":{\"default\":[],\"unstable_const\":[],\"unstable_offset_of\":[]}}", "mime_0.3.17": "{\"dependencies\":[],\"features\":{}}", "mime_guess_2.0.5": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"},{\"name\":\"mime\",\"req\":\"^0.3\"},{\"name\":\"unicase\",\"req\":\"^2.4.0\"},{\"kind\":\"build\",\"name\":\"unicase\",\"req\":\"^2.4.0\"}],\"features\":{\"default\":[\"rev-mappings\"],\"rev-mappings\":[]}}", @@ -1048,12 +1066,15 @@ "moka_0.12.13": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"actix-rt\",\"req\":\"^2.8\"},{\"kind\":\"dev\",\"name\":\"ahash\",\"req\":\"^0.8.3\"},{\"kind\":\"dev\",\"name\":\"anyhow\",\"req\":\"^1.0.19\"},{\"name\":\"async-lock\",\"optional\":true,\"req\":\"^3.3\"},{\"name\":\"crossbeam-channel\",\"req\":\"^0.5.15\"},{\"name\":\"crossbeam-epoch\",\"req\":\"^0.9.18\"},{\"name\":\"crossbeam-utils\",\"req\":\"^0.8.21\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10.0\"},{\"name\":\"equivalent\",\"req\":\"^1.0\"},{\"name\":\"event-listener\",\"optional\":true,\"req\":\"^5.3\"},{\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3.17\"},{\"kind\":\"dev\",\"name\":\"getrandom\",\"req\":\"^0.2\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"loom\",\"req\":\"^0.7\",\"target\":\"cfg(moka_loom)\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"^1.7\"},{\"name\":\"parking_lot\",\"req\":\"^0.12\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"quanta\",\"optional\":true,\"req\":\"^0.12.2\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.5\"},{\"default_features\":false,\"features\":[\"rustls-tls\"],\"kind\":\"dev\",\"name\":\"reqwest\",\"req\":\"^0.12\"},{\"name\":\"smallvec\",\"req\":\"^1.8\"},{\"name\":\"tagptr\",\"req\":\"^0.2\"},{\"features\":[\"fs\",\"io-util\",\"macros\",\"rt-multi-thread\",\"sync\",\"time\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.19\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0\",\"target\":\"cfg(trybuild)\"},{\"features\":[\"v4\"],\"name\":\"uuid\",\"req\":\"^1.1\"}],\"features\":{\"atomic64\":[],\"default\":[],\"future\":[\"async-lock\",\"event-listener\",\"futures-util\"],\"logging\":[\"log\"],\"quanta\":[\"dep:quanta\"],\"sync\":[],\"unstable-debug-counters\":[\"future\"]}}", "moxcms_0.7.11": "{\"dependencies\":[{\"name\":\"num-traits\",\"req\":\"^0.2\"},{\"name\":\"pxfm\",\"req\":\"^0.1.1\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"}],\"features\":{\"avx\":[],\"avx512\":[],\"default\":[\"avx\",\"sse\",\"neon\"],\"neon\":[],\"options\":[],\"sse\":[]}}", "multimap_0.10.1": "{\"dependencies\":[{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_test\",\"req\":\"^1.0\"}],\"features\":{\"default\":[\"serde_impl\"],\"serde_impl\":[\"serde\"]}}", + "munge_0.4.7": "{\"dependencies\":[{\"default_features\":false,\"name\":\"munge_macro\",\"req\":\"=0.4.7\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1\"}],\"features\":{}}", + "munge_macro_0.4.7": "{\"dependencies\":[{\"default_features\":false,\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"quote\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"clone-impls\",\"full\",\"parsing\",\"printing\",\"proc-macro\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}", "native-tls_0.2.14": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(target_vendor = \\\"apple\\\")\"},{\"name\":\"log\",\"req\":\"^0.4.5\",\"target\":\"cfg(not(any(target_os = \\\"windows\\\", target_vendor = \\\"apple\\\")))\"},{\"name\":\"openssl\",\"req\":\"^0.10.69\",\"target\":\"cfg(not(any(target_os = \\\"windows\\\", target_vendor = \\\"apple\\\")))\"},{\"name\":\"openssl-probe\",\"req\":\"^0.1\",\"target\":\"cfg(not(any(target_os = \\\"windows\\\", target_vendor = \\\"apple\\\")))\"},{\"name\":\"openssl-sys\",\"req\":\"^0.9.81\",\"target\":\"cfg(not(any(target_os = \\\"windows\\\", target_vendor = \\\"apple\\\")))\"},{\"name\":\"schannel\",\"req\":\"^0.1.17\",\"target\":\"cfg(target_os = \\\"windows\\\")\"},{\"name\":\"security-framework\",\"req\":\"^2.0.0\",\"target\":\"cfg(target_vendor = \\\"apple\\\")\"},{\"name\":\"security-framework-sys\",\"req\":\"^2.0.0\",\"target\":\"cfg(target_vendor = \\\"apple\\\")\"},{\"name\":\"tempfile\",\"req\":\"^3.1.0\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.0\"},{\"kind\":\"dev\",\"name\":\"test-cert-gen\",\"req\":\"^0.9\"}],\"features\":{\"alpn\":[\"security-framework/alpn\"],\"vendored\":[\"openssl/vendored\"]}}", "ndk-context_0.1.1": "{\"dependencies\":[],\"features\":{}}", "ndk-sys_0.5.0+25.2.9519653": "{\"dependencies\":[{\"name\":\"jni-sys\",\"req\":\"^0.3.0\"}],\"features\":{\"audio\":[],\"bitmap\":[],\"media\":[],\"sync\":[],\"test\":[]}}", "ndk_0.8.0": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2.0.0\"},{\"name\":\"ffi\",\"package\":\"ndk-sys\",\"req\":\"^0.5.0\"},{\"name\":\"jni\",\"optional\":true,\"req\":\"^0.21\"},{\"name\":\"jni-sys\",\"req\":\"^0.3.0\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"num_enum\",\"req\":\"^0.7\"},{\"name\":\"rwh_04\",\"optional\":true,\"package\":\"raw-window-handle\",\"req\":\"^0.4\"},{\"name\":\"rwh_05\",\"optional\":true,\"package\":\"raw-window-handle\",\"req\":\"^0.5\"},{\"name\":\"rwh_06\",\"optional\":true,\"package\":\"raw-window-handle\",\"req\":\"^0.6\"},{\"name\":\"thiserror\",\"req\":\"^1.0.23\"}],\"features\":{\"all\":[\"audio\",\"bitmap\",\"media\",\"api-level-31\",\"rwh_04\",\"rwh_05\",\"rwh_06\"],\"api-level-23\":[],\"api-level-24\":[\"api-level-23\"],\"api-level-25\":[\"api-level-24\"],\"api-level-26\":[\"api-level-25\"],\"api-level-27\":[\"api-level-26\"],\"api-level-28\":[\"api-level-27\"],\"api-level-29\":[\"api-level-28\"],\"api-level-30\":[\"api-level-29\"],\"api-level-31\":[\"api-level-30\"],\"audio\":[\"ffi/audio\",\"api-level-26\"],\"bitmap\":[\"ffi/bitmap\"],\"default\":[\"rwh_06\"],\"media\":[\"ffi/media\"],\"sync\":[\"ffi/sync\",\"api-level-26\"],\"test\":[\"ffi/test\",\"jni\",\"all\"]}}", "new_debug_unreachable_1.0.6": "{\"dependencies\":[],\"features\":{}}", "nibble_vec_0.1.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"},{\"name\":\"smallvec\",\"req\":\"^1.0\"}],\"features\":{}}", + "nix_0.26.4": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"assert-impl\",\"req\":\"^0.1\"},{\"name\":\"bitflags\",\"req\":\"^1.1\"},{\"kind\":\"dev\",\"name\":\"caps\",\"req\":\"^0.5.3\",\"target\":\"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"))\"},{\"name\":\"cfg-if\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1.4\"},{\"features\":[\"extra_traits\"],\"name\":\"libc\",\"req\":\"^0.2.137\"},{\"name\":\"memoffset\",\"optional\":true,\"req\":\"^0.7\",\"target\":\"cfg(not(target_os = \\\"redox\\\"))\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12\"},{\"name\":\"pin-utils\",\"optional\":true,\"req\":\"^0.1.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"semver\",\"req\":\"^1.0.7\"},{\"kind\":\"dev\",\"name\":\"sysctl\",\"req\":\"^0.4\",\"target\":\"cfg(target_os = \\\"freebsd\\\")\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.3\"}],\"features\":{\"acct\":[],\"aio\":[\"pin-utils\"],\"default\":[\"acct\",\"aio\",\"dir\",\"env\",\"event\",\"feature\",\"fs\",\"hostname\",\"inotify\",\"ioctl\",\"kmod\",\"mman\",\"mount\",\"mqueue\",\"net\",\"personality\",\"poll\",\"process\",\"pthread\",\"ptrace\",\"quota\",\"reboot\",\"resource\",\"sched\",\"signal\",\"socket\",\"term\",\"time\",\"ucontext\",\"uio\",\"user\",\"zerocopy\"],\"dir\":[\"fs\"],\"env\":[],\"event\":[],\"feature\":[],\"fs\":[],\"hostname\":[],\"inotify\":[],\"ioctl\":[],\"kmod\":[],\"mman\":[],\"mount\":[\"uio\"],\"mqueue\":[\"fs\"],\"net\":[\"socket\"],\"personality\":[],\"poll\":[],\"process\":[],\"pthread\":[],\"ptrace\":[\"process\"],\"quota\":[],\"reboot\":[],\"resource\":[],\"sched\":[\"process\"],\"signal\":[\"process\"],\"socket\":[\"memoffset\"],\"term\":[],\"time\":[],\"ucontext\":[\"signal\"],\"uio\":[],\"user\":[\"feature\"],\"zerocopy\":[\"fs\",\"uio\"]}}", "nix_0.28.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"assert-impl\",\"req\":\"^0.1\"},{\"name\":\"bitflags\",\"req\":\"^2.3.1\"},{\"kind\":\"dev\",\"name\":\"caps\",\"req\":\"^0.5.3\",\"target\":\"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"))\"},{\"name\":\"cfg-if\",\"req\":\"^1.0\"},{\"kind\":\"build\",\"name\":\"cfg_aliases\",\"req\":\"^0.1.1\"},{\"features\":[\"extra_traits\"],\"name\":\"libc\",\"req\":\"^0.2.153\"},{\"name\":\"memoffset\",\"optional\":true,\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12\"},{\"name\":\"pin-utils\",\"optional\":true,\"req\":\"^0.1.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"semver\",\"req\":\"^1.0.7\"},{\"kind\":\"dev\",\"name\":\"sysctl\",\"req\":\"^0.4\",\"target\":\"cfg(target_os = \\\"freebsd\\\")\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.7.1\"}],\"features\":{\"acct\":[],\"aio\":[\"pin-utils\"],\"default\":[],\"dir\":[\"fs\"],\"env\":[],\"event\":[],\"fanotify\":[],\"feature\":[],\"fs\":[],\"hostname\":[],\"inotify\":[],\"ioctl\":[],\"kmod\":[],\"mman\":[],\"mount\":[\"uio\"],\"mqueue\":[\"fs\"],\"net\":[\"socket\"],\"personality\":[],\"poll\":[],\"process\":[],\"pthread\":[],\"ptrace\":[\"process\"],\"quota\":[],\"reboot\":[],\"resource\":[],\"sched\":[\"process\"],\"signal\":[\"process\"],\"socket\":[\"memoffset\"],\"term\":[],\"time\":[],\"ucontext\":[\"signal\"],\"uio\":[],\"user\":[\"feature\"],\"zerocopy\":[\"fs\",\"uio\"]}}", "nix_0.29.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"assert-impl\",\"req\":\"^0.1\"},{\"name\":\"bitflags\",\"req\":\"^2.3.1\"},{\"kind\":\"dev\",\"name\":\"caps\",\"req\":\"^0.5.3\",\"target\":\"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"))\"},{\"name\":\"cfg-if\",\"req\":\"^1.0\"},{\"kind\":\"build\",\"name\":\"cfg_aliases\",\"req\":\"^0.2\"},{\"features\":[\"extra_traits\"],\"name\":\"libc\",\"req\":\"^0.2.155\"},{\"name\":\"memoffset\",\"optional\":true,\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12\"},{\"name\":\"pin-utils\",\"optional\":true,\"req\":\"^0.1.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"semver\",\"req\":\"^1.0.7\"},{\"kind\":\"dev\",\"name\":\"sysctl\",\"req\":\"^0.4\",\"target\":\"cfg(target_os = \\\"freebsd\\\")\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.7.1\"}],\"features\":{\"acct\":[],\"aio\":[\"pin-utils\"],\"default\":[],\"dir\":[\"fs\"],\"env\":[],\"event\":[],\"fanotify\":[],\"feature\":[],\"fs\":[],\"hostname\":[],\"inotify\":[],\"ioctl\":[],\"kmod\":[],\"mman\":[],\"mount\":[\"uio\"],\"mqueue\":[\"fs\"],\"net\":[\"socket\"],\"personality\":[],\"poll\":[],\"process\":[],\"pthread\":[],\"ptrace\":[\"process\"],\"quota\":[],\"reboot\":[],\"resource\":[],\"sched\":[\"process\"],\"signal\":[\"process\"],\"socket\":[\"memoffset\"],\"term\":[],\"time\":[],\"ucontext\":[\"signal\"],\"uio\":[],\"user\":[\"feature\"],\"zerocopy\":[\"fs\",\"uio\"]}}", "nix_0.30.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"assert-impl\",\"req\":\"^0.1\"},{\"name\":\"bitflags\",\"req\":\"^2.3.3\"},{\"kind\":\"dev\",\"name\":\"caps\",\"req\":\"^0.5.3\",\"target\":\"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\"))\"},{\"name\":\"cfg-if\",\"req\":\"^1.0\"},{\"kind\":\"build\",\"name\":\"cfg_aliases\",\"req\":\"^0.2.1\"},{\"features\":[\"extra_traits\"],\"name\":\"libc\",\"req\":\"^0.2.171\"},{\"name\":\"memoffset\",\"optional\":true,\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"^0.12\"},{\"name\":\"pin-utils\",\"optional\":true,\"req\":\"^0.1.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"semver\",\"req\":\"^1.0.7\"},{\"kind\":\"dev\",\"name\":\"sysctl\",\"req\":\"^0.4\",\"target\":\"cfg(target_os = \\\"freebsd\\\")\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.7.1\"}],\"features\":{\"acct\":[],\"aio\":[\"pin-utils\"],\"default\":[],\"dir\":[\"fs\"],\"env\":[],\"event\":[\"poll\"],\"fanotify\":[],\"feature\":[],\"fs\":[],\"hostname\":[],\"inotify\":[],\"ioctl\":[],\"kmod\":[],\"mman\":[],\"mount\":[\"uio\"],\"mqueue\":[\"fs\"],\"net\":[\"socket\"],\"personality\":[],\"poll\":[],\"process\":[],\"pthread\":[],\"ptrace\":[\"process\"],\"quota\":[],\"reboot\":[],\"resource\":[],\"sched\":[\"process\"],\"signal\":[\"process\"],\"socket\":[\"memoffset\"],\"syslog\":[],\"term\":[],\"time\":[],\"ucontext\":[\"signal\"],\"uio\":[],\"user\":[\"feature\"],\"zerocopy\":[\"fs\",\"uio\"]}}", @@ -1096,6 +1117,7 @@ "object_0.37.3": "{\"dependencies\":[{\"name\":\"alloc\",\"optional\":true,\"package\":\"rustc-std-workspace-alloc\",\"req\":\"^1.0.0\"},{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"default_features\":false,\"name\":\"crc32fast\",\"optional\":true,\"req\":\"^1.2\"},{\"name\":\"flate2\",\"optional\":true,\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"default-hasher\"],\"name\":\"hashbrown\",\"optional\":true,\"req\":\"^0.15.0\"},{\"default_features\":false,\"name\":\"indexmap\",\"optional\":true,\"req\":\"^2.0\"},{\"default_features\":false,\"name\":\"memchr\",\"req\":\"^2.4.1\"},{\"name\":\"ruzstd\",\"optional\":true,\"req\":\"^0.8.1\"},{\"default_features\":false,\"name\":\"wasmparser\",\"optional\":true,\"req\":\"^0.236.0\"}],\"features\":{\"all\":[\"read\",\"write\",\"build\",\"std\",\"compression\",\"wasm\"],\"archive\":[],\"build\":[\"build_core\",\"write_std\",\"elf\"],\"build_core\":[\"read_core\",\"write_core\"],\"cargo-all\":[],\"coff\":[],\"compression\":[\"dep:flate2\",\"dep:ruzstd\",\"std\"],\"default\":[\"read\",\"compression\"],\"doc\":[\"read_core\",\"write_std\",\"build_core\",\"std\",\"compression\",\"archive\",\"coff\",\"elf\",\"macho\",\"pe\",\"wasm\",\"xcoff\"],\"elf\":[],\"macho\":[],\"pe\":[\"coff\"],\"read\":[\"read_core\",\"archive\",\"coff\",\"elf\",\"macho\",\"pe\",\"xcoff\",\"unaligned\"],\"read_core\":[],\"rustc-dep-of-std\":[\"core\",\"alloc\",\"memchr/rustc-dep-of-std\"],\"std\":[\"memchr/std\"],\"unaligned\":[],\"unstable\":[],\"unstable-all\":[\"all\",\"unstable\"],\"wasm\":[\"dep:wasmparser\"],\"write\":[\"write_std\",\"coff\",\"elf\",\"macho\",\"pe\",\"xcoff\"],\"write_core\":[\"dep:crc32fast\",\"dep:indexmap\",\"dep:hashbrown\"],\"write_std\":[\"write_core\",\"std\",\"indexmap?/std\",\"crc32fast?/std\"],\"xcoff\":[]}}", "oboe-sys_0.6.1": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"bindgen\",\"optional\":true,\"req\":\"^0.69\"},{\"features\":[\"parallel\"],\"kind\":\"build\",\"name\":\"cc\",\"req\":\"^1\"},{\"kind\":\"build\",\"name\":\"fetch_unroll\",\"optional\":true,\"req\":\"^0.3\"}],\"features\":{\"fetch-prebuilt\":[\"fetch_unroll\"],\"generate-bindings\":[\"bindgen\"],\"shared-link\":[],\"shared-stdcxx\":[],\"test\":[]}}", "oboe_0.6.1": "{\"dependencies\":[{\"name\":\"jni\",\"optional\":true,\"req\":\"^0.21\"},{\"default_features\":false,\"name\":\"ndk\",\"optional\":true,\"req\":\"^0.8\"},{\"name\":\"ndk-context\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"num-derive\",\"req\":\"^0.4\"},{\"name\":\"num-traits\",\"req\":\"^0.2\"},{\"name\":\"oboe-sys\",\"req\":\"^0.6\"}],\"features\":{\"doc-cfg\":[],\"fetch-prebuilt\":[\"oboe-sys/fetch-prebuilt\"],\"generate-bindings\":[\"oboe-sys/generate-bindings\"],\"java-interface\":[\"ndk\",\"ndk-context\",\"jni\"],\"shared-link\":[\"oboe-sys/shared-link\"],\"shared-stdcxx\":[\"oboe-sys/shared-stdcxx\"]}}", + "oid-registry_0.7.1": "{\"dependencies\":[{\"name\":\"asn1-rs\",\"req\":\"^0.6\"}],\"features\":{\"crypto\":[\"kdf\",\"pkcs1\",\"pkcs7\",\"pkcs9\",\"pkcs12\",\"nist_algs\",\"x962\"],\"default\":[\"registry\"],\"kdf\":[],\"ms_spc\":[],\"nist_algs\":[],\"pkcs1\":[],\"pkcs12\":[],\"pkcs7\":[],\"pkcs9\":[],\"registry\":[],\"x500\":[],\"x509\":[],\"x962\":[]}}", "oid-registry_0.8.1": "{\"dependencies\":[{\"name\":\"asn1-rs\",\"req\":\"^0.7\"}],\"features\":{\"crypto\":[\"kdf\",\"pkcs1\",\"pkcs7\",\"pkcs9\",\"pkcs12\",\"nist_algs\",\"x962\"],\"default\":[\"registry\"],\"kdf\":[],\"ms_spc\":[],\"nist_algs\":[],\"pkcs1\":[],\"pkcs12\":[],\"pkcs7\":[],\"pkcs9\":[],\"registry\":[],\"x500\":[],\"x509\":[],\"x962\":[]}}", "once_cell_1.21.3": "{\"dependencies\":[{\"name\":\"critical-section\",\"optional\":true,\"req\":\"^1.1.3\"},{\"features\":[\"std\"],\"kind\":\"dev\",\"name\":\"critical-section\",\"req\":\"^1.1.3\"},{\"default_features\":false,\"name\":\"parking_lot_core\",\"optional\":true,\"req\":\"^0.9.10\"},{\"default_features\":false,\"name\":\"portable-atomic\",\"optional\":true,\"req\":\"^1.8\"},{\"kind\":\"dev\",\"name\":\"regex\",\"req\":\"^1.10.6\"}],\"features\":{\"alloc\":[\"race\"],\"atomic-polyfill\":[\"critical-section\"],\"critical-section\":[\"dep:critical-section\",\"portable-atomic\"],\"default\":[\"std\"],\"parking_lot\":[\"dep:parking_lot_core\"],\"portable-atomic\":[\"dep:portable-atomic\"],\"race\":[],\"std\":[\"alloc\"],\"unstable\":[]}}", "once_cell_1.21.4": "{\"dependencies\":[{\"name\":\"critical-section\",\"optional\":true,\"req\":\"^1.1.3\"},{\"features\":[\"std\"],\"kind\":\"dev\",\"name\":\"critical-section\",\"req\":\"^1.1.3\"},{\"default_features\":false,\"name\":\"parking_lot_core\",\"optional\":true,\"req\":\"^0.9.10\"},{\"default_features\":false,\"name\":\"portable-atomic\",\"optional\":true,\"req\":\"^1.8\"},{\"kind\":\"dev\",\"name\":\"regex\",\"req\":\"^1.10.6\"}],\"features\":{\"alloc\":[\"race\"],\"atomic-polyfill\":[\"critical-section\"],\"critical-section\":[\"dep:critical-section\",\"portable-atomic\"],\"default\":[\"std\"],\"parking_lot\":[\"dep:parking_lot_core\"],\"portable-atomic\":[\"dep:portable-atomic\"],\"race\":[],\"std\":[\"alloc\"],\"unstable\":[]}}", @@ -1118,10 +1140,13 @@ "opentelemetry_0.31.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3\"},{\"name\":\"futures-core\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"futures-sink\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"js-sys\",\"req\":\"^0.3.63\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", not(target_os = \\\"wasi\\\")))\"},{\"name\":\"pin-project-lite\",\"optional\":true,\"req\":\"^0.2\"},{\"default_features\":false,\"features\":[\"os_rng\",\"thread_rng\"],\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"},{\"default_features\":false,\"name\":\"thiserror\",\"optional\":true,\"req\":\"^2\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"tracing\",\"optional\":true,\"req\":\">=0.1.40\"}],\"features\":{\"default\":[\"trace\",\"metrics\",\"logs\",\"internal-logs\",\"futures\"],\"futures\":[\"futures-core\",\"futures-sink\",\"pin-project-lite\"],\"internal-logs\":[\"tracing\"],\"logs\":[],\"metrics\":[],\"spec_unstable_logs_enabled\":[\"logs\"],\"testing\":[\"trace\"],\"trace\":[\"futures\",\"thiserror\"]}}", "opentelemetry_sdk_0.31.0": "{\"dependencies\":[{\"features\":[\"html_reports\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"name\":\"futures-channel\",\"req\":\"^0.3\"},{\"name\":\"futures-executor\",\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"std\",\"sink\",\"async-await-macro\"],\"name\":\"futures-util\",\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"http\",\"optional\":true,\"req\":\"^1.1\"},{\"default_features\":false,\"name\":\"opentelemetry\",\"req\":\"^0.31\"},{\"default_features\":false,\"name\":\"opentelemetry-http\",\"optional\":true,\"req\":\"^0.31\"},{\"name\":\"percent-encoding\",\"optional\":true,\"req\":\"^2.0\"},{\"features\":[\"flamegraph\",\"criterion\"],\"kind\":\"dev\",\"name\":\"pprof\",\"req\":\"^0.14\",\"target\":\"cfg(not(target_os = \\\"windows\\\"))\"},{\"default_features\":false,\"features\":[\"std\",\"std_rng\",\"small_rng\",\"os_rng\",\"thread_rng\"],\"name\":\"rand\",\"optional\":true,\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"rstest\",\"req\":\"^0.23.0\"},{\"default_features\":false,\"features\":[\"derive\",\"rc\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"temp-env\",\"req\":\"^0.3.6\"},{\"default_features\":false,\"name\":\"thiserror\",\"req\":\"^2\"},{\"default_features\":false,\"name\":\"tokio\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"tokio-stream\",\"optional\":true,\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"url\",\"optional\":true,\"req\":\"^2.5\"}],\"features\":{\"default\":[\"trace\",\"metrics\",\"logs\",\"internal-logs\"],\"experimental_async_runtime\":[],\"experimental_logs_batch_log_processor_with_async_runtime\":[\"logs\",\"experimental_async_runtime\"],\"experimental_logs_concurrent_log_processor\":[\"logs\"],\"experimental_metrics_custom_reader\":[\"metrics\"],\"experimental_metrics_disable_name_validation\":[\"metrics\"],\"experimental_metrics_periodicreader_with_async_runtime\":[\"metrics\",\"experimental_async_runtime\"],\"experimental_trace_batch_span_processor_with_async_runtime\":[\"tokio/sync\",\"trace\",\"experimental_async_runtime\"],\"internal-logs\":[\"opentelemetry/internal-logs\"],\"jaeger_remote_sampler\":[\"trace\",\"opentelemetry-http\",\"http\",\"serde\",\"serde_json\",\"url\",\"experimental_async_runtime\"],\"logs\":[\"opentelemetry/logs\"],\"metrics\":[\"opentelemetry/metrics\"],\"rt-tokio\":[\"tokio/rt\",\"tokio/time\",\"tokio-stream\",\"experimental_async_runtime\"],\"rt-tokio-current-thread\":[\"tokio/rt\",\"tokio/time\",\"tokio-stream\",\"experimental_async_runtime\"],\"spec_unstable_logs_enabled\":[\"logs\",\"opentelemetry/spec_unstable_logs_enabled\"],\"spec_unstable_metrics_views\":[\"metrics\"],\"testing\":[\"opentelemetry/testing\",\"trace\",\"metrics\",\"logs\",\"rt-tokio\",\"rt-tokio-current-thread\",\"tokio/macros\",\"tokio/rt-multi-thread\"],\"trace\":[\"opentelemetry/trace\",\"rand\",\"percent-encoding\"]}}", "option-ext_0.2.0": "{\"dependencies\":[],\"features\":{}}", + "opus-rs_0.1.11": "{\"dependencies\":[{\"features\":[\"html_reports\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.8.2\"},{\"name\":\"num-complex\",\"req\":\"^0.4\"},{\"name\":\"once_cell\",\"req\":\"^1.17\"},{\"kind\":\"dev\",\"name\":\"opusic-sys\",\"req\":\"^0.6.0\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"}],\"features\":{}}", "ordered-stream_0.2.0": "{\"dependencies\":[{\"name\":\"futures-core\",\"req\":\"^0.3\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"futures-executor\",\"req\":\"^0.3.25\"},{\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3.25\"}],\"features\":{}}", "os_info_3.14.0": "{\"dependencies\":[{\"name\":\"android_system_properties\",\"req\":\"^0.1\",\"target\":\"cfg(target_os = \\\"android\\\")\"},{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"features\":[\"feature\"],\"name\":\"nix\",\"req\":\"^0.30\",\"target\":\"cfg(any(target_os = \\\"aix\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"illumos\\\", target_os = \\\"linux\\\", target_os = \\\"macos\\\", target_os = \\\"netbsd\\\", target_os = \\\"openbsd\\\", target_os = \\\"cygwin\\\"))\"},{\"name\":\"objc2\",\"req\":\"^0.6\",\"target\":\"cfg(target_os = \\\"ios\\\")\"},{\"features\":[\"NSString\"],\"name\":\"objc2-foundation\",\"req\":\"^0.3\",\"target\":\"cfg(target_os = \\\"ios\\\")\"},{\"features\":[\"NSData\",\"NSError\",\"NSEnumerator\",\"NSString\"],\"name\":\"objc2-foundation\",\"req\":\"^0.3\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"name\":\"objc2-ui-kit\",\"req\":\"^0.3\",\"target\":\"cfg(target_os = \\\"ios\\\")\"},{\"kind\":\"dev\",\"name\":\"pretty_assertions\",\"req\":\"^1\"},{\"name\":\"schemars\",\"optional\":true,\"req\":\"^1.0.3\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"Win32_Foundation\",\"Win32_System_LibraryLoader\",\"Win32_System_Registry\",\"Win32_System_SystemInformation\",\"Win32_System_SystemServices\",\"Win32_System_Threading\",\"Win32_UI_WindowsAndMessaging\"],\"name\":\"windows-sys\",\"req\":\"^0.61\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[\"serde\"]}}", "os_pipe_1.2.3": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2.62\",\"target\":\"cfg(not(windows))\"},{\"features\":[\"Win32_Foundation\",\"Win32_System_Pipes\",\"Win32_Security\"],\"name\":\"windows-sys\",\"req\":\">=0.28, <=0.61\",\"target\":\"cfg(windows)\"}],\"features\":{\"io_safety\":[]}}", "owo-colors_4.3.0": "{\"dependencies\":[{\"name\":\"supports-color\",\"optional\":true,\"req\":\"^3.0.0\"},{\"name\":\"supports-color-2\",\"optional\":true,\"package\":\"supports-color\",\"req\":\"^2.0\"}],\"features\":{\"alloc\":[],\"supports-colors\":[\"dep:supports-color-2\",\"supports-color\"]}}", + "p256_0.13.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"blobby\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.4\"},{\"default_features\":false,\"features\":[\"der\"],\"name\":\"ecdsa-core\",\"optional\":true,\"package\":\"ecdsa\",\"req\":\"^0.16\"},{\"default_features\":false,\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"ecdsa-core\",\"package\":\"ecdsa\",\"req\":\"^0.16\"},{\"default_features\":false,\"features\":[\"hazmat\",\"sec1\"],\"name\":\"elliptic-curve\",\"req\":\"^0.13.1\"},{\"name\":\"hex-literal\",\"optional\":true,\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"name\":\"primeorder\",\"optional\":true,\"req\":\"^0.13\"},{\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"primeorder\",\"req\":\"^0.13\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"features\":[\"getrandom\"],\"kind\":\"dev\",\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"default_features\":false,\"name\":\"serdect\",\"optional\":true,\"req\":\"^0.2\"},{\"default_features\":false,\"name\":\"sha2\",\"optional\":true,\"req\":\"^0.10\"}],\"features\":{\"alloc\":[\"ecdsa-core?/alloc\",\"elliptic-curve/alloc\"],\"arithmetic\":[\"dep:primeorder\",\"elliptic-curve/arithmetic\"],\"bits\":[\"arithmetic\",\"elliptic-curve/bits\"],\"default\":[\"arithmetic\",\"ecdsa\",\"pem\",\"std\"],\"digest\":[\"ecdsa-core/digest\",\"ecdsa-core/hazmat\"],\"ecdh\":[\"arithmetic\",\"elliptic-curve/ecdh\"],\"ecdsa\":[\"arithmetic\",\"ecdsa-core/signing\",\"ecdsa-core/verifying\",\"sha256\"],\"expose-field\":[\"arithmetic\"],\"hash2curve\":[\"arithmetic\",\"elliptic-curve/hash2curve\"],\"jwk\":[\"elliptic-curve/jwk\"],\"pem\":[\"elliptic-curve/pem\",\"ecdsa-core/pem\",\"pkcs8\"],\"pkcs8\":[\"ecdsa-core?/pkcs8\",\"elliptic-curve/pkcs8\"],\"serde\":[\"ecdsa-core?/serde\",\"elliptic-curve/serde\",\"primeorder?/serde\",\"serdect\"],\"sha256\":[\"digest\",\"sha2\"],\"std\":[\"alloc\",\"ecdsa-core?/std\",\"elliptic-curve/std\"],\"test-vectors\":[\"dep:hex-literal\"],\"voprf\":[\"elliptic-curve/voprf\",\"sha2\"]}}", + "p384_0.13.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"blobby\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.4\"},{\"default_features\":false,\"features\":[\"der\"],\"name\":\"ecdsa-core\",\"optional\":true,\"package\":\"ecdsa\",\"req\":\"^0.16\"},{\"default_features\":false,\"features\":[\"dev\"],\"kind\":\"dev\",\"name\":\"ecdsa-core\",\"package\":\"ecdsa\",\"req\":\"^0.16\"},{\"default_features\":false,\"features\":[\"hazmat\",\"sec1\"],\"name\":\"elliptic-curve\",\"req\":\"^0.13\"},{\"name\":\"hex-literal\",\"optional\":true,\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3\"},{\"name\":\"primeorder\",\"req\":\"^0.13\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1.1\"},{\"features\":[\"getrandom\"],\"kind\":\"dev\",\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"default_features\":false,\"name\":\"serdect\",\"optional\":true,\"req\":\"^0.2\"},{\"default_features\":false,\"name\":\"sha2\",\"optional\":true,\"req\":\"^0.10\"}],\"features\":{\"alloc\":[\"ecdsa-core?/alloc\",\"elliptic-curve/alloc\"],\"arithmetic\":[\"elliptic-curve/arithmetic\",\"elliptic-curve/digest\"],\"bits\":[\"arithmetic\",\"elliptic-curve/bits\"],\"default\":[\"arithmetic\",\"ecdh\",\"ecdsa\",\"pem\",\"std\"],\"digest\":[\"ecdsa-core/digest\",\"ecdsa-core/hazmat\"],\"ecdh\":[\"arithmetic\",\"elliptic-curve/ecdh\"],\"ecdsa\":[\"arithmetic\",\"ecdsa-core/signing\",\"ecdsa-core/verifying\",\"sha384\"],\"expose-field\":[\"arithmetic\"],\"hash2curve\":[\"arithmetic\",\"elliptic-curve/hash2curve\"],\"jwk\":[\"elliptic-curve/jwk\"],\"pem\":[\"elliptic-curve/pem\",\"ecdsa-core/pem\",\"pkcs8\"],\"pkcs8\":[\"ecdsa-core/pkcs8\",\"elliptic-curve/pkcs8\"],\"serde\":[\"ecdsa-core/serde\",\"elliptic-curve/serde\",\"serdect\"],\"sha384\":[\"digest\",\"sha2\"],\"std\":[\"alloc\",\"ecdsa-core?/std\",\"elliptic-curve/std\"],\"test-vectors\":[\"hex-literal\"],\"voprf\":[\"elliptic-curve/voprf\",\"sha2\"]}}", "parking_2.2.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"easy-parallel\",\"req\":\"^3.0.0\"},{\"name\":\"loom\",\"optional\":true,\"req\":\"^0.7\",\"target\":\"cfg(loom)\"}],\"features\":{}}", "parking_lot_0.12.5": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1.3.3\"},{\"name\":\"lock_api\",\"req\":\"^0.4.14\"},{\"name\":\"parking_lot_core\",\"req\":\"^0.9.12\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.3\"}],\"features\":{\"arc_lock\":[\"lock_api/arc_lock\"],\"deadlock_detection\":[\"parking_lot_core/deadlock_detection\"],\"default\":[],\"hardware-lock-elision\":[],\"nightly\":[\"parking_lot_core/nightly\",\"lock_api/nightly\"],\"owning_ref\":[\"lock_api/owning_ref\"],\"send_guard\":[],\"serde\":[\"lock_api/serde\"]}}", "parking_lot_core_0.9.12": "{\"dependencies\":[{\"name\":\"backtrace\",\"optional\":true,\"req\":\"^0.3.60\"},{\"name\":\"cfg-if\",\"req\":\"^1.0.0\"},{\"name\":\"libc\",\"req\":\"^0.2.95\",\"target\":\"cfg(unix)\"},{\"name\":\"petgraph\",\"optional\":true,\"req\":\"^0.6.0\"},{\"name\":\"redox_syscall\",\"req\":\"^0.5\",\"target\":\"cfg(target_os = \\\"redox\\\")\"},{\"name\":\"smallvec\",\"req\":\"^1.6.1\"},{\"name\":\"windows-link\",\"req\":\"^0.2.0\",\"target\":\"cfg(windows)\"}],\"features\":{\"deadlock_detection\":[\"petgraph\",\"backtrace\"],\"nightly\":[]}}", @@ -1151,6 +1176,7 @@ "png_0.18.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"approx\",\"req\":\"^0.5.1\"},{\"name\":\"bitflags\",\"req\":\"^2.0\"},{\"kind\":\"dev\",\"name\":\"byteorder\",\"req\":\"^1.5.0\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^4.0\"},{\"name\":\"crc32fast\",\"req\":\"^1.2.0\"},{\"default_features\":false,\"features\":[\"cargo_bench_support\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"fdeflate\",\"req\":\"^0.3.3\"},{\"name\":\"flate2\",\"req\":\"^1.0.35\"},{\"kind\":\"dev\",\"name\":\"glob\",\"req\":\"^0.3\"},{\"features\":[\"simd\"],\"name\":\"miniz_oxide\",\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9.2\"}],\"features\":{\"benchmarks\":[],\"unstable\":[\"crc32fast/nightly\"],\"zlib-rs\":[\"flate2/zlib-rs\"]}}", "polling_3.11.0": "{\"dependencies\":[{\"name\":\"cfg-if\",\"req\":\"^1\"},{\"name\":\"concurrent-queue\",\"req\":\"^2.2.0\",\"target\":\"cfg(windows)\"},{\"kind\":\"dev\",\"name\":\"easy-parallel\",\"req\":\"^3.1.0\"},{\"kind\":\"dev\",\"name\":\"fastrand\",\"req\":\"^2.0.0\"},{\"name\":\"hermit-abi\",\"req\":\"^0.5.0\",\"target\":\"cfg(target_os = \\\"hermit\\\")\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(unix)\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.9\",\"target\":\"cfg(windows)\"},{\"default_features\":false,\"features\":[\"event\",\"fs\",\"pipe\",\"process\",\"std\",\"time\"],\"name\":\"rustix\",\"req\":\"^1.0.5\",\"target\":\"cfg(any(unix, target_os = \\\"fuchsia\\\", target_os = \\\"vxworks\\\"))\"},{\"kind\":\"dev\",\"name\":\"signal-hook\",\"req\":\"^0.3.17\",\"target\":\"cfg(all(unix, not(target_os=\\\"vita\\\")))\"},{\"kind\":\"dev\",\"name\":\"socket2\",\"req\":\"^0.6.0\"},{\"default_features\":false,\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.37\"},{\"features\":[\"Wdk_Foundation\",\"Wdk_Storage_FileSystem\",\"Win32_Foundation\",\"Win32_Networking_WinSock\",\"Win32_Security\",\"Win32_Storage_FileSystem\",\"Win32_System_IO\",\"Win32_System_LibraryLoader\",\"Win32_System_Threading\",\"Win32_System_WindowsProgramming\"],\"name\":\"windows-sys\",\"req\":\"^0.61\",\"target\":\"cfg(windows)\"}],\"features\":{}}", "poly1305_0.8.0": "{\"dependencies\":[{\"name\":\"cpufeatures\",\"req\":\"^0.2\",\"target\":\"cfg(any(target_arch = \\\"x86_64\\\", target_arch = \\\"x86\\\"))\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3\"},{\"name\":\"opaque-debug\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"universal-hash\",\"req\":\"^0.5\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"std\":[\"universal-hash/std\"]}}", + "polyval_0.6.2": "{\"dependencies\":[{\"name\":\"cfg-if\",\"req\":\"^1\"},{\"name\":\"cpufeatures\",\"req\":\"^0.2\",\"target\":\"cfg(any(target_arch = \\\"aarch64\\\", target_arch = \\\"x86_64\\\", target_arch = \\\"x86\\\"))\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3\"},{\"name\":\"opaque-debug\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"universal-hash\",\"req\":\"^0.5\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"std\":[\"universal-hash/std\"]}}", "portable-atomic-util_0.2.5": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"build-context\",\"req\":\"^0.1\"},{\"default_features\":false,\"features\":[\"require-cas\"],\"name\":\"portable-atomic\",\"req\":\"^1.5.1\"}],\"features\":{\"alloc\":[],\"default\":[],\"std\":[\"alloc\"]}}", "portable-atomic_1.13.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"build-context\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"crabgrind\",\"req\":\"^0.1\",\"target\":\"cfg(valgrind)\"},{\"name\":\"critical-section\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"crossbeam-utils\",\"req\":\"=0.8.16\"},{\"kind\":\"dev\",\"name\":\"fastrand\",\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"=0.2.163\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"paste\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.60\"},{\"kind\":\"dev\",\"name\":\"sptr\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"static_assertions\",\"req\":\"^1\"},{\"features\":[\"Win32_Foundation\",\"Win32_System_Threading\"],\"kind\":\"dev\",\"name\":\"windows-sys\",\"req\":\"^0.61\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[\"fallback\"],\"disable-fiq\":[],\"fallback\":[],\"float\":[],\"force-amo\":[],\"require-cas\":[],\"s-mode\":[],\"std\":[],\"unsafe-assume-privileged\":[],\"unsafe-assume-single-core\":[]}}", "portable-pty_0.9.0": "{\"dependencies\":[{\"name\":\"anyhow\",\"req\":\"^1.0\"},{\"name\":\"bitflags\",\"req\":\"^1.3\",\"target\":\"cfg(windows)\"},{\"name\":\"downcast-rs\",\"req\":\"^1.0\"},{\"name\":\"filedescriptor\",\"req\":\"^0.8.3\"},{\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3\"},{\"name\":\"lazy_static\",\"req\":\"^1.4\",\"target\":\"cfg(windows)\"},{\"name\":\"libc\",\"req\":\"^0.2\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"features\":[\"term\",\"fs\"],\"name\":\"nix\",\"req\":\"^0.28\"},{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"serde_derive\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"serial2\",\"req\":\"^0.2\"},{\"name\":\"shared_library\",\"req\":\"^0.1\",\"target\":\"cfg(windows)\"},{\"name\":\"shell-words\",\"req\":\"^1.1\"},{\"kind\":\"dev\",\"name\":\"smol\",\"req\":\"^2.0\"},{\"features\":[\"winuser\",\"consoleapi\",\"handleapi\",\"fileapi\",\"namedpipeapi\",\"synchapi\"],\"name\":\"winapi\",\"req\":\"^0.3\",\"target\":\"cfg(windows)\"},{\"name\":\"winreg\",\"req\":\"^0.10\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[],\"serde_support\":[\"serde\",\"serde_derive\"]}}", @@ -1163,6 +1189,7 @@ "predicates_3.1.3": "{\"dependencies\":[{\"name\":\"anstyle\",\"req\":\"^1.0.0\"},{\"name\":\"difflib\",\"optional\":true,\"req\":\"^0.4\"},{\"name\":\"float-cmp\",\"optional\":true,\"req\":\"^0.10\"},{\"name\":\"normalize-line-endings\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"predicates-core\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"predicates-tree\",\"req\":\"^1.0\"},{\"name\":\"regex\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"color\":[],\"default\":[\"diff\",\"regex\",\"float-cmp\",\"normalize-line-endings\",\"color\"],\"diff\":[\"dep:difflib\"],\"unstable\":[]}}", "pretty_assertions_1.4.1": "{\"dependencies\":[{\"name\":\"diff\",\"req\":\"^0.1.12\"},{\"name\":\"yansi\",\"req\":\"^1.0.1\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"std\":[],\"unstable\":[]}}", "prettyplease_0.2.37": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"indoc\",\"req\":\"^2\"},{\"default_features\":false,\"name\":\"proc-macro2\",\"req\":\"^1.0.80\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"proc-macro2\",\"req\":\"^1.0.80\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quote\",\"req\":\"^1.0.35\"},{\"default_features\":false,\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2.0.105\"},{\"default_features\":false,\"features\":[\"clone-impls\",\"extra-traits\",\"parsing\",\"printing\",\"visit-mut\"],\"kind\":\"dev\",\"name\":\"syn\",\"req\":\"^2.0.105\"}],\"features\":{\"verbatim\":[\"syn/parsing\"]}}", + "primeorder_0.13.6": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"arithmetic\",\"sec1\"],\"name\":\"elliptic-curve\",\"req\":\"^0.13.7\"},{\"default_features\":false,\"name\":\"serdect\",\"optional\":true,\"req\":\"^0.2\"}],\"features\":{\"alloc\":[\"elliptic-curve/alloc\"],\"dev\":[],\"serde\":[\"elliptic-curve/serde\",\"serdect\"],\"std\":[\"alloc\",\"elliptic-curve/std\"]}}", "proc-macro-crate_3.4.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"proc-macro2\",\"req\":\"^1.0.94\"},{\"kind\":\"dev\",\"name\":\"quote\",\"req\":\"^1.0.39\"},{\"kind\":\"dev\",\"name\":\"syn\",\"req\":\"^2.0.99\"},{\"default_features\":false,\"features\":[\"parse\"],\"name\":\"toml_edit\",\"req\":\"^0.23.2\"}],\"features\":{}}", "proc-macro-error-attr2_2.0.0": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"}],\"features\":{}}", "proc-macro-error2_2.0.1": "{\"dependencies\":[{\"name\":\"proc-macro-error-attr2\",\"req\":\"=2.0.0\"},{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"syn\",\"optional\":true,\"req\":\"^2\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"syn\",\"req\":\"^2\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.99\"}],\"features\":{\"default\":[\"syn-error\"],\"nightly\":[],\"syn-error\":[\"dep:syn\"]}}", @@ -1173,6 +1200,8 @@ "prost_0.14.3": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bytes\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"name\":\"prost-derive\",\"optional\":true,\"req\":\"^0.14.3\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"}],\"features\":{\"default\":[\"derive\",\"std\"],\"derive\":[\"dep:prost-derive\"],\"no-recursion-limit\":[],\"std\":[]}}", "psl-types_2.0.11": "{\"dependencies\":[],\"features\":{}}", "psl_2.1.184": "{\"dependencies\":[{\"name\":\"psl-types\",\"req\":\"^2.0.11\"},{\"kind\":\"dev\",\"name\":\"rspec\",\"req\":\"^1.0.0\"}],\"features\":{\"default\":[\"helpers\"],\"helpers\":[]}}", + "ptr_meta_0.3.1": "{\"dependencies\":[{\"default_features\":false,\"name\":\"ptr_meta_derive\",\"optional\":true,\"req\":\"=0.3.1\"}],\"features\":{\"default\":[\"derive\",\"std\"],\"derive\":[\"ptr_meta_derive\"],\"std\":[]}}", + "ptr_meta_derive_0.3.1": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"proc-macro\"],\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"proc-macro\"],\"name\":\"quote\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"clone-impls\",\"derive\",\"full\",\"parsing\",\"printing\",\"proc-macro\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}", "pulldown-cmark-escape_0.10.1": "{\"dependencies\":[],\"features\":{\"simd\":[]}}", "pulldown-cmark_0.10.3": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1.3.1\"},{\"name\":\"bitflags\",\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"name\":\"getopts\",\"optional\":true,\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1.4\"},{\"name\":\"memchr\",\"req\":\"^2.5\"},{\"name\":\"pulldown-cmark-escape\",\"optional\":true,\"req\":\"^0.10.0\"},{\"kind\":\"dev\",\"name\":\"regex\",\"req\":\"^1.6\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.61\"},{\"name\":\"unicase\",\"req\":\"^2.6\"}],\"features\":{\"default\":[\"getopts\",\"html\"],\"gen-tests\":[],\"html\":[\"pulldown-cmark-escape\"],\"simd\":[\"pulldown-cmark-escape?/simd\"]}}", "pxfm_0.1.27": "{\"dependencies\":[{\"name\":\"num-traits\",\"req\":\"^0.2.3\"}],\"features\":{}}", @@ -1203,6 +1232,7 @@ "rama-udp_0.3.0-alpha.4": "{\"dependencies\":[{\"name\":\"rama-core\",\"req\":\"^0.3.0-alpha.4\"},{\"name\":\"rama-net\",\"req\":\"^0.3.0-alpha.4\"},{\"features\":[\"macros\",\"net\"],\"name\":\"tokio\",\"req\":\"^1.48\"},{\"features\":[\"net\"],\"name\":\"tokio-util\",\"req\":\"^0.7\"}],\"features\":{\"default\":[]}}", "rama-unix_0.3.0-alpha.4": "{\"dependencies\":[{\"name\":\"pin-project-lite\",\"req\":\"^0.2\"},{\"name\":\"rama-core\",\"req\":\"^0.3.0-alpha.4\"},{\"name\":\"rama-net\",\"req\":\"^0.3.0-alpha.4\"},{\"features\":[\"macros\",\"net\"],\"name\":\"tokio\",\"req\":\"^1.48\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.48\"}],\"features\":{\"default\":[]}}", "rama-utils_0.3.0-alpha.4": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"ahash\",\"req\":\"^0.8\"},{\"name\":\"const_format\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"loom\",\"req\":\"^0.7\",\"target\":\"cfg(loom)\"},{\"name\":\"parking_lot\",\"req\":\"^0.12\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2\"},{\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0\"},{\"name\":\"rama-macros\",\"req\":\"^0.3.0-alpha.4\"},{\"name\":\"regex\",\"req\":\"^1.12\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_test\",\"req\":\"^1\"},{\"features\":[\"write\",\"serde\",\"const_generics\",\"const_new\"],\"name\":\"smallvec\",\"req\":\"^1.15\"},{\"name\":\"smol_str\",\"req\":\"^0.3\"},{\"features\":[\"time\",\"macros\"],\"name\":\"tokio\",\"req\":\"^1.48\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0\"},{\"name\":\"wildcard\",\"req\":\"^0.3\"}],\"features\":{}}", + "rancor_0.1.1": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"derive\"],\"name\":\"ptr_meta\",\"req\":\"^0.3\"}],\"features\":{\"alloc\":[],\"default\":[\"alloc\"]}}", "rand_0.8.5": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1.2.1\"},{\"default_features\":false,\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2.22\",\"target\":\"cfg(unix)\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.4\"},{\"features\":[\"into_bits\"],\"name\":\"packed_simd\",\"optional\":true,\"package\":\"packed_simd_2\",\"req\":\"^0.3.7\"},{\"default_features\":false,\"name\":\"rand_chacha\",\"optional\":true,\"req\":\"^0.3.0\"},{\"name\":\"rand_core\",\"req\":\"^0.6.0\"},{\"kind\":\"dev\",\"name\":\"rand_pcg\",\"req\":\"^0.3.0\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.103\"}],\"features\":{\"alloc\":[\"rand_core/alloc\"],\"default\":[\"std\",\"std_rng\"],\"getrandom\":[\"rand_core/getrandom\"],\"min_const_gen\":[],\"nightly\":[],\"serde1\":[\"serde\",\"rand_core/serde1\"],\"simd_support\":[\"packed_simd\"],\"small_rng\":[],\"std\":[\"rand_core/std\",\"rand_chacha/std\",\"alloc\",\"getrandom\",\"libc\"],\"std_rng\":[\"rand_chacha\"]}}", "rand_0.9.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1.2.1\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.4\"},{\"default_features\":false,\"name\":\"rand_chacha\",\"optional\":true,\"req\":\"^0.9.0\"},{\"default_features\":false,\"name\":\"rand_core\",\"req\":\"^0.9.0\"},{\"kind\":\"dev\",\"name\":\"rand_pcg\",\"req\":\"^0.9.0\"},{\"kind\":\"dev\",\"name\":\"rayon\",\"req\":\"^1.7\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.103\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.140\"}],\"features\":{\"alloc\":[],\"default\":[\"std\",\"std_rng\",\"os_rng\",\"small_rng\",\"thread_rng\"],\"log\":[\"dep:log\"],\"nightly\":[],\"os_rng\":[\"rand_core/os_rng\"],\"serde\":[\"dep:serde\",\"rand_core/serde\"],\"simd_support\":[],\"small_rng\":[],\"std\":[\"rand_core/std\",\"rand_chacha?/std\",\"alloc\"],\"std_rng\":[\"dep:rand_chacha\"],\"thread_rng\":[\"std\",\"std_rng\",\"os_rng\"],\"unbiased\":[]}}", "rand_chacha_0.3.1": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"simd\"],\"name\":\"ppv-lite86\",\"req\":\"^0.2.8\"},{\"name\":\"rand_core\",\"req\":\"^0.6.0\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"}],\"features\":{\"default\":[\"std\"],\"serde1\":[\"serde\"],\"simd\":[],\"std\":[\"ppv-lite86/std\"]}}", @@ -1213,6 +1243,7 @@ "ratatui-macros_0.6.0": "{\"dependencies\":[{\"features\":[\"user-hooks\"],\"kind\":\"dev\",\"name\":\"cargo-husky\",\"req\":\"^1.5.0\"},{\"name\":\"ratatui\",\"req\":\"^0.29.0\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.101\"}],\"features\":{}}", "rayon-core_1.13.0": "{\"dependencies\":[{\"name\":\"crossbeam-deque\",\"req\":\"^0.8.1\"},{\"name\":\"crossbeam-utils\",\"req\":\"^0.8.0\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"rand_xorshift\",\"req\":\"^0.4\"},{\"kind\":\"dev\",\"name\":\"scoped-tls\",\"req\":\"^1.0\"},{\"name\":\"wasm_sync\",\"optional\":true,\"req\":\"^0.1.0\"}],\"features\":{\"web_spin_lock\":[\"dep:wasm_sync\"]}}", "rayon_1.11.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"either\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"rand_xorshift\",\"req\":\"^0.4\"},{\"name\":\"rayon-core\",\"req\":\"^1.13.0\"},{\"name\":\"wasm_sync\",\"optional\":true,\"req\":\"^0.1.0\"}],\"features\":{\"web_spin_lock\":[\"dep:wasm_sync\",\"rayon-core/web_spin_lock\"]}}", + "rcgen_0.13.2": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aws-lc-rs\",\"optional\":true,\"req\":\"^1.6.0\"},{\"features\":[\"vendored\"],\"kind\":\"dev\",\"name\":\"botan\",\"req\":\"^0.10\"},{\"kind\":\"dev\",\"name\":\"openssl\",\"req\":\"^0.10\"},{\"name\":\"pem\",\"optional\":true,\"req\":\"^3.0.2\"},{\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.4.1\"},{\"kind\":\"dev\",\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17\"},{\"kind\":\"dev\",\"name\":\"ring\",\"req\":\"^0.17\"},{\"kind\":\"dev\",\"name\":\"rsa\",\"req\":\"^0.9\"},{\"features\":[\"std\"],\"kind\":\"dev\",\"name\":\"rustls-webpki\",\"req\":\"^0.102\"},{\"default_features\":false,\"name\":\"time\",\"req\":\"^0.3.6\"},{\"features\":[\"verify\"],\"name\":\"x509-parser\",\"optional\":true,\"req\":\"^0.16\"},{\"features\":[\"verify\"],\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.16\"},{\"features\":[\"time\",\"std\"],\"name\":\"yasna\",\"req\":\"^0.5.2\"},{\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1.2\"}],\"features\":{\"aws_lc_rs\":[\"crypto\",\"dep:aws-lc-rs\",\"aws-lc-rs/aws-lc-sys\"],\"crypto\":[],\"default\":[\"crypto\",\"pem\",\"ring\"],\"fips\":[\"crypto\",\"dep:aws-lc-rs\",\"aws-lc-rs/fips\"],\"ring\":[\"crypto\",\"dep:ring\"]}}", "rcgen_0.14.7": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aws-lc-rs\",\"optional\":true,\"req\":\"^1.13.3\"},{\"kind\":\"dev\",\"name\":\"openssl\",\"req\":\"^0.10\",\"target\":\"cfg(unix)\"},{\"name\":\"pem\",\"optional\":true,\"req\":\"^3.0.2\"},{\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.4.1\"},{\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17\"},{\"default_features\":false,\"name\":\"time\",\"req\":\"^0.3.6\"},{\"name\":\"x509-parser\",\"optional\":true,\"req\":\"^0.18\"},{\"features\":[\"time\",\"std\"],\"name\":\"yasna\",\"req\":\"^0.5.2\"},{\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1.2\"}],\"features\":{\"aws_lc_rs\":[\"crypto\",\"dep:aws-lc-rs\",\"aws-lc-rs/aws-lc-sys\",\"x509-parser?/verify-aws\"],\"aws_lc_rs_unstable\":[\"aws_lc_rs\",\"aws-lc-rs/unstable\",\"x509-parser?/verify-aws\"],\"crypto\":[],\"default\":[\"crypto\",\"pem\",\"ring\"],\"fips\":[\"crypto\",\"dep:aws-lc-rs\",\"aws-lc-rs/fips\"],\"ring\":[\"crypto\",\"dep:ring\",\"x509-parser?/verify\"]}}", "redox_syscall_0.5.18": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2.4\"},{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"loom\",\"req\":\"^0.7\",\"target\":\"cfg(loom)\"}],\"features\":{\"default\":[\"userspace\"],\"rustc-dep-of-std\":[\"core\",\"bitflags/rustc-dep-of-std\"],\"std\":[],\"userspace\":[]}}", "redox_syscall_0.7.0": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2.4\"},{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"loom\",\"req\":\"^0.7\",\"target\":\"cfg(loom)\"}],\"features\":{\"default\":[\"userspace\"],\"rustc-dep-of-std\":[\"core\",\"bitflags/rustc-dep-of-std\"],\"std\":[],\"userspace\":[]}}", @@ -1228,13 +1259,19 @@ "regex-syntax_0.8.10": "{\"dependencies\":[{\"features\":[\"derive\"],\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1.3.0\"}],\"features\":{\"arbitrary\":[\"dep:arbitrary\"],\"default\":[\"std\",\"unicode\"],\"std\":[],\"unicode\":[\"unicode-age\",\"unicode-bool\",\"unicode-case\",\"unicode-gencat\",\"unicode-perl\",\"unicode-script\",\"unicode-segment\"],\"unicode-age\":[],\"unicode-bool\":[],\"unicode-case\":[],\"unicode-gencat\":[],\"unicode-perl\":[],\"unicode-script\":[],\"unicode-segment\":[]}}", "regex-syntax_0.8.8": "{\"dependencies\":[{\"features\":[\"derive\"],\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1.3.0\"}],\"features\":{\"arbitrary\":[\"dep:arbitrary\"],\"default\":[\"std\",\"unicode\"],\"std\":[],\"unicode\":[\"unicode-age\",\"unicode-bool\",\"unicode-case\",\"unicode-gencat\",\"unicode-perl\",\"unicode-script\",\"unicode-segment\"],\"unicode-age\":[],\"unicode-bool\":[],\"unicode-case\":[],\"unicode-gencat\":[],\"unicode-perl\":[],\"unicode-script\":[],\"unicode-segment\":[]}}", "regex_1.12.3": "{\"dependencies\":[{\"default_features\":false,\"name\":\"aho-corasick\",\"optional\":true,\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"anyhow\",\"req\":\"^1.0.69\"},{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"atty\",\"humantime\",\"termcolor\"],\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.9.3\"},{\"default_features\":false,\"name\":\"memchr\",\"optional\":true,\"req\":\"^2.6.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0.3\"},{\"default_features\":false,\"features\":[\"alloc\",\"syntax\",\"meta\",\"nfa-pikevm\"],\"name\":\"regex-automata\",\"req\":\"^0.4.12\"},{\"default_features\":false,\"name\":\"regex-syntax\",\"req\":\"^0.8.5\"},{\"kind\":\"dev\",\"name\":\"regex-test\",\"req\":\"^0.1.0\"}],\"features\":{\"default\":[\"std\",\"perf\",\"unicode\",\"regex-syntax/default\"],\"logging\":[\"aho-corasick?/logging\",\"memchr?/logging\",\"regex-automata/logging\"],\"pattern\":[],\"perf\":[\"perf-cache\",\"perf-dfa\",\"perf-onepass\",\"perf-backtrack\",\"perf-inline\",\"perf-literal\"],\"perf-backtrack\":[\"regex-automata/nfa-backtrack\"],\"perf-cache\":[],\"perf-dfa\":[\"regex-automata/hybrid\"],\"perf-dfa-full\":[\"regex-automata/dfa-build\",\"regex-automata/dfa-search\"],\"perf-inline\":[\"regex-automata/perf-inline\"],\"perf-literal\":[\"dep:aho-corasick\",\"dep:memchr\",\"regex-automata/perf-literal\"],\"perf-onepass\":[\"regex-automata/dfa-onepass\"],\"std\":[\"aho-corasick?/std\",\"memchr?/std\",\"regex-automata/std\",\"regex-syntax/std\"],\"unicode\":[\"unicode-age\",\"unicode-bool\",\"unicode-case\",\"unicode-gencat\",\"unicode-perl\",\"unicode-script\",\"unicode-segment\",\"regex-automata/unicode\",\"regex-syntax/unicode\"],\"unicode-age\":[\"regex-automata/unicode-age\",\"regex-syntax/unicode-age\"],\"unicode-bool\":[\"regex-automata/unicode-bool\",\"regex-syntax/unicode-bool\"],\"unicode-case\":[\"regex-automata/unicode-case\",\"regex-syntax/unicode-case\"],\"unicode-gencat\":[\"regex-automata/unicode-gencat\",\"regex-syntax/unicode-gencat\"],\"unicode-perl\":[\"regex-automata/unicode-perl\",\"regex-automata/unicode-word-boundary\",\"regex-syntax/unicode-perl\"],\"unicode-script\":[\"regex-automata/unicode-script\",\"regex-syntax/unicode-script\"],\"unicode-segment\":[\"regex-automata/unicode-segment\",\"regex-syntax/unicode-segment\"],\"unstable\":[\"pattern\"],\"use_std\":[\"std\"]}}", + "rend_0.5.3": "{\"dependencies\":[{\"default_features\":false,\"name\":\"bytecheck\",\"optional\":true,\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"bytemuck-1\",\"optional\":true,\"package\":\"bytemuck\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"zerocopy\",\"optional\":true,\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"zerocopy-derive\",\"optional\":true,\"req\":\"^0.8\"}],\"features\":{\"default\":[],\"zerocopy-0_8\":[\"dep:zerocopy\",\"dep:zerocopy-derive\"]}}", "reqwest_0.12.28": "{\"dependencies\":[{\"name\":\"base64\",\"req\":\"^0.22\"},{\"kind\":\"dev\",\"name\":\"brotli_crate\",\"package\":\"brotli\",\"req\":\"^8\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"bytes\",\"req\":\"^1.2\"},{\"name\":\"cookie_crate\",\"optional\":true,\"package\":\"cookie\",\"req\":\"^0.18.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"cookie_store\",\"optional\":true,\"req\":\"^0.22.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"encoding_rs\",\"optional\":true,\"req\":\"^0.8\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"kind\":\"dev\",\"name\":\"flate2\",\"req\":\"^1.0.13\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"futures-channel\",\"optional\":true,\"req\":\"^0.3\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"name\":\"futures-core\",\"req\":\"^0.3.28\"},{\"default_features\":false,\"name\":\"futures-util\",\"optional\":true,\"req\":\"^0.3.28\"},{\"default_features\":false,\"features\":[\"std\",\"alloc\"],\"kind\":\"dev\",\"name\":\"futures-util\",\"req\":\"^0.3.28\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"h2\",\"optional\":true,\"req\":\"^0.4\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"h3\",\"optional\":true,\"req\":\"^0.0.8\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"h3-quinn\",\"optional\":true,\"req\":\"^0.0.10\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"features\":[\"tokio\"],\"name\":\"hickory-resolver\",\"optional\":true,\"req\":\"^0.25\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"http\",\"req\":\"^1.1\"},{\"name\":\"http-body\",\"req\":\"^1\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"http-body-util\",\"req\":\"^0.1.2\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"features\":[\"http1\",\"client\"],\"name\":\"hyper\",\"req\":\"^1.1\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"http1\",\"http2\",\"client\",\"server\"],\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^1.1.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"http1\",\"tls12\"],\"name\":\"hyper-rustls\",\"optional\":true,\"req\":\"^0.27.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"hyper-tls\",\"optional\":true,\"req\":\"^0.6\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"features\":[\"http1\",\"client\",\"client-legacy\",\"client-proxy\",\"tokio\"],\"name\":\"hyper-util\",\"req\":\"^0.1.12\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"features\":[\"http1\",\"http2\",\"client\",\"client-legacy\",\"server-auto\",\"server-graceful\",\"tokio\"],\"kind\":\"dev\",\"name\":\"hyper-util\",\"req\":\"^0.1.12\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"js-sys\",\"req\":\"^0.3.77\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0\"},{\"name\":\"log\",\"req\":\"^0.4.17\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"mime\",\"optional\":true,\"req\":\"^0.3.16\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"name\":\"mime_guess\",\"optional\":true,\"req\":\"^2.0\"},{\"name\":\"native-tls-crate\",\"optional\":true,\"package\":\"native-tls\",\"req\":\"^0.2.10\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"kind\":\"dev\",\"name\":\"num_cpus\",\"req\":\"^1.0\"},{\"name\":\"once_cell\",\"optional\":true,\"req\":\"^1.18\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"percent-encoding\",\"req\":\"^2.3\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2.11\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"rustls\",\"runtime-tokio\"],\"name\":\"quinn\",\"optional\":true,\"req\":\"^0.11.1\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"std\",\"tls12\"],\"name\":\"rustls\",\"optional\":true,\"req\":\"^0.23.4\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"rustls-native-certs\",\"optional\":true,\"req\":\"^0.8.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"features\":[\"std\"],\"name\":\"rustls-pki-types\",\"optional\":true,\"req\":\"^1.9.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"serde\",\"req\":\"^1.0\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"serde_json\",\"req\":\"^1.0\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"serde_urlencoded\",\"req\":\"^0.7.1\"},{\"features\":[\"futures\"],\"name\":\"sync_wrapper\",\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"net\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"macros\",\"rt-multi-thread\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"tokio-native-tls\",\"optional\":true,\"req\":\"^0.3.0\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"tls12\"],\"name\":\"tokio-rustls\",\"optional\":true,\"req\":\"^0.26\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"io\"],\"name\":\"tokio-util\",\"optional\":true,\"req\":\"^0.7.9\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"retry\",\"timeout\",\"util\"],\"name\":\"tower\",\"req\":\"^0.5.2\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"default_features\":false,\"features\":[\"limit\"],\"kind\":\"dev\",\"name\":\"tower\",\"req\":\"^0.5.2\"},{\"default_features\":false,\"features\":[\"follow-redirect\"],\"name\":\"tower-http\",\"req\":\"^0.6.8\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"tower-service\",\"req\":\"^0.3\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"name\":\"url\",\"req\":\"^2.4\"},{\"name\":\"wasm-bindgen\",\"req\":\"^0.2.89\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"features\":[\"serde-serialize\"],\"kind\":\"dev\",\"name\":\"wasm-bindgen\",\"req\":\"^0.2.89\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"name\":\"wasm-bindgen-futures\",\"req\":\"^0.4.18\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"name\":\"wasm-streams\",\"optional\":true,\"req\":\"^0.4\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"features\":[\"AbortController\",\"AbortSignal\",\"Headers\",\"Request\",\"RequestInit\",\"RequestMode\",\"Response\",\"Window\",\"FormData\",\"Blob\",\"BlobPropertyBag\",\"ServiceWorkerGlobalScope\",\"RequestCredentials\",\"File\",\"ReadableStream\",\"RequestCache\"],\"name\":\"web-sys\",\"req\":\"^0.3.28\",\"target\":\"cfg(target_arch = \\\"wasm32\\\")\"},{\"name\":\"webpki-roots\",\"optional\":true,\"req\":\"^1\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"},{\"kind\":\"dev\",\"name\":\"zstd_crate\",\"package\":\"zstd\",\"req\":\"^0.13\",\"target\":\"cfg(not(target_arch = \\\"wasm32\\\"))\"}],\"features\":{\"__rustls\":[\"dep:hyper-rustls\",\"dep:tokio-rustls\",\"dep:rustls\",\"__tls\"],\"__rustls-ring\":[\"hyper-rustls?/ring\",\"tokio-rustls?/ring\",\"rustls?/ring\",\"quinn?/ring\"],\"__tls\":[\"dep:rustls-pki-types\",\"tokio/io-util\"],\"blocking\":[\"dep:futures-channel\",\"futures-channel?/sink\",\"dep:futures-util\",\"futures-util?/io\",\"futures-util?/sink\",\"tokio/sync\"],\"brotli\":[\"tower-http/decompression-br\"],\"charset\":[\"dep:encoding_rs\",\"dep:mime\"],\"cookies\":[\"dep:cookie_crate\",\"dep:cookie_store\"],\"default\":[\"default-tls\",\"charset\",\"http2\",\"system-proxy\"],\"default-tls\":[\"dep:hyper-tls\",\"dep:native-tls-crate\",\"__tls\",\"dep:tokio-native-tls\"],\"deflate\":[\"tower-http/decompression-deflate\"],\"gzip\":[\"tower-http/decompression-gzip\"],\"hickory-dns\":[\"dep:hickory-resolver\",\"dep:once_cell\"],\"http2\":[\"h2\",\"hyper/http2\",\"hyper-util/http2\",\"hyper-rustls?/http2\"],\"http3\":[\"rustls-tls-manual-roots\",\"dep:h3\",\"dep:h3-quinn\",\"dep:quinn\",\"tokio/macros\"],\"json\":[\"dep:serde_json\"],\"macos-system-configuration\":[\"system-proxy\"],\"multipart\":[\"dep:mime_guess\",\"dep:futures-util\"],\"native-tls\":[\"default-tls\"],\"native-tls-alpn\":[\"native-tls\",\"native-tls-crate?/alpn\",\"hyper-tls?/alpn\"],\"native-tls-vendored\":[\"native-tls\",\"native-tls-crate?/vendored\"],\"rustls-tls\":[\"rustls-tls-webpki-roots\"],\"rustls-tls-manual-roots\":[\"rustls-tls-manual-roots-no-provider\",\"__rustls-ring\"],\"rustls-tls-manual-roots-no-provider\":[\"__rustls\"],\"rustls-tls-native-roots\":[\"rustls-tls-native-roots-no-provider\",\"__rustls-ring\"],\"rustls-tls-native-roots-no-provider\":[\"dep:rustls-native-certs\",\"hyper-rustls?/native-tokio\",\"__rustls\"],\"rustls-tls-no-provider\":[\"rustls-tls-manual-roots-no-provider\"],\"rustls-tls-webpki-roots\":[\"rustls-tls-webpki-roots-no-provider\",\"__rustls-ring\"],\"rustls-tls-webpki-roots-no-provider\":[\"dep:webpki-roots\",\"hyper-rustls?/webpki-tokio\",\"__rustls\"],\"socks\":[],\"stream\":[\"tokio/fs\",\"dep:futures-util\",\"dep:tokio-util\",\"dep:wasm-streams\"],\"system-proxy\":[\"hyper-util/client-proxy-system\"],\"trust-dns\":[],\"zstd\":[\"tower-http/decompression-zstd\"]}}", "resb_0.1.1": "{\"dependencies\":[{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^2.0.0\"},{\"default_features\":false,\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.17\"},{\"name\":\"nom\",\"optional\":true,\"req\":\"^7.0.0\"},{\"default_features\":false,\"name\":\"potential_utf\",\"req\":\"^0.1.3\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"serde_core\",\"req\":\"^1.0.220\"}],\"features\":{\"default\":[],\"logging\":[\"dep:log\"],\"serialize\":[\"std\"],\"std\":[],\"text\":[\"dep:indexmap\",\"dep:nom\",\"std\"]}}", "resolv-conf_0.7.6": "{\"dependencies\":[],\"features\":{\"system\":[]}}", + "rfc6979_0.4.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"reset\"],\"name\":\"hmac\",\"req\":\"^0.12\"},{\"kind\":\"dev\",\"name\":\"sha2\",\"req\":\"^0.10\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2\"}],\"features\":{}}", "ring_0.17.14": "{\"dependencies\":[{\"default_features\":false,\"kind\":\"build\",\"name\":\"cc\",\"req\":\"^1.2.8\"},{\"default_features\":false,\"name\":\"cfg-if\",\"req\":\"^1.0.0\"},{\"name\":\"getrandom\",\"req\":\"^0.2.10\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.148\",\"target\":\"cfg(all(any(all(target_arch = \\\"aarch64\\\", target_endian = \\\"little\\\"), all(target_arch = \\\"arm\\\", target_endian = \\\"little\\\")), any(target_os = \\\"android\\\", target_os = \\\"linux\\\")))\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2.155\",\"target\":\"cfg(all(all(target_arch = \\\"aarch64\\\", target_endian = \\\"little\\\"), target_vendor = \\\"apple\\\", any(target_os = \\\"ios\\\", target_os = \\\"macos\\\", target_os = \\\"tvos\\\", target_os = \\\"visionos\\\", target_os = \\\"watchos\\\")))\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"libc\",\"req\":\"^0.2.148\",\"target\":\"cfg(any(unix, windows, target_os = \\\"wasi\\\"))\"},{\"name\":\"untrusted\",\"req\":\"^0.9\"},{\"default_features\":false,\"features\":[\"std\"],\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3.37\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\"},{\"features\":[\"Win32_Foundation\",\"Win32_System_Threading\"],\"name\":\"windows-sys\",\"req\":\"^0.52\",\"target\":\"cfg(all(all(target_arch = \\\"aarch64\\\", target_endian = \\\"little\\\"), target_os = \\\"windows\\\"))\"}],\"features\":{\"alloc\":[],\"default\":[\"alloc\",\"dev_urandom_fallback\"],\"dev_urandom_fallback\":[],\"less-safe-getrandom-custom-or-rdrand\":[],\"less-safe-getrandom-espidf\":[],\"slow_tests\":[],\"std\":[\"alloc\"],\"test_logging\":[],\"unstable-testing-arm-no-hw\":[],\"unstable-testing-arm-no-neon\":[],\"wasm32_unknown_unknown_js\":[\"getrandom/js\"]}}", + "rkyv_0.8.15": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"ahash\",\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"arrayvec-0_7\",\"optional\":true,\"package\":\"arrayvec\",\"req\":\"^0.7\"},{\"default_features\":false,\"features\":[\"simdutf8\"],\"name\":\"bytecheck\",\"optional\":true,\"req\":\"^0.8\"},{\"default_features\":false,\"name\":\"bytes-1\",\"optional\":true,\"package\":\"bytes\",\"req\":\"^1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"divan\",\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"hashbrown\",\"optional\":true,\"req\":\"^0.16\"},{\"default_features\":false,\"name\":\"hashbrown-0_14\",\"optional\":true,\"package\":\"hashbrown\",\"req\":\"^0.14\"},{\"default_features\":false,\"name\":\"hashbrown-0_15\",\"optional\":true,\"package\":\"hashbrown\",\"req\":\"^0.15\"},{\"default_features\":false,\"name\":\"indexmap-2\",\"optional\":true,\"package\":\"indexmap\",\"req\":\"^2\"},{\"default_features\":false,\"name\":\"munge\",\"req\":\"^0.4\"},{\"default_features\":false,\"name\":\"ptr_meta\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"rancor\",\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"rend\",\"req\":\"^0.5\"},{\"default_features\":false,\"name\":\"rkyv_derive\",\"req\":\"=0.8.15\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"smallvec-1\",\"optional\":true,\"package\":\"smallvec\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"smol_str-0_2\",\"optional\":true,\"package\":\"smol_str\",\"req\":\"^0.2\"},{\"default_features\":false,\"name\":\"smol_str-0_3\",\"optional\":true,\"package\":\"smol_str\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"thin-vec-0_2\",\"optional\":true,\"package\":\"thin-vec\",\"req\":\"^0.2.12\"},{\"default_features\":false,\"name\":\"tinyvec-1\",\"optional\":true,\"package\":\"tinyvec\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"triomphe-0_1\",\"optional\":true,\"package\":\"triomphe\",\"req\":\"^0.1\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"uuid-1\",\"optional\":true,\"package\":\"uuid\",\"req\":\"^1\"}],\"features\":{\"aligned\":[],\"alloc\":[\"dep:hashbrown\",\"tinyvec-1?/alloc\",\"rancor/alloc\"],\"big_endian\":[],\"bytecheck\":[\"dep:bytecheck\",\"rend/bytecheck\",\"rkyv_derive/bytecheck\"],\"default\":[\"std\",\"bytecheck\"],\"hashbrown-0_16\":[\"dep:hashbrown\"],\"indexmap-2\":[\"dep:indexmap-2\",\"alloc\"],\"little_endian\":[],\"pointer_width_16\":[],\"pointer_width_32\":[],\"pointer_width_64\":[],\"std\":[\"alloc\",\"bytes-1?/std\",\"indexmap-2?/std\",\"ptr_meta/std\",\"uuid-1?/std\"],\"triomphe-0_1\":[\"dep:triomphe-0_1\",\"alloc\"],\"unaligned\":[],\"uuid-1\":[\"dep:uuid-1\",\"bytecheck?/uuid-1\"]}}", + "rkyv_derive_0.8.15": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"proc-macro\"],\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"proc-macro\"],\"name\":\"quote\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"clone-impls\",\"derive\",\"parsing\",\"printing\",\"proc-macro\"],\"name\":\"syn\",\"req\":\"^2.0.73\"}],\"features\":{\"bytecheck\":[],\"default\":[]}}", "rmcp-macros_0.15.0": "{\"dependencies\":[{\"name\":\"darling\",\"req\":\"^0.23\"},{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2\"}],\"features\":{}}", "rmcp_0.15.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"anyhow\",\"req\":\"^1.0\"},{\"name\":\"async-trait\",\"req\":\"^0.1.89\"},{\"kind\":\"dev\",\"name\":\"async-trait\",\"req\":\"^0.1\"},{\"name\":\"axum\",\"optional\":true,\"req\":\"^0.8\"},{\"name\":\"base64\",\"optional\":true,\"req\":\"^0.22\"},{\"name\":\"bytes\",\"optional\":true,\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"serde\",\"clock\",\"std\",\"oldtime\"],\"name\":\"chrono\",\"req\":\"^0.4.38\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\"))\"},{\"features\":[\"serde\"],\"name\":\"chrono\",\"req\":\"^0.4.38\",\"target\":\"cfg(not(all(target_family = \\\"wasm\\\", target_os = \\\"unknown\\\")))\"},{\"name\":\"futures\",\"req\":\"^0.3\"},{\"name\":\"http\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"http-body\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"http-body-util\",\"optional\":true,\"req\":\"^0.1\"},{\"default_features\":false,\"features\":[\"reqwest\"],\"name\":\"oauth2\",\"optional\":true,\"req\":\"^5.0\"},{\"name\":\"pastey\",\"optional\":true,\"req\":\"^0.2.0\"},{\"name\":\"pin-project-lite\",\"req\":\"^0.2\"},{\"features\":[\"tokio1\"],\"name\":\"process-wrap\",\"optional\":true,\"req\":\"^9.0\"},{\"name\":\"rand\",\"optional\":true,\"req\":\"^0.9\"},{\"default_features\":false,\"features\":[\"json\",\"stream\"],\"name\":\"reqwest\",\"optional\":true,\"req\":\"^0.12\"},{\"name\":\"rmcp-macros\",\"optional\":true,\"req\":\"^0.15.0\"},{\"features\":[\"chrono04\"],\"name\":\"schemars\",\"optional\":true,\"req\":\"^1.0\"},{\"features\":[\"chrono04\"],\"kind\":\"dev\",\"name\":\"schemars\",\"req\":\"^1.1.0\"},{\"features\":[\"derive\",\"rc\"],\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"sse-stream\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"thiserror\",\"req\":\"^2\"},{\"features\":[\"sync\",\"macros\",\"rt\",\"time\"],\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"name\":\"tokio-stream\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"tokio-util\",\"req\":\"^0.7\"},{\"name\":\"tower-service\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"tracing\",\"req\":\"^0.1\"},{\"features\":[\"env-filter\",\"std\",\"fmt\"],\"kind\":\"dev\",\"name\":\"tracing-subscriber\",\"req\":\"^0.3\"},{\"name\":\"url\",\"optional\":true,\"req\":\"^2.4\"},{\"features\":[\"v4\"],\"name\":\"uuid\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"__reqwest\":[\"dep:reqwest\"],\"auth\":[\"dep:oauth2\",\"__reqwest\",\"dep:url\"],\"client\":[\"dep:tokio-stream\"],\"client-side-sse\":[\"dep:sse-stream\",\"dep:http\"],\"default\":[\"base64\",\"macros\",\"server\"],\"elicitation\":[\"dep:url\"],\"macros\":[\"dep:rmcp-macros\",\"dep:pastey\"],\"reqwest\":[\"__reqwest\",\"reqwest?/rustls-tls\"],\"reqwest-native-tls\":[\"__reqwest\",\"reqwest?/native-tls\"],\"reqwest-tls-no-provider\":[\"__reqwest\",\"reqwest?/rustls-tls-no-provider\"],\"schemars\":[\"dep:schemars\"],\"server\":[\"transport-async-rw\",\"dep:schemars\",\"dep:pastey\"],\"server-side-http\":[\"uuid\",\"dep:rand\",\"dep:tokio-stream\",\"dep:http\",\"dep:http-body\",\"dep:http-body-util\",\"dep:bytes\",\"dep:sse-stream\",\"dep:axum\",\"tower\"],\"tower\":[\"dep:tower-service\"],\"transport-async-rw\":[\"tokio/io-util\",\"tokio-util/codec\"],\"transport-child-process\":[\"transport-async-rw\",\"tokio/process\",\"dep:process-wrap\"],\"transport-io\":[\"transport-async-rw\",\"tokio/io-std\"],\"transport-streamable-http-client\":[\"client-side-sse\",\"transport-worker\"],\"transport-streamable-http-client-reqwest\":[\"transport-streamable-http-client\",\"__reqwest\"],\"transport-streamable-http-server\":[\"transport-streamable-http-server-session\",\"server-side-http\",\"transport-worker\"],\"transport-streamable-http-server-session\":[\"transport-async-rw\",\"dep:tokio-stream\"],\"transport-worker\":[\"dep:tokio-stream\"]}}", "rsa_0.9.10": "{\"dependencies\":[{\"features\":[\"alloc\"],\"kind\":\"dev\",\"name\":\"base64ct\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"const-oid\",\"req\":\"^0.9\"},{\"default_features\":false,\"features\":[\"alloc\",\"oid\"],\"name\":\"digest\",\"req\":\"^0.10.5\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4.1\"},{\"default_features\":false,\"features\":[\"i128\",\"prime\",\"zeroize\"],\"name\":\"num-bigint\",\"package\":\"num-bigint-dig\",\"req\":\"^0.8.6\"},{\"default_features\":false,\"name\":\"num-integer\",\"req\":\"^0.1.39\"},{\"default_features\":false,\"features\":[\"libm\"],\"name\":\"num-traits\",\"req\":\"^0.2.9\"},{\"default_features\":false,\"features\":[\"alloc\",\"pkcs8\"],\"name\":\"pkcs1\",\"req\":\"^0.7.5\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"pkcs8\",\"req\":\"^0.10.2\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"rand_chacha\",\"req\":\"^0.3\"},{\"default_features\":false,\"name\":\"rand_core\",\"req\":\"^0.6.4\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"kind\":\"dev\",\"name\":\"rand_xorshift\",\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.184\"},{\"kind\":\"dev\",\"name\":\"serde_test\",\"req\":\"^1.0.89\"},{\"default_features\":false,\"features\":[\"oid\"],\"name\":\"sha1\",\"optional\":true,\"req\":\"^0.10.5\"},{\"default_features\":false,\"features\":[\"oid\"],\"kind\":\"dev\",\"name\":\"sha1\",\"req\":\"^0.10.5\"},{\"default_features\":false,\"features\":[\"oid\"],\"name\":\"sha2\",\"optional\":true,\"req\":\"^0.10.6\"},{\"default_features\":false,\"features\":[\"oid\"],\"kind\":\"dev\",\"name\":\"sha2\",\"req\":\"^0.10.6\"},{\"default_features\":false,\"features\":[\"oid\"],\"kind\":\"dev\",\"name\":\"sha3\",\"req\":\"^0.10.7\"},{\"default_features\":false,\"features\":[\"alloc\",\"digest\",\"rand_core\"],\"name\":\"signature\",\"req\":\">2.0, <2.3\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"spki\",\"req\":\"^0.7.3\"},{\"default_features\":false,\"name\":\"subtle\",\"req\":\"^2.1.1\"},{\"features\":[\"alloc\"],\"name\":\"zeroize\",\"req\":\"^1.5\"}],\"features\":{\"default\":[\"std\",\"pem\",\"u64_digit\"],\"getrandom\":[\"rand_core/getrandom\"],\"hazmat\":[],\"nightly\":[\"num-bigint/nightly\"],\"pem\":[\"pkcs1/pem\",\"pkcs8/pem\"],\"pkcs5\":[\"pkcs8/encryption\"],\"serde\":[\"dep:serde\",\"num-bigint/serde\"],\"std\":[\"digest/std\",\"pkcs1/std\",\"pkcs8/std\",\"rand_core/std\",\"signature/std\"],\"u64_digit\":[\"num-bigint/u64_digit\"]}}", + "rtcp_0.17.1": "{\"dependencies\":[{\"name\":\"bytes\",\"req\":\"^1\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"marshal\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"}],\"features\":{}}", + "rtp_0.17.1": "{\"dependencies\":[{\"name\":\"bytes\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4.28\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"name\":\"memchr\",\"req\":\"^2.1.1\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"marshal\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"}],\"features\":{}}", "rust-embed-impl_8.11.0": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"name\":\"rust-embed-utils\",\"req\":\"^8.11.0\"},{\"name\":\"shellexpand\",\"optional\":true,\"req\":\"^3\"},{\"default_features\":false,\"features\":[\"derive\",\"parsing\",\"proc-macro\",\"printing\"],\"name\":\"syn\",\"req\":\"^2\"},{\"name\":\"walkdir\",\"req\":\"^2.3.1\"}],\"features\":{\"compression\":[],\"debug-embed\":[],\"deterministic-timestamps\":[],\"include-exclude\":[\"rust-embed-utils/include-exclude\"],\"interpolate-folder-path\":[\"shellexpand\"],\"mime-guess\":[\"rust-embed-utils/mime-guess\"]}}", "rust-embed-utils_8.11.0": "{\"dependencies\":[{\"name\":\"globset\",\"optional\":true,\"req\":\"^0.4.8\"},{\"name\":\"mime_guess\",\"optional\":true,\"req\":\"^2.0.4\"},{\"name\":\"sha2\",\"req\":\"^0.10.5\"},{\"name\":\"walkdir\",\"req\":\"^2.3.1\"}],\"features\":{\"debug-embed\":[],\"include-exclude\":[\"globset\"],\"mime-guess\":[\"mime_guess\"]}}", "rust-embed_8.11.0": "{\"dependencies\":[{\"name\":\"actix-web\",\"optional\":true,\"req\":\"^4\"},{\"default_features\":false,\"features\":[\"http1\",\"tokio\"],\"name\":\"axum\",\"optional\":true,\"req\":\"^0.8\"},{\"name\":\"hex\",\"optional\":true,\"req\":\"^0.4.3\"},{\"name\":\"include-flate\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"mime_guess\",\"optional\":true,\"req\":\"^2.0.5\"},{\"default_features\":false,\"features\":[\"server\"],\"name\":\"poem\",\"optional\":true,\"req\":\"^1.3.30\"},{\"default_features\":false,\"name\":\"rocket\",\"optional\":true,\"req\":\"^0.5.0-rc.2\"},{\"name\":\"rust-embed-impl\",\"req\":\"^8.9.0\"},{\"name\":\"rust-embed-utils\",\"req\":\"^8.9.0\"},{\"default_features\":false,\"name\":\"salvo\",\"optional\":true,\"req\":\"^0.16\"},{\"kind\":\"dev\",\"name\":\"sha2\",\"req\":\"^0.10\"},{\"features\":[\"macros\",\"rt-multi-thread\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"walkdir\",\"req\":\"^2.3.2\"},{\"default_features\":false,\"name\":\"warp\",\"optional\":true,\"req\":\"^0.3\"}],\"features\":{\"actix\":[\"actix-web\",\"mime_guess\"],\"axum-ex\":[\"axum\",\"tokio\",\"mime_guess\"],\"compression\":[\"rust-embed-impl/compression\",\"include-flate\"],\"debug-embed\":[\"rust-embed-impl/debug-embed\",\"rust-embed-utils/debug-embed\"],\"deterministic-timestamps\":[\"rust-embed-impl/deterministic-timestamps\"],\"include-exclude\":[\"rust-embed-impl/include-exclude\",\"rust-embed-utils/include-exclude\"],\"interpolate-folder-path\":[\"rust-embed-impl/interpolate-folder-path\"],\"mime-guess\":[\"rust-embed-impl/mime-guess\",\"rust-embed-utils/mime-guess\"],\"poem-ex\":[\"poem\",\"tokio\",\"mime_guess\",\"hex\"],\"salvo-ex\":[\"salvo\",\"tokio\",\"mime_guess\",\"hex\"],\"warp-ex\":[\"warp\",\"tokio\",\"mime_guess\"]}}", @@ -1272,6 +1309,8 @@ "scopeguard_1.2.0": "{\"dependencies\":[],\"features\":{\"default\":[\"use_std\"],\"use_std\":[]}}", "scrypt_0.11.0": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"rand_core\"],\"name\":\"password-hash\",\"optional\":true,\"req\":\"^0.5\"},{\"features\":[\"rand_core\"],\"kind\":\"dev\",\"name\":\"password-hash\",\"req\":\"^0.5\"},{\"name\":\"pbkdf2\",\"req\":\"^0.12\"},{\"default_features\":false,\"name\":\"salsa20\",\"req\":\"^0.10.2\"},{\"default_features\":false,\"name\":\"sha2\",\"req\":\"^0.10\"}],\"features\":{\"default\":[\"simple\",\"std\"],\"simple\":[\"password-hash\"],\"std\":[\"password-hash/std\"]}}", "sdd_3.0.10": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.6\"},{\"name\":\"loom\",\"optional\":true,\"req\":\"^0.7\"},{\"kind\":\"dev\",\"name\":\"static_assertions\",\"req\":\"^1.1\"}],\"features\":{}}", + "sdp_0.17.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"name\":\"substring\",\"req\":\"^1\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"name\":\"url\",\"req\":\"^2\"}],\"features\":{}}", + "sec1_0.7.3": "{\"dependencies\":[{\"default_features\":false,\"name\":\"base16ct\",\"optional\":true,\"req\":\"^0.2\"},{\"features\":[\"oid\"],\"name\":\"der\",\"optional\":true,\"req\":\"^0.7\"},{\"default_features\":false,\"name\":\"generic-array\",\"optional\":true,\"req\":\"^0.14.7\"},{\"kind\":\"dev\",\"name\":\"hex-literal\",\"req\":\"^0.4\"},{\"default_features\":false,\"name\":\"pkcs8\",\"optional\":true,\"req\":\"^0.10\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"serdect\",\"optional\":true,\"req\":\"^0.2\"},{\"default_features\":false,\"name\":\"subtle\",\"optional\":true,\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"alloc\":[\"der?/alloc\",\"pkcs8?/alloc\",\"zeroize?/alloc\"],\"default\":[\"der\",\"point\"],\"der\":[\"dep:der\",\"zeroize\"],\"pem\":[\"alloc\",\"der/pem\",\"pkcs8/pem\"],\"point\":[\"dep:base16ct\",\"dep:generic-array\"],\"serde\":[\"dep:serdect\"],\"std\":[\"alloc\",\"der?/std\"],\"zeroize\":[\"dep:zeroize\",\"der?/zeroize\"]}}", "seccompiler_0.5.0": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2.153\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.27\"},{\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1.0.9\"}],\"features\":{\"json\":[\"serde\",\"serde_json\"]}}", "secrecy_0.10.3": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"zeroize\",\"req\":\"^1.6\"}],\"features\":{}}", "secret-service_4.0.0": "{\"dependencies\":[{\"name\":\"aes\",\"optional\":true,\"req\":\"^0.8\"},{\"features\":[\"block-padding\",\"alloc\"],\"name\":\"cbc\",\"optional\":true,\"req\":\"^0.1\"},{\"name\":\"futures-util\",\"req\":\"^0.3\"},{\"name\":\"generic-array\",\"req\":\"^0.14\"},{\"name\":\"hkdf\",\"optional\":true,\"req\":\"^0.12.0\"},{\"name\":\"num\",\"req\":\"^0.4.0\"},{\"name\":\"once_cell\",\"req\":\"^1\"},{\"name\":\"openssl\",\"optional\":true,\"req\":\"^0.10.40\"},{\"name\":\"rand\",\"req\":\"^0.8.1\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1.0.103\"},{\"name\":\"sha2\",\"optional\":true,\"req\":\"^0.10.0\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"test-with\",\"req\":\"^0.8\"},{\"features\":[\"rt\",\"macros\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"default_features\":false,\"name\":\"zbus\",\"req\":\"^4\"}],\"features\":{\"crypto-openssl\":[\"dep:openssl\"],\"crypto-rust\":[\"dep:aes\",\"dep:cbc\",\"dep:sha2\",\"dep:hkdf\"],\"rt-async-io-crypto-openssl\":[\"zbus/async-io\",\"crypto-openssl\"],\"rt-async-io-crypto-rust\":[\"zbus/async-io\",\"crypto-rust\"],\"rt-tokio-crypto-openssl\":[\"zbus/tokio\",\"crypto-openssl\"],\"rt-tokio-crypto-rust\":[\"zbus/tokio\",\"crypto-rust\"]}}", @@ -1325,6 +1364,7 @@ "slab_0.4.12": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"alloc\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.95\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_test\",\"req\":\"^1\"}],\"features\":{\"default\":[\"std\"],\"std\":[]}}", "smallvec_1.15.1": "{\"dependencies\":[{\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1\"},{\"default_features\":false,\"name\":\"bincode\",\"optional\":true,\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"bincode1\",\"package\":\"bincode\",\"req\":\"^1.0.1\"},{\"kind\":\"dev\",\"name\":\"debugger_test\",\"req\":\"^0.1.0\"},{\"kind\":\"dev\",\"name\":\"debugger_test_parser\",\"req\":\"^0.1.0\"},{\"default_features\":false,\"name\":\"malloc_size_of\",\"optional\":true,\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1\"},{\"default_features\":false,\"name\":\"unty\",\"optional\":true,\"req\":\"^0.0.4\"}],\"features\":{\"const_generics\":[],\"const_new\":[\"const_generics\"],\"debugger_visualizer\":[],\"drain_filter\":[],\"drain_keep_rest\":[\"drain_filter\"],\"impl_bincode\":[\"bincode\",\"unty\"],\"may_dangle\":[],\"specialization\":[],\"union\":[],\"write\":[]}}", "smawk_0.3.2": "{\"dependencies\":[{\"name\":\"ndarray\",\"optional\":true,\"req\":\"^0.15.4\"},{\"kind\":\"dev\",\"name\":\"num-traits\",\"req\":\"^0.2.14\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8.4\"},{\"kind\":\"dev\",\"name\":\"rand_chacha\",\"req\":\"^0.3.1\"},{\"kind\":\"dev\",\"name\":\"version-sync\",\"req\":\"^0.9.4\"}],\"features\":{}}", + "smol_str_0.2.2": "{\"dependencies\":[{\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1.1.0\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1.0.0\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.136\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.136\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.79\"}],\"features\":{\"default\":[\"std\"],\"std\":[\"serde?/std\"]}}", "smol_str_0.3.5": "{\"dependencies\":[{\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1.3\"},{\"default_features\":false,\"name\":\"borsh\",\"optional\":true,\"req\":\"^1.4.0\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.7\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1.5\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9.2\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"serde_core\",\"optional\":true,\"req\":\"^1.0.220\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"}],\"features\":{\"default\":[\"std\"],\"serde\":[\"dep:serde_core\"],\"std\":[\"serde_core?/std\",\"borsh?/std\"]}}", "socket2_0.5.10": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2.171\",\"target\":\"cfg(unix)\"},{\"features\":[\"Win32_Foundation\",\"Win32_Networking_WinSock\",\"Win32_System_IO\",\"Win32_System_Threading\",\"Win32_System_WindowsProgramming\"],\"name\":\"windows-sys\",\"req\":\"^0.52\",\"target\":\"cfg(windows)\"}],\"features\":{\"all\":[]}}", "socket2_0.6.2": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2.172\",\"target\":\"cfg(unix)\"},{\"features\":[\"Win32_Foundation\",\"Win32_Networking_WinSock\",\"Win32_System_IO\",\"Win32_System_Threading\",\"Win32_System_WindowsProgramming\"],\"name\":\"windows-sys\",\"req\":\"^0.60\",\"target\":\"cfg(windows)\"}],\"features\":{\"all\":[]}}", @@ -1356,6 +1396,8 @@ "strum_macros_0.26.4": "{\"dependencies\":[{\"name\":\"heck\",\"req\":\"^0.5.0\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"name\":\"rustversion\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"strum\",\"req\":\"^0.26\"},{\"features\":[\"parsing\",\"extra-traits\"],\"name\":\"syn\",\"req\":\"^2.0\"}],\"features\":{}}", "strum_macros_0.27.2": "{\"dependencies\":[{\"name\":\"heck\",\"req\":\"^0.5.0\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"features\":[\"parsing\"],\"name\":\"syn\",\"req\":\"^2.0\"}],\"features\":{}}", "strum_macros_0.28.0": "{\"dependencies\":[{\"name\":\"heck\",\"req\":\"^0.5.0\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"features\":[\"parsing\"],\"name\":\"syn\",\"req\":\"^2.0\"}],\"features\":{}}", + "stun_0.17.1": "{\"dependencies\":[{\"name\":\"base64\",\"req\":\"^0.22.1\"},{\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^3\"},{\"name\":\"crc\",\"req\":\"^3\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"name\":\"lazy_static\",\"req\":\"^1\"},{\"name\":\"md-5\",\"req\":\"^0.10\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"name\":\"ring\",\"req\":\"^0.17.14\"},{\"name\":\"subtle\",\"req\":\"^2.4\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"name\":\"url\",\"req\":\"^2\"},{\"default_features\":false,\"features\":[\"conn\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"}],\"features\":{\"bench\":[],\"default\":[]}}", + "substring_1.4.5": "{\"dependencies\":[{\"kind\":\"build\",\"name\":\"autocfg\",\"req\":\"^1.0.1\"}],\"features\":{}}", "subtle_2.6.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.8\"}],\"features\":{\"const-generics\":[],\"core_hint_black_box\":[],\"default\":[\"std\",\"i128\"],\"i128\":[],\"nightly\":[],\"std\":[]}}", "supports-color_2.1.0": "{\"dependencies\":[{\"name\":\"is-terminal\",\"req\":\"^0.4.0\"},{\"name\":\"is_ci\",\"req\":\"^1.1.1\"}],\"features\":{}}", "supports-color_3.0.2": "{\"dependencies\":[{\"name\":\"is_ci\",\"req\":\"^1.2.0\"}],\"features\":{}}", @@ -1367,7 +1409,7 @@ "syntect_5.3.0": "{\"dependencies\":[{\"name\":\"bincode\",\"optional\":true,\"req\":\"^1.0\"},{\"features\":[\"html_reports\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"},{\"name\":\"fancy-regex\",\"optional\":true,\"req\":\"^0.16.2\"},{\"name\":\"flate2\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"fnv\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"getopts\",\"req\":\"^0.2\"},{\"name\":\"once_cell\",\"req\":\"^1.8\"},{\"default_features\":false,\"name\":\"onig\",\"optional\":true,\"req\":\"^6.5.1\"},{\"name\":\"plist\",\"optional\":true,\"req\":\"^1.3\"},{\"kind\":\"dev\",\"name\":\"pretty_assertions\",\"req\":\"^0.6\"},{\"kind\":\"dev\",\"name\":\"public-api\",\"req\":\"^0.50.1\"},{\"kind\":\"dev\",\"name\":\"rayon\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"regex\",\"req\":\"^1.0\"},{\"name\":\"regex-syntax\",\"optional\":true,\"req\":\"^0.8\"},{\"kind\":\"dev\",\"name\":\"rustdoc-json\",\"req\":\"^0.9.7\"},{\"kind\":\"dev\",\"name\":\"rustup-toolchain\",\"req\":\"^0.1.5\"},{\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_derive\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0\"},{\"name\":\"thiserror\",\"req\":\"^2.0.12\"},{\"name\":\"walkdir\",\"req\":\"^2.0\"},{\"name\":\"yaml-rust\",\"optional\":true,\"req\":\"^0.4.5\"}],\"features\":{\"default\":[\"default-onig\"],\"default-fancy\":[\"parsing\",\"default-syntaxes\",\"default-themes\",\"html\",\"plist-load\",\"yaml-load\",\"dump-load\",\"dump-create\",\"regex-fancy\"],\"default-onig\":[\"parsing\",\"default-syntaxes\",\"default-themes\",\"html\",\"plist-load\",\"yaml-load\",\"dump-load\",\"dump-create\",\"regex-onig\"],\"default-syntaxes\":[\"parsing\",\"dump-load\"],\"default-themes\":[\"dump-load\"],\"dump-create\":[\"flate2\",\"bincode\"],\"dump-load\":[\"flate2\",\"bincode\"],\"html\":[\"parsing\"],\"metadata\":[\"parsing\",\"plist-load\",\"dep:serde_json\"],\"parsing\":[\"regex-syntax\",\"fnv\",\"dump-create\",\"dump-load\"],\"plist-load\":[\"plist\",\"dep:serde_json\"],\"regex-fancy\":[\"fancy-regex\"],\"regex-onig\":[\"onig\"],\"yaml-load\":[\"yaml-rust\",\"parsing\"]}}", "sys-locale_0.3.2": "{\"dependencies\":[{\"name\":\"js-sys\",\"optional\":true,\"req\":\"^0.3\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", not(unix)))\"},{\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(target_os = \\\"android\\\")\"},{\"name\":\"wasm-bindgen\",\"optional\":true,\"req\":\"^0.2\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", not(unix)))\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", not(unix)))\"},{\"features\":[\"Window\",\"WorkerGlobalScope\",\"Navigator\",\"WorkerNavigator\"],\"name\":\"web-sys\",\"optional\":true,\"req\":\"^0.3\",\"target\":\"cfg(all(target_family = \\\"wasm\\\", not(unix)))\"}],\"features\":{\"js\":[\"js-sys\",\"wasm-bindgen\",\"web-sys\"]}}", "system-configuration-sys_0.6.0": "{\"dependencies\":[{\"name\":\"core-foundation-sys\",\"req\":\"^0.8\"},{\"name\":\"libc\",\"req\":\"^0.2.149\"}],\"features\":{}}", - "system-configuration_0.7.0": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2\"},{\"name\":\"core-foundation\",\"req\":\"^0.9\"},{\"name\":\"system-configuration-sys\",\"req\":\"^0.6\"}],\"features\":{}}", + "system-configuration_0.6.1": "{\"dependencies\":[{\"name\":\"bitflags\",\"req\":\"^2\"},{\"name\":\"core-foundation\",\"req\":\"^0.9\"},{\"name\":\"system-configuration-sys\",\"req\":\"^0.6\"}],\"features\":{}}", "tagptr_0.2.0": "{\"dependencies\":[],\"features\":{}}", "tar_0.4.44": "{\"dependencies\":[{\"name\":\"filetime\",\"req\":\"^0.2.8\"},{\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(unix)\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3\"},{\"name\":\"xattr\",\"optional\":true,\"req\":\"^1.1.3\",\"target\":\"cfg(unix)\"}],\"features\":{\"default\":[\"xattr\"]}}", "tempfile_3.24.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\"},{\"name\":\"fastrand\",\"req\":\"^2.1.1\"},{\"default_features\":false,\"name\":\"getrandom\",\"optional\":true,\"req\":\"^0.3.0\",\"target\":\"cfg(any(unix, windows, target_os = \\\"wasi\\\"))\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"once_cell\",\"req\":\"^1.19.0\"},{\"features\":[\"fs\"],\"name\":\"rustix\",\"req\":\"^1.1.3\",\"target\":\"cfg(any(unix, target_os = \\\"wasi\\\"))\"},{\"features\":[\"Win32_Storage_FileSystem\",\"Win32_Foundation\"],\"name\":\"windows-sys\",\"req\":\">=0.52, <0.62\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[\"getrandom\"],\"nightly\":[]}}", @@ -1442,6 +1484,7 @@ "try-lock_0.2.5": "{\"dependencies\":[],\"features\":{}}", "ts-rs-macros_11.1.0": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1\"},{\"name\":\"quote\",\"req\":\"^1\"},{\"features\":[\"full\",\"extra-traits\"],\"name\":\"syn\",\"req\":\"^2.0.28\"},{\"name\":\"termcolor\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"no-serde-warnings\":[],\"serde-compat\":[\"termcolor\"]}}", "ts-rs_11.1.0": "{\"dependencies\":[{\"features\":[\"serde\"],\"name\":\"bigdecimal\",\"optional\":true,\"req\":\">=0.0.13, <0.5\"},{\"name\":\"bson\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"bytes\",\"optional\":true,\"req\":\"^1\"},{\"name\":\"chrono\",\"optional\":true,\"req\":\"^0.4\"},{\"features\":[\"serde\"],\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4\"},{\"name\":\"dprint-plugin-typescript\",\"optional\":true,\"req\":\"=0.95\"},{\"name\":\"heapless\",\"optional\":true,\"req\":\">=0.7, <0.9\"},{\"name\":\"indexmap\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"ordered-float\",\"optional\":true,\"req\":\">=3, <6\"},{\"name\":\"semver\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0\"},{\"name\":\"serde_json\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1\"},{\"name\":\"smol_str\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"thiserror\",\"req\":\"^2\"},{\"features\":[\"sync\"],\"name\":\"tokio\",\"optional\":true,\"req\":\"^1\"},{\"features\":[\"sync\",\"rt\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1.40\"},{\"name\":\"ts-rs-macros\",\"req\":\"=11.1.0\"},{\"name\":\"url\",\"optional\":true,\"req\":\"^2\"},{\"name\":\"uuid\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"bigdecimal-impl\":[\"bigdecimal\"],\"bson-uuid-impl\":[\"bson\"],\"bytes-impl\":[\"bytes\"],\"chrono-impl\":[\"chrono\"],\"default\":[\"serde-compat\"],\"format\":[\"dprint-plugin-typescript\"],\"heapless-impl\":[\"heapless\"],\"import-esm\":[],\"indexmap-impl\":[\"indexmap\"],\"no-serde-warnings\":[\"ts-rs-macros/no-serde-warnings\"],\"ordered-float-impl\":[\"ordered-float\"],\"semver-impl\":[\"semver\"],\"serde-compat\":[\"ts-rs-macros/serde-compat\"],\"serde-json-impl\":[\"serde_json\"],\"smol_str-impl\":[\"smol_str\"],\"tokio-impl\":[\"tokio\"],\"url-impl\":[\"url\"],\"uuid-impl\":[\"uuid\"]}}", + "turn_0.17.1": "{\"dependencies\":[{\"name\":\"async-trait\",\"req\":\"^0.1\"},{\"name\":\"base64\",\"req\":\"^0.22.1\"},{\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^3\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11.3\"},{\"name\":\"futures\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"md-5\",\"req\":\"^0.10\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"name\":\"ring\",\"req\":\"^0.17.14\"},{\"name\":\"stun\",\"req\":\"^0.17.0\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"signal\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"name\":\"tokio-util\",\"req\":\"^0.7\"},{\"default_features\":false,\"features\":[\"conn\",\"vnet\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"}],\"features\":{\"metrics\":[]}}", "two-face_0.5.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"cargo-lock\",\"req\":\"^10.1.0\"},{\"kind\":\"dev\",\"name\":\"insta\",\"req\":\"^1.44.3\"},{\"default_features\":false,\"features\":[\"read\"],\"kind\":\"dev\",\"name\":\"object\",\"req\":\"^0.36.7\"},{\"name\":\"serde\",\"req\":\"^1.0.228\"},{\"name\":\"serde_derive\",\"req\":\"^1.0.228\"},{\"kind\":\"dev\",\"name\":\"similar\",\"req\":\"^2.7.0\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"strum\",\"req\":\"^0.26.3\"},{\"default_features\":false,\"features\":[\"dump-load\",\"parsing\"],\"name\":\"syntect\",\"req\":\"^5.3.0\"},{\"default_features\":false,\"features\":[\"html\"],\"kind\":\"dev\",\"name\":\"syntect\",\"req\":\"^5.3.0\"},{\"kind\":\"dev\",\"name\":\"toml\",\"req\":\"^0.8.23\"},{\"default_features\":false,\"features\":[\"std\",\"xxhash64\"],\"kind\":\"dev\",\"name\":\"twox-hash\",\"req\":\"^2.1.2\"}],\"features\":{\"default\":[\"syntect-onig\"],\"syntect-default-fancy\":[\"syntect-fancy\",\"syntect/default-fancy\"],\"syntect-default-onig\":[\"syntect-onig\",\"syntect/default-onig\"],\"syntect-fancy\":[\"syntect/regex-fancy\"],\"syntect-onig\":[\"syntect/regex-onig\"]}}", "type-map_0.5.1": "{\"dependencies\":[{\"name\":\"rustc-hash\",\"req\":\"^2\"}],\"features\":{}}", "typenum_1.19.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"scale-info\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"const-generics\":[],\"force_unix_path_separator\":[],\"i128\":[],\"no_std\":[],\"scale_info\":[\"scale-info/derive\"],\"strict\":[]}}", @@ -1482,6 +1525,7 @@ "vt100_0.16.2": "{\"dependencies\":[{\"name\":\"itoa\",\"req\":\"^1.0.15\"},{\"features\":[\"term\"],\"kind\":\"dev\",\"name\":\"nix\",\"req\":\"^0.30.1\"},{\"kind\":\"dev\",\"name\":\"quickcheck\",\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"rand\",\"req\":\"^0.9\"},{\"features\":[\"derive\"],\"kind\":\"dev\",\"name\":\"serde\",\"req\":\"^1.0.219\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.140\"},{\"kind\":\"dev\",\"name\":\"terminal_size\",\"req\":\"^0.4.2\"},{\"name\":\"unicode-width\",\"req\":\"^0.2.1\"},{\"name\":\"vte\",\"req\":\"^0.15.0\"}],\"features\":{}}", "vte_0.15.0": "{\"dependencies\":[{\"default_features\":false,\"name\":\"arrayvec\",\"req\":\"^0.7.2\"},{\"default_features\":false,\"name\":\"bitflags\",\"optional\":true,\"req\":\"^2.3.3\"},{\"default_features\":false,\"name\":\"cursor-icon\",\"optional\":true,\"req\":\"^1.0.0\"},{\"name\":\"log\",\"optional\":true,\"req\":\"^0.4.17\"},{\"default_features\":false,\"name\":\"memchr\",\"req\":\"^2.7.4\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.160\"}],\"features\":{\"ansi\":[\"log\",\"cursor-icon\",\"bitflags\"],\"default\":[\"std\"],\"serde\":[\"dep:serde\"],\"std\":[\"memchr/std\"]}}", "wait-timeout_0.2.1": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2.56\",\"target\":\"cfg(unix)\"}],\"features\":{}}", + "waitgroup_0.1.2": "{\"dependencies\":[{\"features\":[\"attributes\"],\"kind\":\"dev\",\"name\":\"async-std\",\"req\":\"^1.5.0\"},{\"name\":\"atomic-waker\",\"req\":\"^1.0\"}],\"features\":{}}", "walkdir_2.5.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"doc-comment\",\"req\":\"^0.3\"},{\"name\":\"same-file\",\"req\":\"^1.0.1\"},{\"name\":\"winapi-util\",\"req\":\"^0.1.1\",\"target\":\"cfg(windows)\"}],\"features\":{}}", "want_0.3.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"tokio-executor\",\"req\":\"^0.2.0-alpha.2\"},{\"kind\":\"dev\",\"name\":\"tokio-sync\",\"req\":\"^0.2.0-alpha.2\"},{\"name\":\"try-lock\",\"req\":\"^0.2.4\"}],\"features\":{}}", "wasi_0.11.1+wasi-snapshot-preview1": "{\"dependencies\":[{\"name\":\"core\",\"optional\":true,\"package\":\"rustc-std-workspace-core\",\"req\":\"^1.0\"},{\"name\":\"rustc-std-workspace-alloc\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"default\":[\"std\"],\"rustc-dep-of-std\":[\"core\",\"rustc-std-workspace-alloc\"],\"std\":[]}}", @@ -1509,6 +1553,14 @@ "webpki-root-certs_1.0.5": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4.3\"},{\"kind\":\"dev\",\"name\":\"percent-encoding\",\"req\":\"^2.3\"},{\"default_features\":false,\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.8\"},{\"kind\":\"dev\",\"name\":\"ring\",\"req\":\"^0.17.0\"},{\"features\":[\"macros\",\"rt-multi-thread\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"alloc\"],\"kind\":\"dev\",\"name\":\"webpki\",\"package\":\"rustls-webpki\",\"req\":\"^0.103\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.17.0\"}],\"features\":{}}", "webpki-roots_0.26.11": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4.3\"},{\"name\":\"parent\",\"package\":\"webpki-roots\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"percent-encoding\",\"req\":\"^2.3\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.8\"},{\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.13\"},{\"kind\":\"dev\",\"name\":\"ring\",\"req\":\"^0.17.0\"},{\"kind\":\"dev\",\"name\":\"rustls\",\"req\":\"^0.23\"},{\"features\":[\"macros\",\"rt-multi-thread\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"alloc\"],\"kind\":\"dev\",\"name\":\"webpki\",\"package\":\"rustls-webpki\",\"req\":\"^0.102\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.17.0\"},{\"kind\":\"dev\",\"name\":\"yasna\",\"req\":\"^0.5.2\"}],\"features\":{}}", "webpki-roots_1.0.5": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"hex\",\"req\":\"^0.4.3\"},{\"kind\":\"dev\",\"name\":\"percent-encoding\",\"req\":\"^2.3\"},{\"default_features\":false,\"name\":\"pki-types\",\"package\":\"rustls-pki-types\",\"req\":\"^1.8\"},{\"kind\":\"dev\",\"name\":\"rcgen\",\"req\":\"^0.14.3\"},{\"kind\":\"dev\",\"name\":\"ring\",\"req\":\"^0.17.0\"},{\"kind\":\"dev\",\"name\":\"rustls\",\"req\":\"^0.23\"},{\"features\":[\"macros\",\"rt-multi-thread\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"features\":[\"alloc\"],\"kind\":\"dev\",\"name\":\"webpki\",\"package\":\"rustls-webpki\",\"req\":\"^0.103\"},{\"kind\":\"dev\",\"name\":\"x509-parser\",\"req\":\"^0.17.0\"},{\"kind\":\"dev\",\"name\":\"yasna\",\"req\":\"^0.5.2\"}],\"features\":{}}", + "webrtc-data_0.17.1": "{\"dependencies\":[{\"name\":\"bytes\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4.28\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11.3\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"sctp\",\"package\":\"webrtc-sctp\",\"req\":\"^0.17.1\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"default_features\":false,\"features\":[\"conn\",\"marshal\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"}],\"features\":{}}", + "webrtc-ice_0.17.1": "{\"dependencies\":[{\"name\":\"arc-swap\",\"req\":\"^1\"},{\"name\":\"async-trait\",\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4.28\"},{\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^3\"},{\"name\":\"crc\",\"req\":\"^3\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11.3\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"hyper\",\"req\":\"^0.14.27\"},{\"kind\":\"dev\",\"name\":\"ipnet\",\"req\":\"^2\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"mdns\",\"package\":\"webrtc-mdns\",\"req\":\"^0.17.1\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"kind\":\"dev\",\"name\":\"regex\",\"req\":\"^1.9.5\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1\"},{\"name\":\"serde_json\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"sha1\",\"req\":\"^0.10\"},{\"name\":\"stun\",\"req\":\"^0.17.0\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"name\":\"turn\",\"req\":\"^0.17.1\"},{\"name\":\"url\",\"req\":\"^2\"},{\"default_features\":false,\"features\":[\"conn\",\"vnet\",\"sync\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"},{\"features\":[\"v4\"],\"name\":\"uuid\",\"req\":\"^1\"},{\"name\":\"waitgroup\",\"req\":\"^0.1\"}],\"features\":{}}", + "webrtc-mdns_0.17.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4.28\"},{\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^3\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11.3\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"features\":[\"all\"],\"name\":\"socket2\",\"req\":\"^0.5\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"default_features\":false,\"features\":[\"ifaces\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"}],\"features\":{\"default\":[\"reuse_port\"],\"reuse_port\":[]}}", + "webrtc-media_0.17.1": "{\"dependencies\":[{\"name\":\"byteorder\",\"req\":\"^1\"},{\"name\":\"bytes\",\"req\":\"^1\"},{\"features\":[\"html_reports\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"nearly_eq\",\"req\":\"^0.2\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"name\":\"rtp\",\"req\":\"^0.17.1\"},{\"name\":\"thiserror\",\"req\":\"^1\"}],\"features\":{}}", + "webrtc-sctp_0.17.1": "{\"dependencies\":[{\"name\":\"arc-swap\",\"req\":\"^1\"},{\"name\":\"async-trait\",\"req\":\"^0.1\"},{\"name\":\"bytes\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4.28\"},{\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^3\"},{\"name\":\"crc\",\"req\":\"^3.2.1\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11.3\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"default_features\":false,\"features\":[\"conn\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"}],\"features\":{}}", + "webrtc-srtp_0.17.1": "{\"dependencies\":[{\"features\":[\"std\"],\"name\":\"aead\",\"req\":\"^0.5\"},{\"name\":\"aes\",\"req\":\"^0.8\"},{\"features\":[\"std\"],\"name\":\"aes-gcm\",\"req\":\"^0.10\"},{\"name\":\"byteorder\",\"req\":\"^1\"},{\"name\":\"bytes\",\"req\":\"^1\"},{\"features\":[\"async_futures\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"name\":\"ctr\",\"req\":\"^0.9\"},{\"features\":[\"std\"],\"name\":\"hmac\",\"req\":\"^0.12\"},{\"kind\":\"dev\",\"name\":\"lazy_static\",\"req\":\"^1\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"openssl\",\"optional\":true,\"req\":\"^0.10.72\"},{\"name\":\"rtcp\",\"req\":\"^0.17.1\"},{\"name\":\"rtp\",\"req\":\"^0.17.1\"},{\"name\":\"sha1\",\"req\":\"^0.10\"},{\"name\":\"subtle\",\"req\":\"^2\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"default_features\":false,\"features\":[\"conn\",\"buffer\",\"marshal\"],\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"}],\"features\":{\"openssl\":[\"dep:openssl\"],\"vendored-openssl\":[\"openssl/vendored\"]}}", + "webrtc-util_0.17.1": "{\"dependencies\":[{\"name\":\"async-trait\",\"req\":\"^0.1\"},{\"name\":\"bitflags\",\"req\":\"^1.3\",\"target\":\"cfg(windows)\"},{\"name\":\"bytes\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"chrono\",\"req\":\"^0.4.28\"},{\"features\":[\"async_futures\"],\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11.3\"},{\"name\":\"ipnet\",\"req\":\"^2.6.0\"},{\"name\":\"lazy_static\",\"req\":\"^1\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"nix\",\"req\":\"^0.26.2\",\"target\":\"cfg(not(windows))\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"rand\",\"req\":\"^0.9\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"kind\":\"dev\",\"name\":\"tokio-test\",\"req\":\"^0.4.4\"},{\"features\":[\"basetsd\",\"guiddef\",\"ws2def\",\"winerror\",\"ws2ipdef\"],\"name\":\"winapi\",\"req\":\"^0.3.9\",\"target\":\"cfg(windows)\"}],\"features\":{\"buffer\":[],\"conn\":[\"buffer\",\"sync\"],\"default\":[\"buffer\",\"conn\",\"ifaces\",\"vnet\",\"marshal\",\"sync\"],\"ifaces\":[],\"marshal\":[],\"sync\":[],\"vnet\":[\"ifaces\"]}}", + "webrtc_0.17.1": "{\"dependencies\":[{\"name\":\"arc-swap\",\"req\":\"^1\"},{\"name\":\"async-trait\",\"req\":\"^0.1\"},{\"name\":\"bytes\",\"req\":\"^1\"},{\"name\":\"data\",\"package\":\"webrtc-data\",\"req\":\"^0.17.1\"},{\"name\":\"dtls\",\"req\":\"^0.17.1\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.11.3\"},{\"name\":\"hex\",\"req\":\"^0.4\"},{\"name\":\"ice\",\"package\":\"webrtc-ice\",\"req\":\"^0.17.1\"},{\"name\":\"interceptor\",\"req\":\"^0.17.1\"},{\"name\":\"lazy_static\",\"req\":\"^1.4\"},{\"name\":\"log\",\"req\":\"^0.4\"},{\"name\":\"mdns\",\"package\":\"webrtc-mdns\",\"req\":\"^0.17.1\"},{\"name\":\"media\",\"package\":\"webrtc-media\",\"req\":\"^0.17.1\"},{\"name\":\"pem\",\"optional\":true,\"req\":\"^3\"},{\"name\":\"portable-atomic\",\"req\":\"^1.6\"},{\"name\":\"rand\",\"req\":\"^0.9.1\"},{\"features\":[\"pem\",\"x509-parser\"],\"name\":\"rcgen\",\"req\":\"^0.13\"},{\"name\":\"regex\",\"req\":\"^1.9.5\"},{\"name\":\"ring\",\"req\":\"^0.17.14\"},{\"name\":\"rtcp\",\"req\":\"^0.17.1\"},{\"name\":\"rtp\",\"req\":\"^0.17.1\"},{\"name\":\"sctp\",\"package\":\"webrtc-sctp\",\"req\":\"^0.17.1\"},{\"name\":\"sdp\",\"req\":\"^0.17.1\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"req\":\"^1\"},{\"name\":\"serde_json\",\"req\":\"^1\"},{\"name\":\"sha2\",\"req\":\"^0.10\"},{\"features\":[\"serde\"],\"name\":\"smol_str\",\"req\":\"^0.2\"},{\"name\":\"srtp\",\"package\":\"webrtc-srtp\",\"req\":\"^0.17.1\"},{\"name\":\"stun\",\"req\":\"^0.17.0\"},{\"name\":\"thiserror\",\"req\":\"^1\"},{\"features\":[\"fs\",\"io-util\",\"io-std\",\"macros\",\"net\",\"parking_lot\",\"rt\",\"rt-multi-thread\",\"sync\",\"time\"],\"name\":\"tokio\",\"req\":\"^1.32.0\"},{\"name\":\"turn\",\"req\":\"^0.17.1\"},{\"name\":\"unicase\",\"req\":\"^2.8\"},{\"name\":\"url\",\"req\":\"^2\"},{\"default_features\":false,\"name\":\"util\",\"package\":\"webrtc-util\",\"req\":\"^0.17.1\"},{\"name\":\"waitgroup\",\"req\":\"^0.1\"}],\"features\":{\"openssl\":[\"srtp/openssl\"],\"pem\":[\"dep:pem\",\"dtls/pem\"],\"vendored-openssl\":[\"srtp/vendored-openssl\"]}}", "weezl_0.1.12": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3.1\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"futures\",\"optional\":true,\"req\":\"^0.3.12\"},{\"default_features\":false,\"features\":[\"macros\",\"io-util\",\"net\",\"rt\",\"rt-multi-thread\"],\"kind\":\"dev\",\"name\":\"tokio\",\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"compat\"],\"kind\":\"dev\",\"name\":\"tokio-util\",\"req\":\"^0.6.2\"}],\"features\":{\"alloc\":[],\"async\":[\"futures\",\"std\"],\"default\":[\"std\"],\"std\":[\"alloc\"]}}", "which_6.0.3": "{\"dependencies\":[{\"name\":\"either\",\"req\":\"^1.9.0\"},{\"name\":\"home\",\"req\":\"^0.5.9\",\"target\":\"cfg(any(windows, unix, target_os = \\\"redox\\\"))\"},{\"name\":\"regex\",\"optional\":true,\"req\":\"^1.10.2\"},{\"default_features\":false,\"features\":[\"fs\",\"std\"],\"name\":\"rustix\",\"req\":\"^0.38.30\",\"target\":\"cfg(any(unix, target_os = \\\"wasi\\\", target_os = \\\"redox\\\"))\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.9.0\"},{\"default_features\":false,\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.40\"},{\"features\":[\"kernel\"],\"name\":\"winsafe\",\"req\":\"^0.0.19\",\"target\":\"cfg(windows)\"}],\"features\":{\"regex\":[\"dep:regex\"],\"tracing\":[\"dep:tracing\"]}}", "which_8.0.0": "{\"dependencies\":[{\"name\":\"env_home\",\"optional\":true,\"req\":\"^0.1.0\",\"target\":\"cfg(any(windows, unix, target_os = \\\"redox\\\"))\"},{\"name\":\"regex\",\"optional\":true,\"req\":\"^1.10.2\"},{\"default_features\":false,\"features\":[\"fs\",\"std\"],\"name\":\"rustix\",\"optional\":true,\"req\":\"^1.0.5\",\"target\":\"cfg(any(unix, target_os = \\\"wasi\\\", target_os = \\\"redox\\\"))\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3.9.0\"},{\"default_features\":false,\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1.40\"},{\"features\":[\"kernel\"],\"name\":\"winsafe\",\"optional\":true,\"req\":\"^0.0.19\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[\"real-sys\"],\"real-sys\":[\"dep:env_home\",\"dep:rustix\",\"dep:winsafe\"],\"regex\":[\"dep:regex\"],\"tracing\":[\"dep:tracing\"]}}", @@ -1600,6 +1652,7 @@ "x11rb-protocol_0.13.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"all-extensions\":[\"composite\",\"damage\",\"dbe\",\"dpms\",\"dri2\",\"dri3\",\"glx\",\"present\",\"randr\",\"record\",\"render\",\"res\",\"screensaver\",\"shape\",\"shm\",\"sync\",\"xevie\",\"xf86dri\",\"xf86vidmode\",\"xfixes\",\"xinerama\",\"xinput\",\"xkb\",\"xprint\",\"xselinux\",\"xtest\",\"xv\",\"xvmc\"],\"composite\":[\"xfixes\"],\"damage\":[\"xfixes\"],\"dbe\":[],\"default\":[\"std\"],\"dpms\":[],\"dri2\":[],\"dri3\":[],\"extra-traits\":[],\"glx\":[],\"present\":[\"randr\",\"xfixes\",\"sync\",\"dri3\"],\"randr\":[\"render\"],\"record\":[],\"render\":[],\"request-parsing\":[],\"res\":[],\"resource_manager\":[\"std\"],\"screensaver\":[],\"shape\":[],\"shm\":[],\"std\":[],\"sync\":[],\"xevie\":[],\"xf86dri\":[],\"xf86vidmode\":[],\"xfixes\":[\"render\",\"shape\"],\"xinerama\":[],\"xinput\":[\"xfixes\"],\"xkb\":[],\"xprint\":[],\"xselinux\":[],\"xtest\":[],\"xv\":[\"shm\"],\"xvmc\":[\"xv\"]}}", "x11rb_0.13.2": "{\"dependencies\":[{\"name\":\"as-raw-xcb-connection\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"gethostname\",\"req\":\"^1.0\"},{\"name\":\"libc\",\"optional\":true,\"req\":\"^0.2\"},{\"name\":\"libloading\",\"optional\":true,\"req\":\"^0.8.0\"},{\"name\":\"once_cell\",\"optional\":true,\"req\":\"^1.19\"},{\"kind\":\"dev\",\"name\":\"polling\",\"req\":\"^3.4\"},{\"name\":\"raw-window-handle\",\"optional\":true,\"req\":\"^0.5.0\"},{\"default_features\":false,\"features\":[\"std\",\"event\",\"fs\",\"net\",\"system\"],\"name\":\"rustix\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"tracing\",\"optional\":true,\"req\":\"^0.1\"},{\"kind\":\"dev\",\"name\":\"tracing-subscriber\",\"req\":\"^0.3\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"x11rb-protocol\",\"req\":\"^0.13.2\"},{\"name\":\"xcursor\",\"optional\":true,\"req\":\"^0.3.7\"}],\"features\":{\"all-extensions\":[\"x11rb-protocol/all-extensions\",\"composite\",\"damage\",\"dbe\",\"dpms\",\"dri2\",\"dri3\",\"glx\",\"present\",\"randr\",\"record\",\"render\",\"res\",\"screensaver\",\"shape\",\"shm\",\"sync\",\"xevie\",\"xf86dri\",\"xf86vidmode\",\"xfixes\",\"xinerama\",\"xinput\",\"xkb\",\"xprint\",\"xselinux\",\"xtest\",\"xv\",\"xvmc\"],\"allow-unsafe-code\":[\"libc\",\"as-raw-xcb-connection\"],\"composite\":[\"x11rb-protocol/composite\",\"xfixes\"],\"cursor\":[\"render\",\"resource_manager\",\"xcursor\"],\"damage\":[\"x11rb-protocol/damage\",\"xfixes\"],\"dbe\":[\"x11rb-protocol/dbe\"],\"dl-libxcb\":[\"allow-unsafe-code\",\"libloading\",\"once_cell\"],\"dpms\":[\"x11rb-protocol/dpms\"],\"dri2\":[\"x11rb-protocol/dri2\"],\"dri3\":[\"x11rb-protocol/dri3\"],\"extra-traits\":[\"x11rb-protocol/extra-traits\"],\"glx\":[\"x11rb-protocol/glx\"],\"image\":[],\"present\":[\"x11rb-protocol/present\",\"randr\",\"xfixes\",\"sync\"],\"randr\":[\"x11rb-protocol/randr\",\"render\"],\"record\":[\"x11rb-protocol/record\"],\"render\":[\"x11rb-protocol/render\"],\"request-parsing\":[\"x11rb-protocol/request-parsing\"],\"res\":[\"x11rb-protocol/res\"],\"resource_manager\":[\"x11rb-protocol/resource_manager\"],\"screensaver\":[\"x11rb-protocol/screensaver\"],\"shape\":[\"x11rb-protocol/shape\"],\"shm\":[\"x11rb-protocol/shm\"],\"sync\":[\"x11rb-protocol/sync\"],\"xevie\":[\"x11rb-protocol/xevie\"],\"xf86dri\":[\"x11rb-protocol/xf86dri\"],\"xf86vidmode\":[\"x11rb-protocol/xf86vidmode\"],\"xfixes\":[\"x11rb-protocol/xfixes\",\"render\",\"shape\"],\"xinerama\":[\"x11rb-protocol/xinerama\"],\"xinput\":[\"x11rb-protocol/xinput\",\"xfixes\"],\"xkb\":[\"x11rb-protocol/xkb\"],\"xprint\":[\"x11rb-protocol/xprint\"],\"xselinux\":[\"x11rb-protocol/xselinux\"],\"xtest\":[\"x11rb-protocol/xtest\"],\"xv\":[\"x11rb-protocol/xv\",\"shm\"],\"xvmc\":[\"x11rb-protocol/xvmc\",\"xv\"]}}", "x25519-dalek_2.0.1": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.5\"},{\"default_features\":false,\"name\":\"curve25519-dalek\",\"req\":\"^4\"},{\"default_features\":false,\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"default_features\":false,\"features\":[\"getrandom\"],\"kind\":\"dev\",\"name\":\"rand_core\",\"req\":\"^0.6\"},{\"default_features\":false,\"features\":[\"derive\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1\"},{\"default_features\":false,\"features\":[\"zeroize_derive\"],\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1\"}],\"features\":{\"alloc\":[\"curve25519-dalek/alloc\",\"serde?/alloc\",\"zeroize?/alloc\"],\"default\":[\"alloc\",\"precomputed-tables\",\"zeroize\"],\"getrandom\":[\"rand_core/getrandom\"],\"precomputed-tables\":[\"curve25519-dalek/precomputed-tables\"],\"reusable_secrets\":[],\"serde\":[\"dep:serde\",\"curve25519-dalek/serde\"],\"static_secrets\":[],\"zeroize\":[\"dep:zeroize\",\"curve25519-dalek/zeroize\"]}}", + "x509-parser_0.16.0": "{\"dependencies\":[{\"features\":[\"datetime\"],\"name\":\"asn1-rs\",\"req\":\"^0.6.1\"},{\"name\":\"data-encoding\",\"req\":\"^2.2.1\"},{\"features\":[\"bigint\"],\"name\":\"der-parser\",\"req\":\"^9.0\"},{\"name\":\"lazy_static\",\"req\":\"^1.4\"},{\"name\":\"nom\",\"req\":\"^7.0\"},{\"features\":[\"crypto\",\"x509\",\"x962\"],\"name\":\"oid-registry\",\"req\":\"^0.7\"},{\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17.7\"},{\"name\":\"rusticata-macros\",\"req\":\"^4.0\"},{\"name\":\"thiserror\",\"req\":\"^1.0.2\"},{\"features\":[\"formatting\"],\"name\":\"time\",\"req\":\"^0.3.20\"}],\"features\":{\"default\":[],\"validate\":[],\"verify\":[\"ring\"]}}", "x509-parser_0.18.1": "{\"dependencies\":[{\"features\":[\"datetime\"],\"name\":\"asn1-rs\",\"req\":\"^0.7.0\"},{\"name\":\"aws-lc-rs\",\"optional\":true,\"req\":\"^1.0\"},{\"name\":\"data-encoding\",\"req\":\"^2.2.1\"},{\"features\":[\"bigint\"],\"name\":\"der-parser\",\"req\":\"^10.0\"},{\"name\":\"lazy_static\",\"req\":\"^1.4\"},{\"name\":\"nom\",\"req\":\"^7.0\"},{\"features\":[\"crypto\",\"x509\",\"x962\"],\"name\":\"oid-registry\",\"req\":\"^0.8.1\"},{\"name\":\"ring\",\"optional\":true,\"req\":\"^0.17.12\"},{\"name\":\"rusticata-macros\",\"req\":\"^4.0\"},{\"name\":\"thiserror\",\"req\":\"^2.0\"},{\"features\":[\"formatting\"],\"name\":\"time\",\"req\":\"^0.3.35\"}],\"features\":{\"default\":[],\"validate\":[],\"verify\":[\"ring\"],\"verify-aws\":[\"aws-lc-rs\"]}}", "xattr_1.6.1": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2.150\",\"target\":\"cfg(any(target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\"},{\"default_features\":false,\"features\":[\"fs\",\"std\"],\"name\":\"rustix\",\"req\":\"^1.0.0\",\"target\":\"cfg(any(target_os = \\\"android\\\", target_os = \\\"linux\\\", target_os = \\\"macos\\\", target_os = \\\"hurd\\\"))\"},{\"kind\":\"dev\",\"name\":\"tempfile\",\"req\":\"^3\"}],\"features\":{\"default\":[\"unsupported\"],\"unsupported\":[]}}", "xdg-home_1.3.0": "{\"dependencies\":[{\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(unix)\"},{\"features\":[\"Win32_Foundation\",\"Win32_UI_Shell\",\"Win32_System_Com\"],\"name\":\"windows-sys\",\"req\":\"^0.59\",\"target\":\"cfg(windows)\"}],\"features\":{}}", diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 5cc4fe2ee5c..87818789a81 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -196,6 +196,20 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "age" version = "0.11.2" @@ -448,7 +462,7 @@ dependencies = [ "objc2-foundation", "parking_lot", "percent-encoding", - "windows-sys 0.52.0", + "windows-sys 0.60.2", "wl-clipboard-rs", "x11rb", ] @@ -483,13 +497,29 @@ dependencies = [ "term", ] +[[package]] +name = "asn1-rs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +dependencies = [ + "asn1-rs-derive 0.5.1", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + [[package]] name = "asn1-rs" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" dependencies = [ - "asn1-rs-derive", + "asn1-rs-derive 0.6.0", "asn1-rs-impl", "displaydoc", "nom 7.1.3", @@ -499,6 +529,18 @@ dependencies = [ "time", ] +[[package]] +name = "asn1-rs-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + [[package]] name = "asn1-rs-derive" version = "0.6.0" @@ -841,6 +883,12 @@ dependencies = [ "windows-link", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.21.7" @@ -1019,6 +1067,29 @@ version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +[[package]] +name = "bytecheck" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0caa33a2c0edca0419d15ac723dff03f1956f7978329b1e3b5fdaaaed9d3ca8b" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "rancor", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "bytemuck" version = "1.25.0" @@ -1150,6 +1221,18 @@ dependencies = [ "shlex", ] +[[package]] +name = "ccm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae3c82e4355234767756212c570e29833699ab63e6ffd161887314cc5b43847" +dependencies = [ + "aead", + "cipher", + "ctr", + "subtle", +] + [[package]] name = "cesu8" version = "1.1.0" @@ -1377,6 +1460,8 @@ dependencies = [ "eventsource-stream", "futures", "http 1.4.0", + "interceptor", + "opus-rs", "pretty_assertions", "regex-lite", "reqwest", @@ -1390,6 +1475,7 @@ dependencies = [ "tracing", "tungstenite", "url", + "webrtc", "wiremock", ] @@ -3305,11 +3391,13 @@ dependencies = [ "codex-protocol", "codex-utils-absolute-path", "codex-utils-cargo-bin", + "codex-utils-rustls-provider", "ctor 0.6.3", "futures", "notify", "opentelemetry", "opentelemetry_sdk", + "opus-rs", "pretty_assertions", "regex-lite", "reqwest", @@ -3322,6 +3410,7 @@ dependencies = [ "tracing-opentelemetry", "tracing-subscriber", "walkdir", + "webrtc", "wiremock", "zstd", ] @@ -3482,6 +3571,18 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.7" @@ -3489,6 +3590,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] @@ -3539,6 +3641,15 @@ version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -3766,13 +3877,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs 0.6.2", + "displaydoc", + "nom 7.1.3", + "num-bigint", + "num-traits", + "rusticata-macros", +] + [[package]] name = "der-parser" version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" dependencies = [ - "asn1-rs", + "asn1-rs 0.7.1", "displaydoc", "nom 7.1.3", "num-bigint", @@ -3956,7 +4081,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4013,6 +4138,42 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +[[package]] +name = "dtls" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f016db07b91e9d79cc60a152c163d3f0ce2d4c0173cb3964de3526aab6e07fa" +dependencies = [ + "aes", + "aes-gcm", + "async-trait", + "bytecheck", + "byteorder", + "cbc", + "ccm", + "chacha20poly1305", + "der-parser 9.0.0", + "hmac", + "log", + "p256", + "p384", + "portable-atomic", + "rand 0.9.2", + "rand_core 0.6.4", + "rcgen 0.13.2", + "ring", + "rkyv", + "rustls", + "sec1", + "sha1", + "sha2", + "thiserror 1.0.69", + "tokio", + "webrtc-util", + "x25519-dalek", + "x509-parser 0.16.0", +] + [[package]] name = "dtor" version = "0.1.1" @@ -4060,6 +4221,20 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + [[package]] name = "either" version = "1.15.0" @@ -4069,6 +4244,27 @@ dependencies = [ "serde", ] +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "ena" version = "0.14.3" @@ -4201,7 +4397,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -4312,6 +4508,16 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "fiat-crypto" version = "0.2.9" @@ -4678,6 +4884,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -4726,6 +4933,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "gif" version = "0.14.1" @@ -4761,6 +4978,17 @@ dependencies = [ "regex-syntax 0.8.8", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "gzip-header" version = "1.0.0" @@ -5107,13 +5335,14 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.20" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", + "futures-core", "futures-util", "http 1.4.0", "http-body", @@ -5122,7 +5351,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2 0.6.2", "system-configuration", "tokio", "tower-service", @@ -5558,6 +5787,27 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "interceptor" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f73f4fdb971cab2d599cbdc2ccf0c6ea8fb27347b871ed14c65ce2353dbe75b" +dependencies = [ + "async-trait", + "bytes", + "futures", + "log", + "portable-atomic", + "rand 0.9.2", + "rtcp", + "rtp", + "thiserror 1.0.69", + "tokio", + "waitgroup", + "webrtc-srtp", + "webrtc-util", +] + [[package]] name = "intl-memoizer" version = "0.5.3" @@ -5628,7 +5878,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -6161,6 +6411,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -6250,6 +6509,26 @@ dependencies = [ "serde", ] +[[package]] +name = "munge" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "native-tls" version = "0.2.14" @@ -6311,6 +6590,19 @@ dependencies = [ "smallvec", ] +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", +] + [[package]] name = "nix" version = "0.28.0" @@ -6406,7 +6698,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -6582,7 +6874,7 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "chrono", "getrandom 0.2.17", "http 1.4.0", @@ -6799,13 +7091,22 @@ dependencies = [ "cc", ] +[[package]] +name = "oid-registry" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" +dependencies = [ + "asn1-rs 0.6.2", +] + [[package]] name = "oid-registry" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" dependencies = [ - "asn1-rs", + "asn1-rs 0.7.1", ] [[package]] @@ -7017,6 +7318,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "opus-rs" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f857fcc607bea70f9b073ad267e829080646b14c260ea5e43c48ba9fca8e7dd4" +dependencies = [ + "num-complex", + "once_cell", +] + [[package]] name = "ordered-stream" version = "0.2.0" @@ -7050,7 +7361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.45.0", + "windows-sys 0.61.2", ] [[package]] @@ -7063,6 +7374,30 @@ dependencies = [ "supports-color 3.0.2", ] +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "parking" version = "2.2.1" @@ -7315,8 +7650,20 @@ dependencies = [ ] [[package]] -name = "portable-atomic" -version = "1.13.1" +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" @@ -7432,6 +7779,15 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro-crate" version = "3.4.0" @@ -7539,6 +7895,26 @@ version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "pulldown-cmark" version = "0.10.3" @@ -7596,7 +7972,7 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2 0.5.10", + "socket2 0.6.2", "thiserror 2.0.18", "tokio", "tracing", @@ -7633,9 +8009,9 @@ dependencies = [ "cfg_aliases 0.2.1", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -7931,14 +8307,14 @@ dependencies = [ "rama-http-types", "rama-net", "rama-utils", - "rcgen", + "rcgen 0.14.7", "rustls", "rustls-native-certs", "rustls-pki-types", "tokio", "tokio-rustls", "webpki-roots 1.0.5", - "x509-parser", + "x509-parser 0.18.1", ] [[package]] @@ -7978,11 +8354,20 @@ dependencies = [ "regex", "serde", "smallvec", - "smol_str", + "smol_str 0.3.5", "tokio", "wildcard", ] +[[package]] +name = "rancor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +dependencies = [ + "ptr_meta", +] + [[package]] name = "rand" version = "0.8.5" @@ -8100,6 +8485,20 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rcgen" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" +dependencies = [ + "pem", + "ring", + "rustls-pki-types", + "time", + "x509-parser 0.16.0", + "yasna", +] + [[package]] name = "rcgen" version = "0.14.7" @@ -8110,7 +8509,7 @@ dependencies = [ "pem", "rustls-pki-types", "time", - "x509-parser", + "x509-parser 0.18.1", "yasna", ] @@ -8215,6 +8614,15 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "rend" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqwest" version = "0.12.28" @@ -8238,6 +8646,7 @@ dependencies = [ "js-sys", "log", "mime", + "mime_guess", "native-tls", "percent-encoding", "pin-project-lite", @@ -8280,6 +8689,16 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ring" version = "0.17.14" @@ -8294,6 +8713,36 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rkyv" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" +dependencies = [ + "bytecheck", + "bytes", + "hashbrown 0.16.1", + "indexmap 2.13.0", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "rmcp" version = "0.15.0" @@ -8363,6 +8812,32 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rtcp" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb22f1cc99aea8152fdae6a4bc52a9caddf4bd1ff083d897c1f9f279956177e8" +dependencies = [ + "bytes", + "thiserror 1.0.69", + "webrtc-util", +] + +[[package]] +name = "rtp" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8d41f3565d9add11caabe7c61745517f4ef511c168a6aa2b59ce4c701802cde" +dependencies = [ + "bytes", + "memchr", + "portable-atomic", + "rand 0.9.2", + "serde", + "thiserror 1.0.69", + "webrtc-util", +] + [[package]] name = "runfiles" version = "0.1.0" @@ -8471,7 +8946,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -8727,6 +9202,32 @@ version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" +[[package]] +name = "sdp" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22c3b0257608d7de4de4c4ea650ccc2e6e3e45e3cd80039fcdee768bcb449253" +dependencies = [ + "rand 0.9.2", + "substring", + "thiserror 1.0.69", + "url", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "seccompiler" version = "0.5.0" @@ -9291,6 +9792,15 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + [[package]] name = "smol_str" version = "0.3.5" @@ -9771,6 +10281,34 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "stun" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e0fd33c04d4617df42c9c84c698511c59f59869629fb7a193067eec41bce347" +dependencies = [ + "base64 0.22.1", + "crc", + "lazy_static", + "md-5", + "rand 0.9.2", + "ring", + "subtle", + "thiserror 1.0.69", + "tokio", + "url", + "webrtc-util", +] + +[[package]] +name = "substring" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" +dependencies = [ + "autocfg", +] + [[package]] name = "subtle" version = "2.6.1" @@ -9870,9 +10408,9 @@ dependencies = [ [[package]] name = "system-configuration" -version = "0.7.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.10.0", "core-foundation 0.9.4", @@ -9905,7 +10443,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix 1.1.3", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -10707,6 +11245,27 @@ dependencies = [ "utf-8", ] +[[package]] +name = "turn" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a8b8ac3543b2a8eb0b28c7ac3d5f2db6221e057f3b3ae47cf7637b1333a5c3" +dependencies = [ + "async-trait", + "base64 0.22.1", + "futures", + "log", + "md-5", + "portable-atomic", + "rand 0.9.2", + "ring", + "stun", + "thiserror 1.0.69", + "tokio", + "tokio-util", + "webrtc-util", +] + [[package]] name = "two-face" version = "0.5.1" @@ -11024,6 +11583,15 @@ dependencies = [ "libc", ] +[[package]] +name = "waitgroup" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292" +dependencies = [ + "atomic-waker", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -11269,6 +11837,175 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webrtc" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ba06986c4fcfbbb4b490abe4b88887b0ac9de0d3eb0aae36f3254e38d6ecdd1" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "dtls", + "hex", + "interceptor", + "lazy_static", + "log", + "portable-atomic", + "rand 0.9.2", + "rcgen 0.13.2", + "regex", + "ring", + "rtcp", + "rtp", + "sdp", + "serde", + "serde_json", + "sha2", + "smol_str 0.2.2", + "stun", + "thiserror 1.0.69", + "tokio", + "turn", + "unicase", + "url", + "waitgroup", + "webrtc-data", + "webrtc-ice", + "webrtc-mdns", + "webrtc-media", + "webrtc-sctp", + "webrtc-srtp", + "webrtc-util", +] + +[[package]] +name = "webrtc-data" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ca42127ee64bcb71da36d151e6f87b12488c5f14c4f379e73d2d52a8e54aa0" +dependencies = [ + "bytes", + "log", + "portable-atomic", + "thiserror 1.0.69", + "tokio", + "webrtc-sctp", + "webrtc-util", +] + +[[package]] +name = "webrtc-ice" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ede72a36e5dda685814c389b2b34ac60b3ed000a81789e93626e27180eb785" +dependencies = [ + "arc-swap", + "async-trait", + "crc", + "log", + "portable-atomic", + "rand 0.9.2", + "serde", + "serde_json", + "stun", + "thiserror 1.0.69", + "tokio", + "turn", + "url", + "uuid", + "waitgroup", + "webrtc-mdns", + "webrtc-util", +] + +[[package]] +name = "webrtc-mdns" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b62bc8d3fb5024bc6ffde5f4aad2127ce17f8359dbc6f70208a324a12e44677" +dependencies = [ + "log", + "socket2 0.5.10", + "thiserror 1.0.69", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-media" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a28290bd0cdda196f8bf5c6f7dddaef18cc913ee0702cd1ea237bad203e337" +dependencies = [ + "byteorder", + "bytes", + "rand 0.9.2", + "rtp", + "thiserror 1.0.69", +] + +[[package]] +name = "webrtc-sctp" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ea6633bf951b3fd71eba3244731c8d0814f6a80300620a4370cad2983a5a42f" +dependencies = [ + "arc-swap", + "async-trait", + "bytes", + "crc", + "log", + "portable-atomic", + "rand 0.9.2", + "thiserror 1.0.69", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-srtp" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e437f74b04f42049192e25cbb33c21c86be308875e6afe14cf8e28d1ffa35ac" +dependencies = [ + "aead", + "aes", + "aes-gcm", + "byteorder", + "bytes", + "ctr", + "hmac", + "log", + "rtcp", + "rtp", + "sha1", + "subtle", + "thiserror 1.0.69", + "tokio", + "webrtc-util", +] + +[[package]] +name = "webrtc-util" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65c1e0143a43d40f69e1d8c2ffc8734e379b49c06d45892ea4104c388bf9ead" +dependencies = [ + "async-trait", + "bitflags 1.3.2", + "bytes", + "ipnet", + "lazy_static", + "log", + "nix 0.26.4", + "portable-atomic", + "rand 0.9.2", + "thiserror 1.0.69", + "tokio", + "winapi", +] + [[package]] name = "weezl" version = "0.1.12" @@ -11351,7 +12088,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -12002,19 +12739,37 @@ dependencies = [ "zeroize", ] +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs 0.6.2", + "data-encoding", + "der-parser 9.0.0", + "lazy_static", + "nom 7.1.3", + "oid-registry 0.7.1", + "ring", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + [[package]] name = "x509-parser" version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" dependencies = [ - "asn1-rs", + "asn1-rs 0.7.1", "aws-lc-rs", "data-encoding", - "der-parser", + "der-parser 10.0.0", "lazy_static", "nom 7.1.3", - "oid-registry", + "oid-registry 0.8.1", "ring", "rusticata-macros", "thiserror 2.0.18", diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index 16329276cd6..a02dcb1c6e7 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -239,6 +239,7 @@ image = { version = "^0.25.9", default-features = false } include_dir = "0.7.4" indexmap = "2.12.0" insta = "1.46.3" +interceptor = "0.17.1" inventory = "0.3.19" itertools = "0.14.0" jsonwebtoken = "9.3.1" @@ -255,6 +256,7 @@ notify = "8.2.0" nucleo = { git = "https://github.com/helix-editor/nucleo.git", rev = "4253de9faabb4e5c6d81d946a5e35a90f87347ee" } once_cell = "1.20.2" openssl-sys = "*" +opus-rs = "0.1.11" opentelemetry = "0.31.0" opentelemetry-appender-tracing = "0.31.0" opentelemetry-otlp = "0.31.0" @@ -349,6 +351,7 @@ v8 = "=146.4.0" vt100 = "0.16.2" walkdir = "2.5.0" webbrowser = "1.0" +webrtc = "0.17.1" which = "8" wildmatch = "2.6.1" zip = "2.4.2" diff --git a/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs b/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs index 317155da701..5c5f7750e5c 100644 --- a/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs +++ b/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs @@ -3,6 +3,8 @@ use anyhow::Result; use app_test_support::McpProcess; use app_test_support::create_mock_responses_server_sequence_unchecked; use app_test_support::to_response; +use base64::Engine; +use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use codex_app_server_protocol::JSONRPCError; use codex_app_server_protocol::JSONRPCResponse; use codex_app_server_protocol::LoginAccountResponse; @@ -40,6 +42,16 @@ use tokio::time::timeout; const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10); const STARTUP_CONTEXT_HEADER: &str = "Startup context from Codex."; +fn realtime_pcm_test_tone_20ms_base64() -> String { + let pcm_bytes: Vec = (0..480) + .flat_map(|index| { + let sample = if index % 2 == 0 { 1024_i16 } else { -1024_i16 }; + sample.to_le_bytes() + }) + .collect(); + BASE64_STANDARD.encode(pcm_bytes) +} + #[tokio::test] async fn realtime_conversation_streams_v2_notifications() -> Result<()> { skip_if_no_network!(Ok(())); @@ -155,7 +167,7 @@ async fn realtime_conversation_streams_v2_notifications() -> Result<()> { .send_thread_realtime_append_audio_request(ThreadRealtimeAppendAudioParams { thread_id: started.thread_id.clone(), audio: ThreadRealtimeAudioChunk { - data: "BQYH".to_string(), + data: realtime_pcm_test_tone_20ms_base64(), sample_rate: 24_000, num_channels: 1, samples_per_channel: Some(480), diff --git a/codex-rs/codex-api/Cargo.toml b/codex-rs/codex-api/Cargo.toml index 7bafd153288..f5679f91ab1 100644 --- a/codex-rs/codex-api/Cargo.toml +++ b/codex-rs/codex-api/Cargo.toml @@ -14,17 +14,21 @@ codex-protocol = { workspace = true } codex-utils-rustls-provider = { workspace = true } futures = { workspace = true } http = { workspace = true } +interceptor = { workspace = true } +opus-rs = { workspace = true } +reqwest = { workspace = true, features = ["multipart"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["macros", "net", "rt", "sync", "time"] } tokio-tungstenite = { workspace = true } -tungstenite = { workspace = true } tracing = { workspace = true } eventsource-stream = { workspace = true } regex-lite = { workspace = true } tokio-util = { workspace = true, features = ["codec"] } +tungstenite = { workspace = true } url = { workspace = true } +webrtc = { workspace = true } [dev-dependencies] anyhow = { workspace = true } @@ -32,7 +36,6 @@ assert_matches = { workspace = true } pretty_assertions = { workspace = true } tokio-test = { workspace = true } wiremock = { workspace = true } -reqwest = { workspace = true } [lints] workspace = true diff --git a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs index eed0e470a47..b897ca6a496 100644 --- a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs +++ b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs @@ -2,7 +2,6 @@ use crate::endpoint::realtime_websocket::methods_common::conversation_handoff_ap use crate::endpoint::realtime_websocket::methods_common::conversation_item_create_message; use crate::endpoint::realtime_websocket::methods_common::normalized_session_mode; use crate::endpoint::realtime_websocket::methods_common::session_update_session; -use crate::endpoint::realtime_websocket::methods_common::websocket_intent; use crate::endpoint::realtime_websocket::protocol::RealtimeAudioFrame; use crate::endpoint::realtime_websocket::protocol::RealtimeEvent; use crate::endpoint::realtime_websocket::protocol::RealtimeEventParser; @@ -14,194 +13,96 @@ use crate::endpoint::realtime_websocket::protocol::RealtimeTranscriptEntry; use crate::endpoint::realtime_websocket::protocol::parse_realtime_event; use crate::error::ApiError; use crate::provider::Provider; -use codex_client::maybe_build_rustls_client_config_with_custom_ca; +use base64::Engine; +use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; +use bytes::Bytes; +use codex_client::build_reqwest_client_with_custom_ca; use codex_utils_rustls_provider::ensure_rustls_crypto_provider; -use futures::SinkExt; -use futures::StreamExt; use http::HeaderMap; use http::HeaderValue; +use interceptor::registry::Registry; +use opus_rs::Application; +use opus_rs::OpusDecoder; +use opus_rs::OpusEncoder; use std::collections::HashMap; use std::sync::Arc; +use std::sync::Mutex as StdMutex; use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering; -use tokio::net::TcpStream; use tokio::sync::Mutex; use tokio::sync::mpsc; use tokio::sync::oneshot; -use tokio_tungstenite::MaybeTlsStream; -use tokio_tungstenite::WebSocketStream; -use tokio_tungstenite::tungstenite::Error as WsError; -use tokio_tungstenite::tungstenite::Message; -use tokio_tungstenite::tungstenite::client::IntoClientRequest; +use tokio::time::Duration; +use tokio::time::timeout; use tracing::debug; use tracing::error; use tracing::info; use tracing::trace; -use tungstenite::protocol::WebSocketConfig; +use tracing::warn; use url::Url; - -struct WsStream { - tx_command: mpsc::Sender, - pump_task: tokio::task::JoinHandle<()>, -} - -enum WsCommand { - Send { - message: Message, - tx_result: oneshot::Sender>, - }, - Close { - tx_result: oneshot::Sender>, - }, +use webrtc::api::APIBuilder; +use webrtc::api::interceptor_registry::register_default_interceptors; +use webrtc::api::media_engine::MIME_TYPE_OPUS; +use webrtc::api::media_engine::MediaEngine; +use webrtc::data_channel::RTCDataChannel; +use webrtc::data_channel::data_channel_message::DataChannelMessage; +use webrtc::media::Sample; +use webrtc::peer_connection::RTCPeerConnection; +use webrtc::peer_connection::configuration::RTCConfiguration; +use webrtc::peer_connection::peer_connection_state::RTCPeerConnectionState; +use webrtc::peer_connection::sdp::session_description::RTCSessionDescription; +use webrtc::rtp_transceiver::rtp_codec::RTCRtpCodecCapability; +use webrtc::rtp_transceiver::rtp_codec::RTPCodecType; +use webrtc::track::track_local::TrackLocal; +use webrtc::track::track_local::track_local_static_sample::TrackLocalStaticSample; +use webrtc::track::track_remote::TrackRemote; + +const REALTIME_CALLS_PATH: &str = "/v1/realtime/calls"; +const REALTIME_DATA_CHANNEL_LABEL: &str = "oai-events"; +const REALTIME_AUDIO_TRACK_ID: &str = "audio"; +const REALTIME_AUDIO_STREAM_ID: &str = "codex-realtime"; +const REALTIME_AUDIO_CHANNELS: u16 = 1; +const REALTIME_AUDIO_PACKET_SAMPLES: usize = 480; +const REALTIME_AUDIO_PACKET_DURATION: Duration = Duration::from_millis(20); +const REALTIME_DATA_CHANNEL_OPEN_TIMEOUT: Duration = Duration::from_secs(10); +const REALTIME_AUDIO_TRACK_BINDING_SETTLE_TIME: Duration = Duration::from_millis(250); +const OPUS_MAX_PACKET_BYTES: usize = 4_000; +const OPUS_MAX_DECODED_SAMPLES_PER_CHANNEL: usize = 2_880; + +enum RealtimeTransportEvent { + DataChannelPayload(String), + AudioOut(RealtimeAudioFrame), + Closed, } -impl WsStream { - fn new( - inner: WebSocketStream>, - ) -> (Self, mpsc::UnboundedReceiver>) { - let (tx_command, mut rx_command) = mpsc::channel::(32); - let (tx_message, rx_message) = mpsc::unbounded_channel::>(); - - let pump_task = tokio::spawn(async move { - let mut inner = inner; - loop { - tokio::select! { - command = rx_command.recv() => { - let Some(command) = command else { - break; - }; - match command { - WsCommand::Send { message, tx_result } => { - debug!("realtime websocket sending message"); - let result = inner.send(message).await; - let should_break = result.is_err(); - if let Err(err) = &result { - error!("realtime websocket send failed: {err}"); - } - let _ = tx_result.send(result); - if should_break { - break; - } - } - WsCommand::Close { tx_result } => { - info!("realtime websocket sending close"); - let result = inner.close(None).await; - if let Err(err) = &result { - error!("realtime websocket close failed: {err}"); - } - let _ = tx_result.send(result); - break; - } - } - } - message = inner.next() => { - let Some(message) = message else { - break; - }; - match message { - Ok(Message::Ping(payload)) => { - trace!(payload_len = payload.len(), "realtime websocket received ping"); - if let Err(err) = inner.send(Message::Pong(payload)).await { - error!("realtime websocket failed to send pong: {err}"); - let _ = tx_message.send(Err(err)); - break; - } - } - Ok(Message::Pong(_)) => {} - Ok(message @ (Message::Text(_) - | Message::Binary(_) - | Message::Close(_) - | Message::Frame(_))) => { - let is_close = matches!(message, Message::Close(_)); - match &message { - Message::Text(_) => trace!("realtime websocket received text frame"), - Message::Binary(binary) => { - error!( - payload_len = binary.len(), - "realtime websocket received unexpected binary frame" - ); - } - Message::Close(frame) => info!( - "realtime websocket received close frame: code={:?} reason={:?}", - frame.as_ref().map(|frame| frame.code), - frame.as_ref().map(|frame| frame.reason.as_str()) - ), - Message::Frame(_) => { - trace!("realtime websocket received raw frame"); - } - Message::Ping(_) | Message::Pong(_) => {} - } - if tx_message.send(Ok(message)).is_err() { - break; - } - if is_close { - break; - } - } - Err(err) => { - error!("realtime websocket receive failed: {err}"); - let _ = tx_message.send(Err(err)); - break; - } - } - } - } - } - info!("realtime websocket pump exiting"); - }); - - ( - Self { - tx_command, - pump_task, - }, - rx_message, - ) - } - - async fn request( - &self, - make_command: impl FnOnce(oneshot::Sender>) -> WsCommand, - ) -> Result<(), WsError> { - let (tx_result, rx_result) = oneshot::channel(); - if self.tx_command.send(make_command(tx_result)).await.is_err() { - return Err(WsError::ConnectionClosed); - } - rx_result.await.unwrap_or(Err(WsError::ConnectionClosed)) - } - - async fn send(&self, message: Message) -> Result<(), WsError> { - self.request(|tx_result| WsCommand::Send { message, tx_result }) - .await - } - - async fn close(&self) -> Result<(), WsError> { - self.request(|tx_result| WsCommand::Close { tx_result }) - .await - } +struct RealtimeWebRtcTransport { + peer_connection: Arc, + data_channel: Arc, + input_audio_track: Arc, + input_audio_encoder: StdMutex, } -impl Drop for WsStream { - fn drop(&mut self) { - self.pump_task.abort(); - } +struct RealtimeInputAudioEncoder { + opus_encoder: OpusEncoder, + pending_samples: Vec, + encoded_packet: Vec, } -pub struct RealtimeWebsocketConnection { - writer: RealtimeWebsocketWriter, - events: RealtimeWebsocketEvents, +pub struct RealtimeWebRtcConnection { + writer: RealtimeWebRtcWriter, + events: RealtimeWebRtcEvents, } #[derive(Clone)] -pub struct RealtimeWebsocketWriter { - stream: Arc, +pub struct RealtimeWebRtcWriter { + transport: Arc, is_closed: Arc, event_parser: RealtimeEventParser, } #[derive(Clone)] -pub struct RealtimeWebsocketEvents { - rx_message: Arc>>>, +pub struct RealtimeWebRtcEvents { + rx_message: Arc>>>, active_transcript: Arc>, event_parser: RealtimeEventParser, is_closed: Arc, @@ -212,7 +113,7 @@ struct ActiveTranscriptState { entries: Vec, } -impl RealtimeWebsocketConnection { +impl RealtimeWebRtcConnection { pub async fn send_audio_frame(&self, frame: RealtimeAudioFrame) -> Result<(), ApiError> { self.writer.send_audio_frame(frame).await } @@ -239,28 +140,28 @@ impl RealtimeWebsocketConnection { self.events.next_event().await } - pub fn writer(&self) -> RealtimeWebsocketWriter { + pub fn writer(&self) -> RealtimeWebRtcWriter { self.writer.clone() } - pub fn events(&self) -> RealtimeWebsocketEvents { + pub fn events(&self) -> RealtimeWebRtcEvents { self.events.clone() } fn new( - stream: WsStream, - rx_message: mpsc::UnboundedReceiver>, + transport: RealtimeWebRtcTransport, + rx_message: mpsc::UnboundedReceiver>, event_parser: RealtimeEventParser, ) -> Self { - let stream = Arc::new(stream); + let transport = Arc::new(transport); let is_closed = Arc::new(AtomicBool::new(false)); Self { - writer: RealtimeWebsocketWriter { - stream: Arc::clone(&stream), + writer: RealtimeWebRtcWriter { + transport: Arc::clone(&transport), is_closed: Arc::clone(&is_closed), event_parser, }, - events: RealtimeWebsocketEvents { + events: RealtimeWebRtcEvents { rx_message: Arc::new(Mutex::new(rx_message)), active_transcript: Arc::new(Mutex::new(ActiveTranscriptState::default())), event_parser, @@ -270,10 +171,31 @@ impl RealtimeWebsocketConnection { } } -impl RealtimeWebsocketWriter { +impl RealtimeWebRtcWriter { pub async fn send_audio_frame(&self, frame: RealtimeAudioFrame) -> Result<(), ApiError> { - self.send_json(&RealtimeOutboundMessage::InputAudioBufferAppend { audio: frame.data }) - .await + if self.is_closed.load(Ordering::SeqCst) { + return Err(ApiError::Stream( + "realtime WebRTC connection is closed".to_string(), + )); + } + + let opus_samples = { + let mut encoder = self.transport.input_audio_encoder.lock().map_err(|_| { + ApiError::Stream("failed to lock realtime input audio encoder".to_string()) + })?; + encoder.encode_frame(frame)? + }; + + for sample in opus_samples { + self.transport + .input_audio_track + .write_sample(&sample) + .await + .map_err(|err| { + ApiError::Stream(format!("failed to send realtime audio sample: {err}")) + })?; + } + Ok(()) } pub async fn send_conversation_item_create(&self, text: String) -> Result<(), ApiError> { @@ -314,39 +236,42 @@ impl RealtimeWebsocketWriter { if self.is_closed.swap(true, Ordering::SeqCst) { return Ok(()); } - if let Err(err) = self.stream.close().await - && !matches!(err, WsError::ConnectionClosed | WsError::AlreadyClosed) - { - return Err(ApiError::Stream(format!( - "failed to close websocket: {err}" - ))); + + if let Err(err) = self.transport.data_channel.close().await { + warn!("failed to close realtime data channel: {err}"); } + self.transport + .peer_connection + .close() + .await + .map_err(|err| ApiError::Stream(format!("failed to close WebRTC session: {err}")))?; Ok(()) } async fn send_json(&self, message: &RealtimeOutboundMessage) -> Result<(), ApiError> { let payload = serde_json::to_string(message) .map_err(|err| ApiError::Stream(format!("failed to encode realtime request: {err}")))?; - debug!(?message, "realtime websocket request"); + debug!(?message, "realtime data-channel request"); self.send_payload(payload).await } pub async fn send_payload(&self, payload: String) -> Result<(), ApiError> { if self.is_closed.load(Ordering::SeqCst) { return Err(ApiError::Stream( - "realtime websocket connection is closed".to_string(), + "realtime WebRTC connection is closed".to_string(), )); } - self.stream - .send(Message::Text(payload.into())) + self.transport + .data_channel + .send_text(payload) .await .map_err(|err| ApiError::Stream(format!("failed to send realtime request: {err}")))?; Ok(()) } } -impl RealtimeWebsocketEvents { +impl RealtimeWebRtcEvents { pub async fn next_event(&self) -> Result, ApiError> { if self.is_closed.load(Ordering::SeqCst) { return Ok(None); @@ -357,42 +282,38 @@ impl RealtimeWebsocketEvents { Some(Ok(msg)) => msg, Some(Err(err)) => { self.is_closed.store(true, Ordering::SeqCst); - error!("realtime websocket read failed: {err}"); - return Err(ApiError::Stream(format!( - "failed to read websocket message: {err}" - ))); + error!("realtime WebRTC read failed: {err}"); + return Err(err); } None => { self.is_closed.store(true, Ordering::SeqCst); - info!("realtime websocket event stream ended"); + info!("realtime WebRTC event stream ended"); return Ok(None); } }; match msg { - Message::Text(text) => { - if let Some(mut event) = parse_realtime_event(&text, self.event_parser) { + RealtimeTransportEvent::DataChannelPayload(payload) => { + if let Some(mut event) = parse_realtime_event(&payload, self.event_parser) { self.update_active_transcript(&mut event).await; - debug!(?event, "realtime websocket parsed event"); + debug!(?event, "realtime data-channel parsed event"); return Ok(Some(event)); } - debug!("realtime websocket ignored unsupported text frame"); + debug!("realtime data channel ignored unsupported event"); } - Message::Close(frame) => { + RealtimeTransportEvent::AudioOut(mut event) => { + let mut wrapped = RealtimeEvent::AudioOut(event.clone()); + self.update_active_transcript(&mut wrapped).await; + if let RealtimeEvent::AudioOut(audio_frame) = wrapped { + event = audio_frame; + } + return Ok(Some(RealtimeEvent::AudioOut(event))); + } + RealtimeTransportEvent::Closed => { self.is_closed.store(true, Ordering::SeqCst); - info!( - "realtime websocket closed: code={:?} reason={:?}", - frame.as_ref().map(|frame| frame.code), - frame.as_ref().map(|frame| frame.reason.as_str()) - ); + info!("realtime WebRTC session closed"); return Ok(None); } - Message::Binary(_) => { - return Ok(Some(RealtimeEvent::Error( - "unexpected binary realtime websocket event".to_string(), - ))); - } - Message::Frame(_) | Message::Ping(_) | Message::Pong(_) => {} } } } @@ -440,11 +361,11 @@ fn append_transcript_delta(entries: &mut Vec, role: &st }); } -pub struct RealtimeWebsocketClient { +pub struct RealtimeWebRtcClient { provider: Provider, } -impl RealtimeWebsocketClient { +impl RealtimeWebRtcClient { pub fn new(provider: Provider) -> Self { Self { provider } } @@ -454,52 +375,33 @@ impl RealtimeWebsocketClient { config: RealtimeSessionConfig, extra_headers: HeaderMap, default_headers: HeaderMap, - ) -> Result { + ) -> Result { ensure_rustls_crypto_provider(); - let ws_url = websocket_url_from_api_url( + let calls_url = calls_url_from_api_url( self.provider.base_url.as_str(), self.provider.query_params.as_ref(), - config.model.as_deref(), - config.event_parser, - config.session_mode, )?; - let mut request = ws_url - .as_str() - .into_client_request() - .map_err(|err| ApiError::Stream(format!("failed to build websocket request: {err}")))?; let headers = merge_request_headers( &self.provider.headers, with_session_id_header(extra_headers, config.session_id.as_deref())?, default_headers, ); - request.headers_mut().extend(headers); - - info!("connecting realtime websocket: {ws_url}"); - // Realtime websocket TLS should honor the same custom-CA env vars as the rest of Codex's - // outbound HTTPS and websocket traffic. - let connector = maybe_build_rustls_client_config_with_custom_ca() - .map_err(|err| ApiError::Stream(format!("failed to configure websocket TLS: {err}")))? - .map(tokio_tungstenite::Connector::Rustls); - let (stream, response) = tokio_tungstenite::connect_async_tls_with_config( - request, - Some(websocket_config()), - false, - connector, - ) - .await - .map_err(|err| ApiError::Stream(format!("failed to connect realtime websocket: {err}")))?; - info!( - ws_url = %ws_url, - status = %response.status(), - "realtime websocket connected" - ); - let (stream, rx_message) = WsStream::new(stream); - let connection = RealtimeWebsocketConnection::new(stream, rx_message, config.event_parser); + info!("connecting realtime WebRTC session: {calls_url}"); + let (transport, rx_message) = connect_webrtc_transport( + calls_url, + headers, + config.event_parser, + config.model.clone(), + config.instructions.clone(), + config.session_mode, + ) + .await?; + let connection = RealtimeWebRtcConnection::new(transport, rx_message, config.event_parser); debug!( session_id = config.session_id.as_deref().unwrap_or(""), - "realtime websocket sending session.update" + "realtime WebRTC sending session.update" ); connection .writer @@ -540,27 +442,22 @@ fn with_session_id_header( Ok(headers) } -fn websocket_config() -> WebSocketConfig { - WebSocketConfig::default() -} - -fn websocket_url_from_api_url( +fn calls_url_from_api_url( api_url: &str, query_params: Option<&HashMap>, - model: Option<&str>, - event_parser: RealtimeEventParser, - _session_mode: RealtimeSessionMode, ) -> Result { let mut url = Url::parse(api_url) .map_err(|err| ApiError::Stream(format!("failed to parse realtime api_url: {err}")))?; - normalize_realtime_path(&mut url); + normalize_realtime_calls_path(&mut url); match url.scheme() { - "ws" | "wss" => {} - "http" | "https" => { - let scheme = if url.scheme() == "http" { "ws" } else { "wss" }; - let _ = url.set_scheme(scheme); + "http" | "https" => {} + "ws" => { + let _ = url.set_scheme("http"); + } + "wss" => { + let _ = url.set_scheme("https"); } scheme => { return Err(ApiError::Stream(format!( @@ -569,1304 +466,589 @@ fn websocket_url_from_api_url( } } - let intent = websocket_intent(event_parser); - let has_extra_query_params = query_params.is_some_and(|query_params| { - query_params - .iter() - .any(|(key, _)| key != "intent" && !(key == "model" && model.is_some())) - }); - if intent.is_some() || model.is_some() || has_extra_query_params { + if let Some(query_params) = query_params { let mut query = url.query_pairs_mut(); - if let Some(intent) = intent { - query.append_pair("intent", intent); - } - if let Some(model) = model { - query.append_pair("model", model); - } - if let Some(query_params) = query_params { - for (key, value) in query_params { - if key == "intent" || (key == "model" && model.is_some()) { - continue; - } - query.append_pair(key, value); - } + for (key, value) in query_params { + query.append_pair(key, value); } } Ok(url) } -fn normalize_realtime_path(url: &mut Url) { +fn normalize_realtime_calls_path(url: &mut Url) { let path = url.path().to_string(); if path.is_empty() || path == "/" { - url.set_path("/v1/realtime"); + url.set_path(REALTIME_CALLS_PATH); + return; + } + + if path.ends_with("/realtime/calls") { + return; + } + + if path.ends_with("/realtime/calls/") { + url.set_path(path.trim_end_matches('/')); return; } if path.ends_with("/realtime") { + url.set_path(&format!("{path}/calls")); return; } if path.ends_with("/realtime/") { - url.set_path(path.trim_end_matches('/')); + url.set_path(&format!("{}/calls", path.trim_end_matches('/'))); return; } if path.ends_with("/v1") { - url.set_path(&format!("{path}/realtime")); + url.set_path(&format!("{path}/realtime/calls")); return; } if path.ends_with("/v1/") { - url.set_path(&format!("{path}realtime")); + url.set_path(&format!("{path}realtime/calls")); } } -#[cfg(test)] -mod tests { - use super::*; - use crate::endpoint::realtime_websocket::protocol::RealtimeHandoffRequested; - use crate::endpoint::realtime_websocket::protocol::RealtimeTranscriptDelta; - use crate::endpoint::realtime_websocket::protocol::RealtimeTranscriptEntry; - use codex_protocol::protocol::RealtimeInputAudioSpeechStarted; - use codex_protocol::protocol::RealtimeResponseCancelled; - use http::HeaderValue; - use pretty_assertions::assert_eq; - use serde_json::Value; - use serde_json::json; - use std::collections::HashMap; - use std::time::Duration; - use tokio::net::TcpListener; - use tokio_tungstenite::accept_async; - use tokio_tungstenite::tungstenite::Message; +async fn connect_webrtc_transport( + calls_url: Url, + headers: HeaderMap, + event_parser: RealtimeEventParser, + model: Option, + instructions: String, + session_mode: RealtimeSessionMode, +) -> Result< + ( + RealtimeWebRtcTransport, + mpsc::UnboundedReceiver>, + ), + ApiError, +> { + let peer_connection = create_peer_connection().await?; + let input_audio_track = Arc::new(TrackLocalStaticSample::new( + RTCRtpCodecCapability { + mime_type: MIME_TYPE_OPUS.to_string(), + ..Default::default() + }, + REALTIME_AUDIO_TRACK_ID.to_string(), + REALTIME_AUDIO_STREAM_ID.to_string(), + )); + let rtp_sender = peer_connection + .add_track(Arc::clone(&input_audio_track) as Arc) + .await + .map_err(|err| ApiError::Stream(format!("failed to add realtime audio track: {err}")))?; + tokio::spawn(async move { + let mut rtcp_buf = vec![0u8; 1500]; + while let Ok((_, _)) = rtp_sender.read(&mut rtcp_buf).await {} + }); - #[test] - fn parse_session_updated_event() { - let payload = json!({ - "type": "session.updated", - "session": {"id": "sess_123", "instructions": "backend prompt"} - }) - .to_string(); + let (tx_message, rx_message) = + mpsc::unbounded_channel::>(); + let (tx_data_channel_open, rx_data_channel_open) = oneshot::channel::<()>(); + let data_channel = peer_connection + .create_data_channel(REALTIME_DATA_CHANNEL_LABEL, None) + .await + .map_err(|err| { + ApiError::Stream(format!("failed to create realtime data channel: {err}")) + })?; - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::V1), - Some(RealtimeEvent::SessionUpdated { - session_id: "sess_123".to_string(), - instructions: Some("backend prompt".to_string()), - }) - ); - } + register_data_channel_handlers(&data_channel, tx_message.clone(), tx_data_channel_open); + register_peer_connection_handlers(&peer_connection, tx_message.clone()); + register_remote_audio_handler(&peer_connection, tx_message); - #[test] - fn parse_audio_delta_event() { - let payload = json!({ - "type": "conversation.output_audio.delta", - "delta": "AAA=", - "sample_rate": 48000, - "channels": 1, - "samples_per_channel": 960 + let mut gather_complete = peer_connection.gathering_complete_promise().await; + let offer = peer_connection + .create_offer(None) + .await + .map_err(|err| ApiError::Stream(format!("failed to create WebRTC offer: {err}")))?; + peer_connection + .set_local_description(offer) + .await + .map_err(|err| { + ApiError::Stream(format!("failed to set local WebRTC description: {err}")) + })?; + let _ = gather_complete.recv().await; + + let local_description = peer_connection.local_description().await.ok_or_else(|| { + ApiError::Stream("WebRTC local description was not available".to_string()) + })?; + let answer = fetch_realtime_answer( + calls_url.clone(), + headers, + local_description.sdp, + event_parser, + model, + instructions, + session_mode, + ) + .await?; + let remote_description = RTCSessionDescription::answer(answer) + .map_err(|err| ApiError::Stream(format!("invalid WebRTC answer SDP: {err}")))?; + peer_connection + .set_remote_description(remote_description) + .await + .map_err(|err| { + ApiError::Stream(format!("failed to set remote WebRTC description: {err}")) + })?; + + timeout(REALTIME_DATA_CHANNEL_OPEN_TIMEOUT, rx_data_channel_open) + .await + .map_err(|_| { + ApiError::Stream( + "timed out waiting for realtime WebRTC data channel to open".to_string(), + ) + })? + .map_err(|_| ApiError::Stream("realtime WebRTC data channel did not open".to_string()))?; + + // `TrackLocalStaticSample::write_sample()` silently drops samples until the RTP sender has + // finished binding after negotiation. Give webrtc-rs a short grace period so the first user + // audio frame is not discarded during startup. + tokio::time::sleep(REALTIME_AUDIO_TRACK_BINDING_SETTLE_TIME).await; + + info!( + calls_url = %calls_url, + "realtime WebRTC session connected" + ); + + let opus_encoder = new_realtime_opus_encoder(Application::Voip)?; + + Ok(( + RealtimeWebRtcTransport { + peer_connection, + data_channel, + input_audio_track, + input_audio_encoder: StdMutex::new(RealtimeInputAudioEncoder { + opus_encoder, + pending_samples: Vec::new(), + encoded_packet: vec![0; OPUS_MAX_PACKET_BYTES], + }), + }, + rx_message, + )) +} + +async fn create_peer_connection() -> Result, ApiError> { + let mut media_engine = MediaEngine::default(); + media_engine + .register_default_codecs() + .map_err(|err| ApiError::Stream(format!("failed to register WebRTC codecs: {err}")))?; + let registry = + register_default_interceptors(Registry::new(), &mut media_engine).map_err(|err| { + ApiError::Stream(format!("failed to register WebRTC interceptors: {err}")) + })?; + let api = APIBuilder::new() + .with_media_engine(media_engine) + .with_interceptor_registry(registry) + .build(); + api.new_peer_connection(RTCConfiguration::default()) + .await + .map(Arc::new) + .map_err(|err| ApiError::Stream(format!("failed to create WebRTC peer connection: {err}"))) +} + +fn register_data_channel_handlers( + data_channel: &Arc, + tx_message: mpsc::UnboundedSender>, + tx_data_channel_open: oneshot::Sender<()>, +) { + let tx_open = StdMutex::new(Some(tx_data_channel_open)); + data_channel.on_open(Box::new(move || { + if let Ok(mut tx_open) = tx_open.lock() + && let Some(tx_open) = tx_open.take() + { + let _ = tx_open.send(()); + } + Box::pin(async {}) + })); + + let tx_data_channel_message = tx_message.clone(); + data_channel.on_message(Box::new(move |message: DataChannelMessage| { + let tx_data_channel_message = tx_data_channel_message.clone(); + Box::pin(async move { + if !message.is_string { + let _ = tx_data_channel_message.send(Err(ApiError::Stream( + "unexpected binary realtime data-channel message".to_string(), + ))); + return; + } + let payload = match String::from_utf8(message.data.to_vec()) { + Ok(payload) => payload, + Err(err) => { + let _ = tx_data_channel_message.send(Err(ApiError::Stream(format!( + "invalid realtime data-channel UTF-8 payload: {err}" + )))); + return; + } + }; + trace!( + payload_len = payload.len(), + "realtime data-channel received text event" + ); + let _ = tx_data_channel_message + .send(Ok(RealtimeTransportEvent::DataChannelPayload(payload))); }) - .to_string(); - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::V1), - Some(RealtimeEvent::AudioOut(RealtimeAudioFrame { - data: "AAA=".to_string(), - sample_rate: 48000, - num_channels: 1, - samples_per_channel: Some(960), - item_id: None, - })) - ); - } + })); - #[test] - fn parse_conversation_item_added_event() { - let payload = json!({ - "type": "conversation.item.added", - "item": {"type": "message", "seq": 7} + data_channel.on_close(Box::new(move || { + let tx_message = tx_message.clone(); + Box::pin(async move { + let _ = tx_message.send(Ok(RealtimeTransportEvent::Closed)); }) - .to_string(); - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::V1), - Some(RealtimeEvent::ConversationItemAdded( - json!({"type": "message", "seq": 7}) - )) - ); - } + })); +} - #[test] - fn parse_conversation_item_done_event() { - let payload = json!({ - "type": "conversation.item.done", - "item": {"id": "item_123", "type": "message"} +fn register_peer_connection_handlers( + peer_connection: &Arc, + tx_message: mpsc::UnboundedSender>, +) { + peer_connection.on_peer_connection_state_change(Box::new(move |state| { + let tx_message = tx_message.clone(); + Box::pin(async move { + match state { + RTCPeerConnectionState::Closed => { + let _ = tx_message.send(Ok(RealtimeTransportEvent::Closed)); + } + RTCPeerConnectionState::Failed => { + let _ = tx_message.send(Err(ApiError::Stream( + "realtime WebRTC peer connection failed".to_string(), + ))); + } + RTCPeerConnectionState::New + | RTCPeerConnectionState::Connecting + | RTCPeerConnectionState::Connected + | RTCPeerConnectionState::Disconnected + | RTCPeerConnectionState::Unspecified => {} + } }) - .to_string(); - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::V1), - Some(RealtimeEvent::ConversationItemDone { - item_id: "item_123".to_string(), - }) - ); - } + })); +} - #[test] - fn parse_handoff_requested_event() { - let payload = json!({ - "type": "conversation.handoff.requested", - "handoff_id": "handoff_123", - "item_id": "item_123", - "input_transcript": "delegate this" +fn register_remote_audio_handler( + peer_connection: &Arc, + tx_message: mpsc::UnboundedSender>, +) { + peer_connection.on_track(Box::new(move |track, _, _| { + let tx_message = tx_message.clone(); + Box::pin(async move { + if track.kind() != RTPCodecType::Audio { + return; + } + pump_remote_audio_track(track, tx_message).await; }) - .to_string(); + })); +} - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::V1), - Some(RealtimeEvent::HandoffRequested(RealtimeHandoffRequested { - handoff_id: "handoff_123".to_string(), - item_id: "item_123".to_string(), - input_transcript: "delegate this".to_string(), - active_transcript: Vec::new(), - })) - ); - } +async fn pump_remote_audio_track( + track: Arc, + tx_message: mpsc::UnboundedSender>, +) { + let mut decoder = match new_realtime_opus_decoder() { + Ok(decoder) => decoder, + Err(err) => { + let _ = tx_message.send(Err(ApiError::Stream(format!( + "failed to initialize realtime Opus decoder: {err}" + )))); + return; + } + }; + let mut decoded = vec![0.0f32; OPUS_MAX_DECODED_SAMPLES_PER_CHANNEL]; + + loop { + let packet = match track.read_rtp().await { + Ok((packet, _)) => packet, + Err(err) => { + let _ = tx_message.send(Err(ApiError::Stream(format!( + "failed to read realtime WebRTC audio packet: {err}" + )))); + return; + } + }; + if packet.payload.is_empty() { + continue; + } - #[test] - fn parse_input_transcript_delta_event() { - let payload = json!({ - "type": "conversation.input_transcript.delta", - "delta": "hello " - }) - .to_string(); + let samples_per_channel = match decoder.decode( + &packet.payload, + OPUS_MAX_DECODED_SAMPLES_PER_CHANNEL, + &mut decoded, + ) { + Ok(samples_per_channel) => samples_per_channel, + Err(err) => { + warn!( + %err, + payload_len = packet.payload.len(), + "failed to decode realtime Opus packet" + ); + let _ = tx_message.send(Err(ApiError::Stream(format!( + "failed to decode realtime Opus packet: {err}" + )))); + return; + } + }; + if samples_per_channel == 0 { + continue; + } - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::V1), - Some(RealtimeEvent::InputTranscriptDelta( - RealtimeTranscriptDelta { - delta: "hello ".to_string(), - } - )) - ); + let mut pcm_bytes = Vec::with_capacity(samples_per_channel * 2); + for sample in &decoded[..samples_per_channel] { + pcm_bytes.extend_from_slice(&f32_to_i16(*sample).to_le_bytes()); + } + let _ = tx_message.send(Ok(RealtimeTransportEvent::AudioOut(RealtimeAudioFrame { + data: BASE64_STANDARD.encode(pcm_bytes), + sample_rate: 24_000, + num_channels: REALTIME_AUDIO_CHANNELS, + samples_per_channel: Some(samples_per_channel as u32), + item_id: None, + }))); } +} - #[test] - fn parse_output_transcript_delta_event() { - let payload = json!({ - "type": "conversation.output_transcript.delta", - "delta": "hi" - }) - .to_string(); +async fn fetch_realtime_answer( + calls_url: Url, + headers: HeaderMap, + offer_sdp: String, + event_parser: RealtimeEventParser, + model: Option, + instructions: String, + session_mode: RealtimeSessionMode, +) -> Result { + let client = build_reqwest_client_with_custom_ca(reqwest::Client::builder()) + .map_err(|err| ApiError::Stream(format!("failed to build realtime HTTP client: {err}")))?; + let session_mode = normalized_session_mode(event_parser, session_mode); + let session = session_update_session(event_parser, instructions, session_mode); + let mut session_json = serde_json::to_value(&session) + .map_err(|err| ApiError::Stream(format!("failed to encode realtime session: {err}")))?; + if let Some(model) = model + && let Some(session_json) = session_json.as_object_mut() + { + session_json.insert("model".to_string(), serde_json::Value::String(model)); + } + let session_payload = serde_json::to_string(&session_json) + .map_err(|err| ApiError::Stream(format!("failed to encode realtime session: {err}")))?; + let form = reqwest::multipart::Form::new() + .text("sdp", offer_sdp) + .text("session", session_payload); + let response = client + .post(calls_url) + .headers(headers) + .multipart(form) + .send() + .await + .map_err(|err| ApiError::Stream(format!("failed to create realtime WebRTC call: {err}")))?; + let status = response.status(); + let body = response.text().await.map_err(|err| { + ApiError::Stream(format!("failed to read realtime WebRTC answer SDP: {err}")) + })?; + if !status.is_success() { + return Err(ApiError::Stream(format!( + "failed to create realtime WebRTC call: status={status} body={body}" + ))); + } + Ok(body) +} - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::V1), - Some(RealtimeEvent::OutputTranscriptDelta( - RealtimeTranscriptDelta { - delta: "hi".to_string(), - } - )) - ); +impl RealtimeInputAudioEncoder { + fn encode_frame(&mut self, frame: RealtimeAudioFrame) -> Result, ApiError> { + if frame.sample_rate != 24_000 || frame.num_channels != REALTIME_AUDIO_CHANNELS { + return Err(ApiError::Stream(format!( + "realtime WebRTC audio input must be {} Hz mono PCM; got {} Hz / {} channels", + 24_000, frame.sample_rate, frame.num_channels + ))); + } + + let pcm_bytes = BASE64_STANDARD.decode(frame.data).map_err(|err| { + ApiError::Stream(format!("failed to decode realtime input audio: {err}")) + })?; + if pcm_bytes.len() % 2 != 0 { + return Err(ApiError::Stream( + "realtime input audio had odd byte length".to_string(), + )); + } + for sample in pcm_bytes.chunks_exact(2) { + self.pending_samples + .push(i16::from_le_bytes([sample[0], sample[1]])); + } + + let mut samples = Vec::new(); + while self.pending_samples.len() >= REALTIME_AUDIO_PACKET_SAMPLES { + let frame: Vec = self.pending_samples[..REALTIME_AUDIO_PACKET_SAMPLES] + .iter() + .copied() + .map(i16_to_f32) + .collect(); + let encoded_len = self + .opus_encoder + .encode( + &frame, + REALTIME_AUDIO_PACKET_SAMPLES, + &mut self.encoded_packet, + ) + .map_err(|err| { + warn!( + %err, + pending_samples = self.pending_samples.len(), + "failed to encode realtime input Opus" + ); + ApiError::Stream(format!("failed to encode realtime input Opus: {err}")) + })?; + self.pending_samples.drain(..REALTIME_AUDIO_PACKET_SAMPLES); + samples.push(Sample { + data: Bytes::copy_from_slice(&self.encoded_packet[..encoded_len]), + duration: REALTIME_AUDIO_PACKET_DURATION, + ..Default::default() + }); + } + + Ok(samples) } +} + +fn new_realtime_opus_encoder(application: Application) -> Result { + let encoder = OpusEncoder::new(24_000, usize::from(REALTIME_AUDIO_CHANNELS), application) + .map_err(|err| { + warn!( + %err, + sample_rate = 24_000, + channels = REALTIME_AUDIO_CHANNELS, + "failed to initialize realtime Opus encoder" + ); + ApiError::Stream(format!("failed to initialize realtime Opus encoder: {err}")) + })?; + debug!( + sample_rate = 24_000, + channels = REALTIME_AUDIO_CHANNELS, + "initialized realtime Opus encoder" + ); + Ok(encoder) +} + +fn new_realtime_opus_decoder() -> Result { + let decoder = + OpusDecoder::new(24_000, usize::from(REALTIME_AUDIO_CHANNELS)).map_err(|err| { + warn!( + %err, + sample_rate = 24_000, + channels = REALTIME_AUDIO_CHANNELS, + "failed to initialize realtime Opus decoder" + ); + ApiError::Stream(format!("failed to initialize realtime Opus decoder: {err}")) + })?; + debug!( + sample_rate = 24_000, + channels = REALTIME_AUDIO_CHANNELS, + "initialized realtime Opus decoder" + ); + Ok(decoder) +} + +fn i16_to_f32(sample: i16) -> f32 { + (sample as f32) / (i16::MAX as f32) +} + +fn f32_to_i16(sample: f32) -> i16 { + (sample.clamp(-1.0, 1.0) * i16::MAX as f32) as i16 +} + +#[cfg(test)] +mod tests { + use super::*; + use pretty_assertions::assert_eq; + use serde_json::json; + use std::collections::HashMap; #[test] - fn parse_realtime_v2_handoff_tool_call_event() { - let payload = json!({ - "type": "conversation.item.done", - "item": { - "id": "item_123", - "type": "function_call", - "name": "codex", - "call_id": "call_123", - "arguments": "{\"prompt\":\"delegate this\"}" - } - }) - .to_string(); + fn calls_url_from_api_url_normalizes_http_root() { + let query_params = HashMap::from([("model".to_string(), "gpt-realtime".to_string())]); + let calls_url = + calls_url_from_api_url("http://example.com", Some(&query_params)).expect("calls url"); assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::RealtimeV2), - Some(RealtimeEvent::HandoffRequested(RealtimeHandoffRequested { - handoff_id: "call_123".to_string(), - item_id: "item_123".to_string(), - input_transcript: "delegate this".to_string(), - active_transcript: Vec::new(), - })) + calls_url.as_str(), + "http://example.com/v1/realtime/calls?model=gpt-realtime" ); } #[test] - fn parse_realtime_v2_input_audio_transcription_delta_event() { - let payload = json!({ - "type": "conversation.item.input_audio_transcription.delta", - "delta": "hello" - }) - .to_string(); + fn calls_url_from_api_url_preserves_v1_realtime_path_and_query() { + let query_params = HashMap::from([("model".to_string(), "gpt-realtime".to_string())]); + let calls_url = + calls_url_from_api_url("wss://example.com/v1/realtime?foo=bar", Some(&query_params)) + .expect("calls url"); assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::RealtimeV2), - Some(RealtimeEvent::InputTranscriptDelta( - RealtimeTranscriptDelta { - delta: "hello".to_string(), - } - )) + calls_url.as_str(), + "https://example.com/v1/realtime/calls?foo=bar&model=gpt-realtime" ); } #[test] - fn parse_realtime_v2_output_audio_delta_defaults_audio_shape() { + fn parse_session_updated_event() { let payload = json!({ - "type": "response.output_audio.delta", - "delta": "AQID" + "type": "session.updated", + "session": {"id": "sess_123", "instructions": "backend prompt"} }) .to_string(); assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::RealtimeV2), - Some(RealtimeEvent::AudioOut(RealtimeAudioFrame { - data: "AQID".to_string(), - sample_rate: 24_000, - num_channels: 1, - samples_per_channel: None, - item_id: None, - })) + parse_realtime_event(payload.as_str(), RealtimeEventParser::V1), + Some(RealtimeEvent::SessionUpdated { + session_id: "sess_123".to_string(), + instructions: Some("backend prompt".to_string()), + }) ); } #[test] - fn parse_realtime_v2_response_audio_delta_with_item_id() { + fn parse_audio_delta_event() { let payload = json!({ - "type": "response.audio.delta", - "delta": "AQID", - "item_id": "item_audio_1" + "type": "conversation.output_audio.delta", + "delta": "AAA=", + "sample_rate": 24_000, + "channels": 1, + "samples_per_channel": 480, + "item_id": "item_123" }) .to_string(); assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::RealtimeV2), + parse_realtime_event(payload.as_str(), RealtimeEventParser::V1), Some(RealtimeEvent::AudioOut(RealtimeAudioFrame { - data: "AQID".to_string(), + data: "AAA=".to_string(), sample_rate: 24_000, num_channels: 1, - samples_per_channel: None, - item_id: Some("item_audio_1".to_string()), + samples_per_channel: Some(480), + item_id: Some("item_123".to_string()), })) ); } #[test] - fn parse_realtime_v2_speech_started_event() { - let payload = json!({ - "type": "input_audio_buffer.speech_started", - "item_id": "item_input_1" - }) - .to_string(); - - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::RealtimeV2), - Some(RealtimeEvent::InputAudioSpeechStarted( - RealtimeInputAudioSpeechStarted { - item_id: Some("item_input_1".to_string()), - } - )) - ); - } - - #[test] - fn parse_realtime_v2_response_cancelled_event() { - let payload = json!({ - "type": "response.cancelled", - "response": {"id": "resp_cancelled_1"} - }) - .to_string(); - - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::RealtimeV2), - Some(RealtimeEvent::ResponseCancelled( - RealtimeResponseCancelled { - response_id: Some("resp_cancelled_1".to_string()), - } - )) - ); - } - - #[test] - fn parse_realtime_v2_response_done_handoff_event() { - let payload = json!({ - "type": "response.done", - "response": { - "output": [{ - "id": "item_123", - "type": "function_call", - "name": "codex", - "call_id": "call_123", - "arguments": "{\"prompt\":\"delegate from done\"}" - }] - } - }) - .to_string(); - - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::RealtimeV2), - Some(RealtimeEvent::HandoffRequested(RealtimeHandoffRequested { - handoff_id: "call_123".to_string(), - item_id: "item_123".to_string(), - input_transcript: "delegate from done".to_string(), - active_transcript: Vec::new(), - })) - ); - } - - #[test] - fn parse_realtime_v2_response_created_event() { - let payload = json!({ - "type": "response.created", - "response": {"id": "resp_created_1"} - }) - .to_string(); - - assert_eq!( - parse_realtime_event(payload.as_str(), RealtimeEventParser::RealtimeV2), - Some(RealtimeEvent::ConversationItemAdded(json!({ - "type": "response.created", - "response": {"id": "resp_created_1"} - }))) - ); - } - - #[test] - fn merge_request_headers_matches_http_precedence() { - let mut provider_headers = HeaderMap::new(); - provider_headers.insert( - "originator", - HeaderValue::from_static("provider-originator"), - ); - provider_headers.insert("x-priority", HeaderValue::from_static("provider")); - - let mut extra_headers = HeaderMap::new(); - extra_headers.insert("x-priority", HeaderValue::from_static("extra")); - - let mut default_headers = HeaderMap::new(); - default_headers.insert("originator", HeaderValue::from_static("default-originator")); - default_headers.insert("x-priority", HeaderValue::from_static("default")); - default_headers.insert("x-default-only", HeaderValue::from_static("default-only")); - - let merged = merge_request_headers(&provider_headers, extra_headers, default_headers); - - assert_eq!( - merged.get("originator"), - Some(&HeaderValue::from_static("provider-originator")) - ); - assert_eq!( - merged.get("x-priority"), - Some(&HeaderValue::from_static("extra")) - ); - assert_eq!( - merged.get("x-default-only"), - Some(&HeaderValue::from_static("default-only")) - ); - } - - #[test] - fn websocket_url_from_http_base_defaults_to_ws_path() { - let url = websocket_url_from_api_url( - "http://127.0.0.1:8011", - /*query_params*/ None, - /*model*/ None, - RealtimeEventParser::V1, - RealtimeSessionMode::Conversational, - ) - .expect("build ws url"); - assert_eq!( - url.as_str(), - "ws://127.0.0.1:8011/v1/realtime?intent=quicksilver" - ); - } - - #[test] - fn websocket_url_from_ws_base_defaults_to_ws_path() { - let url = websocket_url_from_api_url( - "wss://example.com", - /*query_params*/ None, - Some("realtime-test-model"), - RealtimeEventParser::V1, - RealtimeSessionMode::Conversational, - ) - .expect("build ws url"); - assert_eq!( - url.as_str(), - "wss://example.com/v1/realtime?intent=quicksilver&model=realtime-test-model" - ); - } - - #[test] - fn websocket_url_from_v1_base_appends_realtime_path() { - let url = websocket_url_from_api_url( - "https://api.openai.com/v1", - /*query_params*/ None, - Some("snapshot"), - RealtimeEventParser::V1, - RealtimeSessionMode::Conversational, - ) - .expect("build ws url"); - assert_eq!( - url.as_str(), - "wss://api.openai.com/v1/realtime?intent=quicksilver&model=snapshot" - ); - } - - #[test] - fn websocket_url_from_nested_v1_base_appends_realtime_path() { - let url = websocket_url_from_api_url( - "https://example.com/openai/v1", - /*query_params*/ None, - Some("snapshot"), - RealtimeEventParser::V1, - RealtimeSessionMode::Conversational, - ) - .expect("build ws url"); - assert_eq!( - url.as_str(), - "wss://example.com/openai/v1/realtime?intent=quicksilver&model=snapshot" - ); - } - - #[test] - fn websocket_url_preserves_existing_realtime_path_and_extra_query_params() { - let url = websocket_url_from_api_url( - "https://example.com/v1/realtime?foo=bar", - Some(&HashMap::from([ - ("trace".to_string(), "1".to_string()), - ("intent".to_string(), "ignored".to_string()), - ])), - Some("snapshot"), - RealtimeEventParser::V1, - RealtimeSessionMode::Conversational, - ) - .expect("build ws url"); - assert_eq!( - url.as_str(), - "wss://example.com/v1/realtime?foo=bar&intent=quicksilver&model=snapshot&trace=1" - ); - } - - #[test] - fn websocket_url_v1_ignores_transcription_mode() { - let url = websocket_url_from_api_url( - "https://example.com", - /*query_params*/ None, - /*model*/ None, - RealtimeEventParser::V1, - RealtimeSessionMode::Transcription, - ) - .expect("build ws url"); - assert_eq!( - url.as_str(), - "wss://example.com/v1/realtime?intent=quicksilver" - ); - } - - #[test] - fn websocket_url_omits_intent_for_realtime_v2_conversational_mode() { - let url = websocket_url_from_api_url( - "https://example.com/v1/realtime?foo=bar", - Some(&HashMap::from([ - ("trace".to_string(), "1".to_string()), - ("intent".to_string(), "ignored".to_string()), - ])), - Some("snapshot"), - RealtimeEventParser::RealtimeV2, - RealtimeSessionMode::Conversational, - ) - .expect("build ws url"); - assert_eq!( - url.as_str(), - "wss://example.com/v1/realtime?foo=bar&model=snapshot&trace=1" - ); - } - - #[test] - fn websocket_url_omits_intent_for_realtime_v2_transcription_mode() { - let url = websocket_url_from_api_url( - "https://example.com", - /*query_params*/ None, - /*model*/ None, - RealtimeEventParser::RealtimeV2, - RealtimeSessionMode::Transcription, - ) - .expect("build ws url"); - assert_eq!(url.as_str(), "wss://example.com/v1/realtime"); - } - - #[tokio::test] - async fn e2e_connect_and_exchange_events_against_mock_ws_server() { - let listener = TcpListener::bind("127.0.0.1:0").await.expect("bind"); - let addr = listener.local_addr().expect("local addr"); - - let server = tokio::spawn(async move { - let (stream, _) = listener.accept().await.expect("accept"); - let mut ws = accept_async(stream).await.expect("accept ws"); - - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - assert_eq!( - first_json["session"]["type"], - Value::String("quicksilver".to_string()) - ); - assert_eq!( - first_json["session"]["instructions"], - Value::String("backend prompt".to_string()) - ); - assert_eq!( - first_json["session"]["audio"]["input"]["format"]["type"], - Value::String("audio/pcm".to_string()) - ); - assert_eq!( - first_json["session"]["audio"]["input"]["format"]["rate"], - Value::from(24_000) - ); - assert_eq!( - first_json["session"]["audio"]["output"]["voice"], - Value::String("fathom".to_string()) - ); - - ws.send(Message::Text( - json!({ - "type": "session.updated", - "session": {"id": "sess_mock", "instructions": "backend prompt"} - }) - .to_string() - .into(), - )) - .await - .expect("send session.updated"); - - let second = ws - .next() - .await - .expect("second msg") - .expect("second msg ok") - .into_text() - .expect("text"); - let second_json: Value = serde_json::from_str(&second).expect("json"); - assert_eq!(second_json["type"], "input_audio_buffer.append"); - - let third = ws - .next() - .await - .expect("third msg") - .expect("third msg ok") - .into_text() - .expect("text"); - let third_json: Value = serde_json::from_str(&third).expect("json"); - assert_eq!(third_json["type"], "conversation.item.create"); - assert_eq!(third_json["item"]["content"][0]["text"], "hello agent"); - - let fourth = ws - .next() - .await - .expect("fourth msg") - .expect("fourth msg ok") - .into_text() - .expect("text"); - let fourth_json: Value = serde_json::from_str(&fourth).expect("json"); - assert_eq!(fourth_json["type"], "conversation.handoff.append"); - assert_eq!(fourth_json["handoff_id"], "handoff_1"); - assert_eq!( - fourth_json["output_text"], - "\"Agent Final Message\":\n\nhello from codex" - ); - - ws.send(Message::Text( - json!({ - "type": "conversation.output_audio.delta", - "delta": "AQID", - "sample_rate": 48000, - "channels": 1 - }) - .to_string() - .into(), - )) - .await - .expect("send audio"); - - ws.send(Message::Text( - json!({ - "type": "conversation.input_transcript.delta", - "delta": "delegate " - }) - .to_string() - .into(), - )) - .await - .expect("send input transcript delta"); - - ws.send(Message::Text( - json!({ - "type": "conversation.input_transcript.delta", - "delta": "now" - }) - .to_string() - .into(), - )) - .await - .expect("send input transcript delta"); - - ws.send(Message::Text( - json!({ - "type": "conversation.output_transcript.delta", - "delta": "working" - }) - .to_string() - .into(), - )) - .await - .expect("send output transcript delta"); - - ws.send(Message::Text( - json!({ - "type": "conversation.handoff.requested", - "handoff_id": "handoff_1", - "item_id": "item_2", - "input_transcript": "delegate now" - }) - .to_string() - .into(), - )) - .await - .expect("send item added"); - }); - - let provider = Provider { - name: "test".to_string(), - base_url: format!("http://{addr}"), - query_params: Some(HashMap::new()), - headers: HeaderMap::new(), - retry: crate::provider::RetryConfig { - max_attempts: 1, - base_delay: Duration::from_millis(1), - retry_429: false, - retry_5xx: false, - retry_transport: false, - }, - stream_idle_timeout: Duration::from_secs(5), + fn input_audio_encoder_rejects_non_mono_24khz_audio() { + let mut encoder = RealtimeInputAudioEncoder { + opus_encoder: new_realtime_opus_encoder(Application::Audio).expect("encoder"), + pending_samples: Vec::new(), + encoded_packet: vec![0u8; OPUS_MAX_PACKET_BYTES], }; - let client = RealtimeWebsocketClient::new(provider); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_1".to_string()), - event_parser: RealtimeEventParser::V1, - session_mode: RealtimeSessionMode::Conversational, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - - let created = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - created, - RealtimeEvent::SessionUpdated { - session_id: "sess_mock".to_string(), - instructions: Some("backend prompt".to_string()), - } - ); - connection - .send_audio_frame(RealtimeAudioFrame { - data: "AQID".to_string(), - sample_rate: 48000, - num_channels: 1, - samples_per_channel: Some(960), + let err = encoder + .encode_frame(RealtimeAudioFrame { + data: "AAAA".to_string(), + sample_rate: 48_000, + num_channels: 2, + samples_per_channel: Some(1), item_id: None, }) - .await - .expect("send audio"); - connection - .send_conversation_item_create("hello agent".to_string()) - .await - .expect("send item"); - connection - .send_conversation_handoff_append( - "handoff_1".to_string(), - "hello from codex".to_string(), - ) - .await - .expect("send handoff"); - - let audio_event = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - audio_event, - RealtimeEvent::AudioOut(RealtimeAudioFrame { - data: "AQID".to_string(), - sample_rate: 48000, - num_channels: 1, - samples_per_channel: None, - item_id: None, - }) - ); - - let input_delta_event = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - input_delta_event, - RealtimeEvent::InputTranscriptDelta(RealtimeTranscriptDelta { - delta: "delegate ".to_string(), - }) - ); - - let input_delta_event = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - input_delta_event, - RealtimeEvent::InputTranscriptDelta(RealtimeTranscriptDelta { - delta: "now".to_string(), - }) - ); - - let output_delta_event = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - output_delta_event, - RealtimeEvent::OutputTranscriptDelta(RealtimeTranscriptDelta { - delta: "working".to_string(), - }) - ); - - let added_event = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - added_event, - RealtimeEvent::HandoffRequested(RealtimeHandoffRequested { - handoff_id: "handoff_1".to_string(), - item_id: "item_2".to_string(), - input_transcript: "delegate now".to_string(), - active_transcript: vec![ - RealtimeTranscriptEntry { - role: "user".to_string(), - text: "delegate now".to_string(), - }, - RealtimeTranscriptEntry { - role: "assistant".to_string(), - text: "working".to_string(), - }, - ], - }) - ); - - connection.close().await.expect("close"); - server.await.expect("server task"); - } - - #[tokio::test] - async fn realtime_v2_session_update_includes_codex_tool_and_handoff_output_item() { - let listener = TcpListener::bind("127.0.0.1:0").await.expect("bind"); - let addr = listener.local_addr().expect("local addr"); - - let server = tokio::spawn(async move { - let (stream, _) = listener.accept().await.expect("accept"); - let mut ws = accept_async(stream).await.expect("accept ws"); - - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - assert_eq!( - first_json["session"]["type"], - Value::String("realtime".to_string()) - ); - assert_eq!(first_json["session"]["output_modalities"], json!(["audio"])); - assert_eq!( - first_json["session"]["audio"]["input"]["format"], - json!({ - "type": "audio/pcm", - "rate": 24_000, - }) - ); - assert_eq!( - first_json["session"]["audio"]["input"]["noise_reduction"], - json!({ - "type": "near_field", - }) - ); - assert_eq!( - first_json["session"]["audio"]["input"]["turn_detection"], - json!({ - "type": "server_vad", - "interrupt_response": true, - "create_response": true, - }) - ); - assert_eq!( - first_json["session"]["audio"]["output"]["format"], - json!({ - "type": "audio/pcm", - "rate": 24_000, - }) - ); - assert_eq!( - first_json["session"]["audio"]["output"]["voice"], - Value::String("marin".to_string()) - ); - assert_eq!( - first_json["session"]["tools"][0]["type"], - Value::String("function".to_string()) - ); - assert_eq!( - first_json["session"]["tools"][0]["name"], - Value::String("codex".to_string()) - ); - assert_eq!( - first_json["session"]["tools"][0]["parameters"]["required"], - json!(["prompt"]) - ); - assert_eq!( - first_json["session"]["tool_choice"], - Value::String("auto".to_string()) - ); - - ws.send(Message::Text( - json!({ - "type": "session.updated", - "session": {"id": "sess_v2", "instructions": "backend prompt"} - }) - .to_string() - .into(), - )) - .await - .expect("send session.updated"); - - let second = ws - .next() - .await - .expect("second msg") - .expect("second msg ok") - .into_text() - .expect("text"); - let second_json: Value = serde_json::from_str(&second).expect("json"); - assert_eq!(second_json["type"], "conversation.item.create"); - assert_eq!( - second_json["item"]["type"], - Value::String("message".to_string()) - ); - assert_eq!( - second_json["item"]["content"][0]["type"], - Value::String("input_text".to_string()) - ); - assert_eq!( - second_json["item"]["content"][0]["text"], - Value::String("delegate this".to_string()) - ); - - let third = ws - .next() - .await - .expect("third msg") - .expect("third msg ok") - .into_text() - .expect("text"); - let third_json: Value = serde_json::from_str(&third).expect("json"); - assert_eq!(third_json["type"], "conversation.item.create"); - assert_eq!( - third_json["item"]["type"], - Value::String("function_call_output".to_string()) - ); - assert_eq!( - third_json["item"]["call_id"], - Value::String("call_1".to_string()) - ); - assert_eq!( - third_json["item"]["output"], - Value::String("\"Agent Final Message\":\n\ndelegated result".to_string()) - ); - }); - - let provider = Provider { - name: "test".to_string(), - base_url: format!("http://{addr}"), - query_params: Some(HashMap::new()), - headers: HeaderMap::new(), - retry: crate::provider::RetryConfig { - max_attempts: 1, - base_delay: Duration::from_millis(1), - retry_429: false, - retry_5xx: false, - retry_transport: false, - }, - stream_idle_timeout: Duration::from_secs(5), - }; - let client = RealtimeWebsocketClient::new(provider); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_1".to_string()), - event_parser: RealtimeEventParser::RealtimeV2, - session_mode: RealtimeSessionMode::Conversational, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - - let created = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - created, - RealtimeEvent::SessionUpdated { - session_id: "sess_v2".to_string(), - instructions: Some("backend prompt".to_string()), - } - ); - - connection - .send_conversation_item_create("delegate this".to_string()) - .await - .expect("send text item"); - connection - .send_conversation_handoff_append("call_1".to_string(), "delegated result".to_string()) - .await - .expect("send handoff output"); + .expect_err("reject unsupported audio"); - connection.close().await.expect("close"); - server.await.expect("server task"); - } - - #[tokio::test] - async fn transcription_mode_session_update_omits_output_audio_and_instructions() { - let listener = TcpListener::bind("127.0.0.1:0").await.expect("bind"); - let addr = listener.local_addr().expect("local addr"); - - let server = tokio::spawn(async move { - let (stream, _) = listener.accept().await.expect("accept"); - let mut ws = accept_async(stream).await.expect("accept ws"); - - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - assert_eq!( - first_json["session"]["type"], - Value::String("transcription".to_string()) - ); - assert!(first_json["session"].get("instructions").is_none()); - assert!(first_json["session"]["audio"].get("output").is_none()); - assert!(first_json["session"].get("tools").is_none()); - - ws.send(Message::Text( - json!({ - "type": "session.updated", - "session": {"id": "sess_transcription"} - }) - .to_string() - .into(), - )) - .await - .expect("send session.updated"); - - let second = ws - .next() - .await - .expect("second msg") - .expect("second msg ok") - .into_text() - .expect("text"); - let second_json: Value = serde_json::from_str(&second).expect("json"); - assert_eq!(second_json["type"], "input_audio_buffer.append"); - }); - - let provider = Provider { - name: "test".to_string(), - base_url: format!("http://{addr}"), - query_params: Some(HashMap::new()), - headers: HeaderMap::new(), - retry: crate::provider::RetryConfig { - max_attempts: 1, - base_delay: Duration::from_millis(1), - retry_429: false, - retry_5xx: false, - retry_transport: false, - }, - stream_idle_timeout: Duration::from_secs(5), + let ApiError::Stream(message) = err else { + panic!("expected stream error, got {err:?}"); }; - let client = RealtimeWebsocketClient::new(provider); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_1".to_string()), - event_parser: RealtimeEventParser::RealtimeV2, - session_mode: RealtimeSessionMode::Transcription, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - let created = connection - .next_event() - .await - .expect("next event") - .expect("event"); assert_eq!( - created, - RealtimeEvent::SessionUpdated { - session_id: "sess_transcription".to_string(), - instructions: None, - } + message, + "realtime WebRTC audio input must be 24000 Hz mono PCM; got 48000 Hz / 2 channels" ); - - connection - .send_audio_frame(RealtimeAudioFrame { - data: "AQID".to_string(), - sample_rate: 24_000, - num_channels: 1, - samples_per_channel: Some(480), - item_id: None, - }) - .await - .expect("send audio"); - - connection.close().await.expect("close"); - server.await.expect("server task"); - } - - #[tokio::test] - async fn v1_transcription_mode_is_treated_as_conversational() { - let listener = TcpListener::bind("127.0.0.1:0").await.expect("bind"); - let addr = listener.local_addr().expect("local addr"); - - let server = tokio::spawn(async move { - let (stream, _) = listener.accept().await.expect("accept"); - let mut ws = accept_async(stream).await.expect("accept ws"); - - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - assert_eq!( - first_json["session"]["type"], - Value::String("quicksilver".to_string()) - ); - assert_eq!( - first_json["session"]["instructions"], - Value::String("backend prompt".to_string()) - ); - assert_eq!( - first_json["session"]["audio"]["output"]["voice"], - Value::String("fathom".to_string()) - ); - assert!(first_json["session"].get("tools").is_none()); - - ws.send(Message::Text( - json!({ - "type": "session.updated", - "session": {"id": "sess_v1_mode"} - }) - .to_string() - .into(), - )) - .await - .expect("send session.updated"); - }); - - let provider = Provider { - name: "test".to_string(), - base_url: format!("http://{addr}"), - query_params: Some(HashMap::new()), - headers: HeaderMap::new(), - retry: crate::provider::RetryConfig { - max_attempts: 1, - base_delay: Duration::from_millis(1), - retry_429: false, - retry_5xx: false, - retry_transport: false, - }, - stream_idle_timeout: Duration::from_secs(5), - }; - let client = RealtimeWebsocketClient::new(provider); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_1".to_string()), - event_parser: RealtimeEventParser::V1, - session_mode: RealtimeSessionMode::Transcription, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - - let created = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - created, - RealtimeEvent::SessionUpdated { - session_id: "sess_v1_mode".to_string(), - instructions: None, - } - ); - - connection.close().await.expect("close"); - server.await.expect("server task"); - } - - #[tokio::test] - async fn send_does_not_block_while_next_event_waits_for_inbound_data() { - let listener = TcpListener::bind("127.0.0.1:0").await.expect("bind"); - let addr = listener.local_addr().expect("local addr"); - - let server = tokio::spawn(async move { - let (stream, _) = listener.accept().await.expect("accept"); - let mut ws = accept_async(stream).await.expect("accept ws"); - - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - - let second = ws - .next() - .await - .expect("second msg") - .expect("second msg ok") - .into_text() - .expect("text"); - let second_json: Value = serde_json::from_str(&second).expect("json"); - assert_eq!(second_json["type"], "input_audio_buffer.append"); - - ws.send(Message::Text( - json!({ - "type": "session.updated", - "session": {"id": "sess_after_send", "instructions": "backend prompt"} - }) - .to_string() - .into(), - )) - .await - .expect("send session.updated"); - }); - - let provider = Provider { - name: "test".to_string(), - base_url: format!("http://{addr}"), - query_params: Some(HashMap::new()), - headers: HeaderMap::new(), - retry: crate::provider::RetryConfig { - max_attempts: 1, - base_delay: Duration::from_millis(1), - retry_429: false, - retry_5xx: false, - retry_transport: false, - }, - stream_idle_timeout: Duration::from_secs(5), - }; - let client = RealtimeWebsocketClient::new(provider); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_1".to_string()), - event_parser: RealtimeEventParser::V1, - session_mode: RealtimeSessionMode::Conversational, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - - let (send_result, next_result) = tokio::join!( - async { - tokio::time::timeout( - Duration::from_millis(200), - connection.send_audio_frame(RealtimeAudioFrame { - data: "AQID".to_string(), - sample_rate: 48000, - num_channels: 1, - samples_per_channel: Some(960), - item_id: None, - }), - ) - .await - }, - connection.next_event() - ); - - send_result - .expect("send should not block on next_event") - .expect("send audio"); - let next_event = next_result.expect("next event").expect("event"); - assert_eq!( - next_event, - RealtimeEvent::SessionUpdated { - session_id: "sess_after_send".to_string(), - instructions: Some("backend prompt".to_string()), - } - ); - - connection.close().await.expect("close"); - server.await.expect("server task"); } } diff --git a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_common.rs b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_common.rs index 1b79122b27f..83be0ca77a1 100644 --- a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_common.rs +++ b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_common.rs @@ -1,11 +1,9 @@ use crate::endpoint::realtime_websocket::methods_v1::conversation_handoff_append_message as v1_conversation_handoff_append_message; use crate::endpoint::realtime_websocket::methods_v1::conversation_item_create_message as v1_conversation_item_create_message; use crate::endpoint::realtime_websocket::methods_v1::session_update_session as v1_session_update_session; -use crate::endpoint::realtime_websocket::methods_v1::websocket_intent as v1_websocket_intent; use crate::endpoint::realtime_websocket::methods_v2::conversation_handoff_append_message as v2_conversation_handoff_append_message; use crate::endpoint::realtime_websocket::methods_v2::conversation_item_create_message as v2_conversation_item_create_message; use crate::endpoint::realtime_websocket::methods_v2::session_update_session as v2_session_update_session; -use crate::endpoint::realtime_websocket::methods_v2::websocket_intent as v2_websocket_intent; use crate::endpoint::realtime_websocket::protocol::RealtimeEventParser; use crate::endpoint::realtime_websocket::protocol::RealtimeOutboundMessage; use crate::endpoint::realtime_websocket::protocol::RealtimeSessionMode; @@ -59,10 +57,3 @@ pub(super) fn session_update_session( RealtimeEventParser::RealtimeV2 => v2_session_update_session(instructions, session_mode), } } - -pub(super) fn websocket_intent(event_parser: RealtimeEventParser) -> Option<&'static str> { - match event_parser { - RealtimeEventParser::V1 => v1_websocket_intent(), - RealtimeEventParser::RealtimeV2 => v2_websocket_intent(), - } -} diff --git a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_v1.rs b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_v1.rs index b31899ff8d7..7907f891a84 100644 --- a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_v1.rs +++ b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_v1.rs @@ -61,7 +61,3 @@ pub(super) fn session_update_session(instructions: String) -> SessionUpdateSessi tool_choice: None, } } - -pub(super) fn websocket_intent() -> Option<&'static str> { - Some("quicksilver") -} diff --git a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_v2.rs b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_v2.rs index afff680c132..906a8d77670 100644 --- a/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_v2.rs +++ b/codex-rs/codex-api/src/endpoint/realtime_websocket/methods_v2.rs @@ -126,7 +126,3 @@ pub(super) fn session_update_session( }, } } - -pub(super) fn websocket_intent() -> Option<&'static str> { - None -} diff --git a/codex-rs/codex-api/src/endpoint/realtime_websocket/mod.rs b/codex-rs/codex-api/src/endpoint/realtime_websocket/mod.rs index d13585034a3..d75bd7b8380 100644 --- a/codex-rs/codex-api/src/endpoint/realtime_websocket/mod.rs +++ b/codex-rs/codex-api/src/endpoint/realtime_websocket/mod.rs @@ -9,10 +9,10 @@ mod protocol_v2; pub use codex_protocol::protocol::RealtimeAudioFrame; pub use codex_protocol::protocol::RealtimeEvent; -pub use methods::RealtimeWebsocketClient; -pub use methods::RealtimeWebsocketConnection; -pub use methods::RealtimeWebsocketEvents; -pub use methods::RealtimeWebsocketWriter; +pub use methods::RealtimeWebRtcClient; +pub use methods::RealtimeWebRtcConnection; +pub use methods::RealtimeWebRtcEvents; +pub use methods::RealtimeWebRtcWriter; pub use protocol::RealtimeEventParser; pub use protocol::RealtimeSessionConfig; pub use protocol::RealtimeSessionMode; diff --git a/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol.rs b/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol.rs index 2c629249fa3..619a9318d5d 100644 --- a/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol.rs +++ b/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol.rs @@ -32,8 +32,6 @@ pub struct RealtimeSessionConfig { #[derive(Debug, Clone, Serialize)] #[serde(tag = "type")] pub(super) enum RealtimeOutboundMessage { - #[serde(rename = "input_audio_buffer.append")] - InputAudioBufferAppend { audio: String }, #[serde(rename = "conversation.handoff.append")] ConversationHandoffAppend { handoff_id: String, diff --git a/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol_v1.rs b/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol_v1.rs index b66cf2b24b8..7f2e2c1159a 100644 --- a/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol_v1.rs +++ b/codex-rs/codex-api/src/endpoint/realtime_websocket/protocol_v1.rs @@ -35,7 +35,10 @@ pub(super) fn parse_realtime_event_v1(payload: &str) -> Option { .get("samples_per_channel") .and_then(Value::as_u64) .and_then(|value| u32::try_from(value).ok()), - item_id: None, + item_id: parsed + .get("item_id") + .and_then(Value::as_str) + .map(str::to_string), })) } "conversation.input_transcript.delta" => { diff --git a/codex-rs/codex-api/src/lib.rs b/codex-rs/codex-api/src/lib.rs index c7bb6070595..2f8e01645e0 100644 --- a/codex-rs/codex-api/src/lib.rs +++ b/codex-rs/codex-api/src/lib.rs @@ -34,8 +34,8 @@ pub use crate::endpoint::models::ModelsClient; pub use crate::endpoint::realtime_websocket::RealtimeEventParser; pub use crate::endpoint::realtime_websocket::RealtimeSessionConfig; pub use crate::endpoint::realtime_websocket::RealtimeSessionMode; -pub use crate::endpoint::realtime_websocket::RealtimeWebsocketClient; -pub use crate::endpoint::realtime_websocket::RealtimeWebsocketConnection; +pub use crate::endpoint::realtime_websocket::RealtimeWebRtcClient; +pub use crate::endpoint::realtime_websocket::RealtimeWebRtcConnection; pub use crate::endpoint::responses::ResponsesClient; pub use crate::endpoint::responses::ResponsesOptions; pub use crate::endpoint::responses_websocket::ResponsesWebsocketClient; diff --git a/codex-rs/codex-api/tests/realtime_websocket_e2e.rs b/codex-rs/codex-api/tests/realtime_websocket_e2e.rs deleted file mode 100644 index 130ab6fd353..00000000000 --- a/codex-rs/codex-api/tests/realtime_websocket_e2e.rs +++ /dev/null @@ -1,460 +0,0 @@ -use std::collections::HashMap; -use std::future::Future; -use std::time::Duration; - -use codex_api::RealtimeAudioFrame; -use codex_api::RealtimeEvent; -use codex_api::RealtimeEventParser; -use codex_api::RealtimeSessionConfig; -use codex_api::RealtimeSessionMode; -use codex_api::RealtimeWebsocketClient; -use codex_api::provider::Provider; -use codex_api::provider::RetryConfig; -use codex_protocol::protocol::RealtimeHandoffRequested; -use futures::SinkExt; -use futures::StreamExt; -use http::HeaderMap; -use serde_json::Value; -use serde_json::json; -use tokio::net::TcpListener; -use tokio_tungstenite::accept_async; -use tokio_tungstenite::tungstenite::Message; - -type RealtimeWsStream = tokio_tungstenite::WebSocketStream; - -async fn spawn_realtime_ws_server( - handler: Handler, -) -> (String, tokio::task::JoinHandle<()>) -where - Handler: FnOnce(RealtimeWsStream) -> Fut + Send + 'static, - Fut: Future + Send + 'static, -{ - let listener = match TcpListener::bind("127.0.0.1:0").await { - Ok(listener) => listener, - Err(err) => panic!("failed to bind test websocket listener: {err}"), - }; - let addr = match listener.local_addr() { - Ok(addr) => addr.to_string(), - Err(err) => panic!("failed to read local websocket listener address: {err}"), - }; - - let server = tokio::spawn(async move { - let (stream, _) = match listener.accept().await { - Ok(stream) => stream, - Err(err) => panic!("failed to accept test websocket connection: {err}"), - }; - let ws = match accept_async(stream).await { - Ok(ws) => ws, - Err(err) => panic!("failed to complete websocket handshake: {err}"), - }; - handler(ws).await; - }); - - (addr, server) -} - -fn test_provider(base_url: String) -> Provider { - Provider { - name: "test".to_string(), - base_url, - query_params: Some(HashMap::new()), - headers: HeaderMap::new(), - retry: RetryConfig { - max_attempts: 1, - base_delay: Duration::from_millis(1), - retry_429: false, - retry_5xx: false, - retry_transport: false, - }, - stream_idle_timeout: Duration::from_secs(5), - } -} - -#[tokio::test] -async fn realtime_ws_e2e_session_create_and_event_flow() { - let (addr, server) = spawn_realtime_ws_server(|mut ws: RealtimeWsStream| async move { - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - assert_eq!( - first_json["session"]["type"], - Value::String("quicksilver".to_string()) - ); - assert_eq!( - first_json["session"]["instructions"], - Value::String("backend prompt".to_string()) - ); - assert_eq!( - first_json["session"]["audio"]["input"]["format"]["type"], - Value::String("audio/pcm".to_string()) - ); - assert_eq!( - first_json["session"]["audio"]["input"]["format"]["rate"], - Value::from(24_000) - ); - - ws.send(Message::Text( - json!({ - "type": "session.updated", - "session": {"id": "sess_mock", "instructions": "backend prompt"} - }) - .to_string() - .into(), - )) - .await - .expect("send session.updated"); - - let second = ws - .next() - .await - .expect("second msg") - .expect("second msg ok") - .into_text() - .expect("text"); - let second_json: Value = serde_json::from_str(&second).expect("json"); - assert_eq!(second_json["type"], "input_audio_buffer.append"); - - ws.send(Message::Text( - json!({ - "type": "conversation.output_audio.delta", - "delta": "AQID", - "sample_rate": 48000, - "channels": 1 - }) - .to_string() - .into(), - )) - .await - .expect("send audio out"); - }) - .await; - - let client = RealtimeWebsocketClient::new(test_provider(format!("http://{addr}"))); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_123".to_string()), - event_parser: RealtimeEventParser::V1, - session_mode: RealtimeSessionMode::Conversational, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - - let created = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - created, - RealtimeEvent::SessionUpdated { - session_id: "sess_mock".to_string(), - instructions: Some("backend prompt".to_string()), - } - ); - - connection - .send_audio_frame(RealtimeAudioFrame { - data: "AQID".to_string(), - sample_rate: 48000, - num_channels: 1, - samples_per_channel: Some(960), - item_id: None, - }) - .await - .expect("send audio"); - - let audio_event = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - audio_event, - RealtimeEvent::AudioOut(RealtimeAudioFrame { - data: "AQID".to_string(), - sample_rate: 48000, - num_channels: 1, - samples_per_channel: None, - item_id: None, - }) - ); - - connection.close().await.expect("close"); - server.await.expect("server task"); -} - -#[tokio::test] -async fn realtime_ws_e2e_send_while_next_event_waits() { - let (addr, server) = spawn_realtime_ws_server(|mut ws: RealtimeWsStream| async move { - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - - let second = ws - .next() - .await - .expect("second msg") - .expect("second msg ok") - .into_text() - .expect("text"); - let second_json: Value = serde_json::from_str(&second).expect("json"); - assert_eq!(second_json["type"], "input_audio_buffer.append"); - - ws.send(Message::Text( - json!({ - "type": "session.updated", - "session": {"id": "sess_after_send", "instructions": "backend prompt"} - }) - .to_string() - .into(), - )) - .await - .expect("send session.updated"); - }) - .await; - - let client = RealtimeWebsocketClient::new(test_provider(format!("http://{addr}"))); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_123".to_string()), - event_parser: RealtimeEventParser::V1, - session_mode: RealtimeSessionMode::Conversational, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - - let (send_result, next_result) = tokio::join!( - async { - tokio::time::timeout( - Duration::from_millis(200), - connection.send_audio_frame(RealtimeAudioFrame { - data: "AQID".to_string(), - sample_rate: 48000, - num_channels: 1, - samples_per_channel: Some(960), - item_id: None, - }), - ) - .await - }, - connection.next_event() - ); - - send_result - .expect("send should not block on next_event") - .expect("send audio"); - let next_event = next_result.expect("next event").expect("event"); - assert_eq!( - next_event, - RealtimeEvent::SessionUpdated { - session_id: "sess_after_send".to_string(), - instructions: Some("backend prompt".to_string()), - } - ); - - connection.close().await.expect("close"); - server.await.expect("server task"); -} - -#[tokio::test] -async fn realtime_ws_e2e_disconnected_emitted_once() { - let (addr, server) = spawn_realtime_ws_server(|mut ws: RealtimeWsStream| async move { - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - - ws.send(Message::Close(None)).await.expect("send close"); - }) - .await; - - let client = RealtimeWebsocketClient::new(test_provider(format!("http://{addr}"))); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_123".to_string()), - event_parser: RealtimeEventParser::V1, - session_mode: RealtimeSessionMode::Conversational, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - - let first = connection.next_event().await.expect("next event"); - assert_eq!(first, None); - - let second = connection.next_event().await.expect("next event"); - assert_eq!(second, None); - - server.await.expect("server task"); -} - -#[tokio::test] -async fn realtime_ws_e2e_ignores_unknown_text_events() { - let (addr, server) = spawn_realtime_ws_server(|mut ws: RealtimeWsStream| async move { - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - - ws.send(Message::Text( - json!({ - "type": "response.created", - "response": {"id": "resp_unknown"} - }) - .to_string() - .into(), - )) - .await - .expect("send unknown event"); - - ws.send(Message::Text( - json!({ - "type": "session.updated", - "session": {"id": "sess_after_unknown", "instructions": "backend prompt"} - }) - .to_string() - .into(), - )) - .await - .expect("send session.updated"); - }) - .await; - - let client = RealtimeWebsocketClient::new(test_provider(format!("http://{addr}"))); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_123".to_string()), - event_parser: RealtimeEventParser::V1, - session_mode: RealtimeSessionMode::Conversational, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - - let event = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - event, - RealtimeEvent::SessionUpdated { - session_id: "sess_after_unknown".to_string(), - instructions: Some("backend prompt".to_string()), - } - ); - - connection.close().await.expect("close"); - server.await.expect("server task"); -} - -#[tokio::test] -async fn realtime_ws_e2e_realtime_v2_parser_emits_handoff_requested() { - let (addr, server) = spawn_realtime_ws_server(|mut ws: RealtimeWsStream| async move { - let first = ws - .next() - .await - .expect("first msg") - .expect("first msg ok") - .into_text() - .expect("text"); - let first_json: Value = serde_json::from_str(&first).expect("json"); - assert_eq!(first_json["type"], "session.update"); - - ws.send(Message::Text( - json!({ - "type": "conversation.item.done", - "item": { - "id": "item_123", - "type": "function_call", - "name": "codex", - "call_id": "call_123", - "arguments": "{\"prompt\":\"delegate now\"}" - } - }) - .to_string() - .into(), - )) - .await - .expect("send function call"); - }) - .await; - - let client = RealtimeWebsocketClient::new(test_provider(format!("http://{addr}"))); - let connection = client - .connect( - RealtimeSessionConfig { - instructions: "backend prompt".to_string(), - model: Some("realtime-test-model".to_string()), - session_id: Some("conv_123".to_string()), - event_parser: RealtimeEventParser::RealtimeV2, - session_mode: RealtimeSessionMode::Conversational, - }, - HeaderMap::new(), - HeaderMap::new(), - ) - .await - .expect("connect"); - - let event = connection - .next_event() - .await - .expect("next event") - .expect("event"); - assert_eq!( - event, - RealtimeEvent::HandoffRequested(RealtimeHandoffRequested { - handoff_id: "call_123".to_string(), - item_id: "item_123".to_string(), - input_transcript: "delegate now".to_string(), - active_transcript: Vec::new(), - }) - ); - - connection.close().await.expect("close"); - server.await.expect("server task"); -} diff --git a/codex-rs/core/src/realtime_conversation.rs b/codex-rs/core/src/realtime_conversation.rs index dae8f5c5ce7..6887accfe55 100644 --- a/codex-rs/core/src/realtime_conversation.rs +++ b/codex-rs/core/src/realtime_conversation.rs @@ -13,10 +13,10 @@ use codex_api::RealtimeEvent; use codex_api::RealtimeEventParser; use codex_api::RealtimeSessionConfig; use codex_api::RealtimeSessionMode; -use codex_api::RealtimeWebsocketClient; +use codex_api::RealtimeWebRtcClient; use codex_api::api_bridge::map_api_error; -use codex_api::endpoint::realtime_websocket::RealtimeWebsocketEvents; -use codex_api::endpoint::realtime_websocket::RealtimeWebsocketWriter; +use codex_api::endpoint::realtime_websocket::RealtimeWebRtcEvents; +use codex_api::endpoint::realtime_websocket::RealtimeWebRtcWriter; use codex_app_server_protocol::AuthMode; use codex_login::CodexAuth; use codex_login::default_client::default_headers; @@ -107,8 +107,8 @@ struct OutputAudioState { } struct RealtimeInputTask { - writer: RealtimeWebsocketWriter, - events: RealtimeWebsocketEvents, + writer: RealtimeWebRtcWriter, + events: RealtimeWebRtcEvents, user_text_rx: Receiver, handoff_output_rx: Receiver, audio_rx: Receiver, @@ -132,7 +132,7 @@ impl RealtimeHandoffState { struct ConversationState { audio_tx: Sender, user_text_tx: Sender, - writer: RealtimeWebsocketWriter, + writer: RealtimeWebRtcWriter, handoff: RealtimeHandoffState, input_task: JoinHandle<()>, fanout_task: Option>, @@ -172,7 +172,7 @@ impl RealtimeConversationManager { RealtimeEventParser::RealtimeV2 => RealtimeSessionKind::V2, }; - let client = RealtimeWebsocketClient::new(api_provider); + let client = RealtimeWebRtcClient::new(api_provider); let connection = client .connect( session_config, @@ -392,6 +392,7 @@ async fn stop_conversation_state( fanout_task_stop: RealtimeFanoutTaskStop, ) { state.realtime_active.store(false, Ordering::Relaxed); + let _ = state.writer.close().await; state.input_task.abort(); let _ = state.input_task.await; diff --git a/codex-rs/core/tests/common/BUILD.bazel b/codex-rs/core/tests/common/BUILD.bazel index aec0c178174..6c677b14c69 100644 --- a/codex-rs/core/tests/common/BUILD.bazel +++ b/codex-rs/core/tests/common/BUILD.bazel @@ -3,7 +3,11 @@ load("//:defs.bzl", "codex_rust_crate") codex_rust_crate( name = "common", crate_name = "core_test_support", - crate_srcs = glob(["*.rs"]), + crate_srcs = glob([ + "*.rs", + "responses/*.rs", + "responses/**/*.rs", + ]), lib_data_extra = [ "//codex-rs/core:model_availability_nux_fixtures", ], diff --git a/codex-rs/core/tests/common/Cargo.toml b/codex-rs/core/tests/common/Cargo.toml index e2765e8be6f..2850dd200fb 100644 --- a/codex-rs/core/tests/common/Cargo.toml +++ b/codex-rs/core/tests/common/Cargo.toml @@ -24,11 +24,13 @@ codex-models-manager = { workspace = true } codex-protocol = { workspace = true } codex-utils-absolute-path = { workspace = true } codex-utils-cargo-bin = { workspace = true } +codex-utils-rustls-provider = { workspace = true } ctor = { workspace = true } futures = { workspace = true } notify = { workspace = true } opentelemetry = { workspace = true } opentelemetry_sdk = { workspace = true } +opus-rs = { workspace = true } regex-lite = { workspace = true } serde_json = { workspace = true } tempfile = { workspace = true } @@ -38,6 +40,7 @@ tracing = { workspace = true } tracing-opentelemetry = { workspace = true } tracing-subscriber = { workspace = true } walkdir = { workspace = true } +webrtc = { workspace = true } wiremock = { workspace = true } shlex = { workspace = true } zstd = { workspace = true } diff --git a/codex-rs/core/tests/common/responses.rs b/codex-rs/core/tests/common/responses.rs index 2e2155ebddf..bf3970140a2 100644 --- a/codex-rs/core/tests/common/responses.rs +++ b/codex-rs/core/tests/common/responses.rs @@ -37,6 +37,8 @@ use wiremock::matchers::path_regex; use crate::test_codex::ApplyPatchModelOutput; +mod realtime_webrtc_server; + #[derive(Debug, Clone)] pub struct ResponseMock { requests: Arc>>, @@ -1238,6 +1240,28 @@ pub async fn start_websocket_server_with_headers( tokio::time::sleep(delay).await; } + if realtime_webrtc_server::accept_is_http_post(&stream).await { + let connection_index = { + let mut log = requests.lock().unwrap(); + log.push(Vec::new()); + log.len() - 1 + }; + realtime_webrtc_server::serve_connection( + stream, + connection, + connection_index, + Arc::clone(&requests), + Arc::clone(&handshakes), + Arc::clone(&request_log), + ) + .await; + + if connections.lock().unwrap().is_empty() { + return; + } + continue; + } + let response_headers = connection.response_headers.clone(); let handshake_log = Arc::clone(&handshakes); let callback = move |req: &Request, mut response: Response| { diff --git a/codex-rs/core/tests/common/responses/realtime_webrtc_server.rs b/codex-rs/core/tests/common/responses/realtime_webrtc_server.rs new file mode 100644 index 00000000000..bfae934aa4f --- /dev/null +++ b/codex-rs/core/tests/common/responses/realtime_webrtc_server.rs @@ -0,0 +1,431 @@ +use std::collections::VecDeque; +use std::sync::Arc; +use std::sync::Mutex; +use std::time::Duration; + +use base64::Engine; +use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; +use codex_utils_rustls_provider::ensure_rustls_crypto_provider; +use opus_rs::OpusDecoder; +use serde_json::Value; +use tokio::io::AsyncReadExt; +use tokio::io::AsyncWriteExt; +use tokio::net::TcpStream; +use tokio::sync::Notify; +use tokio::sync::mpsc; +use tokio::sync::oneshot; +use tokio::time::timeout; +use tracing::debug; +use tracing::warn; +use webrtc::api::APIBuilder; +use webrtc::api::interceptor_registry::register_default_interceptors; +use webrtc::api::media_engine::MediaEngine; +use webrtc::data_channel::RTCDataChannel; +use webrtc::data_channel::data_channel_message::DataChannelMessage; +use webrtc::interceptor::registry::Registry; +use webrtc::peer_connection::RTCPeerConnection; +use webrtc::peer_connection::configuration::RTCConfiguration; +use webrtc::peer_connection::peer_connection_state::RTCPeerConnectionState; +use webrtc::peer_connection::sdp::session_description::RTCSessionDescription; +use webrtc::rtp_transceiver::rtp_codec::RTPCodecType; +use webrtc::track::track_remote::TrackRemote; + +use super::WebSocketConnectionConfig; +use super::WebSocketHandshake; +use super::WebSocketRequest; + +const HTTP_HEADER_TERMINATOR: &[u8] = b"\r\n\r\n"; +const REALTIME_AUDIO_CHANNELS: u8 = 1; +const REALTIME_AUDIO_SAMPLE_RATE: u32 = 24_000; +const REALTIME_DATA_CHANNEL_TIMEOUT: Duration = Duration::from_secs(10); +const REALTIME_DATA_CHANNEL_FLUSH_DELAY: Duration = Duration::from_millis(25); +const REALTIME_MAX_DECODED_SAMPLES_PER_CHANNEL: usize = 5760; + +pub(super) async fn accept_is_http_post(stream: &TcpStream) -> bool { + let mut method = [0u8; 4]; + matches!(stream.peek(&mut method).await, Ok(4)) && method == *b"POST" +} + +pub(super) async fn serve_connection( + mut stream: TcpStream, + connection: WebSocketConnectionConfig, + connection_index: usize, + requests: Arc>>>, + handshakes: Arc>>, + request_log_updated: Arc, +) { + let Some(request) = read_http_request(&mut stream).await else { + return; + }; + + handshakes.lock().unwrap().push(WebSocketHandshake { + uri: request.uri, + headers: request.headers, + }); + + let Some(offer_sdp) = parse_multipart_field(&request.body, &request.boundary, "sdp") else { + let _ = stream + .write_all(b"HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n") + .await; + return; + }; + + let Some(session) = start_session( + offer_sdp, + connection, + connection_index, + requests, + request_log_updated, + ) + .await + else { + let _ = stream + .write_all(b"HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n") + .await; + return; + }; + + let response = format!( + "HTTP/1.1 200 OK\r\nContent-Type: application/sdp\r\nContent-Length: {}\r\n\r\n{}", + session.answer_sdp.len(), + session.answer_sdp + ); + if stream.write_all(response.as_bytes()).await.is_err() { + return; + } + + let _ = session.done_rx.await; + let _ = session.peer_connection.close().await; +} + +struct HttpRealtimeRequest { + uri: String, + headers: Vec<(String, String)>, + boundary: String, + body: Vec, +} + +struct RealtimeSession { + answer_sdp: String, + peer_connection: Arc, + done_rx: oneshot::Receiver<()>, +} + +async fn read_http_request(stream: &mut TcpStream) -> Option { + let mut received = Vec::new(); + let headers_end = loop { + if let Some(headers_end) = received + .windows(HTTP_HEADER_TERMINATOR.len()) + .position(|window| window == HTTP_HEADER_TERMINATOR) + { + break headers_end + HTTP_HEADER_TERMINATOR.len(); + } + + let mut chunk = [0u8; 1024]; + let read = stream.read(&mut chunk).await.ok()?; + if read == 0 { + return None; + } + received.extend_from_slice(&chunk[..read]); + }; + + let header_text = std::str::from_utf8(&received[..headers_end]).ok()?; + let mut lines = header_text.split("\r\n").filter(|line| !line.is_empty()); + let request_line = lines.next()?; + let mut request_line_parts = request_line.split_whitespace(); + if request_line_parts.next()? != "POST" { + return None; + } + let uri = request_line_parts.next()?.to_string(); + + let mut headers = Vec::new(); + let mut content_length = None; + let mut boundary = None; + for line in lines { + let Some((name, value)) = line.split_once(':') else { + continue; + }; + let name = name.trim().to_string(); + let value = value.trim().to_string(); + if name.eq_ignore_ascii_case("content-length") { + content_length = value.parse::().ok(); + } + if name.eq_ignore_ascii_case("content-type") { + boundary = value + .split(';') + .map(str::trim) + .find_map(|part| part.strip_prefix("boundary=")) + .map(|boundary| boundary.trim_matches('"').to_string()); + } + headers.push((name, value)); + } + + let content_length = content_length?; + while received.len() - headers_end < content_length { + let mut chunk = [0u8; 1024]; + let read = stream.read(&mut chunk).await.ok()?; + if read == 0 { + return None; + } + received.extend_from_slice(&chunk[..read]); + } + + let body_end = headers_end + content_length; + let body = received[headers_end..body_end].to_vec(); + Some(HttpRealtimeRequest { + uri, + headers, + boundary: boundary?, + body, + }) +} + +fn parse_multipart_field(body: &[u8], boundary: &str, field_name: &str) -> Option { + let body = std::str::from_utf8(body).ok()?; + let delimiter = format!("--{boundary}"); + body.split(&delimiter).find_map(|part| { + let (headers, value) = part.split_once("\r\n\r\n")?; + if !headers.contains(&format!("name=\"{field_name}\"")) { + return None; + } + Some(value.trim_end_matches("\r\n").to_string()) + }) +} + +async fn start_session( + offer_sdp: String, + connection: WebSocketConnectionConfig, + connection_index: usize, + requests: Arc>>>, + request_log_updated: Arc, +) -> Option { + let peer_connection = create_peer_connection().await?; + let (tx_request, rx_request) = mpsc::unbounded_channel::(); + let (tx_data_channel, rx_data_channel) = oneshot::channel::>(); + let tx_data_channel = Mutex::new(Some(tx_data_channel)); + let tx_data_channel_request = tx_request.clone(); + let connection_closed = Arc::new(Notify::new()); + let on_data_channel_closed = Arc::clone(&connection_closed); + let on_peer_connection_closed = Arc::clone(&connection_closed); + + peer_connection.on_data_channel(Box::new(move |data_channel| { + let tx_request = tx_data_channel_request.clone(); + let on_data_channel_closed = Arc::clone(&on_data_channel_closed); + if let Ok(mut tx_data_channel) = tx_data_channel.lock() + && let Some(tx_data_channel) = tx_data_channel.take() + { + let _ = tx_data_channel.send(Arc::clone(&data_channel)); + } + data_channel.on_close(Box::new(move || { + let on_data_channel_closed = Arc::clone(&on_data_channel_closed); + Box::pin(async move { + on_data_channel_closed.notify_waiters(); + }) + })); + data_channel.on_message(Box::new(move |message: DataChannelMessage| { + let tx_request = tx_request.clone(); + Box::pin(async move { + if !message.is_string { + return; + } + let Ok(text) = String::from_utf8(message.data.to_vec()) else { + return; + }; + let Ok(body) = serde_json::from_str::(&text) else { + return; + }; + let _ = tx_request.send(body); + }) + })); + Box::pin(async {}) + })); + peer_connection.on_peer_connection_state_change(Box::new(move |state| { + let on_peer_connection_closed = Arc::clone(&on_peer_connection_closed); + Box::pin(async move { + if matches!( + state, + RTCPeerConnectionState::Closed + | RTCPeerConnectionState::Disconnected + | RTCPeerConnectionState::Failed + ) { + on_peer_connection_closed.notify_waiters(); + } + }) + })); + + register_remote_audio_handler(&peer_connection, tx_request.clone()); + + let mut gather_complete = peer_connection.gathering_complete_promise().await; + let offer = RTCSessionDescription::offer(offer_sdp).ok()?; + peer_connection.set_remote_description(offer).await.ok()?; + let answer = peer_connection.create_answer(None).await.ok()?; + peer_connection.set_local_description(answer).await.ok()?; + let _ = gather_complete.recv().await; + let answer_sdp = peer_connection.local_description().await?.sdp; + + let (done_tx, done_rx) = oneshot::channel(); + tokio::spawn(async move { + serve_scripted_requests( + connection, + connection_index, + requests, + request_log_updated, + rx_request, + rx_data_channel, + connection_closed, + ) + .await; + let _ = done_tx.send(()); + }); + + Some(RealtimeSession { + answer_sdp, + peer_connection, + done_rx, + }) +} + +async fn create_peer_connection() -> Option> { + ensure_rustls_crypto_provider(); + + let mut media_engine = MediaEngine::default(); + media_engine.register_default_codecs().ok()?; + let registry = register_default_interceptors(Registry::new(), &mut media_engine).ok()?; + let api = APIBuilder::new() + .with_media_engine(media_engine) + .with_interceptor_registry(registry) + .build(); + api.new_peer_connection(RTCConfiguration::default()) + .await + .map(Arc::new) + .ok() +} + +fn register_remote_audio_handler( + peer_connection: &Arc, + tx_request: mpsc::UnboundedSender, +) { + peer_connection.on_track(Box::new(move |track, _, _| { + let tx_request = tx_request.clone(); + Box::pin(async move { + if track.kind() != RTPCodecType::Audio { + return; + } + pump_remote_audio_track(track, tx_request).await; + }) + })); +} + +async fn pump_remote_audio_track( + track: Arc, + tx_request: mpsc::UnboundedSender, +) { + let mut decoder = match OpusDecoder::new(24_000, usize::from(REALTIME_AUDIO_CHANNELS)) { + Ok(decoder) => decoder, + Err(err) => { + warn!(%err, "failed to initialize realtime Opus decoder in test server"); + return; + } + }; + debug!("initialized realtime Opus decoder in test server"); + let mut decoded = vec![0.0f32; REALTIME_MAX_DECODED_SAMPLES_PER_CHANNEL]; + + while let Ok((packet, _)) = track.read_rtp().await { + if packet.payload.is_empty() { + continue; + } + let samples_per_channel = match decoder.decode( + &packet.payload, + REALTIME_MAX_DECODED_SAMPLES_PER_CHANNEL, + &mut decoded, + ) { + Ok(samples_per_channel) => samples_per_channel, + Err(err) => { + warn!( + %err, + payload_len = packet.payload.len(), + "failed to decode realtime Opus packet in test server" + ); + return; + } + }; + if samples_per_channel == 0 { + continue; + } + + let mut pcm_bytes = Vec::with_capacity(samples_per_channel * 2); + for sample in &decoded[..samples_per_channel] { + pcm_bytes.extend_from_slice(&f32_to_i16(*sample).to_le_bytes()); + } + let _ = tx_request.send(serde_json::json!({ + "type": "input_audio_buffer.append", + "audio": BASE64_STANDARD.encode(pcm_bytes), + "sample_rate": REALTIME_AUDIO_SAMPLE_RATE, + "channels": REALTIME_AUDIO_CHANNELS, + "samples_per_channel": samples_per_channel, + })); + } +} + +fn f32_to_i16(sample: f32) -> i16 { + (sample.clamp(-1.0, 1.0) * i16::MAX as f32) as i16 +} + +async fn serve_scripted_requests( + connection: WebSocketConnectionConfig, + connection_index: usize, + requests: Arc>>>, + request_log_updated: Arc, + mut rx_request: mpsc::UnboundedReceiver, + rx_data_channel: oneshot::Receiver>, + connection_closed: Arc, +) { + let Ok(Ok(data_channel)) = timeout(REALTIME_DATA_CHANNEL_TIMEOUT, rx_data_channel).await else { + return; + }; + + let mut scripted_requests = VecDeque::from(connection.requests); + while let Some(request_events) = scripted_requests.pop_front() { + // WebRTC compact-remote tests often close the session before consuming every scripted + // request slot. Treat transport closure as end-of-script instead of waiting forever for + // another request that can no longer arrive. + let body = tokio::select! { + body = rx_request.recv() => body, + _ = connection_closed.notified() => None, + }; + let Some(body) = body else { + break; + }; + log_request(connection_index, body, &requests, &request_log_updated); + for event in &request_events { + let Ok(payload) = serde_json::to_string(event) else { + continue; + }; + if data_channel.send_text(payload).await.is_err() { + return; + } + } + } + + if connection.close_after_requests { + tokio::time::sleep(REALTIME_DATA_CHANNEL_FLUSH_DELAY).await; + let _ = data_channel.close().await; + } +} + +fn log_request( + connection_index: usize, + body: Value, + requests: &Arc>>>, + request_log_updated: &Arc, +) { + let mut log = requests.lock().unwrap(); + if log.len() <= connection_index { + log.resize_with(connection_index + 1, Vec::new); + } + if let Some(connection_log) = log.get_mut(connection_index) { + connection_log.push(WebSocketRequest { body }); + } + drop(log); + request_log_updated.notify_waiters(); +} diff --git a/codex-rs/core/tests/suite/realtime_conversation.rs b/codex-rs/core/tests/suite/realtime_conversation.rs index b169e229a57..120185d0a96 100644 --- a/codex-rs/core/tests/suite/realtime_conversation.rs +++ b/codex-rs/core/tests/suite/realtime_conversation.rs @@ -1,5 +1,7 @@ use anyhow::Context; use anyhow::Result; +use base64::Engine; +use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; use chrono::Utc; use codex_login::CodexAuth; use codex_login::OPENAI_API_KEY_ENV_VAR; @@ -41,6 +43,17 @@ const MEMORY_PROMPT_PHRASE: &str = "You have access to a memory folder with guidance from prior runs."; const REALTIME_CONVERSATION_TEST_SUBPROCESS_ENV_VAR: &str = "CODEX_REALTIME_CONVERSATION_TEST_SUBPROCESS"; + +fn realtime_pcm_test_tone_20ms_base64() -> String { + let pcm_bytes: Vec = (0..480) + .flat_map(|index| { + let sample = if index % 2 == 0 { 1024_i16 } else { -1024_i16 }; + sample.to_le_bytes() + }) + .collect(); + BASE64_STANDARD.encode(pcm_bytes) +} + fn websocket_request_text( request: &core_test_support::responses::WebSocketRequest, ) -> Option { @@ -207,7 +220,7 @@ async fn conversation_start_audio_text_close_round_trip() -> Result<()> { test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_test_tone_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480), @@ -254,10 +267,7 @@ async fn conversation_start_audio_text_close_round_trip() -> Result<()> { server.handshakes()[1].header("authorization").as_deref(), Some("Bearer dummy") ); - assert_eq!( - server.handshakes()[1].uri(), - "/v1/realtime?intent=quicksilver&model=realtime-test-model" - ); + assert_eq!(server.handshakes()[1].uri(), "/v1/realtime/calls"); let mut request_types = [ connection[1].body_json()["type"] .as_str() @@ -426,7 +436,7 @@ async fn conversation_audio_before_start_emits_error() -> Result<()> { test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_test_tone_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480), @@ -625,7 +635,7 @@ async fn conversation_second_start_replaces_runtime() -> Result<()> { test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_test_tone_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480), @@ -1585,7 +1595,7 @@ async fn inbound_handoff_request_clears_active_transcript_after_each_handoff() - test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_test_tone_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480), @@ -2073,7 +2083,7 @@ async fn inbound_handoff_request_steers_active_turn() -> Result<()> { test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { frame: RealtimeAudioFrame { - data: "AQID".to_string(), + data: realtime_pcm_test_tone_20ms_base64(), sample_rate: 24000, num_channels: 1, samples_per_channel: Some(480),