From 72578296db5be46004f4d6f05feef51137d45ae6 Mon Sep 17 00:00:00 2001 From: Per Stark Date: Mon, 27 Oct 2025 13:05:10 +0100 Subject: [PATCH] feat: reranking with fastembed added --- CHANGELOG.md | 1 + Cargo.lock | 1024 ++++++++++++++++- Cargo.toml | 50 +- README.md | 21 + common/src/storage/store.rs | 1 + common/src/storage/types/file_info.rs | 117 +- common/src/utils/config.rs | 37 + composite-retrieval/Cargo.toml | 1 + composite-retrieval/src/answer_retrieval.rs | 52 +- composite-retrieval/src/lib.rs | 6 + composite-retrieval/src/pipeline/config.rs | 6 + composite-retrieval/src/pipeline/mod.rs | 8 +- .../src/pipeline/stages/mod.rs | 174 ++- composite-retrieval/src/pipeline/state.rs | 6 +- composite-retrieval/src/reranking/mod.rs | 170 +++ html-router/assets/style.css | 2 +- html-router/src/html_state.rs | 4 + .../routes/chat/message_response_stream.rs | 6 + html-router/src/routes/knowledge/handlers.rs | 15 +- ingestion-pipeline/src/pipeline/mod.rs | 10 +- ingestion-pipeline/src/pipeline/services.rs | 21 +- main/Cargo.toml | 1 + main/src/main.rs | 35 +- main/src/server.rs | 12 +- main/src/worker.rs | 8 +- 25 files changed, 1586 insertions(+), 202 deletions(-) create mode 100644 composite-retrieval/src/reranking/mod.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 50c5c04..30ecd6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog ## Unreleased +- Added an opt-in FastEmbed-based reranking stage behind `reranking_enabled`. It improves retrieval accuracy by re-scoring hybrid results. ## Version 0.2.5 (2025-10-24) - Added manual knowledge entity creation flows using a modal, with the option for suggested relationships diff --git a/Cargo.lock b/Cargo.lock index d08ba93..515a3c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,6 +112,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.16", "once_cell", + "serde", "version_check", "zerocopy 0.7.35", ] @@ -125,6 +126,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b" +dependencies = [ + "equator", +] + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -271,6 +281,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "argon2" version = "0.5.3" @@ -547,7 +574,7 @@ dependencies = [ "quote", "serde", "serde_json", - "ureq", + "ureq 2.12.1", ] [[package]] @@ -556,6 +583,29 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "av1-grain" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom 8.0.0", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c8fbc0f831f4519fe8b810b6a7a91410ec83031b8233f730a0480029f6a23f" +dependencies = [ + "arrayvec", +] + [[package]] name = "axum" version = "0.8.4" @@ -764,6 +814,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.7" @@ -834,6 +890,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bit_field" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -849,6 +911,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitstream-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" + [[package]] name = "bitvec" version = "1.0.1" @@ -955,6 +1023,12 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "built" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b" + [[package]] name = "bumpalo" version = "3.17.0" @@ -1001,6 +1075,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.10.1" @@ -1102,6 +1182,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31f5b6e9141c036f3ff4ce7b2f7e432b0f00dee416ddcd4f17741d189ddc2e9d" +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec 1.15.0", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -1126,7 +1216,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -1245,7 +1335,7 @@ dependencies = [ "cli-table-derive", "csv", "termcolor", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -1286,6 +1376,12 @@ dependencies = [ "tracing-error", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "colorchoice" version = "1.0.3" @@ -1334,6 +1430,21 @@ dependencies = [ "uuid", ] +[[package]] +name = "compact_str" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "serde", + "static_assertions", +] + [[package]] name = "composite-retrieval" version = "0.1.0" @@ -1342,6 +1453,7 @@ dependencies = [ "async-openai", "axum", "common", + "fastembed", "futures", "serde", "serde_json", @@ -1401,6 +1513,19 @@ dependencies = [ "yaml-rust2", ] +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width 0.2.2", + "windows-sys 0.59.0", +] + [[package]] name = "const-random" version = "0.1.18" @@ -1553,7 +1678,7 @@ dependencies = [ "dtoa-short", "itoa", "phf", - "smallvec", + "smallvec 1.15.0", ] [[package]] @@ -1566,7 +1691,7 @@ dependencies = [ "dtoa-short", "itoa", "phf", - "smallvec", + "smallvec 1.15.0", ] [[package]] @@ -1644,6 +1769,15 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "dary_heap" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06d2e3287df1c007e74221c49ca10a95d557349e54b3a75dc2fb14712c751f04" +dependencies = [ + "serde", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -1677,6 +1811,16 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.4.0" @@ -1766,6 +1910,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -1776,6 +1929,18 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.5.2", + "windows-sys 0.59.0", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -1783,7 +1948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", - "redox_users", + "redox_users 0.4.6", "winapi", ] @@ -1907,6 +2072,12 @@ dependencies = [ "log", ] +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -1928,6 +2099,26 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" +[[package]] +name = "equator" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" +dependencies = [ + "equator-macro", +] + +[[package]] +name = "equator-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -1944,6 +2135,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "esaxx-rs" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d817e038c30374a4bcb22f94d0a8a0e216958d4c3dcde369b1439fec4bdda6e6" + [[package]] name = "euclid" version = "0.20.14" @@ -1985,6 +2182,21 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.73.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec 1.15.0", + "zune-inflate", +] + [[package]] name = "ext-sort" version = "0.1.4" @@ -2008,12 +2220,56 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fastembed" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e9bf3ea201e5d338450555088e02cff23b00be92bead3eff7ed341c68f5ac6" +dependencies = [ + "anyhow", + "hf-hub", + "image", + "ndarray 0.16.1", + "ort", + "serde_json", + "tokenizers", +] + [[package]] name = "fastrand" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "fax" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" +dependencies = [ + "fax_derive", +] + +[[package]] +name = "fax_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + [[package]] name = "filetime" version = "0.2.25" @@ -2349,6 +2605,16 @@ dependencies = [ "polyval", ] +[[package]] +name = "gif" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.31.1" @@ -2485,6 +2751,27 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hf-hub" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629d8f3bbeda9d148036d6b0de0a3ab947abd08ce90626327fc3547a49d59d97" +dependencies = [ + "dirs", + "http", + "indicatif", + "libc", + "log", + "native-tls", + "rand 0.9.1", + "reqwest", + "serde", + "serde_json", + "thiserror 2.0.12", + "ureq 2.12.1", + "windows-sys 0.60.2", +] + [[package]] name = "hmac" version = "0.12.1" @@ -2638,7 +2925,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "smallvec", + "smallvec 1.15.0", "tokio", "want", ] @@ -2778,7 +3065,7 @@ dependencies = [ "icu_normalizer_data", "icu_properties", "icu_provider", - "smallvec", + "smallvec 1.15.0", "utf16_iter", "utf8_iter", "write16", @@ -2853,7 +3140,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ "idna_adapter", - "smallvec", + "smallvec 1.15.0", "utf8_iter", ] @@ -2867,6 +3154,46 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "image" +version = "0.25.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "moxcms", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imgref" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" + [[package]] name = "include_dir" version = "0.7.4" @@ -2914,6 +3241,19 @@ dependencies = [ "serde", ] +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width 0.2.2", + "web-time", +] + [[package]] name = "ingestion-pipeline" version = "0.1.0" @@ -2983,6 +3323,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "ipnet" version = "2.11.0" @@ -3013,6 +3364,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.13.0" @@ -3147,6 +3507,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lebe" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" + [[package]] name = "lexicmp" version = "0.1.0" @@ -3171,6 +3537,16 @@ version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +[[package]] +name = "libfuzzer-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404" +dependencies = [ + "arbitrary", + "cc", +] + [[package]] name = "libm" version = "0.2.13" @@ -3194,7 +3570,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e7562b41c8876d3367897067013bb2884cc78e6893f092ecd26b305176ac82" dependencies = [ - "ndarray", + "ndarray 0.15.6", "num-traits", "rand 0.8.5", "thiserror 1.0.69", @@ -3234,6 +3610,15 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "lopdf" version = "0.32.0" @@ -3294,6 +3679,22 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +[[package]] +name = "macro_rules_attribute" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65049d7923698040cd0b1ddcced9b0eb14dd22c5f86ae59c3740eab64a676520" +dependencies = [ + "macro_rules_attribute-proc_macro", + "paste", +] + +[[package]] +name = "macro_rules_attribute-proc_macro" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" + [[package]] name = "main" version = "0.2.5" @@ -3303,6 +3704,7 @@ dependencies = [ "async-openai", "axum", "common", + "composite-retrieval", "futures", "html-router", "ingestion-pipeline", @@ -3384,6 +3786,16 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "md-5" version = "0.10.6" @@ -3421,7 +3833,7 @@ dependencies = [ "miette-derive", "once_cell", "thiserror 1.0.69", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -3503,6 +3915,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -3517,6 +3930,38 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "monostate" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3341a273f6c9d5bef1908f17b7267bbab0e95c9bf69a0d4dcf8e9e1b2c76ef67" +dependencies = [ + "monostate-impl", + "serde", + "serde_core", +] + +[[package]] +name = "monostate-impl" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4db6d5580af57bf992f59068d4ea26fd518574ff48d7639b255a36f9de6e7e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "moxcms" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c588e11a3082784af229e23e8e4ecf5bcc6fbe4f69101e0421ce8d79da7f0b40" +dependencies = [ + "num-traits", + "pxfm", +] + [[package]] name = "multer" version = "3.1.0" @@ -3574,6 +4019,21 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "ndarray" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" +dependencies = [ + "matrixmultiply", + "num-complex", + "num-integer", + "num-traits", + "portable-atomic", + "portable-atomic-util", + "rawpointer", +] + [[package]] name = "ndarray-stats" version = "0.5.1" @@ -3582,7 +4042,7 @@ checksum = "af5a8477ac96877b5bd1fd67e0c28736c12943aba24eda92b127e036b0c8f400" dependencies = [ "indexmap 1.9.3", "itertools 0.10.5", - "ndarray", + "ndarray 0.15.6", "noisy_float", "num-integer", "num-traits", @@ -3601,7 +4061,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" dependencies = [ - "smallvec", + "smallvec 1.15.0", ] [[package]] @@ -3649,6 +4109,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + [[package]] name = "notify" version = "8.0.0" @@ -3727,6 +4193,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "num-integer" version = "0.1.46" @@ -3736,6 +4213,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -3756,6 +4244,12 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.36.7" @@ -3814,6 +4308,28 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "onig" +version = "6.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" +dependencies = [ + "bitflags 2.9.0", + "libc", + "once_cell", + "onig_sys", +] + +[[package]] +name = "onig_sys" +version = "69.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f86c6eef3d6df15f23bcfb6af487cbd2fed4e5581d58d5bf1f5f8b7f6727dc" +dependencies = [ + "cc", + "pkg-config", +] + [[package]] name = "opaque-debug" version = "0.3.1" @@ -3864,6 +4380,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "ordered-multimap" version = "0.7.3" @@ -3874,6 +4396,31 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "ort" +version = "2.0.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa7e49bd669d32d7bc2a15ec540a527e7764aec722a45467814005725bcd721" +dependencies = [ + "ndarray 0.16.1", + "ort-sys", + "smallvec 2.0.0-alpha.10", + "tracing", +] + +[[package]] +name = "ort-sys" +version = "2.0.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2aba9f5c7c479925205799216e7e5d07cc1d4fa76ea8058c60a9a30f6a4e890" +dependencies = [ + "flate2", + "pkg-config", + "sha2", + "tar", + "ureq 3.1.2", +] + [[package]] name = "overload" version = "0.1.1" @@ -3911,7 +4458,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "smallvec", + "smallvec 1.15.0", "windows-targets 0.52.6", ] @@ -3992,6 +4539,15 @@ dependencies = [ "serde", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -4161,6 +4717,19 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.9.0", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "polyval" version = "0.6.2" @@ -4179,6 +4748,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60f6ce597ecdcc9a098e7fddacb1065093a3d66446fa16c675e7e71d1b5c28e6" +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "postscript" version = "0.14.1" @@ -4246,6 +4830,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" +dependencies = [ + "quote", + "syn 2.0.101", +] + [[package]] name = "psl-types" version = "2.0.11" @@ -4281,6 +4884,30 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "pxfm" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cbdf373972bf78df4d3b518d07003938e2c7d1fb5891e55f9cb6df57009d84" +dependencies = [ + "num-traits", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick_cache" version = "0.5.2" @@ -4456,6 +5083,56 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93e7e49bb0bf967717f7bd674458b3d6b0c5f48ec7e3038166026a69fc22223" +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.12.1", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand 0.8.5", + "rand_chacha 0.3.1", + "simd_helpers", + "system-deps", + "thiserror 1.0.69", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5825c26fddd16ab9f515930d49028a630efec172e903483c94796cfe31893e6b" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "rawpointer" version = "0.2.1" @@ -4472,6 +5149,17 @@ dependencies = [ "rayon-core", ] +[[package]] +name = "rayon-cond" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2964d0cf57a3e7a06e8183d14a8b527195c706b7983549cd5462d5aa3747438f" +dependencies = [ + "either", + "itertools 0.14.0", + "rayon", +] + [[package]] name = "rayon-core" version = "1.12.1" @@ -4508,6 +5196,17 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 2.0.12", +] + [[package]] name = "ref-cast" version = "1.0.24" @@ -4702,6 +5401,12 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "rgb" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" + [[package]] name = "ring" version = "0.17.14" @@ -4814,7 +5519,7 @@ checksum = "421400d13ccfd26dfa5858199c30a5d76f9c54e0dba7575273025b43c5175dbb" dependencies = [ "heapless", "num-traits", - "smallvec", + "smallvec 1.15.0", ] [[package]] @@ -5078,7 +5783,7 @@ dependencies = [ "phf_codegen", "precomputed-hash", "servo_arc", - "smallvec", + "smallvec 1.15.0", ] [[package]] @@ -5104,10 +5809,11 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -5133,10 +5839,19 @@ dependencies = [ ] [[package]] -name = "serde_derive" -version = "1.0.219" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -5272,6 +5987,21 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "simdutf8" version = "0.1.5" @@ -5311,6 +6041,12 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +[[package]] +name = "smallvec" +version = "2.0.0-alpha.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d44cfb396c3caf6fbfd0ab422af02631b69ddd96d2eff0b0f0724f9024051b" + [[package]] name = "smol_str" version = "0.2.2" @@ -5377,7 +6113,7 @@ dependencies = [ "hashbrown 0.15.3", "num-traits", "robust", - "smallvec", + "smallvec 1.15.0", ] [[package]] @@ -5386,6 +6122,18 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spm_precompiled" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5851699c4033c63636f7ea4cf7b7c1f1bf06d0cc03cfb42e711de5a5c46cf326" +dependencies = [ + "base64 0.13.1", + "nom 7.1.3", + "serde", + "unicode-segmentation", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -5433,6 +6181,12 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "static_assertions_next" version = "1.1.2" @@ -5605,7 +6359,7 @@ dependencies = [ "linfa-linalg", "md-5", "nanoid", - "ndarray", + "ndarray 0.15.6", "ndarray-stats", "num-traits", "num_cpus", @@ -5776,12 +6530,42 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tar" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "tempfile" version = "3.19.1" @@ -5893,6 +6677,20 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tiff" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" +dependencies = [ + "fax", + "flate2", + "half", + "quick-error", + "weezl", + "zune-jpeg", +] + [[package]] name = "time" version = "0.3.41" @@ -5975,6 +6773,39 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokenizers" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6475a27088c98ea96d00b39a9ddfb63780d1ad4cceb6f48374349a96ab2b7842" +dependencies = [ + "ahash 0.8.11", + "aho-corasick", + "compact_str", + "dary_heap", + "derive_builder", + "esaxx-rs", + "getrandom 0.3.2", + "itertools 0.14.0", + "log", + "macro_rules_attribute", + "monostate", + "onig", + "paste", + "rand 0.9.1", + "rayon", + "rayon-cond", + "regex", + "regex-syntax 0.8.5", + "serde", + "serde_json", + "spm_precompiled", + "thiserror 2.0.12", + "unicode-normalization-alignments", + "unicode-segmentation", + "unicode_categories", +] + [[package]] name = "tokio" version = "1.44.2" @@ -6251,7 +7082,7 @@ dependencies = [ "once_cell", "regex", "sharded-slab", - "smallvec", + "smallvec 1.15.0", "thread_local", "tracing", "tracing-core", @@ -6384,6 +7215,15 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-normalization-alignments" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f613e4fa046e69818dd287fdc4bc78175ff20331479dab6e1b0f98d57062de" +dependencies = [ + "smallvec 1.15.0", +] + [[package]] name = "unicode-properties" version = "0.1.3" @@ -6418,12 +7258,24 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[package]] name = "unicode-xid" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + [[package]] name = "universal-hash" version = "0.5.1" @@ -6449,14 +7301,48 @@ dependencies = [ "base64 0.22.1", "flate2", "log", + "native-tls", "once_cell", "rustls", "rustls-pki-types", + "serde", + "serde_json", "socks", "url", "webpki-roots", ] +[[package]] +name = "ureq" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99ba1025f18a4a3fc3e9b48c868e9beb4f24f4b4b1a325bada26bd4119f46537" +dependencies = [ + "base64 0.22.1", + "der", + "log", + "native-tls", + "percent-encoding", + "rustls-pemfile", + "rustls-pki-types", + "socks", + "ureq-proto", + "utf-8", + "webpki-root-certs", +] + +[[package]] +name = "ureq-proto" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" +dependencies = [ + "base64 0.22.1", + "http", + "httparse", + "log", +] + [[package]] name = "url" version = "2.5.4" @@ -6517,6 +7403,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "v_frame" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" @@ -6541,6 +7438,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.5" @@ -6710,6 +7613,15 @@ dependencies = [ "string_cache_codegen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d651ec480de84b762e7be71e6efa7461699c19d9e2c272c8d93455f567786e" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.26.10" @@ -6798,7 +7710,7 @@ checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ "windows-implement 0.60.0", "windows-interface 0.59.1", - "windows-link", + "windows-link 0.1.1", "windows-result 0.3.2", "windows-strings 0.4.0", ] @@ -6853,6 +7765,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-registry" version = "0.4.0" @@ -6861,7 +7779,7 @@ checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ "windows-result 0.3.2", "windows-strings 0.3.1", - "windows-targets 0.53.0", + "windows-targets 0.53.5", ] [[package]] @@ -6879,7 +7797,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -6888,7 +7806,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -6897,7 +7815,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" dependencies = [ - "windows-link", + "windows-link 0.1.1", ] [[package]] @@ -6918,6 +7836,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -6936,10 +7863,11 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.0" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ + "windows-link 0.2.1", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -7120,6 +8048,16 @@ dependencies = [ "tap", ] +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix", +] + [[package]] name = "xml-rs" version = "0.8.26" @@ -7277,3 +8215,27 @@ dependencies = [ "cc", "pkg-config", ] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" +dependencies = [ + "zune-core", +] diff --git a/Cargo.toml b/Cargo.toml index bdafa19..252bb93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,18 +56,56 @@ base64 = "0.22.1" object_store = { version = "0.11.2" } bytes = "1.7.1" state-machines = "0.2.0" +fastembed = "5.2.0" [profile.dist] inherits = "release" lto = "thin" [workspace.lints.clippy] -perf = { level = "warn", priority = -1 } -pedantic = { level = "warn", priority = -1 } -nursery = { level = "warn", priority = -1 } -cargo = { level = "warn", priority = -1 } +# Performance-focused lints +perf = { level = "warn", priority = -1 } +vec_init_then_push = "warn" +large_stack_frames = "warn" +redundant_allocation = "warn" +single_char_pattern = "warn" +string_extend_chars = "warn" +format_in_format_args = "warn" +slow_vector_initialization = "warn" +inefficient_to_string = "warn" +implicit_clone = "warn" +redundant_clone = "warn" -needless_question_mark = "allow" -single_call_fn = "allow" +# Security-focused lints +integer_arithmetic = "warn" +indexing_slicing = "warn" +unwrap_used = "warn" +expect_used = "warn" +panic = "warn" +unimplemented = "warn" +todo = "warn" + +# Async/Network lints +async_yields_async = "warn" +await_holding_invalid_state = "warn" +rc_buffer = "warn" + +# Maintainability-focused lints +cargo = { level = "warn", priority = -1 } +pedantic = { level = "warn", priority = -1 } +clone_on_ref_ptr = "warn" +float_cmp = "warn" +manual_string_new = "warn" +uninlined_format_args = "warn" +unused_self = "warn" must_use_candidate = "allow" missing_errors_doc = "allow" +missing_panics_doc = "warn" +module_name_repetitions = "warn" +wildcard_dependencies = "warn" +missing_docs_in_private_items = "warn" + +# Allow noisy lints that don't add value for this project +manual_must_use = "allow" +needless_raw_string_hashes = "allow" +multiple_bound_locations = "allow" diff --git a/README.md b/README.md index e393d4f..0634706 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,23 @@ The graph visualization shows: - Relationships as connections (manually defined, AI-discovered, or suggested) - Interactive navigation for discovery and editing +### Optional FastEmbed Reranking + +Minne ships with an opt-in reranking stage powered by [fastembed-rs](https://github.com/Anush008/fastembed-rs). When enabled, the hybrid retrieval results are rescored with a lightweight cross-encoder before being returned to chat or ingestion flows. In practice this often means more relevant results, boosting answer quality and downstream enrichment. + +⚠️ **Resource notes** +- Enabling reranking downloads and caches ~1.1 GB of model data on first startup (cached under `/fastembed/reranker` by default). +- Initialization takes longer while warming the cache, and each query consumes extra CPU. The default pool size (2) is tuned for a singe user setup, but could work with a pool size on 1 as well. +- The feature is disabled by default. Set `reranking_enabled: true` (or `RERANKING_ENABLED=true`) if you’re comfortable with the additional footprint. + +Example configuration: + +```yaml +reranking_enabled: true +reranking_pool_size: 2 +fastembed_cache_dir: "/var/lib/minne/fastembed" # optional override, defaults to .fastembed_cache +``` + ## Tech Stack - **Backend:** Rust with Axum framework and Server-Side Rendering (SSR) @@ -125,6 +142,10 @@ Minne can be configured using environment variables or a `config.yaml` file. Env - `RUST_LOG`: Controls logging level (e.g., `minne=info,tower_http=debug`) - `DATA_DIR`: Directory to store local data (e.g., `./data`) - `OPENAI_BASE_URL`: Base URL for custom AI providers (like Ollama) +- `RERANKING_ENABLED` / `reranking_enabled`: Set to `true` to enable the FastEmbed reranking stage (default `false`) +- `RERANKING_POOL_SIZE` / `reranking_pool_size`: Maximum concurrent reranker workers (defaults to `2`) +- `FASTEMBED_CACHE_DIR` / `fastembed_cache_dir`: Directory for cached FastEmbed models (defaults to `/fastembed/reranker`) +- `FASTEMBED_SHOW_DOWNLOAD_PROGRESS` / `fastembed_show_download_progress`: Show model download progress when warming the cache (default `true`) ### Example config.yaml diff --git a/common/src/storage/store.rs b/common/src/storage/store.rs index db0292f..c5a703e 100644 --- a/common/src/storage/store.rs +++ b/common/src/storage/store.rs @@ -214,6 +214,7 @@ mod tests { openai_base_url: "..".into(), storage: StorageKind::Local, pdf_ingest_mode: LlmFirst, + ..Default::default() } } diff --git a/common/src/storage/types/file_info.rs b/common/src/storage/types/file_info.rs index 62ef993..08c8075 100644 --- a/common/src/storage/types/file_info.rs +++ b/common/src/storage/types/file_info.rs @@ -270,12 +270,29 @@ impl FileInfo { #[cfg(test)] mod tests { use super::*; - use crate::utils::config::{PdfIngestMode::LlmFirst, StorageKind}; + use crate::utils::config::{AppConfig, PdfIngestMode::LlmFirst, StorageKind}; use axum::http::HeaderMap; use axum_typed_multipart::FieldMetadata; use std::io::Write; use tempfile::NamedTempFile; + fn test_config(data_dir: &str) -> AppConfig { + AppConfig { + data_dir: data_dir.to_string(), + openai_api_key: "test_key".to_string(), + surrealdb_address: "test_address".to_string(), + surrealdb_username: "test_user".to_string(), + surrealdb_password: "test_pass".to_string(), + surrealdb_namespace: "test_ns".to_string(), + surrealdb_database: "test_db".to_string(), + http_port: 3000, + openai_base_url: "..".to_string(), + storage: StorageKind::Local, + pdf_ingest_mode: LlmFirst, + ..Default::default() + } + } + /// Creates a test temporary file with the given content fn create_test_file(content: &[u8], file_name: &str) -> FieldData { let mut temp_file = NamedTempFile::new().expect("Failed to create temp file"); @@ -314,19 +331,7 @@ mod tests { // Create a FileInfo instance with data_dir in /tmp let user_id = "test_user"; - let config = AppConfig { - data_dir: "/tmp/minne_test_data".to_string(), // Using /tmp which is typically on a different filesystem - openai_api_key: "test_key".to_string(), - surrealdb_address: "test_address".to_string(), - surrealdb_username: "test_user".to_string(), - surrealdb_password: "test_pass".to_string(), - surrealdb_namespace: "test_ns".to_string(), - surrealdb_database: "test_db".to_string(), - http_port: 3000, - openai_base_url: "..".to_string(), - storage: StorageKind::Local, - pdf_ingest_mode: LlmFirst, - }; + let config = test_config("/tmp/minne_test_data"); // Test file creation let file_info = FileInfo::new(field_data, &db, user_id, &config) @@ -375,19 +380,7 @@ mod tests { // Create a FileInfo instance with data_dir in /tmp let user_id = "test_user"; - let config = AppConfig { - data_dir: "/tmp/minne_test_data".to_string(), - openai_api_key: "test_key".to_string(), - surrealdb_address: "test_address".to_string(), - surrealdb_username: "test_user".to_string(), - surrealdb_password: "test_pass".to_string(), - surrealdb_namespace: "test_ns".to_string(), - surrealdb_database: "test_db".to_string(), - http_port: 3000, - openai_base_url: "..".to_string(), - storage: StorageKind::Local, - pdf_ingest_mode: LlmFirst, - }; + let config = test_config("/tmp/minne_test_data"); // Store the original file let original_file_info = FileInfo::new(field_data, &db, user_id, &config) @@ -432,19 +425,7 @@ mod tests { // Create a FileInfo instance let user_id = "test_user"; - let config = AppConfig { - data_dir: "./data".to_string(), - openai_api_key: "test_key".to_string(), - surrealdb_address: "test_address".to_string(), - surrealdb_username: "test_user".to_string(), - surrealdb_password: "test_pass".to_string(), - surrealdb_namespace: "test_ns".to_string(), - surrealdb_database: "test_db".to_string(), - http_port: 3000, - openai_base_url: "..".to_string(), - storage: StorageKind::Local, - pdf_ingest_mode: LlmFirst, - }; + let config = test_config("./data"); let file_info = FileInfo::new(field_data, &db, user_id, &config).await; // We can't fully test persistence to disk in unit tests, @@ -490,19 +471,7 @@ mod tests { let file_name = "original.txt"; let user_id = "test_user"; - let config = AppConfig { - data_dir: "./data".to_string(), - openai_api_key: "test_key".to_string(), - surrealdb_address: "test_address".to_string(), - surrealdb_username: "test_user".to_string(), - surrealdb_password: "test_pass".to_string(), - surrealdb_namespace: "test_ns".to_string(), - surrealdb_database: "test_db".to_string(), - http_port: 3000, - openai_base_url: "..".to_string(), - storage: StorageKind::Local, - pdf_ingest_mode: LlmFirst, - }; + let config = test_config("./data"); let field_data1 = create_test_file(content, file_name); let original_file_info = FileInfo::new(field_data1, &db, user_id, &config) @@ -655,19 +624,7 @@ mod tests { // Create and persist a test file via FileInfo::new let user_id = "user123"; - let cfg = AppConfig { - data_dir: "./data".to_string(), - openai_api_key: "".to_string(), - surrealdb_address: "".to_string(), - surrealdb_username: "".to_string(), - surrealdb_password: "".to_string(), - surrealdb_namespace: "".to_string(), - surrealdb_database: "".to_string(), - http_port: 0, - openai_base_url: "".to_string(), - storage: crate::utils::config::StorageKind::Local, - pdf_ingest_mode: LlmFirst, - }; + let cfg = test_config("./data"); let temp = create_test_file(b"test content", "test_file.txt"); let file_info = FileInfo::new(temp, &db, user_id, &cfg) .await @@ -710,19 +667,7 @@ mod tests { let result = FileInfo::delete_by_id( "nonexistent_id", &db, - &AppConfig { - data_dir: "./data".to_string(), - openai_api_key: "".to_string(), - surrealdb_address: "".to_string(), - surrealdb_username: "".to_string(), - surrealdb_password: "".to_string(), - surrealdb_namespace: "".to_string(), - surrealdb_database: "".to_string(), - http_port: 0, - openai_base_url: "".to_string(), - storage: crate::utils::config::StorageKind::Local, - pdf_ingest_mode: LlmFirst, - }, + &test_config("./data"), ) .await; @@ -813,19 +758,7 @@ mod tests { // Create a FileInfo instance with a custom data directory let user_id = "test_user"; let custom_data_dir = "/tmp/minne_custom_data_dir"; - let config = AppConfig { - data_dir: custom_data_dir.to_string(), - openai_api_key: "test_key".to_string(), - surrealdb_address: "test_address".to_string(), - surrealdb_username: "test_user".to_string(), - surrealdb_password: "test_pass".to_string(), - surrealdb_namespace: "test_ns".to_string(), - surrealdb_database: "test_db".to_string(), - http_port: 3000, - openai_base_url: "..".to_string(), - storage: StorageKind::Local, - pdf_ingest_mode: LlmFirst, - }; + let config = test_config(custom_data_dir); // Test file creation let file_info = FileInfo::new(field_data, &db, user_id, &config) diff --git a/common/src/utils/config.rs b/common/src/utils/config.rs index 6b3dd65..51c21bf 100644 --- a/common/src/utils/config.rs +++ b/common/src/utils/config.rs @@ -42,6 +42,16 @@ pub struct AppConfig { pub storage: StorageKind, #[serde(default = "default_pdf_ingest_mode")] pub pdf_ingest_mode: PdfIngestMode, + #[serde(default = "default_reranking_enabled")] + pub reranking_enabled: bool, + #[serde(default)] + pub reranking_pool_size: Option, + #[serde(default)] + pub fastembed_cache_dir: Option, + #[serde(default)] + pub fastembed_show_download_progress: Option, + #[serde(default)] + pub fastembed_max_length: Option, } fn default_data_dir() -> String { @@ -52,6 +62,33 @@ fn default_base_url() -> String { "https://api.openai.com/v1".to_string() } +fn default_reranking_enabled() -> bool { + false +} + +impl Default for AppConfig { + fn default() -> Self { + Self { + openai_api_key: String::new(), + surrealdb_address: String::new(), + surrealdb_username: String::new(), + surrealdb_password: String::new(), + surrealdb_namespace: String::new(), + surrealdb_database: String::new(), + data_dir: default_data_dir(), + http_port: 0, + openai_base_url: default_base_url(), + storage: default_storage_kind(), + pdf_ingest_mode: default_pdf_ingest_mode(), + reranking_enabled: default_reranking_enabled(), + reranking_pool_size: None, + fastembed_cache_dir: None, + fastembed_show_download_progress: None, + fastembed_max_length: None, + } + } +} + pub fn get_config() -> Result { let config = Config::builder() .add_source(File::with_name("config").required(false)) diff --git a/composite-retrieval/Cargo.toml b/composite-retrieval/Cargo.toml index 8ec509c..1ef08a1 100644 --- a/composite-retrieval/Cargo.toml +++ b/composite-retrieval/Cargo.toml @@ -19,6 +19,7 @@ surrealdb = { workspace = true } futures = { workspace = true } async-openai = { workspace = true } uuid = { workspace = true } +fastembed = { workspace = true } common = { path = "../common", features = ["test-utils"] } state-machines = { workspace = true } diff --git a/composite-retrieval/src/answer_retrieval.rs b/composite-retrieval/src/answer_retrieval.rs index c8c9993..e0f0108 100644 --- a/composite-retrieval/src/answer_retrieval.rs +++ b/composite-retrieval/src/answer_retrieval.rs @@ -8,19 +8,14 @@ use async_openai::{ }; use common::{ error::AppError, - storage::{ - db::SurrealDbClient, - types::{ - message::{format_history, Message}, - system_settings::SystemSettings, - }, + storage::types::{ + message::{format_history, Message}, + system_settings::SystemSettings, }, }; use serde::Deserialize; use serde_json::Value; -use crate::{retrieve_entities, retrieved_entities_to_json}; - use super::answer_retrieval_helper::get_query_response_schema; #[derive(Debug, Deserialize)] @@ -36,53 +31,12 @@ pub struct LLMResponseFormat { pub references: Vec, } -/// Orchestrates query processing and returns an answer with references -/// -/// Takes a query and uses the provided clients to generate an answer with supporting references. -/// -/// # Arguments -/// -/// * `surreal_db_client` - Client for `SurrealDB` interactions -/// * `openai_client` - Client for `OpenAI` API calls -/// * `query` - The user's query string -/// * `user_id` - The user's id -/// -/// # Returns -/// -/// Returns a tuple of the answer and its references, or an API error #[derive(Debug)] pub struct Answer { pub content: String, pub references: Vec, } -pub async fn get_answer_with_references( - surreal_db_client: &SurrealDbClient, - openai_client: &async_openai::Client, - query: &str, - user_id: &str, -) -> Result { - let entities = retrieve_entities(surreal_db_client, openai_client, query, user_id).await?; - let settings = SystemSettings::get_current(surreal_db_client).await?; - - let entities_json = retrieved_entities_to_json(&entities); - let user_message = create_user_message(&entities_json, query); - - let request = create_chat_request(user_message, &settings)?; - let response = openai_client.chat().create(request).await?; - - let llm_response = process_llm_response(response).await?; - - Ok(Answer { - content: llm_response.answer, - references: llm_response - .references - .into_iter() - .map(|r| r.reference) - .collect(), - }) -} - pub fn create_user_message(entities_json: &Value, query: &str) -> String { format!( r" diff --git a/composite-retrieval/src/lib.rs b/composite-retrieval/src/lib.rs index 207d48a..cc2e8ab 100644 --- a/composite-retrieval/src/lib.rs +++ b/composite-retrieval/src/lib.rs @@ -3,6 +3,7 @@ pub mod answer_retrieval_helper; pub mod fts; pub mod graph; pub mod pipeline; +pub mod reranking; pub mod scoring; pub mod vector; @@ -13,6 +14,7 @@ use common::{ types::{knowledge_entity::KnowledgeEntity, text_chunk::TextChunk}, }, }; +use reranking::RerankerLease; use tracing::instrument; pub use pipeline::{retrieved_entities_to_json, RetrievalConfig, RetrievalTuning}; @@ -39,6 +41,7 @@ pub async fn retrieve_entities( openai_client: &async_openai::Client, input_text: &str, user_id: &str, + reranker: Option, ) -> Result, AppError> { pipeline::run_pipeline( db_client, @@ -46,6 +49,7 @@ pub async fn retrieve_entities( input_text, user_id, RetrievalConfig::default(), + reranker, ) .await } @@ -142,6 +146,7 @@ mod tests { "Rust concurrency async tasks", user_id, RetrievalConfig::default(), + None, ) .await .expect("Hybrid retrieval failed"); @@ -232,6 +237,7 @@ mod tests { "Rust concurrency async tasks", user_id, RetrievalConfig::default(), + None, ) .await .expect("Hybrid retrieval failed"); diff --git a/composite-retrieval/src/pipeline/config.rs b/composite-retrieval/src/pipeline/config.rs index d461440..71a964e 100644 --- a/composite-retrieval/src/pipeline/config.rs +++ b/composite-retrieval/src/pipeline/config.rs @@ -17,6 +17,9 @@ pub struct RetrievalTuning { pub graph_score_decay: f32, pub graph_seed_min_score: f32, pub graph_vector_inheritance: f32, + pub rerank_blend_weight: f32, + pub rerank_scores_only: bool, + pub rerank_keep_top: usize, } impl Default for RetrievalTuning { @@ -36,6 +39,9 @@ impl Default for RetrievalTuning { graph_score_decay: 0.75, graph_seed_min_score: 0.4, graph_vector_inheritance: 0.6, + rerank_blend_weight: 0.65, + rerank_scores_only: false, + rerank_keep_top: 8, } } } diff --git a/composite-retrieval/src/pipeline/mod.rs b/composite-retrieval/src/pipeline/mod.rs index 15fc3b3..a0023ef 100644 --- a/composite-retrieval/src/pipeline/mod.rs +++ b/composite-retrieval/src/pipeline/mod.rs @@ -4,7 +4,7 @@ mod state; pub use config::{RetrievalConfig, RetrievalTuning}; -use crate::RetrievedEntity; +use crate::{reranking::RerankerLease, RetrievedEntity}; use async_openai::Client; use common::{error::AppError, storage::db::SurrealDbClient}; use tracing::info; @@ -16,6 +16,7 @@ pub async fn run_pipeline( input_text: &str, user_id: &str, config: RetrievalConfig, + reranker: Option, ) -> Result, AppError> { let machine = state::ready(); let input_chars = input_text.chars().count(); @@ -35,11 +36,13 @@ pub async fn run_pipeline( input_text.to_owned(), user_id.to_owned(), config, + reranker, ); let machine = stages::embed(machine, &mut ctx).await?; let machine = stages::collect_candidates(machine, &mut ctx).await?; let machine = stages::expand_graph(machine, &mut ctx).await?; let machine = stages::attach_chunks(machine, &mut ctx).await?; + let machine = stages::rerank(machine, &mut ctx).await?; let results = stages::assemble(machine, &mut ctx)?; Ok(results) @@ -53,6 +56,7 @@ pub async fn run_pipeline_with_embedding( input_text: &str, user_id: &str, config: RetrievalConfig, + reranker: Option, ) -> Result, AppError> { let machine = state::ready(); let mut ctx = stages::PipelineContext::with_embedding( @@ -62,11 +66,13 @@ pub async fn run_pipeline_with_embedding( input_text.to_owned(), user_id.to_owned(), config, + reranker, ); let machine = stages::embed(machine, &mut ctx).await?; let machine = stages::collect_candidates(machine, &mut ctx).await?; let machine = stages::expand_graph(machine, &mut ctx).await?; let machine = stages::attach_chunks(machine, &mut ctx).await?; + let machine = stages::rerank(machine, &mut ctx).await?; let results = stages::assemble(machine, &mut ctx)?; Ok(results) diff --git a/composite-retrieval/src/pipeline/stages/mod.rs b/composite-retrieval/src/pipeline/stages/mod.rs index 3d33f26..1a8ebb9 100644 --- a/composite-retrieval/src/pipeline/stages/mod.rs +++ b/composite-retrieval/src/pipeline/stages/mod.rs @@ -7,6 +7,7 @@ use common::{ }, utils::embedding::generate_embedding, }; +use fastembed::RerankResult; use futures::{stream::FuturesUnordered, StreamExt}; use state_machines::core::GuardError; use std::collections::{HashMap, HashSet}; @@ -15,6 +16,7 @@ use tracing::{debug, instrument, warn}; use crate::{ fts::find_items_by_fts, graph::{find_entities_by_relationship_by_id, find_entities_by_source_ids}, + reranking::RerankerLease, scoring::{ clamp_unit, fuse_scores, merge_scored_by_id, min_max_normalize, sort_by_fused_desc, FusionWeights, Scored, @@ -27,6 +29,7 @@ use super::{ config::RetrievalConfig, state::{ CandidatesLoaded, ChunksAttached, Embedded, GraphExpanded, HybridRetrievalMachine, Ready, + Reranked, }, }; @@ -41,6 +44,7 @@ pub struct PipelineContext<'a> { pub chunk_candidates: HashMap>, pub filtered_entities: Vec>, pub chunk_values: Vec>, + pub reranker: Option, } impl<'a> PipelineContext<'a> { @@ -50,6 +54,7 @@ impl<'a> PipelineContext<'a> { input_text: String, user_id: String, config: RetrievalConfig, + reranker: Option, ) -> Self { Self { db_client, @@ -62,6 +67,7 @@ impl<'a> PipelineContext<'a> { chunk_candidates: HashMap::new(), filtered_entities: Vec::new(), chunk_values: Vec::new(), + reranker, } } @@ -73,8 +79,16 @@ impl<'a> PipelineContext<'a> { input_text: String, user_id: String, config: RetrievalConfig, + reranker: Option, ) -> Self { - let mut ctx = Self::new(db_client, openai_client, input_text, user_id, config); + let mut ctx = Self::new( + db_client, + openai_client, + input_text, + user_id, + config, + reranker, + ); ctx.query_embedding = Some(query_embedding); ctx } @@ -327,9 +341,58 @@ pub async fn attach_chunks( } #[instrument(level = "trace", skip_all)] -pub fn assemble( +pub async fn rerank( machine: HybridRetrievalMachine<(), ChunksAttached>, ctx: &mut PipelineContext<'_>, +) -> Result, AppError> { + let mut applied = false; + + if let Some(reranker) = ctx.reranker.as_ref() { + if ctx.filtered_entities.len() > 1 { + let documents = build_rerank_documents(ctx, ctx.config.tuning.max_chunks_per_entity); + + if documents.len() > 1 { + match reranker.rerank(&ctx.input_text, documents).await { + Ok(results) if !results.is_empty() => { + apply_rerank_results(ctx, results); + applied = true; + } + Ok(_) => { + debug!("Reranker returned no results; retaining original ordering"); + } + Err(err) => { + warn!( + error = %err, + "Reranking failed; continuing with original ordering" + ); + } + } + } else { + debug!( + document_count = documents.len(), + "Skipping reranking stage; insufficient document context" + ); + } + } else { + debug!("Skipping reranking stage; less than two entities available"); + } + } else { + debug!("No reranker lease provided; skipping reranking stage"); + } + + if applied { + debug!("Applied reranking adjustments to candidate ordering"); + } + + machine + .rerank() + .map_err(|(_, guard)| map_guard_error("rerank", guard)) +} + +#[instrument(level = "trace", skip_all)] +pub fn assemble( + machine: HybridRetrievalMachine<(), Reranked>, + ctx: &mut PipelineContext<'_>, ) -> Result, AppError> { debug!("Assembling final retrieved entities"); let tuning = &ctx.config.tuning; @@ -561,6 +624,113 @@ async fn enrich_chunks_from_entities( Ok(()) } +fn build_rerank_documents(ctx: &PipelineContext<'_>, max_chunks_per_entity: usize) -> Vec { + if ctx.filtered_entities.is_empty() { + return Vec::new(); + } + + let mut chunk_by_source: HashMap<&str, Vec<&Scored>> = HashMap::new(); + for chunk in &ctx.chunk_values { + chunk_by_source + .entry(chunk.item.source_id.as_str()) + .or_default() + .push(chunk); + } + + ctx.filtered_entities + .iter() + .map(|entity| { + let mut doc = format!( + "Name: {}\nType: {:?}\nDescription: {}\n", + entity.item.name, entity.item.entity_type, entity.item.description + ); + + if let Some(chunks) = chunk_by_source.get(entity.item.source_id.as_str()) { + let mut chunk_refs = chunks.clone(); + chunk_refs.sort_by(|a, b| { + b.fused + .partial_cmp(&a.fused) + .unwrap_or(std::cmp::Ordering::Equal) + }); + + let mut header_added = false; + for chunk in chunk_refs.into_iter().take(max_chunks_per_entity.max(1)) { + let snippet = chunk.item.chunk.trim(); + if snippet.is_empty() { + continue; + } + if !header_added { + doc.push_str("Chunks:\n"); + header_added = true; + } + doc.push_str("- "); + doc.push_str(snippet); + doc.push('\n'); + } + } + + doc + }) + .collect() +} + +fn apply_rerank_results(ctx: &mut PipelineContext<'_>, results: Vec) { + if results.is_empty() || ctx.filtered_entities.is_empty() { + return; + } + + let mut remaining: Vec>> = + std::mem::take(&mut ctx.filtered_entities) + .into_iter() + .map(Some) + .collect(); + + let raw_scores: Vec = results.iter().map(|r| r.score).collect(); + let normalized_scores = min_max_normalize(&raw_scores); + + let use_only = ctx.config.tuning.rerank_scores_only; + let blend = if use_only { + 1.0 + } else { + clamp_unit(ctx.config.tuning.rerank_blend_weight) + }; + let mut reranked: Vec> = Vec::with_capacity(remaining.len()); + for (result, normalized) in results.into_iter().zip(normalized_scores.into_iter()) { + if let Some(slot) = remaining.get_mut(result.index) { + if let Some(mut candidate) = slot.take() { + let original = candidate.fused; + let blended = if use_only { + clamp_unit(normalized) + } else { + clamp_unit(original * (1.0 - blend) + normalized * blend) + }; + candidate.update_fused(blended); + reranked.push(candidate); + } + } else { + warn!( + result_index = result.index, + "Reranker returned out-of-range index; skipping" + ); + } + if reranked.len() == remaining.len() { + break; + } + } + + for slot in remaining.into_iter() { + if let Some(candidate) = slot { + reranked.push(candidate); + } + } + + ctx.filtered_entities = reranked; + let keep_top = ctx.config.tuning.rerank_keep_top; + if keep_top > 0 && ctx.filtered_entities.len() > keep_top { + ctx.filtered_entities.truncate(keep_top); + } +} + fn estimate_tokens(text: &str, avg_chars_per_token: usize) -> usize { let chars = text.chars().count().max(1); (chars / avg_chars_per_token).max(1) diff --git a/composite-retrieval/src/pipeline/state.rs b/composite-retrieval/src/pipeline/state.rs index fb605c8..91d3803 100644 --- a/composite-retrieval/src/pipeline/state.rs +++ b/composite-retrieval/src/pipeline/state.rs @@ -4,18 +4,20 @@ state_machine! { name: HybridRetrievalMachine, state: HybridRetrievalState, initial: Ready, - states: [Ready, Embedded, CandidatesLoaded, GraphExpanded, ChunksAttached, Completed, Failed], + states: [Ready, Embedded, CandidatesLoaded, GraphExpanded, ChunksAttached, Reranked, Completed, Failed], events { embed { transition: { from: Ready, to: Embedded } } collect_candidates { transition: { from: Embedded, to: CandidatesLoaded } } expand_graph { transition: { from: CandidatesLoaded, to: GraphExpanded } } attach_chunks { transition: { from: GraphExpanded, to: ChunksAttached } } - assemble { transition: { from: ChunksAttached, to: Completed } } + rerank { transition: { from: ChunksAttached, to: Reranked } } + assemble { transition: { from: Reranked, to: Completed } } abort { transition: { from: Ready, to: Failed } transition: { from: CandidatesLoaded, to: Failed } transition: { from: GraphExpanded, to: Failed } transition: { from: ChunksAttached, to: Failed } + transition: { from: Reranked, to: Failed } } } } diff --git a/composite-retrieval/src/reranking/mod.rs b/composite-retrieval/src/reranking/mod.rs new file mode 100644 index 0000000..c7ae22b --- /dev/null +++ b/composite-retrieval/src/reranking/mod.rs @@ -0,0 +1,170 @@ +use std::{ + env, fs, + path::{Path, PathBuf}, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, + thread::available_parallelism, +}; + +use common::{error::AppError, utils::config::AppConfig}; +use fastembed::{RerankInitOptions, RerankResult, TextRerank}; +use tokio::sync::{Mutex, OwnedSemaphorePermit, Semaphore}; +use tracing::debug; + +static NEXT_ENGINE: AtomicUsize = AtomicUsize::new(0); + +fn pick_engine_index(pool_len: usize) -> usize { + let n = NEXT_ENGINE.fetch_add(1, Ordering::Relaxed); + n % pool_len +} + +pub struct RerankerPool { + engines: Vec>>, + semaphore: Arc, +} + +impl RerankerPool { + /// Build the pool at startup. + /// `pool_size` controls max parallel reranks. + pub fn new(pool_size: usize) -> Result, AppError> { + Self::new_with_options(pool_size, RerankInitOptions::default()) + } + + fn new_with_options( + pool_size: usize, + init_options: RerankInitOptions, + ) -> Result, AppError> { + if pool_size == 0 { + return Err(AppError::Validation( + "RERANKING_POOL_SIZE must be greater than zero".to_string(), + )); + } + + fs::create_dir_all(&init_options.cache_dir)?; + + let mut engines = Vec::with_capacity(pool_size); + for x in 0..pool_size { + debug!("Creating reranking engine: {x}"); + let model = TextRerank::try_new(init_options.clone()) + .map_err(|e| AppError::InternalError(e.to_string()))?; + engines.push(Arc::new(Mutex::new(model))); + } + + Ok(Arc::new(Self { + engines, + semaphore: Arc::new(Semaphore::new(pool_size)), + })) + } + + /// Initialize a pool using application configuration. + pub fn maybe_from_config(config: &AppConfig) -> Result>, AppError> { + if !config.reranking_enabled { + return Ok(None); + } + + let pool_size = config.reranking_pool_size.unwrap_or_else(default_pool_size); + + let init_options = build_rerank_init_options(config)?; + Self::new_with_options(pool_size, init_options).map(Some) + } + + /// Check out capacity + pick an engine. + /// This returns a lease that can perform rerank(). + pub async fn checkout(self: &Arc) -> RerankerLease { + // Acquire a permit. This enforces backpressure. + let permit = self + .semaphore + .clone() + .acquire_owned() + .await + .expect("semaphore closed"); + + // Pick an engine. + // This is naive: just pick based on a simple modulo counter. + // We use an atomic counter to avoid always choosing index 0. + let idx = pick_engine_index(self.engines.len()); + let engine = self.engines[idx].clone(); + + RerankerLease { + _permit: permit, + engine, + } + } +} + +fn default_pool_size() -> usize { + available_parallelism() + .map(|value| value.get().min(2)) + .unwrap_or(2) + .max(1) +} + +fn is_truthy(value: &str) -> bool { + matches!( + value.trim().to_ascii_lowercase().as_str(), + "1" | "true" | "yes" | "on" + ) +} + +fn build_rerank_init_options(config: &AppConfig) -> Result { + let mut options = RerankInitOptions::default(); + + let cache_dir = config + .fastembed_cache_dir + .as_ref() + .map(PathBuf::from) + .or_else(|| env::var("RERANKING_CACHE_DIR").ok().map(PathBuf::from)) + .or_else(|| env::var("FASTEMBED_CACHE_DIR").ok().map(PathBuf::from)) + .unwrap_or_else(|| { + Path::new(&config.data_dir) + .join("fastembed") + .join("reranker") + }); + fs::create_dir_all(&cache_dir)?; + options.cache_dir = cache_dir; + + let show_progress = config + .fastembed_show_download_progress + .or_else(|| env_bool("RERANKING_SHOW_DOWNLOAD_PROGRESS")) + .or_else(|| env_bool("FASTEMBED_SHOW_DOWNLOAD_PROGRESS")) + .unwrap_or(true); + options.show_download_progress = show_progress; + + if let Some(max_length) = config.fastembed_max_length.or_else(|| { + env::var("RERANKING_MAX_LENGTH") + .ok() + .and_then(|value| value.parse().ok()) + }) { + options.max_length = max_length; + } + + Ok(options) +} + +fn env_bool(key: &str) -> Option { + env::var(key).ok().map(|value| is_truthy(&value)) +} + +/// Active lease on a single TextRerank instance. +pub struct RerankerLease { + // When this drops the semaphore permit is released. + _permit: OwnedSemaphorePermit, + engine: Arc>, +} + +impl RerankerLease { + pub async fn rerank( + &self, + query: &str, + documents: Vec, + ) -> Result, AppError> { + // Lock this specific engine so we get &mut TextRerank + let mut guard = self.engine.lock().await; + + guard + .rerank(query.to_owned(), documents, false, None) + .map_err(|e| AppError::InternalError(e.to_string())) + } +} diff --git a/html-router/assets/style.css b/html-router/assets/style.css index ab970d0..875ae05 100644 --- a/html-router/assets/style.css +++ b/html-router/assets/style.css @@ -1,2 +1,2 @@ /*! tailwindcss v4.1.2 | MIT License | https://tailwindcss.com */ -@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:rotateX(0);--tw-rotate-y:rotateY(0);--tw-rotate-z:rotateZ(0);--tw-skew-x:skewX(0);--tw-skew-y:skewY(0);--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-yellow-300:oklch(90.5% .182 98.111);--color-gray-200:oklch(92.8% .006 264.531);--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-3xl:48rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-snug:1.375;--leading-relaxed:1.625;--ease-out:cubic-bezier(0,0,.2,1);--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{--nb-shadow:4px 4px 0 0 #000;--nb-shadow-hover:6px 6px 0 0 #000}[data-theme=light]{color-scheme:light;--color-base-100:oklch(98.42% .012 96.42);--color-base-200:oklch(94.52% .0122 96.43);--color-base-300:oklch(90.96% .0125 91.53);--color-base-content:oklch(17.76% 0 89.88);--color-primary:oklch(20.77% .0398 265.75);--color-primary-content:oklch(100% 0 89.88);--color-secondary:oklch(54.61% .2152 262.88);--color-secondary-content:oklch(100% 0 89.88);--color-accent:oklch(72% .19 80);--color-accent-content:oklch(21% .035 80);--color-neutral:oklch(17.76% 0 89.88);--color-neutral-content:oklch(96.99% .0013 106.42);--color-info:oklch(60.89% .1109 221.72);--color-info-content:oklch(96.99% .0013 106.42);--color-success:oklch(62.71% .1699 149.21);--color-success-content:oklch(96.99% .0013 106.42);--color-warning:oklch(79.52% .1617 86.05);--color-warning-content:oklch(17.76% 0 89.88);--color-error:oklch(57.71% .2152 27.33);--color-error-content:oklch(96.99% .0013 106.42);--radius-selector:0rem;--radius-field:0rem;--radius-box:0rem;--size-selector:.25rem;--size-field:.25rem;--border:2px}[data-theme=dark]{color-scheme:dark;--color-base-100:oklch(22% .015 255);--color-base-200:oklch(18% .014 253);--color-base-300:oklch(14% .012 251);--color-base-content:oklch(97.2% .02 255);--color-primary:oklch(58% .233 277.12);--color-primary-content:oklch(96% .018 272.31);--color-secondary:oklch(65% .241 354.31);--color-secondary-content:oklch(94% .028 342.26);--color-accent:oklch(78% .22 80);--color-accent-content:oklch(20% .035 80);--color-neutral:oklch(26% .02 255);--color-neutral-content:oklch(97% .03 255);--color-info:oklch(74% .16 232.66);--color-info-content:oklch(29% .066 243.16);--color-success:oklch(76% .177 163.22);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.43);--color-warning-content:oklch(41% .112 45.9);--color-error:oklch(71% .194 13.43);--color-error-content:oklch(27% .105 12.09);--radius-selector:0rem;--radius-field:0rem;--radius-box:0rem;--size-selector:.25rem;--size-field:.25rem;--border:2px}body{background-color:var(--color-base-100);color:var(--color-base-content);-webkit-font-smoothing:antialiased;font-family:Satoshi,sans-serif}body ::selection{background-color:#ffe02a66}@supports (color:color-mix(in lab, red, red)){body ::selection{background-color:color-mix(in oklab,var(--color-yellow-300)40%,transparent)}}body::selection{background-color:#ffe02a66}@supports (color:color-mix(in lab, red, red)){body::selection{background-color:color-mix(in oklab,var(--color-yellow-300)40%,transparent)}}body ::selection{color:var(--color-neutral)}body::selection{color:var(--color-neutral)}html{scrollbar-gutter:stable}*,:after,:before,::backdrop{border-color:var(--color-gray-200,currentColor)}::file-selector-button{border-color:var(--color-gray-200,currentColor)}.container{padding-inline:10px}@media (min-width:640px){.container{padding-inline:2rem}}@media (min-width:1024px){.container{padding-inline:4rem}}@media (min-width:1280px){.container{padding-inline:5rem}}@media (min-width:1536px){.container{padding-inline:6rem}}.custom-scrollbar{scrollbar-width:thin;scrollbar-color:#0003 transparent}.custom-scrollbar::-webkit-scrollbar{width:4px}.custom-scrollbar::-webkit-scrollbar-track{background:0 0}.custom-scrollbar::-webkit-scrollbar-thumb{background-color:#0003;border-radius:3px}.hide-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.hide-scrollbar::-webkit-scrollbar{display:none}form.htmx-request{opacity:.5}[data-theme=dark] .nb-input::placeholder,[data-theme=dark] .input::placeholder,[data-theme=dark] .textarea::placeholder,[data-theme=dark] textarea::placeholder,[data-theme=dark] input::placeholder{opacity:.85;color:#ffffffc7!important}@property --radialprogress{syntax: ""; inherits: true; initial-value: 0%;}:root{scrollbar-color:currentColor #0000}@supports (color:color-mix(in lab, red, red)){:root{scrollbar-color:color-mix(in oklch,currentColor 35%,#0000)#0000}}:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not([class*=drawer-open])>.drawer-toggle:checked){overflow:hidden}:root,[data-theme]{background-color:var(--root-bg,var(--color-base-100));color:var(--color-base-content)}:root{--fx-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E")}.chat{--mask-chat:url("data:image/svg+xml,%3csvg width='13' height='13' xmlns='http://www.w3.org/2000/svg'%3e%3cpath fill='black' d='M0 11.5004C0 13.0004 2 13.0004 2 13.0004H12H13V0.00036329L12.5 0C12.5 0 11.977 2.09572 11.8581 2.50033C11.6075 3.35237 10.9149 4.22374 9 5.50036C6 7.50036 0 10.0004 0 11.5004Z'/%3e%3c/svg%3e")}}@layer components{.nb-shadow{box-shadow:var(--nb-shadow);transition:transform .15s,box-shadow .15s}.nb-shadow-hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-card{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding:calc(var(--spacing)*4);box-shadow:var(--nb-shadow);transition:transform .15s,box-shadow .15s}.nb-card:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-panel{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--nb-panel-bg,var(--color-base-200));box-shadow:var(--nb-shadow);transition:transform .15s,box-shadow .15s}.nb-panel:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-panel-canvas{--nb-panel-bg:var(--color-base-100)}.nb-canvas{background-color:var(--color-base-100)}.nb-btn{cursor:pointer;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--color-base-content);--tw-prose-links:var(--btn-fg);height:var(--size);font-size:var(--fontsize,.875rem);outline-color:var(--btn-color,var(--color-base-content));background-color:var(--btn-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--btn-noise);border-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0/calc(var(--depth)*.15));box-shadow:0 .5px 0 .5px oklch(100% 0 0/calc(var(--depth)*6%))inset,var(--btn-shadow);--size:calc(var(--size-field,.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-p:1rem;--btn-border:var(--btn-bg);--btn-shadow:0 3px 2px -2px var(--btn-bg),0 4px 3px -2px var(--btn-bg);--btn-noise:none;border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);--btn-color:var(--color-base-100);box-shadow:var(--nb-shadow);background-image:none;border-radius:0;flex-wrap:nowrap;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;font-weight:600;transition:transform .15s,box-shadow .15s;display:inline-flex}:where(.nb-btn){width:unset}@supports (color:color-mix(in lab, red, red)){.nb-btn{--btn-border:color-mix(in oklab,var(--btn-bg),#000 calc(var(--depth)*5%));--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000)}}.prose .nb-btn{text-decoration-line:none}@media (hover:hover){.nb-btn:hover{--btn-bg:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab, red, red)){.nb-btn:hover{--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}}.nb-btn:focus-visible{outline-width:2px;outline-style:solid}.nb-btn:active:not(.btn-active){--btn-bg:var(--btn-color,var(--color-base-200));--btn-border:var(--btn-color,var(--color-base-200));--btn-shadow:0 0 0 0 oklch(0% 0 0/0),0 0 0 0 oklch(0% 0 0/0);translate:0 .5px}@supports (color:color-mix(in lab, red, red)){.nb-btn:active:not(.btn-active){--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 5%);--btn-border:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}.nb-btn:is(:disabled,[disabled],.btn-disabled){pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}.nb-btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in srgb,var(--color-base-content)10%,transparent);box-shadow:none}@supports (color:color-mix(in lab, red, red)){.nb-btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}.nb-btn:is(:disabled,[disabled],.btn-disabled){--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}@media (hover:hover){.nb-btn:is(:disabled,[disabled],.btn-disabled):hover{pointer-events:none;background-color:color-mix(in srgb,var(--color-neutral)20%,transparent);--btn-border:#0000;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}@supports (color:color-mix(in lab, red, red)){.nb-btn:is(:disabled,[disabled],.btn-disabled):hover{background-color:color-mix(in oklab,var(--color-neutral)20%,transparent);--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}}.nb-btn:is(input[type=checkbox],input[type=radio]){appearance:none}.nb-btn:is(input[type=checkbox],input[type=radio]):after{content:attr(aria-label)}.nb-btn:where(input:checked:not(.filter .btn)){--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content);isolation:isolate}.nb-btn:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-link{text-decoration-line:underline;-webkit-text-decoration-color:var(--color-neutral);-webkit-text-decoration-color:var(--color-neutral);text-decoration-color:var(--color-neutral);text-underline-offset:2px}@media (hover:hover){.nb-link:hover{text-decoration-thickness:4px}}.nb-stat{gap:calc(var(--spacing)*1);border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding:calc(var(--spacing)*5);box-shadow:var(--nb-shadow);flex-direction:column;transition:transform .15s,box-shadow .15s;display:flex}.u-hairline{border-top-style:var(--tw-border-style);border-top-width:1px;border-color:color-mix(in srgb,var(--color-neutral)20%,transparent)}@supports (color:color-mix(in lab, red, red)){.u-hairline{border-color:color-mix(in oklab,var(--color-neutral)20%,transparent)}}.prose-tufte{color:var(--tw-prose-body);--tw-prose-body:oklch(37.1% 0 0);--tw-prose-headings:oklch(20.5% 0 0);--tw-prose-lead:oklch(43.9% 0 0);--tw-prose-links:oklch(20.5% 0 0);--tw-prose-bold:oklch(20.5% 0 0);--tw-prose-counters:oklch(55.6% 0 0);--tw-prose-bullets:oklch(87% 0 0);--tw-prose-hr:oklch(92.2% 0 0);--tw-prose-quotes:oklch(20.5% 0 0);--tw-prose-quote-borders:oklch(92.2% 0 0);--tw-prose-captions:oklch(55.6% 0 0);--tw-prose-kbd:oklch(20.5% 0 0);--tw-prose-kbd-shadows:NaN NaN NaN;--tw-prose-code:oklch(20.5% 0 0);--tw-prose-pre-code:oklch(92.2% 0 0);--tw-prose-pre-bg:oklch(26.9% 0 0);--tw-prose-th-borders:oklch(87% 0 0);--tw-prose-td-borders:oklch(92.2% 0 0);--tw-prose-invert-body:oklch(87% 0 0);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.8% 0 0);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.8% 0 0);--tw-prose-invert-bullets:oklch(43.9% 0 0);--tw-prose-invert-hr:oklch(37.1% 0 0);--tw-prose-invert-quotes:oklch(97% 0 0);--tw-prose-invert-quote-borders:oklch(37.1% 0 0);--tw-prose-invert-captions:oklch(70.8% 0 0);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87% 0 0);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(43.9% 0 0);--tw-prose-invert-td-borders:oklch(37.1% 0 0);max-width:min(90ch,100%);font-size:1rem;line-height:1.7}.prose-tufte :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-tufte :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose-tufte :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose-tufte :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose-tufte :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose-tufte :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose-tufte :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose-tufte :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose-tufte :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose-tufte :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose-tufte :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose-tufte :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose-tufte :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose-tufte :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose-tufte :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose-tufte :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose-tufte :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose-tufte :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose-tufte :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose-tufte :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose-tufte :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose-tufte :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose-tufte :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose-tufte :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose-tufte :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose-tufte :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose-tufte :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose-tufte :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose-tufte :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose-tufte :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose-tufte :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose-tufte :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px 0 rgb(var(--tw-prose-kbd-shadows)/10%);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose-tufte :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose-tufte :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose-tufte :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose-tufte :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose-tufte :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose-tufte :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose-tufte :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose-tufte :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose-tufte :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose-tufte :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose-tufte :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose-tufte :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose-tufte :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose-tufte :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose-tufte :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose-tufte :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose-tufte :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose-tufte :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose-tufte :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-tufte :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose-tufte :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-tufte :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose-tufte :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-tufte :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-tufte :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-tufte :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-tufte :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-tufte :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-tufte :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-tufte :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-tufte :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose-tufte :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-tufte :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-tufte :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-tufte :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose-tufte :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-tufte :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-tufte :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-tufte :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-tufte-compact{color:var(--tw-prose-body);--tw-prose-body:oklch(37.1% 0 0);--tw-prose-headings:oklch(20.5% 0 0);--tw-prose-lead:oklch(43.9% 0 0);--tw-prose-links:oklch(20.5% 0 0);--tw-prose-bold:oklch(20.5% 0 0);--tw-prose-counters:oklch(55.6% 0 0);--tw-prose-bullets:oklch(87% 0 0);--tw-prose-hr:oklch(92.2% 0 0);--tw-prose-quotes:oklch(20.5% 0 0);--tw-prose-quote-borders:oklch(92.2% 0 0);--tw-prose-captions:oklch(55.6% 0 0);--tw-prose-kbd:oklch(20.5% 0 0);--tw-prose-kbd-shadows:NaN NaN NaN;--tw-prose-code:oklch(20.5% 0 0);--tw-prose-pre-code:oklch(92.2% 0 0);--tw-prose-pre-bg:oklch(26.9% 0 0);--tw-prose-th-borders:oklch(87% 0 0);--tw-prose-td-borders:oklch(92.2% 0 0);--tw-prose-invert-body:oklch(87% 0 0);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.8% 0 0);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.8% 0 0);--tw-prose-invert-bullets:oklch(43.9% 0 0);--tw-prose-invert-hr:oklch(37.1% 0 0);--tw-prose-invert-quotes:oklch(97% 0 0);--tw-prose-invert-quote-borders:oklch(37.1% 0 0);--tw-prose-invert-captions:oklch(70.8% 0 0);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87% 0 0);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(43.9% 0 0);--tw-prose-invert-td-borders:oklch(37.1% 0 0);max-width:min(90ch,100%);font-size:.875rem;line-height:1.6}.prose-tufte-compact :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-tufte-compact :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose-tufte-compact :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose-tufte-compact :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose-tufte-compact :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte-compact :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose-tufte-compact :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose-tufte-compact :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose-tufte-compact :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose-tufte-compact :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose-tufte-compact :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose-tufte-compact :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose-tufte-compact :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose-tufte-compact :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose-tufte-compact :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose-tufte-compact :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose-tufte-compact :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose-tufte-compact :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose-tufte-compact :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose-tufte-compact :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose-tufte-compact :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose-tufte-compact :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose-tufte-compact :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose-tufte-compact :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose-tufte-compact :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose-tufte-compact :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose-tufte-compact :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose-tufte-compact :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose-tufte-compact :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose-tufte-compact :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose-tufte-compact :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose-tufte-compact :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte-compact :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose-tufte-compact :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte-compact :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px 0 rgb(var(--tw-prose-kbd-shadows)/10%);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose-tufte-compact :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose-tufte-compact :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose-tufte-compact :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose-tufte-compact :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte-compact :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose-tufte-compact :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose-tufte-compact :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte-compact :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose-tufte-compact :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose-tufte-compact :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose-tufte-compact :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose-tufte-compact :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose-tufte-compact :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose-tufte-compact :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose-tufte-compact :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose-tufte-compact :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose-tufte-compact :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose-tufte-compact :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose-tufte-compact :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose-tufte-compact :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose-tufte-compact :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-tufte-compact :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose-tufte-compact :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-tufte-compact :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose-tufte-compact :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-tufte-compact :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-tufte-compact :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-tufte-compact :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-tufte-compact :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-tufte-compact :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-tufte-compact :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-tufte-compact :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-tufte-compact :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose-tufte-compact :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-tufte-compact :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-tufte-compact :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-tufte-compact :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose-tufte-compact :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-tufte-compact :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-tufte-compact :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte-compact :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-tufte-compact :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}[data-theme=dark] .prose-tufte,[data-theme=dark] .prose-tufte-compact{color:var(--color-base-content);--tw-prose-body:var(--color-base-content);--tw-prose-headings:var(--color-base-content);--tw-prose-lead:#ffffffc7;--tw-prose-links:var(--color-accent);--tw-prose-bold:var(--color-base-content);--tw-prose-counters:#ffffffb3;--tw-prose-bullets:#ffffff59;--tw-prose-hr:#fff3;--tw-prose-quotes:var(--color-base-content);--tw-prose-quote-borders:#ffffff40;--tw-prose-captions:#ffffffa6;--tw-prose-code:var(--color-base-content);--tw-prose-pre-code:inherit;--tw-prose-pre-bg:#ffffff12;--tw-prose-th-borders:#ffffff40;--tw-prose-td-borders:#fff3}[data-theme=dark] .prose-tufte a,[data-theme=dark] .prose-tufte-compact a{color:var(--color-accent)}.card{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);box-shadow:var(--nb-shadow);border-radius:0;transition:transform .15s,box-shadow .15s}.card:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-input{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding-inline:calc(var(--spacing)*3);color:var(--color-base-content);box-shadow:var(--nb-shadow);border-radius:0;padding-block:.5rem;transition:transform .15s,box-shadow .15s,border-color .15s}.nb-input::placeholder{color:color-mix(in srgb,var(--color-base-content)60%,transparent)}@supports (color:color-mix(in lab, red, red)){.nb-input::placeholder{color:color-mix(in oklab,var(--color-base-content)60%,transparent)}}.nb-input:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-input:focus{box-shadow:var(--nb-shadow-hover);outline:none}.nb-select{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding-inline:calc(var(--spacing)*3);color:var(--color-base-content);box-shadow:var(--nb-shadow);border-radius:0;padding-block:.5rem;transition:transform .15s,box-shadow .15s,border-color .15s}.nb-select:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-select:focus{box-shadow:var(--nb-shadow-hover);outline:none}.nb-input-sm,.nb-select-sm{padding-inline:calc(var(--spacing)*2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));padding-block:.25rem}.nb-cta{--btn-color:var(--color-accent);--btn-fg:var(--color-accent-content);--btn-noise:none;background-image:none;background-color:var(--color-accent);color:var(--color-accent-content)}.nb-cta:hover{background-color:var(--color-accent);color:var(--color-accent-content);filter:saturate(1.1)brightness(1.05)}.nb-badge{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding-inline:calc(var(--spacing)*2);padding-block:calc(var(--spacing)*.5);--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide);text-transform:uppercase;border-radius:0;align-items:center;font-size:10px;display:inline-flex;box-shadow:3px 3px #000}.nb-masonry{column-count:1;column-gap:1rem}.nb-masonry>*{break-inside:avoid;display:block}@media (min-width:768px){.nb-masonry{column-count:2}}@media (min-width:1536px){.nb-masonry{column-count:3}}.chat .chat-bubble{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);color:var(--color-neutral);box-shadow:var(--nb-shadow);border-radius:0;transition:transform .15s,box-shadow .15s}.chat .chat-bubble:before,.chat .chat-bubble:after{content:none!important;display:none!important}.chat.chat-start .chat-bubble{background-color:var(--color-secondary);color:var(--color-secondary-content)}.chat.chat-end .chat-bubble{background-color:var(--color-base-100);color:var(--color-neutral)}.nb-table{border-collapse:separate;border-spacing:0;width:100%}.nb-table thead th{border-bottom-style:var(--tw-border-style);border-bottom-width:2px;border-color:var(--color-neutral);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide);text-transform:uppercase}.nb-table th,.nb-table td{padding:calc(var(--spacing)*3)}.nb-table tbody tr+tr td{border-top-style:var(--tw-border-style);border-top-width:1px;border-color:color-mix(in srgb,var(--color-neutral)30%,transparent)}@supports (color:color-mix(in lab, red, red)){.nb-table tbody tr+tr td{border-color:color-mix(in oklab,var(--color-neutral)30%,transparent)}}.nb-table tbody tr:hover{background-color:color-mix(in srgb,var(--color-base-200)40%,transparent)}@supports (color:color-mix(in lab, red, red)){.nb-table tbody tr:hover{background-color:color-mix(in oklab,var(--color-base-200)40%,transparent)}}.nb-table tbody tr:hover td:first-child{box-shadow:inset 3px 0 #000}.kg-overlay{top:calc(var(--spacing)*4);right:calc(var(--spacing)*4);left:calc(var(--spacing)*4);z-index:10;align-items:stretch;gap:calc(var(--spacing)*2);flex-direction:column;max-width:min(420px,100% - 2rem);display:flex;position:absolute}.kg-control-row{align-items:center;gap:calc(var(--spacing)*2);flex-wrap:wrap;display:flex}.kg-control-row-primary{justify-content:flex-start}.kg-control-row-secondary{justify-content:center}.kg-search-input{padding-left:calc(var(--spacing)*2);width:100%;min-width:0;max-width:320px;height:2rem}.kg-control-row-primary .kg-search-input{flex:auto}.kg-search-btn{flex:none}.kg-toggle{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.kg-toggle-active{--btn-color:var(--color-accent);--btn-fg:var(--color-accent-content);--btn-noise:none;background-image:none;background-color:var(--color-accent);color:var(--color-accent-content)}.kg-toggle-active:hover{background-color:var(--color-accent);color:var(--color-accent-content);filter:saturate(1.1)brightness(1.05)}@media (min-width:768px){.kg-overlay{width:auto;max-width:none;right:auto}}.kg-legend{bottom:calc(var(--spacing)*2);left:calc(var(--spacing)*2);z-index:10;gap:calc(var(--spacing)*4);flex-wrap:wrap;display:flex;position:absolute}.kg-legend-card{padding:calc(var(--spacing)*2)}.kg-legend-heading{margin-bottom:calc(var(--spacing)*1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));opacity:.7}.kg-legend-row{align-items:center;gap:calc(var(--spacing)*2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));display:flex}.nb-checkbox{appearance:none;border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);vertical-align:middle;width:1rem;height:1rem;box-shadow:var(--nb-shadow);cursor:pointer;background-position:50%;background-repeat:no-repeat;background-size:80% 80%;border-radius:0;transition:transform .15s,box-shadow .15s,border-color .15s,background-color .15s;display:inline-block}.nb-checkbox:hover{transform:translate(-1px,-1px);box-shadow:5px 5px #000}.nb-checkbox:focus-visible{outline-offset:2px;outline:2px solid #000}.nb-checkbox:active{transform:translate(0);box-shadow:3px 3px #000}.nb-checkbox:checked{background-image:url("data:image/svg+xml;utf8,")}[data-theme=dark] .nb-checkbox:checked{background-image:url("data:image/svg+xml;utf8,")}.nb-checkbox-sm{width:.875rem;height:.875rem}.nb-input::placeholder{letter-spacing:.02em;opacity:.75;font-size:.75rem}.markdown-content{word-wrap:break-word;line-height:1.5}.markdown-content p{margin-bottom:.75em}.markdown-content p:last-child{margin-bottom:0}.markdown-content ul,.markdown-content ol{margin-top:.5em;margin-bottom:.75em;padding-left:2em}.markdown-content li{margin-bottom:.25em}.markdown-content pre{background-color:var(--color-base-200);color:var(--color-base-content);border:1px solid #00000014;border-radius:4px;padding:.75em 1em;overflow-x:auto}.markdown-content pre code{color:inherit;line-height:inherit;background-color:#0000;border-radius:0;padding:0;display:block}.markdown-content :not(pre)>code{color:var(--color-base-content);background-color:#0000000d;border-radius:3px;padding:.15em .4em;font-size:.9em}.markdown-content table{border-collapse:collapse;width:100%;margin:.75em 0}.markdown-content th,.markdown-content td{text-align:left;border:1px solid #00000026;padding:6px 12px}[data-theme=dark] .markdown-content th,[data-theme=dark] .markdown-content td{border-color:#ffffff40}.markdown-content blockquote{color:#0009;border-left:4px solid #00000026;margin:.5em 0 .5em .5em;padding-left:10px}[data-theme=dark] .markdown-content blockquote{color:#fffc;border-color:#ffffff4d}.markdown-content hr{border:none;border-top:1px solid #00000026;margin:.75em 0}[data-theme=dark] .markdown-content hr{border-top-color:#fff3}[data-theme=dark] .markdown-content pre{background-color:var(--color-base-200);color:var(--color-base-content);border-color:#ffffff1f}[data-theme=dark] .markdown-content :not(pre)>code{color:var(--color-base-content);background-color:#ffffff1f}.brand-mark{letter-spacing:.02em}.reference-tooltip{width:calc(var(--spacing)*72);max-width:var(--container-xs);border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding:calc(var(--spacing)*3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-base-content);z-index:9999;box-shadow:var(--nb-shadow);position:fixed}}@layer utilities{.modal{pointer-events:none;visibility:hidden;width:100%;max-width:none;height:100%;max-height:none;color:inherit;transition:transform .3s ease-out,visibility .3s allow-discrete,background-color .3s ease-out,opacity .1s ease-out;overscroll-behavior:contain;z-index:999;background-color:#0000;place-items:center;margin:0;padding:0;display:grid;position:fixed;inset:0;overflow:hidden}.modal::backdrop{display:none}.modal.modal-open,.modal[open],.modal:target{pointer-events:auto;visibility:visible;opacity:1;background-color:oklch(0% 0 0/.4);transition:transform .3s ease-out,background-color .3s ease-out,opacity .1s ease-out}:is(.modal.modal-open,.modal[open],.modal:target) .modal-box{opacity:1;translate:0;scale:1}@starting-style{.modal.modal-open,.modal[open],.modal:target{visibility:hidden;opacity:0}}.drawer-side{pointer-events:none;visibility:hidden;overscroll-behavior:contain;opacity:0;width:100%;transition:opacity .2s ease-out .1s allow-discrete,visibility .3s ease-out .1s allow-discrete;inset-inline-start:0;grid-template-rows:repeat(1,minmax(0,1fr));grid-template-columns:repeat(1,minmax(0,1fr));grid-row-start:1;grid-column-start:1;place-items:flex-start start;height:100dvh;display:grid;position:fixed;top:0;overflow:hidden}.drawer-side>.drawer-overlay{cursor:pointer;background-color:oklch(0% 0 0/.4);place-self:stretch stretch;position:sticky;top:0}.drawer-side>*{grid-row-start:1;grid-column-start:1}.drawer-side>:not(.drawer-overlay){will-change:transform;transition:translate .3s ease-out;translate:-100%}[dir=rtl] :is(.drawer-side>:not(.drawer-overlay)){translate:100%}.drawer-toggle{appearance:none;opacity:0;width:0;height:0;position:fixed}.drawer-toggle:checked~.drawer-side{pointer-events:auto;visibility:visible;opacity:1;overflow-y:auto}.drawer-toggle:checked~.drawer-side>:not(.drawer-overlay){translate:0%}.drawer-toggle:focus-visible~.drawer-content label.drawer-button{outline-offset:2px;outline:2px solid}.menu{--menu-active-fg:var(--color-neutral-content);--menu-active-bg:var(--color-neutral);flex-flow:column wrap;width:fit-content;padding:.5rem;font-size:.875rem;display:flex}.menu :where(li ul){white-space:nowrap;margin-inline-start:1rem;padding-inline-start:.5rem;position:relative}.menu :where(li ul):before{background-color:var(--color-base-content);opacity:.1;width:var(--border);content:"";inset-inline-start:0;position:absolute;top:.75rem;bottom:.75rem}.menu :where(li>.menu-dropdown:not(.menu-dropdown-show)){display:none}.menu :where(li:not(.menu-title)>:not(ul,details,.menu-title,.btn)),.menu :where(li:not(.menu-title)>details>summary:not(.menu-title)){border-radius:var(--radius-field);text-align:start;text-wrap:balance;-webkit-user-select:none;user-select:none;grid-auto-columns:minmax(auto,max-content) auto max-content;grid-auto-flow:column;align-content:flex-start;align-items:center;gap:.5rem;padding-block:.375rem;padding-inline:.75rem;transition-property:color,background-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);display:grid}.menu :where(li>details>summary){--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.menu :where(li>details>summary){outline-offset:2px;outline:2px solid #0000}}.menu :where(li>details>summary)::-webkit-details-marker{display:none}:is(.menu :where(li>details>summary),.menu :where(li>.menu-dropdown-toggle)):after{content:"";transform-origin:50%;pointer-events:none;justify-self:flex-end;width:.375rem;height:.375rem;transition-property:rotate,translate;transition-duration:.2s;display:block;translate:0 -1px;rotate:-135deg;box-shadow:inset 2px 2px}.menu :where(li>details[open]>summary):after,.menu :where(li>.menu-dropdown-toggle.menu-dropdown-show):after{translate:0 1px;rotate:45deg}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible{cursor:pointer;background-color:color-mix(in srgb,var(--color-base-content)10%,transparent);color:var(--color-base-content);--tw-outline-style:none;outline-style:none}@supports (color:color-mix(in lab, red, red)){:is(.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}@media (forced-colors:active){:is(.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible){outline-offset:2px;outline:2px solid #0000}}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){cursor:pointer;background-color:color-mix(in srgb,var(--color-base-content)10%,transparent);--tw-outline-style:none;outline-style:none;box-shadow:inset 0 1px oklch(0% 0 0/.01),inset 0 -1px oklch(100% 0 0/.01)}@supports (color:color-mix(in lab, red, red)){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}@media (forced-colors:active){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){outline-offset:2px;outline:2px solid #0000}}.menu :where(li:empty){background-color:var(--color-base-content);opacity:.1;height:1px;margin:.5rem 1rem}.menu :where(li){flex-flow:column wrap;flex-shrink:0;align-items:stretch;display:flex;position:relative}.menu :where(li) .badge{justify-self:flex-end}.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active{--tw-outline-style:none;color:var(--menu-active-fg);background-color:var(--menu-active-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);outline-style:none}@media (forced-colors:active){:is(.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active){outline-offset:2px;outline:2px solid #0000}}:is(.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active):not(:is(.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active):active){box-shadow:0 2px calc(var(--depth)*3px)-2px var(--menu-active-bg)}.menu :where(li).menu-disabled{pointer-events:none;color:color-mix(in srgb,var(--color-base-content)20%,transparent)}@supports (color:color-mix(in lab, red, red)){.menu :where(li).menu-disabled{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.menu .dropdown:focus-within .menu-dropdown-toggle:after{translate:0 1px;rotate:45deg}.menu .dropdown-content{margin-top:.5rem;padding:.5rem}.menu .dropdown-content:before{display:none}.btn{cursor:pointer;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--btn-fg);--tw-prose-links:var(--btn-fg);height:var(--size);font-size:var(--fontsize,.875rem);outline-color:var(--btn-color,var(--color-base-content));background-color:var(--btn-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--btn-noise);border-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0/calc(var(--depth)*.15));box-shadow:0 .5px 0 .5px oklch(100% 0 0/calc(var(--depth)*6%))inset,var(--btn-shadow);--size:calc(var(--size-field,.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-p:1rem;--btn-border:var(--btn-bg);--btn-shadow:0 3px 2px -2px var(--btn-bg),0 4px 3px -2px var(--btn-bg);--btn-noise:var(--fx-noise);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-wrap:nowrap;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;font-weight:600;transition-property:color,background-color,border-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);display:inline-flex}:where(.btn){width:unset}@supports (color:color-mix(in lab, red, red)){.btn{--btn-border:color-mix(in oklab,var(--btn-bg),#000 calc(var(--depth)*5%));--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000)}}.prose .btn{text-decoration-line:none}@media (hover:hover){.btn:hover{--btn-bg:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab, red, red)){.btn:hover{--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}}.btn:focus-visible{outline-width:2px;outline-style:solid}.btn:active:not(.btn-active){--btn-bg:var(--btn-color,var(--color-base-200));--btn-border:var(--btn-color,var(--color-base-200));--btn-shadow:0 0 0 0 oklch(0% 0 0/0),0 0 0 0 oklch(0% 0 0/0);translate:0 .5px}@supports (color:color-mix(in lab, red, red)){.btn:active:not(.btn-active){--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 5%);--btn-border:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}.btn:is(:disabled,[disabled],.btn-disabled){pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}.btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in srgb,var(--color-base-content)10%,transparent);box-shadow:none}@supports (color:color-mix(in lab, red, red)){.btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}.btn:is(:disabled,[disabled],.btn-disabled){--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}@media (hover:hover){.btn:is(:disabled,[disabled],.btn-disabled):hover{pointer-events:none;background-color:color-mix(in srgb,var(--color-neutral)20%,transparent);--btn-border:#0000;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}@supports (color:color-mix(in lab, red, red)){.btn:is(:disabled,[disabled],.btn-disabled):hover{background-color:color-mix(in oklab,var(--color-neutral)20%,transparent);--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}}.btn:is(input[type=checkbox],input[type=radio]){appearance:none}.btn:is(input[type=checkbox],input[type=radio]):after{content:attr(aria-label)}.btn:where(input:checked:not(.filter .btn)){--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content);isolation:isolate}.loading{pointer-events:none;aspect-ratio:1;vertical-align:middle;width:calc(var(--size-selector,.25rem)*6);background-color:currentColor;display:inline-block;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.pointer-events-none{pointer-events:none}.validator:user-valid{--input-color:var(--color-success)}.validator:user-valid:focus{--input-color:var(--color-success)}.validator:user-valid:checked{--input-color:var(--color-success)}.validator:user-valid[aria-checked=true]{--input-color:var(--color-success)}.validator:user-valid:focus-within{--input-color:var(--color-success)}.validator:has(:user-valid){--input-color:var(--color-success)}.validator:has(:user-valid):focus{--input-color:var(--color-success)}.validator:has(:user-valid):checked{--input-color:var(--color-success)}.validator:has(:user-valid)[aria-checked=true]{--input-color:var(--color-success)}.validator:has(:user-valid):focus-within{--input-color:var(--color-success)}.validator:user-invalid{--input-color:var(--color-error)}.validator:user-invalid:focus{--input-color:var(--color-error)}.validator:user-invalid:checked{--input-color:var(--color-error)}.validator:user-invalid[aria-checked=true]{--input-color:var(--color-error)}.validator:user-invalid:focus-within{--input-color:var(--color-error)}.validator:user-invalid~.validator-hint{visibility:visible;color:var(--color-error);display:block}.validator:has(:user-invalid){--input-color:var(--color-error)}.validator:has(:user-invalid):focus{--input-color:var(--color-error)}.validator:has(:user-invalid):checked{--input-color:var(--color-error)}.validator:has(:user-invalid)[aria-checked=true]{--input-color:var(--color-error)}.validator:has(:user-invalid):focus-within{--input-color:var(--color-error)}.validator:has(:user-invalid)~.validator-hint{visibility:visible;color:var(--color-error);display:block}.validator~.validator-hint{visibility:hidden}.visible{visibility:visible}.input{cursor:text;border:var(--border)solid #0000;appearance:none;background-color:var(--color-base-100);vertical-align:middle;white-space:nowrap;width:clamp(3rem,20rem,100%);height:var(--size);border-color:var(--input-color);box-shadow:0 1px var(--input-color)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;--size:calc(var(--size-field,.25rem)*10);--input-color:color-mix(in srgb,var(--color-base-content)20%,#0000);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.5rem;padding-inline:.75rem;font-size:.875rem;display:inline-flex;position:relative}@supports (color:color-mix(in lab, red, red)){.input{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.input:where(input){display:inline-flex}.input :where(input){appearance:none;background-color:#0000;border:none;width:100%;height:100%;display:inline-flex}.input :where(input):focus,.input :where(input):focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){:is(.input :where(input):focus,.input :where(input):focus-within){outline-offset:2px;outline:2px solid #0000}}.input :where(input[type=date]){display:inline-block}.input:focus,.input:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color);outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}@supports (color:color-mix(in lab, red, red)){:is(.input:focus,.input:focus-within){box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:color-mix(in srgb,var(--color-base-content)40%,transparent);box-shadow:none}@supports (color:color-mix(in lab, red, red)){:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled])){color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]))::placeholder{color:color-mix(in srgb,var(--color-base-content)20%,transparent)}@supports (color:color-mix(in lab, red, red)){:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.input:has(>input[disabled])>input[disabled]{cursor:not-allowed}.input::-webkit-date-and-time-value{text-align:inherit}.input[type=number]::-webkit-inner-spin-button{margin-block:-.75rem;margin-inline-end:-.75rem}.input::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em}.chat-bubble{border-radius:var(--radius-field);background-color:var(--color-base-300);width:fit-content;color:var(--color-base-content);grid-row-end:3;min-width:2.5rem;max-width:90%;min-height:2rem;padding-block:.5rem;padding-inline:1rem;display:block;position:relative}.chat-bubble:before{background-color:inherit;content:"";width:.75rem;height:.75rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-image:var(--mask-chat);-webkit-mask-image:var(--mask-chat);mask-image:var(--mask-chat);position:absolute;bottom:0;-webkit-mask-position:0 -1px;mask-position:0 -1px;-webkit-mask-size:13px;mask-size:13px}.card{border-radius:var(--radius-box);outline-offset:2px;outline:0 solid #0000;flex-direction:column;transition:outline .2s ease-in-out;display:flex;position:relative}.card:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.card:focus{outline-offset:2px;outline:2px solid #0000}}.card:focus-visible{outline-color:currentColor}.card :where(figure:first-child){border-start-start-radius:inherit;border-start-end-radius:inherit;border-end-end-radius:unset;border-end-start-radius:unset;overflow:hidden}.card :where(figure:last-child){border-start-start-radius:unset;border-start-end-radius:unset;border-end-end-radius:inherit;border-end-start-radius:inherit;overflow:hidden}.card:where(.card-border){border:var(--border)solid var(--color-base-200)}.card:where(.card-dash){border:var(--border)dashed var(--color-base-200)}.card.image-full{display:grid}.card.image-full>*{grid-row-start:1;grid-column-start:1}.card.image-full>.card-body{color:var(--color-neutral-content);position:relative}.card.image-full :where(figure){border-radius:inherit;overflow:hidden}.card.image-full>figure img{object-fit:cover;filter:brightness(28%);height:100%}.card figure{justify-content:center;align-items:center;display:flex}.card:has(>input:is(input[type=checkbox],input[type=radio])){cursor:pointer;-webkit-user-select:none;user-select:none}.card:has(>:checked){outline:2px solid}.swap{cursor:pointer;vertical-align:middle;webkit-user-select:none;-webkit-user-select:none;user-select:none;place-content:center;display:inline-grid;position:relative}.swap input{appearance:none;border:none}.swap>*{grid-row-start:1;grid-column-start:1;transition-property:transform,rotate,opacity;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1)}.swap .swap-on,.swap .swap-indeterminate,.swap input:indeterminate~.swap-on,.swap input:is(:checked,:indeterminate)~.swap-off{opacity:0}.swap input:checked~.swap-on,.swap input:indeterminate~.swap-indeterminate{opacity:1}.menu-horizontal{flex-direction:row;display:inline-flex}.menu-horizontal>li:not(.menu-title)>details>ul{margin-inline-start:0;margin-top:1rem;padding-block:.5rem;padding-inline-end:.5rem;position:absolute}.menu-horizontal>li>details>ul:before{content:none}:where(.menu-horizontal>li:not(.menu-title)>details>ul){border-radius:var(--radius-box);background-color:var(--color-base-100);box-shadow:0 1px 3px oklch(0% 0 0/.1),0 1px 2px -1px oklch(0% 0 0/.1)}.drawer{grid-auto-columns:max-content auto;width:100%;display:grid;position:relative}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-y-0{inset-block:calc(var(--spacing)*0)}.chat-end{grid-template-columns:1fr auto;place-items:end}.chat-end .chat-header,.chat-end .chat-footer{grid-column-start:1}.chat-end .chat-image{grid-column-start:2}.chat-end .chat-bubble{border-end-end-radius:0;grid-column-start:1}.chat-end .chat-bubble:before{inset-inline-start:100%;transform:rotateY(180deg)}[dir=rtl] :is(.chat-end .chat-bubble):before{transform:rotateY(0)}.chat-start{grid-template-columns:auto 1fr;place-items:start}.chat-start .chat-header,.chat-start .chat-footer{grid-column-start:2}.chat-start .chat-image{grid-column-start:1}.chat-start .chat-bubble{border-end-start-radius:0;grid-column-start:2}.chat-start .chat-bubble:before{inset-inline-start:-.75rem;transform:rotateY(0)}[dir=rtl] :is(.chat-start .chat-bubble):before{transform:rotateY(180deg)}.\!top-2\.5{top:calc(var(--spacing)*2.5)!important}.top-0{top:calc(var(--spacing)*0)}.top-1{top:calc(var(--spacing)*1)}.top-1\/2{top:50%}.top-9{top:calc(var(--spacing)*9)}.right-0{right:calc(var(--spacing)*0)}.right-0\.5{right:calc(var(--spacing)*.5)}.right-1{right:calc(var(--spacing)*1)}.right-2{right:calc(var(--spacing)*2)}.right-4{right:calc(var(--spacing)*4)}.right-24{right:calc(var(--spacing)*24)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-4{bottom:calc(var(--spacing)*4)}.\!left-3{left:calc(var(--spacing)*3)!important}.left-0{left:calc(var(--spacing)*0)}.file-input{cursor:pointer;cursor:pointer;border:var(--border)solid #0000;appearance:none;background-color:var(--color-base-100);vertical-align:middle;webkit-user-select:none;-webkit-user-select:none;user-select:none;width:clamp(3rem,20rem,100%);height:var(--size);border-color:var(--input-color);box-shadow:0 1px var(--input-color)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;--size:calc(var(--size-field,.25rem)*10);--input-color:color-mix(in srgb,var(--color-base-content)20%,#0000);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));align-items:center;padding-inline-end:.75rem;font-size:.875rem;line-height:2;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.file-input{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.file-input::file-selector-button{cursor:pointer;webkit-user-select:none;-webkit-user-select:none;user-select:none;height:calc(100% + var(--border)*2);margin-inline-end:1rem;margin-block:calc(var(--border)*-1);color:var(--btn-fg);border-width:var(--border);border-style:solid;border-color:var(--btn-border);background-color:var(--btn-bg);background-size:calc(var(--noise)*100%);background-image:var(--btn-noise);text-shadow:0 .5px oklch(1 0 0/calc(var(--depth)*.15));box-shadow:0 .5px 0 .5px white inset,var(--btn-shadow);--size:calc(var(--size-field,.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-border:var(--btn-bg);--btn-shadow:0 3px 2px -2px var(--btn-bg),0 4px 3px -2px var(--btn-bg);--btn-noise:var(--fx-noise);border-start-start-radius:calc(var(--join-ss,var(--radius-field) - var(--border)));border-end-start-radius:calc(var(--join-es,var(--radius-field) - var(--border)));margin-inline-start:calc(var(--border)*-1);padding-inline:1rem;font-size:.875rem;font-weight:600}@supports (color:color-mix(in lab, red, red)){.file-input::file-selector-button{box-shadow:0 .5px 0 .5px color-mix(in oklab,color-mix(in oklab,white 30%,var(--btn-bg))calc(var(--depth)*20%),#0000)inset,var(--btn-shadow);--btn-border:color-mix(in oklab,var(--btn-bg),#000 5%);--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg)30%,#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg)30%,#0000)}}.file-input:focus{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color);outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}@supports (color:color-mix(in lab, red, red)){.file-input:focus{box-shadow:0 1px color-mix(in oklab,var(--input-color)10%,#0000)}}.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);box-shadow:none;color:color-mix(in srgb,var(--color-base-content)20%,#0000)}:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]))::placeholder{color:color-mix(in srgb,var(--color-base-content)20%,transparent)}@supports (color:color-mix(in lab, red, red)){:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled])){color:color-mix(in oklch,var(--color-base-content)20%,#0000)}}:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]))::file-selector-button{cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);--btn-border:#0000;--btn-noise:none;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}@supports (color:color-mix(in lab, red, red)){:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]))::file-selector-button{--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}.modal-backdrop{color:#0000;z-index:-1;grid-row-start:1;grid-column-start:1;place-self:stretch stretch;display:grid}.modal-backdrop button{cursor:pointer}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.col-span-full{grid-column:1/-1}.modal-box{background-color:var(--color-base-100);border-top-left-radius:var(--modal-tl,var(--radius-box));border-top-right-radius:var(--modal-tr,var(--radius-box));border-bottom-left-radius:var(--modal-bl,var(--radius-box));border-bottom-right-radius:var(--modal-br,var(--radius-box));opacity:0;overscroll-behavior:contain;grid-row-start:1;grid-column-start:1;width:91.6667%;max-width:32rem;max-height:100vh;padding:1.5rem;transition:translate .3s ease-out,scale .3s ease-out,opacity .2s ease-out 50ms,box-shadow .3s ease-out;overflow-y:auto;scale:95%;box-shadow:0 25px 50px -12px oklch(0% 0 0/.25)}.drawer-content{grid-row-start:1;grid-column-start:2;min-width:0}.chat-image{grid-row:span 2/span 2;align-self:flex-end}.chat-footer{grid-row-start:3;gap:.25rem;font-size:.6875rem;display:flex}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing)*0)}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-auto{margin-inline:auto}.my-2{margin-block:calc(var(--spacing)*2)}.my-3{margin-block:calc(var(--spacing)*3)}.my-4{margin-block:calc(var(--spacing)*4)}.prose{color:var(--tw-prose-body);--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:NaN NaN NaN;--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);max-width:65ch;font-size:1rem;line-height:1.75}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px 0 rgb(var(--tw-prose-kbd-shadows)/10%);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.validator-hint{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));margin-top:.5rem}.-mt-4{margin-top:calc(var(--spacing)*-4)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-10{margin-top:calc(var(--spacing)*10)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-10{margin-bottom:calc(var(--spacing)*10)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.navbar{align-items:center;width:100%;min-height:4rem;padding:.5rem;display:flex}.card-body{padding:var(--card-p,1.5rem);font-size:var(--card-fs,.875rem);flex-direction:column;flex:auto;gap:.5rem;display:flex}.card-body :where(p){flex-grow:1}.alert{border-radius:var(--radius-box);color:var(--color-base-content);background-color:var(--alert-color,var(--color-base-200));text-align:start;border:var(--border)solid var(--color-base-200);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);box-shadow:0 3px 0 -2px oklch(100% 0 0/calc(var(--depth)*.08))inset,0 1px #000,0 4px 3px -2px oklch(0% 0 0/calc(var(--depth)*.08));grid-template-columns:auto;grid-auto-flow:column;justify-content:start;place-items:center start;gap:1rem;padding-block:.75rem;padding-inline:1rem;font-size:.875rem;line-height:1.25rem;display:grid}@supports (color:color-mix(in lab, red, red)){.alert{box-shadow:0 3px 0 -2px oklch(100% 0 0/calc(var(--depth)*.08))inset,0 1px color-mix(in oklab,color-mix(in oklab,#000 20%,var(--alert-color,var(--color-base-200)))calc(var(--depth)*20%),#0000),0 4px 3px -2px oklch(0% 0 0/calc(var(--depth)*.08))}}.alert:has(:nth-child(2)){grid-template-columns:auto minmax(auto,1fr)}.alert.alert-outline{color:var(--alert-color);box-shadow:none;background-color:#0000;background-image:none}.alert.alert-dash{color:var(--alert-color);box-shadow:none;background-color:#0000;background-image:none;border-style:dashed}.alert.alert-soft{color:var(--alert-color,var(--color-base-content));background:var(--alert-color,var(--color-base-content));border-color:var(--alert-color,var(--color-base-content));box-shadow:none;background-image:none}@supports (color:color-mix(in lab, red, red)){.alert.alert-soft{background:color-mix(in oklab,var(--alert-color,var(--color-base-content))8%,var(--color-base-100));border-color:color-mix(in oklab,var(--alert-color,var(--color-base-content))10%,var(--color-base-100))}}.card-title{font-size:var(--cardtitle-fs,1.125rem);align-items:center;gap:.5rem;font-weight:600;display:flex}.chat{column-gap:.75rem;padding-block:.25rem;display:grid}.line-clamp-6{-webkit-line-clamp:6;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.btn-square{width:var(--size);height:var(--size);padding-inline:0}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.h-3{height:calc(var(--spacing)*3)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-10{height:calc(var(--spacing)*10)}.h-24{height:calc(var(--spacing)*24)}.h-32{height:calc(var(--spacing)*32)}.h-96{height:calc(var(--spacing)*96)}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-56{max-height:calc(var(--spacing)*56)}.max-h-\[95\%\]{max-height:95%}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-24{min-height:calc(var(--spacing)*24)}.min-h-28{min-height:calc(var(--spacing)*28)}.min-h-\[10px\]{min-height:10px}.min-h-\[60vh\]{min-height:60vh}.min-h-\[95\%\]{min-height:95%}.min-h-\[100dvh\]{min-height:100dvh}.min-h-\[400px\]{min-height:400px}.min-h-\[500px\]{min-height:500px}.loading-md{width:calc(var(--size-selector,.25rem)*6)}.loading-sm{width:calc(var(--size-selector,.25rem)*5)}.loading-xs{width:calc(var(--size-selector,.25rem)*4)}.w-3{width:calc(var(--spacing)*3)}.w-6{width:calc(var(--spacing)*6)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-11\/12{width:91.6667%}.w-28{width:calc(var(--spacing)*28)}.w-72{width:calc(var(--spacing)*72)}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-52{max-width:calc(var(--spacing)*52)}.max-w-72{max-width:calc(var(--spacing)*72)}.max-w-\[20ch\]{max-width:20ch}.max-w-\[90ch\]{max-width:90ch}.max-w-\[92vw\]{max-width:92vw}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-72{min-width:calc(var(--spacing)*72)}.min-w-\[90px\]{min-width:90px}.flex-1{flex:1}.flex-none{flex:none}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow,.grow{flex-grow:1}.-translate-y-1{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.swap-rotate .swap-on,.swap-rotate input:indeterminate~.swap-on{rotate:45deg}.swap-rotate input:is(:checked,:indeterminate)~.swap-on,.swap-rotate.swap-active .swap-on{rotate:none}.swap-rotate input:is(:checked,:indeterminate)~.swap-off,.swap-rotate.swap-active .swap-off{rotate:-45deg}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.animate-pulse{animation:var(--animate-pulse)}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing)*4)}.gap-y-2{row-gap:calc(var(--spacing)*2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-none{border-radius:0}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-0{border-top-style:var(--tw-border-style);border-top-width:0}.border-r-2{border-right-style:var(--tw-border-style);border-right-width:2px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.alert-error{border-color:var(--color-error);color:var(--color-error-content);--alert-color:var(--color-error)}.border-base-200{border-color:var(--color-base-200)}.border-error{border-color:var(--color-error)}.border-neutral{border-color:var(--color-neutral)}.border-warning{border-color:var(--color-warning)}.bg-base-100{background-color:var(--color-base-100)}.bg-base-200{background-color:var(--color-base-200)}.bg-transparent{background-color:#0000}.bg-warning{background-color:var(--color-warning)}.bg-warning\/10{background-color:color-mix(in srgb,var(--color-warning)10%,transparent)}@supports (color:color-mix(in lab, red, red)){.bg-warning\/10{background-color:color-mix(in oklab,var(--color-warning)10%,transparent)}}.bg-warning\/20{background-color:color-mix(in srgb,var(--color-warning)20%,transparent)}@supports (color:color-mix(in lab, red, red)){.bg-warning\/20{background-color:color-mix(in oklab,var(--color-warning)20%,transparent)}}.loading-dots{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='4' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1'/%3E%3C/circle%3E%3Ccircle cx='12' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.1s'/%3E%3C/circle%3E%3Ccircle cx='20' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.2s'/%3E%3C/circle%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='4' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1'/%3E%3C/circle%3E%3Ccircle cx='12' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.1s'/%3E%3C/circle%3E%3Ccircle cx='20' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.2s'/%3E%3C/circle%3E%3C/svg%3E")}.loading-spinner{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E")}.fill-current{fill:currentColor}.\!p-0{padding:calc(var(--spacing)*0)!important}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-8{padding:calc(var(--spacing)*8)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-10{padding-right:calc(var(--spacing)*10)}.pr-14{padding-right:calc(var(--spacing)*14)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pb-44{padding-bottom:calc(var(--spacing)*44)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-4{padding-left:calc(var(--spacing)*4)}.pl-9{padding-left:calc(var(--spacing)*9)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.7em\]{font-size:.7em}.text-\[0\.65rem\]{font-size:.65rem}.text-\[11px\]{font-size:11px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.text-base-content{color:var(--color-base-content)}.text-base-content\/40{color:color-mix(in srgb,var(--color-base-content)40%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/40{color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}.text-base-content\/50{color:color-mix(in srgb,var(--color-base-content)50%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/50{color:color-mix(in oklab,var(--color-base-content)50%,transparent)}}.text-base-content\/60{color:color-mix(in srgb,var(--color-base-content)60%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/60{color:color-mix(in oklab,var(--color-base-content)60%,transparent)}}.text-base-content\/70{color:color-mix(in srgb,var(--color-base-content)70%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/70{color:color-mix(in oklab,var(--color-base-content)70%,transparent)}}.text-base-content\/80{color:color-mix(in srgb,var(--color-base-content)80%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/80{color:color-mix(in oklab,var(--color-base-content)80%,transparent)}}.text-error{color:var(--color-error)}.text-primary{color:var(--color-primary)}.text-success{color:var(--color-success)}.text-warning{color:var(--color-warning)}.text-warning-content{color:var(--color-warning-content)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.swap-active .swap-off{opacity:0}.swap-active .swap-on{opacity:1}.opacity-0{opacity:0}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[4px_4px_0_0_\#000\]{--tw-shadow:4px 4px 0 0 var(--tw-shadow-color,#000);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[8px_8px_0_0_\#000\]{--tw-shadow:8px 8px 0 0 var(--tw-shadow-color,#000);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible){--btn-shadow:"";--btn-bg:#0000;--btn-border:#0000;--btn-noise:none}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible):not(:disabled,[disabled],.btn-disabled){--btn-fg:currentColor;outline-color:currentColor}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.btn-outline:not(.btn-active,:hover,:active:focus,:focus-visible,:disabled,[disabled],.btn-disabled,:checked){--btn-shadow:"";--btn-bg:#0000;--btn-fg:var(--btn-color);--btn-border:var(--btn-color);--btn-noise:none}.btn-sm{--fontsize:.75rem;--btn-p:.75rem;--size:calc(var(--size-field,.25rem)*8)}.btn-xs{--fontsize:.6875rem;--btn-p:.5rem;--size:calc(var(--size-field,.25rem)*6)}.btn-error{--btn-color:var(--color-error);--btn-fg:var(--color-error-content)}.btn-primary{--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content)}@media (hover:hover){.hover\:cursor-pointer:hover{cursor:pointer}.hover\:bg-base-200:hover{background-color:var(--color-base-200)}.hover\:bg-base-200\/40:hover{background-color:color-mix(in srgb,var(--color-base-200)40%,transparent)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-base-200\/40:hover{background-color:color-mix(in oklab,var(--color-base-200)40%,transparent)}}}@media (min-width:40rem){.sm\:mt-0{margin-top:calc(var(--spacing)*0)}.sm\:mt-4{margin-top:calc(var(--spacing)*4)}.sm\:mt-8{margin-top:calc(var(--spacing)*8)}.sm\:mr-2{margin-right:calc(var(--spacing)*2)}.sm\:ml-2{margin-left:calc(var(--spacing)*2)}.sm\:flex{display:flex}.sm\:w-auto{width:auto}.sm\:max-w-md{max-width:var(--container-md)}.sm\:max-w-none{max-width:none}.sm\:flex-1{flex:1}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:items-end{align-items:flex-end}.sm\:items-start{align-items:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:justify-end{justify-content:flex-end}.sm\:gap-3{gap:calc(var(--spacing)*3)}:where(.sm\:space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*0)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*0)*calc(1 - var(--tw-space-y-reverse)))}.sm\:text-right{text-align:right}}@media (min-width:48rem){.md\:inline{display:inline}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:64rem){.lg\:drawer-open>.drawer-side{overflow-y:auto}.lg\:drawer-open>.drawer-toggle{display:none}.lg\:drawer-open>.drawer-toggle~.drawer-side{pointer-events:auto;visibility:visible;overscroll-behavior:auto;opacity:1;width:auto;display:block;position:sticky}.lg\:drawer-open>.drawer-toggle~.drawer-side>.drawer-overlay{cursor:default;background-color:#0000}.lg\:drawer-open>.drawer-toggle~.drawer-side>:not(.drawer-overlay),[dir=rtl] :is(.lg\:drawer-open>.drawer-toggle~.drawer-side>:not(.drawer-overlay)){translate:0%}.lg\:drawer-open>.drawer-toggle:checked~.drawer-side{pointer-events:auto;visibility:visible}.lg\:left-72{left:calc(var(--spacing)*72)}.lg\:block{display:block}.lg\:hidden{display:none}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width:80rem){.xl\:hidden{display:none}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width:96rem){.\32 xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}.menu li>.nb-btn:hover{background-color:#0000}.menu li>.nb-cta:hover{background-color:var(--color-accent);color:var(--color-accent-content)}.toast-alert{margin-top:calc(var(--spacing)*2);gap:calc(var(--spacing)*1);text-align:left;box-shadow:var(--nb-shadow);flex-direction:column;display:flex}.toast-alert-title{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}}@view-transition{navigation:auto}@font-face{font-family:Satoshi;src:url(fonts/Satoshi-Variable.woff2)format("woff2"),url(fonts/Satoshi-Variable.woff)format("woff"),url(fonts/Satoshi-Variable.ttf)format("truetype");font-weight:300 900;font-style:normal;font-display:swap}@font-face{font-family:Satoshi;src:url(fonts/Satoshi-VariableItalic.woff2)format("woff2"),url(fonts/Satoshi-VariableItalic.woff)format("woff"),url(fonts/Satoshi-VariableItalic.ttf)format("truetype");font-weight:300 900;font-style:italic;font-display:swap}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}} \ No newline at end of file +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:rotateX(0);--tw-rotate-y:rotateY(0);--tw-rotate-z:rotateZ(0);--tw-skew-x:skewX(0);--tw-skew-y:skewY(0);--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-yellow-300:oklch(90.5% .182 98.111);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-700:oklch(55.4% .135 66.442);--color-green-400:oklch(79.2% .209 151.711);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-3xl:48rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height:calc(1.5/1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-snug:1.375;--leading-relaxed:1.625;--radius-lg:.5rem;--ease-out:cubic-bezier(0,0,.2,1);--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{--nb-shadow:4px 4px 0 0 #000;--nb-shadow-hover:6px 6px 0 0 #000}[data-theme=light]{color-scheme:light;--color-base-100:oklch(98.42% .012 96.42);--color-base-200:oklch(94.52% .0122 96.43);--color-base-300:oklch(90.96% .0125 91.53);--color-base-content:oklch(17.76% 0 89.88);--color-primary:oklch(20.77% .0398 265.75);--color-primary-content:oklch(100% 0 89.88);--color-secondary:oklch(54.61% .2152 262.88);--color-secondary-content:oklch(100% 0 89.88);--color-accent:oklch(72% .19 80);--color-accent-content:oklch(21% .035 80);--color-neutral:oklch(17.76% 0 89.88);--color-neutral-content:oklch(96.99% .0013 106.42);--color-info:oklch(60.89% .1109 221.72);--color-info-content:oklch(96.99% .0013 106.42);--color-success:oklch(62.71% .1699 149.21);--color-success-content:oklch(96.99% .0013 106.42);--color-warning:oklch(79.52% .1617 86.05);--color-warning-content:oklch(17.76% 0 89.88);--color-error:oklch(57.71% .2152 27.33);--color-error-content:oklch(96.99% .0013 106.42);--radius-selector:0rem;--radius-field:0rem;--radius-box:0rem;--size-selector:.25rem;--size-field:.25rem;--border:2px}[data-theme=dark]{color-scheme:dark;--color-base-100:oklch(22% .015 255);--color-base-200:oklch(18% .014 253);--color-base-300:oklch(14% .012 251);--color-base-content:oklch(97.2% .02 255);--color-primary:oklch(58% .233 277.12);--color-primary-content:oklch(96% .018 272.31);--color-secondary:oklch(65% .241 354.31);--color-secondary-content:oklch(94% .028 342.26);--color-accent:oklch(78% .22 80);--color-accent-content:oklch(20% .035 80);--color-neutral:oklch(26% .02 255);--color-neutral-content:oklch(97% .03 255);--color-info:oklch(74% .16 232.66);--color-info-content:oklch(29% .066 243.16);--color-success:oklch(76% .177 163.22);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.43);--color-warning-content:oklch(41% .112 45.9);--color-error:oklch(71% .194 13.43);--color-error-content:oklch(27% .105 12.09);--radius-selector:0rem;--radius-field:0rem;--radius-box:0rem;--size-selector:.25rem;--size-field:.25rem;--border:2px}body{background-color:var(--color-base-100);color:var(--color-base-content);-webkit-font-smoothing:antialiased;font-family:Satoshi,sans-serif}body ::selection{background-color:#ffe02a66}@supports (color:color-mix(in lab, red, red)){body ::selection{background-color:color-mix(in oklab,var(--color-yellow-300)40%,transparent)}}body::selection{background-color:#ffe02a66}@supports (color:color-mix(in lab, red, red)){body::selection{background-color:color-mix(in oklab,var(--color-yellow-300)40%,transparent)}}body ::selection{color:var(--color-neutral)}body::selection{color:var(--color-neutral)}html{scrollbar-gutter:stable}*,:after,:before,::backdrop{border-color:var(--color-gray-200,currentColor)}::file-selector-button{border-color:var(--color-gray-200,currentColor)}.container{padding-inline:10px}@media (min-width:640px){.container{padding-inline:2rem}}@media (min-width:1024px){.container{padding-inline:4rem}}@media (min-width:1280px){.container{padding-inline:5rem}}@media (min-width:1536px){.container{padding-inline:6rem}}.custom-scrollbar{scrollbar-width:thin;scrollbar-color:#0003 transparent}.custom-scrollbar::-webkit-scrollbar{width:4px}.custom-scrollbar::-webkit-scrollbar-track{background:0 0}.custom-scrollbar::-webkit-scrollbar-thumb{background-color:#0003;border-radius:3px}.hide-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.hide-scrollbar::-webkit-scrollbar{display:none}form.htmx-request{opacity:.5}[data-theme=dark] .nb-input::placeholder,[data-theme=dark] .input::placeholder,[data-theme=dark] .textarea::placeholder,[data-theme=dark] textarea::placeholder,[data-theme=dark] input::placeholder{opacity:.85;color:#ffffffc7!important}@property --radialprogress{syntax: ""; inherits: true; initial-value: 0%;}:root{scrollbar-color:currentColor #0000}@supports (color:color-mix(in lab, red, red)){:root{scrollbar-color:color-mix(in oklch,currentColor 35%,#0000)#0000}}:root:has(.modal-open,.modal[open],.modal:target,.modal-toggle:checked,.drawer:not([class*=drawer-open])>.drawer-toggle:checked){overflow:hidden}:root,[data-theme]{background-color:var(--root-bg,var(--color-base-100));color:var(--color-base-content)}:root{--fx-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E")}.chat{--mask-chat:url("data:image/svg+xml,%3csvg width='13' height='13' xmlns='http://www.w3.org/2000/svg'%3e%3cpath fill='black' d='M0 11.5004C0 13.0004 2 13.0004 2 13.0004H12H13V0.00036329L12.5 0C12.5 0 11.977 2.09572 11.8581 2.50033C11.6075 3.35237 10.9149 4.22374 9 5.50036C6 7.50036 0 10.0004 0 11.5004Z'/%3e%3c/svg%3e")}}@layer components{.nb-shadow{box-shadow:var(--nb-shadow);transition:transform .15s,box-shadow .15s}.nb-shadow-hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-card{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding:calc(var(--spacing)*4);box-shadow:var(--nb-shadow);transition:transform .15s,box-shadow .15s}.nb-card:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-panel{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--nb-panel-bg,var(--color-base-200));box-shadow:var(--nb-shadow);transition:transform .15s,box-shadow .15s}.nb-panel:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-panel-canvas{--nb-panel-bg:var(--color-base-100)}.nb-canvas{background-color:var(--color-base-100)}.nb-btn{cursor:pointer;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--color-base-content);--tw-prose-links:var(--btn-fg);height:var(--size);font-size:var(--fontsize,.875rem);outline-color:var(--btn-color,var(--color-base-content));background-color:var(--btn-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--btn-noise);border-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0/calc(var(--depth)*.15));box-shadow:0 .5px 0 .5px oklch(100% 0 0/calc(var(--depth)*6%))inset,var(--btn-shadow);--size:calc(var(--size-field,.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-p:1rem;--btn-border:var(--btn-bg);--btn-shadow:0 3px 2px -2px var(--btn-bg),0 4px 3px -2px var(--btn-bg);--btn-noise:none;border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);--btn-color:var(--color-base-100);box-shadow:var(--nb-shadow);background-image:none;border-radius:0;flex-wrap:nowrap;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;font-weight:600;transition:transform .15s,box-shadow .15s;display:inline-flex}:where(.nb-btn){width:unset}@supports (color:color-mix(in lab, red, red)){.nb-btn{--btn-border:color-mix(in oklab,var(--btn-bg),#000 calc(var(--depth)*5%));--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000)}}.prose .nb-btn{text-decoration-line:none}@media (hover:hover){.nb-btn:hover{--btn-bg:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab, red, red)){.nb-btn:hover{--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}}.nb-btn:focus-visible{outline-width:2px;outline-style:solid}.nb-btn:active:not(.btn-active){--btn-bg:var(--btn-color,var(--color-base-200));--btn-border:var(--btn-color,var(--color-base-200));--btn-shadow:0 0 0 0 oklch(0% 0 0/0),0 0 0 0 oklch(0% 0 0/0);translate:0 .5px}@supports (color:color-mix(in lab, red, red)){.nb-btn:active:not(.btn-active){--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 5%);--btn-border:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}.nb-btn:is(:disabled,[disabled],.btn-disabled){pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}.nb-btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in srgb,var(--color-base-content)10%,transparent);box-shadow:none}@supports (color:color-mix(in lab, red, red)){.nb-btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}.nb-btn:is(:disabled,[disabled],.btn-disabled){--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}@media (hover:hover){.nb-btn:is(:disabled,[disabled],.btn-disabled):hover{pointer-events:none;background-color:color-mix(in srgb,var(--color-neutral)20%,transparent);--btn-border:#0000;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}@supports (color:color-mix(in lab, red, red)){.nb-btn:is(:disabled,[disabled],.btn-disabled):hover{background-color:color-mix(in oklab,var(--color-neutral)20%,transparent);--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}}.nb-btn:is(input[type=checkbox],input[type=radio]){appearance:none}.nb-btn:is(input[type=checkbox],input[type=radio]):after{content:attr(aria-label)}.nb-btn:where(input:checked:not(.filter .btn)){--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content);isolation:isolate}.nb-btn:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-link{text-decoration-line:underline;-webkit-text-decoration-color:var(--color-neutral);-webkit-text-decoration-color:var(--color-neutral);text-decoration-color:var(--color-neutral);text-underline-offset:2px}@media (hover:hover){.nb-link:hover{text-decoration-thickness:4px}}.nb-stat{gap:calc(var(--spacing)*1);border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding:calc(var(--spacing)*5);box-shadow:var(--nb-shadow);flex-direction:column;transition:transform .15s,box-shadow .15s;display:flex}.u-hairline{border-top-style:var(--tw-border-style);border-top-width:1px;border-color:color-mix(in srgb,var(--color-neutral)20%,transparent)}@supports (color:color-mix(in lab, red, red)){.u-hairline{border-color:color-mix(in oklab,var(--color-neutral)20%,transparent)}}.prose-tufte{color:var(--tw-prose-body);--tw-prose-body:oklch(37.1% 0 0);--tw-prose-headings:oklch(20.5% 0 0);--tw-prose-lead:oklch(43.9% 0 0);--tw-prose-links:oklch(20.5% 0 0);--tw-prose-bold:oklch(20.5% 0 0);--tw-prose-counters:oklch(55.6% 0 0);--tw-prose-bullets:oklch(87% 0 0);--tw-prose-hr:oklch(92.2% 0 0);--tw-prose-quotes:oklch(20.5% 0 0);--tw-prose-quote-borders:oklch(92.2% 0 0);--tw-prose-captions:oklch(55.6% 0 0);--tw-prose-kbd:oklch(20.5% 0 0);--tw-prose-kbd-shadows:NaN NaN NaN;--tw-prose-code:oklch(20.5% 0 0);--tw-prose-pre-code:oklch(92.2% 0 0);--tw-prose-pre-bg:oklch(26.9% 0 0);--tw-prose-th-borders:oklch(87% 0 0);--tw-prose-td-borders:oklch(92.2% 0 0);--tw-prose-invert-body:oklch(87% 0 0);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.8% 0 0);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.8% 0 0);--tw-prose-invert-bullets:oklch(43.9% 0 0);--tw-prose-invert-hr:oklch(37.1% 0 0);--tw-prose-invert-quotes:oklch(97% 0 0);--tw-prose-invert-quote-borders:oklch(37.1% 0 0);--tw-prose-invert-captions:oklch(70.8% 0 0);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87% 0 0);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(43.9% 0 0);--tw-prose-invert-td-borders:oklch(37.1% 0 0);max-width:min(90ch,100%);font-size:1rem;line-height:1.7}.prose-tufte :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-tufte :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose-tufte :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose-tufte :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose-tufte :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose-tufte :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose-tufte :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose-tufte :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose-tufte :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose-tufte :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose-tufte :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose-tufte :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose-tufte :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose-tufte :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose-tufte :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose-tufte :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose-tufte :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose-tufte :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose-tufte :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose-tufte :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose-tufte :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose-tufte :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose-tufte :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose-tufte :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose-tufte :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose-tufte :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose-tufte :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose-tufte :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose-tufte :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose-tufte :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose-tufte :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose-tufte :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px 0 rgb(var(--tw-prose-kbd-shadows)/10%);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose-tufte :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose-tufte :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose-tufte :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose-tufte :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose-tufte :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose-tufte :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose-tufte :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose-tufte :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose-tufte :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose-tufte :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose-tufte :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose-tufte :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose-tufte :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose-tufte :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose-tufte :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose-tufte :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose-tufte :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose-tufte :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose-tufte :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-tufte :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose-tufte :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-tufte :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose-tufte :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-tufte :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-tufte :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-tufte :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-tufte :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-tufte :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-tufte :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-tufte :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-tufte :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose-tufte :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-tufte :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-tufte :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-tufte :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose-tufte :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-tufte :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-tufte :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-tufte :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-tufte-compact{color:var(--tw-prose-body);--tw-prose-body:oklch(37.1% 0 0);--tw-prose-headings:oklch(20.5% 0 0);--tw-prose-lead:oklch(43.9% 0 0);--tw-prose-links:oklch(20.5% 0 0);--tw-prose-bold:oklch(20.5% 0 0);--tw-prose-counters:oklch(55.6% 0 0);--tw-prose-bullets:oklch(87% 0 0);--tw-prose-hr:oklch(92.2% 0 0);--tw-prose-quotes:oklch(20.5% 0 0);--tw-prose-quote-borders:oklch(92.2% 0 0);--tw-prose-captions:oklch(55.6% 0 0);--tw-prose-kbd:oklch(20.5% 0 0);--tw-prose-kbd-shadows:NaN NaN NaN;--tw-prose-code:oklch(20.5% 0 0);--tw-prose-pre-code:oklch(92.2% 0 0);--tw-prose-pre-bg:oklch(26.9% 0 0);--tw-prose-th-borders:oklch(87% 0 0);--tw-prose-td-borders:oklch(92.2% 0 0);--tw-prose-invert-body:oklch(87% 0 0);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.8% 0 0);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.8% 0 0);--tw-prose-invert-bullets:oklch(43.9% 0 0);--tw-prose-invert-hr:oklch(37.1% 0 0);--tw-prose-invert-quotes:oklch(97% 0 0);--tw-prose-invert-quote-borders:oklch(37.1% 0 0);--tw-prose-invert-captions:oklch(70.8% 0 0);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87% 0 0);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(43.9% 0 0);--tw-prose-invert-td-borders:oklch(37.1% 0 0);max-width:min(90ch,100%);font-size:.875rem;line-height:1.6}.prose-tufte-compact :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-tufte-compact :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose-tufte-compact :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose-tufte-compact :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose-tufte-compact :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte-compact :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose-tufte-compact :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose-tufte-compact :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose-tufte-compact :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose-tufte-compact :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose-tufte-compact :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose-tufte-compact :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose-tufte-compact :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose-tufte-compact :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose-tufte-compact :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose-tufte-compact :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose-tufte-compact :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose-tufte-compact :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose-tufte-compact :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose-tufte-compact :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose-tufte-compact :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose-tufte-compact :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose-tufte-compact :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose-tufte-compact :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose-tufte-compact :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose-tufte-compact :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose-tufte-compact :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose-tufte-compact :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose-tufte-compact :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose-tufte-compact :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose-tufte-compact :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose-tufte-compact :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte-compact :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose-tufte-compact :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte-compact :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px 0 rgb(var(--tw-prose-kbd-shadows)/10%);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose-tufte-compact :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose-tufte-compact :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose-tufte-compact :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose-tufte-compact :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte-compact :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose-tufte-compact :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose-tufte-compact :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose-tufte-compact :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose-tufte-compact :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose-tufte-compact :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose-tufte-compact :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose-tufte-compact :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose-tufte-compact :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose-tufte-compact :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose-tufte-compact :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose-tufte-compact :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose-tufte-compact :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose-tufte-compact :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose-tufte-compact :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose-tufte-compact :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose-tufte-compact :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-tufte-compact :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose-tufte-compact :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-tufte-compact :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose-tufte-compact :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose-tufte-compact :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-tufte-compact :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-tufte-compact :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-tufte-compact :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose-tufte-compact :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose-tufte-compact :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose-tufte-compact :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose-tufte-compact :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose-tufte-compact :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-tufte-compact :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-tufte-compact :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-tufte-compact :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-tufte-compact :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose-tufte-compact :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-tufte-compact :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-tufte-compact :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose-tufte-compact :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-tufte-compact :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}[data-theme=dark] .prose-tufte,[data-theme=dark] .prose-tufte-compact{color:var(--color-base-content);--tw-prose-body:var(--color-base-content);--tw-prose-headings:var(--color-base-content);--tw-prose-lead:#ffffffc7;--tw-prose-links:var(--color-accent);--tw-prose-bold:var(--color-base-content);--tw-prose-counters:#ffffffb3;--tw-prose-bullets:#ffffff59;--tw-prose-hr:#fff3;--tw-prose-quotes:var(--color-base-content);--tw-prose-quote-borders:#ffffff40;--tw-prose-captions:#ffffffa6;--tw-prose-code:var(--color-base-content);--tw-prose-pre-code:inherit;--tw-prose-pre-bg:#ffffff12;--tw-prose-th-borders:#ffffff40;--tw-prose-td-borders:#fff3}[data-theme=dark] .prose-tufte a,[data-theme=dark] .prose-tufte-compact a{color:var(--color-accent)}.card{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);box-shadow:var(--nb-shadow);border-radius:0;transition:transform .15s,box-shadow .15s}.card:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-input{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding-inline:calc(var(--spacing)*3);color:var(--color-base-content);box-shadow:var(--nb-shadow);border-radius:0;padding-block:.5rem;transition:transform .15s,box-shadow .15s,border-color .15s}.nb-input::placeholder{color:color-mix(in srgb,var(--color-base-content)60%,transparent)}@supports (color:color-mix(in lab, red, red)){.nb-input::placeholder{color:color-mix(in oklab,var(--color-base-content)60%,transparent)}}.nb-input:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-input:focus{box-shadow:var(--nb-shadow-hover);outline:none}.nb-select{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding-inline:calc(var(--spacing)*3);color:var(--color-base-content);box-shadow:var(--nb-shadow);border-radius:0;padding-block:.5rem;transition:transform .15s,box-shadow .15s,border-color .15s}.nb-select:hover{box-shadow:var(--nb-shadow-hover);transform:translate(-1px,-1px)}.nb-select:focus{box-shadow:var(--nb-shadow-hover);outline:none}.nb-input-sm,.nb-select-sm{padding-inline:calc(var(--spacing)*2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));padding-block:.25rem}.nb-cta{--btn-color:var(--color-accent);--btn-fg:var(--color-accent-content);--btn-noise:none;background-image:none;background-color:var(--color-accent);color:var(--color-accent-content)}.nb-cta:hover{background-color:var(--color-accent);color:var(--color-accent-content);filter:saturate(1.1)brightness(1.05)}.nb-badge{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding-inline:calc(var(--spacing)*2);padding-block:calc(var(--spacing)*.5);--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide);text-transform:uppercase;border-radius:0;align-items:center;font-size:10px;display:inline-flex;box-shadow:3px 3px #000}.nb-masonry{column-count:1;column-gap:1rem}.nb-masonry>*{break-inside:avoid;display:block}@media (min-width:768px){.nb-masonry{column-count:2}}@media (min-width:1536px){.nb-masonry{column-count:3}}.chat .chat-bubble{border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);color:var(--color-neutral);box-shadow:var(--nb-shadow);border-radius:0;transition:transform .15s,box-shadow .15s}.chat .chat-bubble:before,.chat .chat-bubble:after{content:none!important;display:none!important}.chat.chat-start .chat-bubble{background-color:var(--color-secondary);color:var(--color-secondary-content)}.chat.chat-end .chat-bubble{background-color:var(--color-base-100);color:var(--color-neutral)}.nb-table{border-collapse:separate;border-spacing:0;width:100%}.nb-table thead th{border-bottom-style:var(--tw-border-style);border-bottom-width:2px;border-color:var(--color-neutral);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide);text-transform:uppercase}.nb-table th,.nb-table td{padding:calc(var(--spacing)*3)}.nb-table tbody tr+tr td{border-top-style:var(--tw-border-style);border-top-width:1px;border-color:color-mix(in srgb,var(--color-neutral)30%,transparent)}@supports (color:color-mix(in lab, red, red)){.nb-table tbody tr+tr td{border-color:color-mix(in oklab,var(--color-neutral)30%,transparent)}}.nb-table tbody tr:hover{background-color:color-mix(in srgb,var(--color-base-200)40%,transparent)}@supports (color:color-mix(in lab, red, red)){.nb-table tbody tr:hover{background-color:color-mix(in oklab,var(--color-base-200)40%,transparent)}}.nb-table tbody tr:hover td:first-child{box-shadow:inset 3px 0 #000}.kg-overlay{top:calc(var(--spacing)*4);right:calc(var(--spacing)*4);left:calc(var(--spacing)*4);z-index:10;align-items:stretch;gap:calc(var(--spacing)*2);flex-direction:column;max-width:min(420px,100% - 2rem);display:flex;position:absolute}.kg-control-row{align-items:center;gap:calc(var(--spacing)*2);flex-wrap:wrap;display:flex}.kg-control-row-primary{justify-content:flex-start}.kg-control-row-secondary{justify-content:center}.kg-search-input{padding-left:calc(var(--spacing)*2);width:100%;min-width:0;max-width:320px;height:2rem}.kg-control-row-primary .kg-search-input{flex:auto}.kg-search-btn{flex:none}.kg-toggle{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.kg-toggle-active{--btn-color:var(--color-accent);--btn-fg:var(--color-accent-content);--btn-noise:none;background-image:none;background-color:var(--color-accent);color:var(--color-accent-content)}.kg-toggle-active:hover{background-color:var(--color-accent);color:var(--color-accent-content);filter:saturate(1.1)brightness(1.05)}@media (min-width:768px){.kg-overlay{width:auto;max-width:none;right:auto}}.kg-legend{bottom:calc(var(--spacing)*2);left:calc(var(--spacing)*2);z-index:10;gap:calc(var(--spacing)*4);flex-wrap:wrap;display:flex;position:absolute}.kg-legend-card{padding:calc(var(--spacing)*2)}.kg-legend-heading{margin-bottom:calc(var(--spacing)*1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));opacity:.7}.kg-legend-row{align-items:center;gap:calc(var(--spacing)*2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));display:flex}.nb-checkbox{appearance:none;border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);vertical-align:middle;width:1rem;height:1rem;box-shadow:var(--nb-shadow);cursor:pointer;background-position:50%;background-repeat:no-repeat;background-size:80% 80%;border-radius:0;transition:transform .15s,box-shadow .15s,border-color .15s,background-color .15s;display:inline-block}.nb-checkbox:hover{transform:translate(-1px,-1px);box-shadow:5px 5px #000}.nb-checkbox:focus-visible{outline-offset:2px;outline:2px solid #000}.nb-checkbox:active{transform:translate(0);box-shadow:3px 3px #000}.nb-checkbox:checked{background-image:url("data:image/svg+xml;utf8,")}[data-theme=dark] .nb-checkbox:checked{background-image:url("data:image/svg+xml;utf8,")}.nb-checkbox-sm{width:.875rem;height:.875rem}.nb-input::placeholder{letter-spacing:.02em;opacity:.75;font-size:.75rem}.markdown-content{word-wrap:break-word;line-height:1.5}.markdown-content p{margin-bottom:.75em}.markdown-content p:last-child{margin-bottom:0}.markdown-content ul,.markdown-content ol{margin-top:.5em;margin-bottom:.75em;padding-left:2em}.markdown-content li{margin-bottom:.25em}.markdown-content pre{background-color:var(--color-base-200);color:var(--color-base-content);border:1px solid #00000014;border-radius:4px;padding:.75em 1em;overflow-x:auto}.markdown-content pre code{color:inherit;line-height:inherit;background-color:#0000;border-radius:0;padding:0;display:block}.markdown-content :not(pre)>code{color:var(--color-base-content);background-color:#0000000d;border-radius:3px;padding:.15em .4em;font-size:.9em}.markdown-content table{border-collapse:collapse;width:100%;margin:.75em 0}.markdown-content th,.markdown-content td{text-align:left;border:1px solid #00000026;padding:6px 12px}[data-theme=dark] .markdown-content th,[data-theme=dark] .markdown-content td{border-color:#ffffff40}.markdown-content blockquote{color:#0009;border-left:4px solid #00000026;margin:.5em 0 .5em .5em;padding-left:10px}[data-theme=dark] .markdown-content blockquote{color:#fffc;border-color:#ffffff4d}.markdown-content hr{border:none;border-top:1px solid #00000026;margin:.75em 0}[data-theme=dark] .markdown-content hr{border-top-color:#fff3}[data-theme=dark] .markdown-content pre{background-color:var(--color-base-200);color:var(--color-base-content);border-color:#ffffff1f}[data-theme=dark] .markdown-content :not(pre)>code{color:var(--color-base-content);background-color:#ffffff1f}.brand-mark{letter-spacing:.02em}.reference-tooltip{width:calc(var(--spacing)*72);max-width:var(--container-xs);border-style:var(--tw-border-style);border-width:2px;border-color:var(--color-neutral);background-color:var(--color-base-100);padding:calc(var(--spacing)*3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-base-content);z-index:9999;box-shadow:var(--nb-shadow);position:fixed}}@layer utilities{.modal{pointer-events:none;visibility:hidden;width:100%;max-width:none;height:100%;max-height:none;color:inherit;transition:transform .3s ease-out,visibility .3s allow-discrete,background-color .3s ease-out,opacity .1s ease-out;overscroll-behavior:contain;z-index:999;background-color:#0000;place-items:center;margin:0;padding:0;display:grid;position:fixed;inset:0;overflow:hidden}.modal::backdrop{display:none}.modal.modal-open,.modal[open],.modal:target{pointer-events:auto;visibility:visible;opacity:1;background-color:oklch(0% 0 0/.4);transition:transform .3s ease-out,background-color .3s ease-out,opacity .1s ease-out}:is(.modal.modal-open,.modal[open],.modal:target) .modal-box{opacity:1;translate:0;scale:1}@starting-style{.modal.modal-open,.modal[open],.modal:target{visibility:hidden;opacity:0}}.drawer-side{pointer-events:none;visibility:hidden;overscroll-behavior:contain;opacity:0;width:100%;transition:opacity .2s ease-out .1s allow-discrete,visibility .3s ease-out .1s allow-discrete;inset-inline-start:0;grid-template-rows:repeat(1,minmax(0,1fr));grid-template-columns:repeat(1,minmax(0,1fr));grid-row-start:1;grid-column-start:1;place-items:flex-start start;height:100dvh;display:grid;position:fixed;top:0;overflow:hidden}.drawer-side>.drawer-overlay{cursor:pointer;background-color:oklch(0% 0 0/.4);place-self:stretch stretch;position:sticky;top:0}.drawer-side>*{grid-row-start:1;grid-column-start:1}.drawer-side>:not(.drawer-overlay){will-change:transform;transition:translate .3s ease-out;translate:-100%}[dir=rtl] :is(.drawer-side>:not(.drawer-overlay)){translate:100%}.drawer-toggle{appearance:none;opacity:0;width:0;height:0;position:fixed}.drawer-toggle:checked~.drawer-side{pointer-events:auto;visibility:visible;opacity:1;overflow-y:auto}.drawer-toggle:checked~.drawer-side>:not(.drawer-overlay){translate:0%}.drawer-toggle:focus-visible~.drawer-content label.drawer-button{outline-offset:2px;outline:2px solid}.menu{--menu-active-fg:var(--color-neutral-content);--menu-active-bg:var(--color-neutral);flex-flow:column wrap;width:fit-content;padding:.5rem;font-size:.875rem;display:flex}.menu :where(li ul){white-space:nowrap;margin-inline-start:1rem;padding-inline-start:.5rem;position:relative}.menu :where(li ul):before{background-color:var(--color-base-content);opacity:.1;width:var(--border);content:"";inset-inline-start:0;position:absolute;top:.75rem;bottom:.75rem}.menu :where(li>.menu-dropdown:not(.menu-dropdown-show)){display:none}.menu :where(li:not(.menu-title)>:not(ul,details,.menu-title,.btn)),.menu :where(li:not(.menu-title)>details>summary:not(.menu-title)){border-radius:var(--radius-field);text-align:start;text-wrap:balance;-webkit-user-select:none;user-select:none;grid-auto-columns:minmax(auto,max-content) auto max-content;grid-auto-flow:column;align-content:flex-start;align-items:center;gap:.5rem;padding-block:.375rem;padding-inline:.75rem;transition-property:color,background-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);display:grid}.menu :where(li>details>summary){--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.menu :where(li>details>summary){outline-offset:2px;outline:2px solid #0000}}.menu :where(li>details>summary)::-webkit-details-marker{display:none}:is(.menu :where(li>details>summary),.menu :where(li>.menu-dropdown-toggle)):after{content:"";transform-origin:50%;pointer-events:none;justify-self:flex-end;width:.375rem;height:.375rem;transition-property:rotate,translate;transition-duration:.2s;display:block;translate:0 -1px;rotate:-135deg;box-shadow:inset 2px 2px}.menu :where(li>details[open]>summary):after,.menu :where(li>.menu-dropdown-toggle.menu-dropdown-show):after{translate:0 1px;rotate:45deg}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible{cursor:pointer;background-color:color-mix(in srgb,var(--color-base-content)10%,transparent);color:var(--color-base-content);--tw-outline-style:none;outline-style:none}@supports (color:color-mix(in lab, red, red)){:is(.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}@media (forced-colors:active){:is(.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn).menu-focus,.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title),li:not(.menu-title,.disabled)>details>summary:not(.menu-title)):not(.menu-active,:active,.btn):focus-visible){outline-offset:2px;outline:2px solid #0000}}.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){cursor:pointer;background-color:color-mix(in srgb,var(--color-base-content)10%,transparent);--tw-outline-style:none;outline-style:none;box-shadow:inset 0 1px oklch(0% 0 0/.01),inset 0 -1px oklch(100% 0 0/.01)}@supports (color:color-mix(in lab, red, red)){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}@media (forced-colors:active){.menu :where(li:not(.menu-title,.disabled)>:not(ul,details,.menu-title):not(.menu-active,:active,.btn):hover,li:not(.menu-title,.disabled)>details>summary:not(.menu-title):not(.menu-active,:active,.btn):hover){outline-offset:2px;outline:2px solid #0000}}.menu :where(li:empty){background-color:var(--color-base-content);opacity:.1;height:1px;margin:.5rem 1rem}.menu :where(li){flex-flow:column wrap;flex-shrink:0;align-items:stretch;display:flex;position:relative}.menu :where(li) .badge{justify-self:flex-end}.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active{--tw-outline-style:none;color:var(--menu-active-fg);background-color:var(--menu-active-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);outline-style:none}@media (forced-colors:active){:is(.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active){outline-offset:2px;outline:2px solid #0000}}:is(.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active):not(:is(.menu :where(li)>:not(ul,.menu-title,details,.btn):active,.menu :where(li)>:not(ul,.menu-title,details,.btn).menu-active,.menu :where(li)>details>summary:active):active){box-shadow:0 2px calc(var(--depth)*3px)-2px var(--menu-active-bg)}.menu :where(li).menu-disabled{pointer-events:none;color:color-mix(in srgb,var(--color-base-content)20%,transparent)}@supports (color:color-mix(in lab, red, red)){.menu :where(li).menu-disabled{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.menu .dropdown:focus-within .menu-dropdown-toggle:after{translate:0 1px;rotate:45deg}.menu .dropdown-content{margin-top:.5rem;padding:.5rem}.menu .dropdown-content:before{display:none}.btn{cursor:pointer;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--btn-fg);--tw-prose-links:var(--btn-fg);height:var(--size);font-size:var(--fontsize,.875rem);outline-color:var(--btn-color,var(--color-base-content));background-color:var(--btn-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--btn-noise);border-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0/calc(var(--depth)*.15));box-shadow:0 .5px 0 .5px oklch(100% 0 0/calc(var(--depth)*6%))inset,var(--btn-shadow);--size:calc(var(--size-field,.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-p:1rem;--btn-border:var(--btn-bg);--btn-shadow:0 3px 2px -2px var(--btn-bg),0 4px 3px -2px var(--btn-bg);--btn-noise:var(--fx-noise);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-wrap:nowrap;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;font-weight:600;transition-property:color,background-color,border-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);display:inline-flex}:where(.btn){width:unset}@supports (color:color-mix(in lab, red, red)){.btn{--btn-border:color-mix(in oklab,var(--btn-bg),#000 calc(var(--depth)*5%));--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000)}}.prose .btn{text-decoration-line:none}@media (hover:hover){.btn:hover{--btn-bg:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab, red, red)){.btn:hover{--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}}.btn:focus-visible{outline-width:2px;outline-style:solid}.btn:active:not(.btn-active){--btn-bg:var(--btn-color,var(--color-base-200));--btn-border:var(--btn-color,var(--color-base-200));--btn-shadow:0 0 0 0 oklch(0% 0 0/0),0 0 0 0 oklch(0% 0 0/0);translate:0 .5px}@supports (color:color-mix(in lab, red, red)){.btn:active:not(.btn-active){--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 5%);--btn-border:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}.btn:is(:disabled,[disabled],.btn-disabled){pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}.btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in srgb,var(--color-base-content)10%,transparent);box-shadow:none}@supports (color:color-mix(in lab, red, red)){.btn:is(:disabled,[disabled],.btn-disabled):not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}.btn:is(:disabled,[disabled],.btn-disabled){--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}@media (hover:hover){.btn:is(:disabled,[disabled],.btn-disabled):hover{pointer-events:none;background-color:color-mix(in srgb,var(--color-neutral)20%,transparent);--btn-border:#0000;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}@supports (color:color-mix(in lab, red, red)){.btn:is(:disabled,[disabled],.btn-disabled):hover{background-color:color-mix(in oklab,var(--color-neutral)20%,transparent);--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}}.btn:is(input[type=checkbox],input[type=radio]){appearance:none}.btn:is(input[type=checkbox],input[type=radio]):after{content:attr(aria-label)}.btn:where(input:checked:not(.filter .btn)){--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content);isolation:isolate}.loading{pointer-events:none;aspect-ratio:1;vertical-align:middle;width:calc(var(--size-selector,.25rem)*6);background-color:currentColor;display:inline-block;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");-webkit-mask-position:50%;mask-position:50%;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.pointer-events-none{pointer-events:none}.validator:user-valid{--input-color:var(--color-success)}.validator:user-valid:focus{--input-color:var(--color-success)}.validator:user-valid:checked{--input-color:var(--color-success)}.validator:user-valid[aria-checked=true]{--input-color:var(--color-success)}.validator:user-valid:focus-within{--input-color:var(--color-success)}.validator:has(:user-valid){--input-color:var(--color-success)}.validator:has(:user-valid):focus{--input-color:var(--color-success)}.validator:has(:user-valid):checked{--input-color:var(--color-success)}.validator:has(:user-valid)[aria-checked=true]{--input-color:var(--color-success)}.validator:has(:user-valid):focus-within{--input-color:var(--color-success)}.validator:user-invalid{--input-color:var(--color-error)}.validator:user-invalid:focus{--input-color:var(--color-error)}.validator:user-invalid:checked{--input-color:var(--color-error)}.validator:user-invalid[aria-checked=true]{--input-color:var(--color-error)}.validator:user-invalid:focus-within{--input-color:var(--color-error)}.validator:user-invalid~.validator-hint{visibility:visible;color:var(--color-error);display:block}.validator:has(:user-invalid){--input-color:var(--color-error)}.validator:has(:user-invalid):focus{--input-color:var(--color-error)}.validator:has(:user-invalid):checked{--input-color:var(--color-error)}.validator:has(:user-invalid)[aria-checked=true]{--input-color:var(--color-error)}.validator:has(:user-invalid):focus-within{--input-color:var(--color-error)}.validator:has(:user-invalid)~.validator-hint{visibility:visible;color:var(--color-error);display:block}.validator~.validator-hint{visibility:hidden}.visible{visibility:visible}.input{cursor:text;border:var(--border)solid #0000;appearance:none;background-color:var(--color-base-100);vertical-align:middle;white-space:nowrap;width:clamp(3rem,20rem,100%);height:var(--size);border-color:var(--input-color);box-shadow:0 1px var(--input-color)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;--size:calc(var(--size-field,.25rem)*10);--input-color:color-mix(in srgb,var(--color-base-content)20%,#0000);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.5rem;padding-inline:.75rem;font-size:.875rem;display:inline-flex;position:relative}@supports (color:color-mix(in lab, red, red)){.input{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.input:where(input){display:inline-flex}.input :where(input){appearance:none;background-color:#0000;border:none;width:100%;height:100%;display:inline-flex}.input :where(input):focus,.input :where(input):focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){:is(.input :where(input):focus,.input :where(input):focus-within){outline-offset:2px;outline:2px solid #0000}}.input :where(input[type=date]){display:inline-block}.input:focus,.input:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color);outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}@supports (color:color-mix(in lab, red, red)){:is(.input:focus,.input:focus-within){box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:color-mix(in srgb,var(--color-base-content)40%,transparent);box-shadow:none}@supports (color:color-mix(in lab, red, red)){:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled])){color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]))::placeholder{color:color-mix(in srgb,var(--color-base-content)20%,transparent)}@supports (color:color-mix(in lab, red, red)){:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.input:has(>input[disabled])>input[disabled]{cursor:not-allowed}.input::-webkit-date-and-time-value{text-align:inherit}.input[type=number]::-webkit-inner-spin-button{margin-block:-.75rem;margin-inline-end:-.75rem}.input::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em}.chat-bubble{border-radius:var(--radius-field);background-color:var(--color-base-300);width:fit-content;color:var(--color-base-content);grid-row-end:3;min-width:2.5rem;max-width:90%;min-height:2rem;padding-block:.5rem;padding-inline:1rem;display:block;position:relative}.chat-bubble:before{background-color:inherit;content:"";width:.75rem;height:.75rem;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-image:var(--mask-chat);-webkit-mask-image:var(--mask-chat);mask-image:var(--mask-chat);position:absolute;bottom:0;-webkit-mask-position:0 -1px;mask-position:0 -1px;-webkit-mask-size:13px;mask-size:13px}.card{border-radius:var(--radius-box);outline-offset:2px;outline:0 solid #0000;flex-direction:column;transition:outline .2s ease-in-out;display:flex;position:relative}.card:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.card:focus{outline-offset:2px;outline:2px solid #0000}}.card:focus-visible{outline-color:currentColor}.card :where(figure:first-child){border-start-start-radius:inherit;border-start-end-radius:inherit;border-end-end-radius:unset;border-end-start-radius:unset;overflow:hidden}.card :where(figure:last-child){border-start-start-radius:unset;border-start-end-radius:unset;border-end-end-radius:inherit;border-end-start-radius:inherit;overflow:hidden}.card:where(.card-border){border:var(--border)solid var(--color-base-200)}.card:where(.card-dash){border:var(--border)dashed var(--color-base-200)}.card.image-full{display:grid}.card.image-full>*{grid-row-start:1;grid-column-start:1}.card.image-full>.card-body{color:var(--color-neutral-content);position:relative}.card.image-full :where(figure){border-radius:inherit;overflow:hidden}.card.image-full>figure img{object-fit:cover;filter:brightness(28%);height:100%}.card figure{justify-content:center;align-items:center;display:flex}.card:has(>input:is(input[type=checkbox],input[type=radio])){cursor:pointer;-webkit-user-select:none;user-select:none}.card:has(>:checked){outline:2px solid}.swap{cursor:pointer;vertical-align:middle;webkit-user-select:none;-webkit-user-select:none;user-select:none;place-content:center;display:inline-grid;position:relative}.swap input{appearance:none;border:none}.swap>*{grid-row-start:1;grid-column-start:1;transition-property:transform,rotate,opacity;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1)}.swap .swap-on,.swap .swap-indeterminate,.swap input:indeterminate~.swap-on,.swap input:is(:checked,:indeterminate)~.swap-off{opacity:0}.swap input:checked~.swap-on,.swap input:indeterminate~.swap-indeterminate{opacity:1}.menu-horizontal{flex-direction:row;display:inline-flex}.menu-horizontal>li:not(.menu-title)>details>ul{margin-inline-start:0;margin-top:1rem;padding-block:.5rem;padding-inline-end:.5rem;position:absolute}.menu-horizontal>li>details>ul:before{content:none}:where(.menu-horizontal>li:not(.menu-title)>details>ul){border-radius:var(--radius-box);background-color:var(--color-base-100);box-shadow:0 1px 3px oklch(0% 0 0/.1),0 1px 2px -1px oklch(0% 0 0/.1)}.drawer{grid-auto-columns:max-content auto;width:100%;display:grid;position:relative}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-y-0{inset-block:calc(var(--spacing)*0)}.chat-end{grid-template-columns:1fr auto;place-items:end}.chat-end .chat-header,.chat-end .chat-footer{grid-column-start:1}.chat-end .chat-image{grid-column-start:2}.chat-end .chat-bubble{border-end-end-radius:0;grid-column-start:1}.chat-end .chat-bubble:before{inset-inline-start:100%;transform:rotateY(180deg)}[dir=rtl] :is(.chat-end .chat-bubble):before{transform:rotateY(0)}.chat-start{grid-template-columns:auto 1fr;place-items:start}.chat-start .chat-header,.chat-start .chat-footer{grid-column-start:2}.chat-start .chat-image{grid-column-start:1}.chat-start .chat-bubble{border-end-start-radius:0;grid-column-start:2}.chat-start .chat-bubble:before{inset-inline-start:-.75rem;transform:rotateY(0)}[dir=rtl] :is(.chat-start .chat-bubble):before{transform:rotateY(180deg)}.\!top-2\.5{top:calc(var(--spacing)*2.5)!important}.top-0{top:calc(var(--spacing)*0)}.top-1{top:calc(var(--spacing)*1)}.top-1\/2{top:50%}.top-9{top:calc(var(--spacing)*9)}.right-0{right:calc(var(--spacing)*0)}.right-0\.5{right:calc(var(--spacing)*.5)}.right-1{right:calc(var(--spacing)*1)}.right-2{right:calc(var(--spacing)*2)}.right-4{right:calc(var(--spacing)*4)}.right-24{right:calc(var(--spacing)*24)}.bottom-0{bottom:calc(var(--spacing)*0)}.bottom-4{bottom:calc(var(--spacing)*4)}.\!left-3{left:calc(var(--spacing)*3)!important}.left-0{left:calc(var(--spacing)*0)}.file-input{cursor:pointer;cursor:pointer;border:var(--border)solid #0000;appearance:none;background-color:var(--color-base-100);vertical-align:middle;webkit-user-select:none;-webkit-user-select:none;user-select:none;width:clamp(3rem,20rem,100%);height:var(--size);border-color:var(--input-color);box-shadow:0 1px var(--input-color)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;--size:calc(var(--size-field,.25rem)*10);--input-color:color-mix(in srgb,var(--color-base-content)20%,#0000);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));align-items:center;padding-inline-end:.75rem;font-size:.875rem;line-height:2;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.file-input{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.file-input::file-selector-button{cursor:pointer;webkit-user-select:none;-webkit-user-select:none;user-select:none;height:calc(100% + var(--border)*2);margin-inline-end:1rem;margin-block:calc(var(--border)*-1);color:var(--btn-fg);border-width:var(--border);border-style:solid;border-color:var(--btn-border);background-color:var(--btn-bg);background-size:calc(var(--noise)*100%);background-image:var(--btn-noise);text-shadow:0 .5px oklch(1 0 0/calc(var(--depth)*.15));box-shadow:0 .5px 0 .5px white inset,var(--btn-shadow);--size:calc(var(--size-field,.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-border:var(--btn-bg);--btn-shadow:0 3px 2px -2px var(--btn-bg),0 4px 3px -2px var(--btn-bg);--btn-noise:var(--fx-noise);border-start-start-radius:calc(var(--join-ss,var(--radius-field) - var(--border)));border-end-start-radius:calc(var(--join-es,var(--radius-field) - var(--border)));margin-inline-start:calc(var(--border)*-1);padding-inline:1rem;font-size:.875rem;font-weight:600}@supports (color:color-mix(in lab, red, red)){.file-input::file-selector-button{box-shadow:0 .5px 0 .5px color-mix(in oklab,color-mix(in oklab,white 30%,var(--btn-bg))calc(var(--depth)*20%),#0000)inset,var(--btn-shadow);--btn-border:color-mix(in oklab,var(--btn-bg),#000 5%);--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg)30%,#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg)30%,#0000)}}.file-input:focus{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color);outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate}@supports (color:color-mix(in lab, red, red)){.file-input:focus{box-shadow:0 1px color-mix(in oklab,var(--input-color)10%,#0000)}}.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]){cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);box-shadow:none;color:color-mix(in srgb,var(--color-base-content)20%,#0000)}:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]))::placeholder{color:color-mix(in srgb,var(--color-base-content)20%,transparent)}@supports (color:color-mix(in lab, red, red)){:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]))::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled])){color:color-mix(in oklch,var(--color-base-content)20%,#0000)}}:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]))::file-selector-button{cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);--btn-border:#0000;--btn-noise:none;--btn-fg:color-mix(in srgb,var(--color-base-content)20%,#0000)}@supports (color:color-mix(in lab, red, red)){:is(.file-input:has(>input[disabled]),.file-input:is(:disabled,[disabled]))::file-selector-button{--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}.modal-backdrop{color:#0000;z-index:-1;grid-row-start:1;grid-column-start:1;place-self:stretch stretch;display:grid}.modal-backdrop button{cursor:pointer}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.col-span-full{grid-column:1/-1}.modal-box{background-color:var(--color-base-100);border-top-left-radius:var(--modal-tl,var(--radius-box));border-top-right-radius:var(--modal-tr,var(--radius-box));border-bottom-left-radius:var(--modal-bl,var(--radius-box));border-bottom-right-radius:var(--modal-br,var(--radius-box));opacity:0;overscroll-behavior:contain;grid-row-start:1;grid-column-start:1;width:91.6667%;max-width:32rem;max-height:100vh;padding:1.5rem;transition:translate .3s ease-out,scale .3s ease-out,opacity .2s ease-out 50ms,box-shadow .3s ease-out;overflow-y:auto;scale:95%;box-shadow:0 25px 50px -12px oklch(0% 0 0/.25)}.drawer-content{grid-row-start:1;grid-column-start:2;min-width:0}.chat-image{grid-row:span 2/span 2;align-self:flex-end}.chat-footer{grid-row-start:3;gap:.25rem;font-size:.6875rem;display:flex}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:calc(var(--spacing)*0)}.-mx-4{margin-inline:calc(var(--spacing)*-4)}.mx-auto{margin-inline:auto}.my-2{margin-block:calc(var(--spacing)*2)}.my-3{margin-block:calc(var(--spacing)*3)}.my-4{margin-block:calc(var(--spacing)*4)}.prose{color:var(--tw-prose-body);--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:NaN NaN NaN;--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:255 255 255;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);max-width:65ch;font-size:1rem;line-height:1.75}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px rgb(var(--tw-prose-kbd-shadows)/10%),0 3px 0 rgb(var(--tw-prose-kbd-shadows)/10%);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.validator-hint{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));margin-top:.5rem}.-mt-4{margin-top:calc(var(--spacing)*-4)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mt-10{margin-top:calc(var(--spacing)*10)}.mr-1{margin-right:calc(var(--spacing)*1)}.mr-2{margin-right:calc(var(--spacing)*2)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-10{margin-bottom:calc(var(--spacing)*10)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.navbar{align-items:center;width:100%;min-height:4rem;padding:.5rem;display:flex}.card-body{padding:var(--card-p,1.5rem);font-size:var(--card-fs,.875rem);flex-direction:column;flex:auto;gap:.5rem;display:flex}.card-body :where(p){flex-grow:1}.alert{border-radius:var(--radius-box);color:var(--color-base-content);background-color:var(--alert-color,var(--color-base-200));text-align:start;border:var(--border)solid var(--color-base-200);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);box-shadow:0 3px 0 -2px oklch(100% 0 0/calc(var(--depth)*.08))inset,0 1px #000,0 4px 3px -2px oklch(0% 0 0/calc(var(--depth)*.08));grid-template-columns:auto;grid-auto-flow:column;justify-content:start;place-items:center start;gap:1rem;padding-block:.75rem;padding-inline:1rem;font-size:.875rem;line-height:1.25rem;display:grid}@supports (color:color-mix(in lab, red, red)){.alert{box-shadow:0 3px 0 -2px oklch(100% 0 0/calc(var(--depth)*.08))inset,0 1px color-mix(in oklab,color-mix(in oklab,#000 20%,var(--alert-color,var(--color-base-200)))calc(var(--depth)*20%),#0000),0 4px 3px -2px oklch(0% 0 0/calc(var(--depth)*.08))}}.alert:has(:nth-child(2)){grid-template-columns:auto minmax(auto,1fr)}.alert.alert-outline{color:var(--alert-color);box-shadow:none;background-color:#0000;background-image:none}.alert.alert-dash{color:var(--alert-color);box-shadow:none;background-color:#0000;background-image:none;border-style:dashed}.alert.alert-soft{color:var(--alert-color,var(--color-base-content));background:var(--alert-color,var(--color-base-content));border-color:var(--alert-color,var(--color-base-content));box-shadow:none;background-image:none}@supports (color:color-mix(in lab, red, red)){.alert.alert-soft{background:color-mix(in oklab,var(--alert-color,var(--color-base-content))8%,var(--color-base-100));border-color:color-mix(in oklab,var(--alert-color,var(--color-base-content))10%,var(--color-base-100))}}.card-title{font-size:var(--cardtitle-fs,1.125rem);align-items:center;gap:.5rem;font-weight:600;display:flex}.chat{column-gap:.75rem;padding-block:.25rem;display:grid}.line-clamp-6{-webkit-line-clamp:6;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.btn-square{width:var(--size);height:var(--size);padding-inline:0}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.h-2{height:calc(var(--spacing)*2)}.h-3{height:calc(var(--spacing)*3)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-10{height:calc(var(--spacing)*10)}.h-24{height:calc(var(--spacing)*24)}.h-32{height:calc(var(--spacing)*32)}.h-96{height:calc(var(--spacing)*96)}.h-auto{height:auto}.h-full{height:100%}.h-screen{height:100vh}.max-h-56{max-height:calc(var(--spacing)*56)}.max-h-\[95\%\]{max-height:95%}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-24{min-height:calc(var(--spacing)*24)}.min-h-28{min-height:calc(var(--spacing)*28)}.min-h-\[10px\]{min-height:10px}.min-h-\[60vh\]{min-height:60vh}.min-h-\[95\%\]{min-height:95%}.min-h-\[100dvh\]{min-height:100dvh}.min-h-\[400px\]{min-height:400px}.min-h-\[500px\]{min-height:500px}.loading-md{width:calc(var(--size-selector,.25rem)*6)}.loading-sm{width:calc(var(--size-selector,.25rem)*5)}.loading-xs{width:calc(var(--size-selector,.25rem)*4)}.w-2{width:calc(var(--spacing)*2)}.w-3{width:calc(var(--spacing)*3)}.w-6{width:calc(var(--spacing)*6)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-11\/12{width:91.6667%}.w-24{width:calc(var(--spacing)*24)}.w-28{width:calc(var(--spacing)*28)}.w-32{width:calc(var(--spacing)*32)}.w-72{width:calc(var(--spacing)*72)}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-52{max-width:calc(var(--spacing)*52)}.max-w-72{max-width:calc(var(--spacing)*72)}.max-w-\[20ch\]{max-width:20ch}.max-w-\[90ch\]{max-width:90ch}.max-w-\[92vw\]{max-width:92vw}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-72{min-width:calc(var(--spacing)*72)}.min-w-\[90px\]{min-width:90px}.flex-1{flex:1}.flex-none{flex:none}.flex-shrink-0,.shrink-0{flex-shrink:0}.flex-grow,.grow{flex-grow:1}.-translate-y-1{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.swap-rotate .swap-on,.swap-rotate input:indeterminate~.swap-on{rotate:45deg}.swap-rotate input:is(:checked,:indeterminate)~.swap-on,.swap-rotate.swap-active .swap-on{rotate:none}.swap-rotate input:is(:checked,:indeterminate)~.swap-off,.swap-rotate.swap-active .swap-off{rotate:-45deg}.transform{transform:var(--tw-rotate-x)var(--tw-rotate-y)var(--tw-rotate-z)var(--tw-skew-x)var(--tw-skew-y)}.animate-pulse{animation:var(--animate-pulse)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.gap-0{gap:calc(var(--spacing)*0)}.gap-0\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing)*4)}.gap-y-2{row-gap:calc(var(--spacing)*2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px*var(--tw-divide-y-reverse));border-bottom-width:calc(1px*calc(1 - var(--tw-divide-y-reverse)))}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-none{border-radius:0}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-t-0{border-top-style:var(--tw-border-style);border-top-width:0}.border-r-2{border-right-style:var(--tw-border-style);border-right-width:2px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.alert-error{border-color:var(--color-error);color:var(--color-error-content);--alert-color:var(--color-error)}.border-base-200{border-color:var(--color-base-200)}.border-error{border-color:var(--color-error)}.border-error\/20{border-color:color-mix(in srgb,var(--color-error)20%,transparent)}@supports (color:color-mix(in lab, red, red)){.border-error\/20{border-color:color-mix(in oklab,var(--color-error)20%,transparent)}}.border-gray-200{border-color:var(--color-gray-200)}.border-neutral{border-color:var(--color-neutral)}.border-warning{border-color:var(--color-warning)}.bg-accent\/10{background-color:color-mix(in srgb,var(--color-accent)10%,transparent)}@supports (color:color-mix(in lab, red, red)){.bg-accent\/10{background-color:color-mix(in oklab,var(--color-accent)10%,transparent)}}.bg-base-100{background-color:var(--color-base-100)}.bg-base-200{background-color:var(--color-base-200)}.bg-blue-600{background-color:var(--color-blue-600)}.bg-error{background-color:var(--color-error)}.bg-error\/10{background-color:color-mix(in srgb,var(--color-error)10%,transparent)}@supports (color:color-mix(in lab, red, red)){.bg-error\/10{background-color:color-mix(in oklab,var(--color-error)10%,transparent)}}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-green-400{background-color:var(--color-green-400)}.bg-info\/10{background-color:color-mix(in srgb,var(--color-info)10%,transparent)}@supports (color:color-mix(in lab, red, red)){.bg-info\/10{background-color:color-mix(in oklab,var(--color-info)10%,transparent)}}.bg-primary\/10{background-color:color-mix(in srgb,var(--color-primary)10%,transparent)}@supports (color:color-mix(in lab, red, red)){.bg-primary\/10{background-color:color-mix(in oklab,var(--color-primary)10%,transparent)}}.bg-red-400{background-color:var(--color-red-400)}.bg-secondary\/10{background-color:color-mix(in srgb,var(--color-secondary)10%,transparent)}@supports (color:color-mix(in lab, red, red)){.bg-secondary\/10{background-color:color-mix(in oklab,var(--color-secondary)10%,transparent)}}.bg-transparent{background-color:#0000}.bg-warning{background-color:var(--color-warning)}.bg-warning\/10{background-color:color-mix(in srgb,var(--color-warning)10%,transparent)}@supports (color:color-mix(in lab, red, red)){.bg-warning\/10{background-color:color-mix(in oklab,var(--color-warning)10%,transparent)}}.bg-warning\/20{background-color:color-mix(in srgb,var(--color-warning)20%,transparent)}@supports (color:color-mix(in lab, red, red)){.bg-warning\/20{background-color:color-mix(in oklab,var(--color-warning)20%,transparent)}}.loading-dots{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='4' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1'/%3E%3C/circle%3E%3Ccircle cx='12' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.1s'/%3E%3C/circle%3E%3Ccircle cx='20' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.2s'/%3E%3C/circle%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='4' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1'/%3E%3C/circle%3E%3Ccircle cx='12' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.1s'/%3E%3C/circle%3E%3Ccircle cx='20' cy='12' r='3'%3E%3Canimate attributeName='cy' values='12;6;12;12' keyTimes='0;0.286;0.571;1' dur='1.05s' repeatCount='indefinite' keySplines='.33,0,.66,.33;.33,.66,.66,1' begin='0.2s'/%3E%3C/circle%3E%3C/svg%3E")}.loading-spinner{-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E")}.fill-current{fill:currentColor}.\!p-0{padding:calc(var(--spacing)*0)!important}.p-0{padding:calc(var(--spacing)*0)}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-8{padding:calc(var(--spacing)*8)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.pt-2{padding-top:calc(var(--spacing)*2)}.pt-3{padding-top:calc(var(--spacing)*3)}.pt-4{padding-top:calc(var(--spacing)*4)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-8{padding-right:calc(var(--spacing)*8)}.pr-10{padding-right:calc(var(--spacing)*10)}.pr-14{padding-right:calc(var(--spacing)*14)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pb-44{padding-bottom:calc(var(--spacing)*44)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-4{padding-left:calc(var(--spacing)*4)}.pl-9{padding-left:calc(var(--spacing)*9)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.7em\]{font-size:.7em}.text-\[0\.65rem\]{font-size:.65rem}.text-\[11px\]{font-size:11px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.text-accent{color:var(--color-accent)}.text-base-content{color:var(--color-base-content)}.text-base-content\/40{color:color-mix(in srgb,var(--color-base-content)40%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/40{color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}.text-base-content\/50{color:color-mix(in srgb,var(--color-base-content)50%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/50{color:color-mix(in oklab,var(--color-base-content)50%,transparent)}}.text-base-content\/60{color:color-mix(in srgb,var(--color-base-content)60%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/60{color:color-mix(in oklab,var(--color-base-content)60%,transparent)}}.text-base-content\/70{color:color-mix(in srgb,var(--color-base-content)70%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/70{color:color-mix(in oklab,var(--color-base-content)70%,transparent)}}.text-base-content\/80{color:color-mix(in srgb,var(--color-base-content)80%,transparent)}@supports (color:color-mix(in lab, red, red)){.text-base-content\/80{color:color-mix(in oklab,var(--color-base-content)80%,transparent)}}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-error{color:var(--color-error)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-info{color:var(--color-info)}.text-primary{color:var(--color-primary)}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-secondary{color:var(--color-secondary)}.text-success{color:var(--color-success)}.text-warning{color:var(--color-warning)}.text-warning-content{color:var(--color-warning-content)}.text-yellow-600{color:var(--color-yellow-600)}.text-yellow-700{color:var(--color-yellow-700)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.swap-active .swap-off{opacity:0}.swap-active .swap-on{opacity:1}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[4px_4px_0_0_\#000\]{--tw-shadow:4px 4px 0 0 var(--tw-shadow-color,#000);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[8px_8px_0_0_\#000\]{--tw-shadow:8px 8px 0 0 var(--tw-shadow-color,#000);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible){--btn-shadow:"";--btn-bg:#0000;--btn-border:#0000;--btn-noise:none}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible):not(:disabled,[disabled],.btn-disabled){--btn-fg:currentColor;outline-color:currentColor}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.btn-outline:not(.btn-active,:hover,:active:focus,:focus-visible,:disabled,[disabled],.btn-disabled,:checked){--btn-shadow:"";--btn-bg:#0000;--btn-fg:var(--btn-color);--btn-border:var(--btn-color);--btn-noise:none}.btn-sm{--fontsize:.75rem;--btn-p:.75rem;--size:calc(var(--size-field,.25rem)*8)}.btn-xs{--fontsize:.6875rem;--btn-p:.5rem;--size:calc(var(--size-field,.25rem)*6)}.btn-error{--btn-color:var(--color-error);--btn-fg:var(--color-error-content)}.btn-primary{--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content)}.btn-warning{--btn-color:var(--color-warning);--btn-fg:var(--color-warning-content)}@media (hover:hover){.hover\:cursor-pointer:hover{cursor:pointer}.hover\:bg-base-200:hover{background-color:var(--color-base-200)}.hover\:bg-base-200\/40:hover{background-color:color-mix(in srgb,var(--color-base-200)40%,transparent)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-base-200\/40:hover{background-color:color-mix(in oklab,var(--color-base-200)40%,transparent)}}.hover\:bg-base-200\/50:hover{background-color:color-mix(in srgb,var(--color-base-200)50%,transparent)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-base-200\/50:hover{background-color:color-mix(in oklab,var(--color-base-200)50%,transparent)}}.hover\:opacity-100:hover{opacity:1}}@media (min-width:40rem){.sm\:mt-0{margin-top:calc(var(--spacing)*0)}.sm\:mt-4{margin-top:calc(var(--spacing)*4)}.sm\:mt-8{margin-top:calc(var(--spacing)*8)}.sm\:mr-2{margin-right:calc(var(--spacing)*2)}.sm\:ml-2{margin-left:calc(var(--spacing)*2)}.sm\:flex{display:flex}.sm\:w-auto{width:auto}.sm\:max-w-md{max-width:var(--container-md)}.sm\:max-w-none{max-width:none}.sm\:flex-1{flex:1}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:items-end{align-items:flex-end}.sm\:items-start{align-items:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:justify-end{justify-content:flex-end}.sm\:gap-3{gap:calc(var(--spacing)*3)}:where(.sm\:space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*0)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*0)*calc(1 - var(--tw-space-y-reverse)))}.sm\:text-right{text-align:right}}@media (min-width:48rem){.md\:inline{display:inline}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:64rem){.lg\:drawer-open>.drawer-side{overflow-y:auto}.lg\:drawer-open>.drawer-toggle{display:none}.lg\:drawer-open>.drawer-toggle~.drawer-side{pointer-events:auto;visibility:visible;overscroll-behavior:auto;opacity:1;width:auto;display:block;position:sticky}.lg\:drawer-open>.drawer-toggle~.drawer-side>.drawer-overlay{cursor:default;background-color:#0000}.lg\:drawer-open>.drawer-toggle~.drawer-side>:not(.drawer-overlay),[dir=rtl] :is(.lg\:drawer-open>.drawer-toggle~.drawer-side>:not(.drawer-overlay)){translate:0%}.lg\:drawer-open>.drawer-toggle:checked~.drawer-side{pointer-events:auto;visibility:visible}.lg\:left-72{left:calc(var(--spacing)*72)}.lg\:block{display:block}.lg\:hidden{display:none}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width:80rem){.xl\:hidden{display:none}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width:96rem){.\32 xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (prefers-color-scheme:dark){.dark\:border-gray-700{border-color:var(--color-gray-700)}.dark\:bg-gray-800{background-color:var(--color-gray-800)}.dark\:bg-gray-900{background-color:var(--color-gray-900)}.dark\:text-blue-300{color:var(--color-blue-300)}.dark\:text-blue-400{color:var(--color-blue-400)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-gray-400{color:var(--color-gray-400)}.dark\:text-red-300{color:var(--color-red-300)}.dark\:text-red-400{color:var(--color-red-400)}.dark\:text-yellow-300{color:var(--color-yellow-300)}.dark\:text-yellow-400{color:var(--color-yellow-400)}}.menu li>.nb-btn:hover{background-color:#0000}.menu li>.nb-cta:hover{background-color:var(--color-accent);color:var(--color-accent-content)}.toast-alert{margin-top:calc(var(--spacing)*2);gap:calc(var(--spacing)*1);text-align:left;box-shadow:var(--nb-shadow);flex-direction:column;display:flex}.toast-alert-title{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}}@view-transition{navigation:auto}@font-face{font-family:Satoshi;src:url(fonts/Satoshi-Variable.woff2)format("woff2"),url(fonts/Satoshi-Variable.woff)format("woff"),url(fonts/Satoshi-Variable.ttf)format("truetype");font-weight:300 900;font-style:normal;font-display:swap}@font-face{font-family:Satoshi;src:url(fonts/Satoshi-VariableItalic.woff2)format("woff2"),url(fonts/Satoshi-VariableItalic.woff)format("woff"),url(fonts/Satoshi-VariableItalic.ttf)format("truetype");font-weight:300 900;font-style:italic;font-display:swap}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false;initial-value:rotateX(0)}@property --tw-rotate-y{syntax:"*";inherits:false;initial-value:rotateY(0)}@property --tw-rotate-z{syntax:"*";inherits:false;initial-value:rotateZ(0)}@property --tw-skew-x{syntax:"*";inherits:false;initial-value:skewX(0)}@property --tw-skew-y{syntax:"*";inherits:false;initial-value:skewY(0)}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}} \ No newline at end of file diff --git a/html-router/src/html_state.rs b/html-router/src/html_state.rs index 04f2fa1..c982fce 100644 --- a/html-router/src/html_state.rs +++ b/html-router/src/html_state.rs @@ -1,6 +1,7 @@ use common::storage::db::SurrealDbClient; use common::utils::template_engine::{ProvidesTemplateEngine, TemplateEngine}; use common::{create_template_engine, storage::db::ProvidesDb, utils::config::AppConfig}; +use composite_retrieval::reranking::RerankerPool; use std::sync::Arc; use tracing::debug; @@ -13,6 +14,7 @@ pub struct HtmlState { pub templates: Arc, pub session_store: Arc, pub config: AppConfig, + pub reranker_pool: Option>, } impl HtmlState { @@ -21,6 +23,7 @@ impl HtmlState { openai_client: Arc, session_store: Arc, config: AppConfig, + reranker_pool: Option>, ) -> Result> { let template_engine = create_template_engine!("templates"); debug!("Template engine created for html_router."); @@ -31,6 +34,7 @@ impl HtmlState { session_store, templates: Arc::new(template_engine), config, + reranker_pool, }) } } diff --git a/html-router/src/routes/chat/message_response_stream.rs b/html-router/src/routes/chat/message_response_stream.rs index b6b05d1..5e6f08b 100644 --- a/html-router/src/routes/chat/message_response_stream.rs +++ b/html-router/src/routes/chat/message_response_stream.rs @@ -118,11 +118,17 @@ pub async fn get_response_stream( }; // 2. Retrieve knowledge entities + let rerank_lease = match state.reranker_pool.as_ref() { + Some(pool) => Some(pool.checkout().await), + None => None, + }; + let entities = match retrieve_entities( &state.db, &state.openai_client, &user_message.content, &user.id, + rerank_lease, ) .await { diff --git a/html-router/src/routes/knowledge/handlers.rs b/html-router/src/routes/knowledge/handlers.rs index 892496f..a5a3c52 100644 --- a/html-router/src/routes/knowledge/handlers.rs +++ b/html-router/src/routes/knowledge/handlers.rs @@ -195,8 +195,19 @@ pub async fn suggest_knowledge_relationships( if !query_parts.is_empty() { let query = query_parts.join(" "); - if let Ok(results) = - retrieve_entities(&state.db, &state.openai_client, &query, &user.id).await + let rerank_lease = match state.reranker_pool.as_ref() { + Some(pool) => Some(pool.checkout().await), + None => None, + }; + + if let Ok(results) = retrieve_entities( + &state.db, + &state.openai_client, + &query, + &user.id, + rerank_lease, + ) + .await { for RetrievedEntity { entity, score, .. } in results { if suggestion_scores.len() >= MAX_RELATIONSHIP_SUGGESTIONS { diff --git a/ingestion-pipeline/src/pipeline/mod.rs b/ingestion-pipeline/src/pipeline/mod.rs index 8f721c3..6abb810 100644 --- a/ingestion-pipeline/src/pipeline/mod.rs +++ b/ingestion-pipeline/src/pipeline/mod.rs @@ -26,6 +26,7 @@ use common::{ }, utils::config::AppConfig, }; +use composite_retrieval::reranking::RerankerPool; use tracing::{debug, info, warn}; use self::{ @@ -45,9 +46,14 @@ impl IngestionPipeline { db: Arc, openai_client: Arc>, config: AppConfig, + reranker_pool: Option>, ) -> Result { - let services = - DefaultPipelineServices::new(db.clone(), openai_client.clone(), config.clone()); + let services = DefaultPipelineServices::new( + db.clone(), + openai_client.clone(), + config.clone(), + reranker_pool, + ); Self::with_services(db, IngestionConfig::default(), Arc::new(services)) } diff --git a/ingestion-pipeline/src/pipeline/services.rs b/ingestion-pipeline/src/pipeline/services.rs index 24f222c..0ac753e 100644 --- a/ingestion-pipeline/src/pipeline/services.rs +++ b/ingestion-pipeline/src/pipeline/services.rs @@ -18,7 +18,9 @@ use common::{ }, utils::{config::AppConfig, embedding::generate_embedding}, }; -use composite_retrieval::{retrieve_entities, retrieved_entities_to_json, RetrievedEntity}; +use composite_retrieval::{ + reranking::RerankerPool, retrieve_entities, retrieved_entities_to_json, RetrievedEntity, +}; use text_splitter::TextSplitter; use super::{enrichment_result::LLMEnrichmentResult, preparation::to_text_content}; @@ -62,6 +64,7 @@ pub struct DefaultPipelineServices { db: Arc, openai_client: Arc>, config: AppConfig, + reranker_pool: Option>, } impl DefaultPipelineServices { @@ -69,11 +72,13 @@ impl DefaultPipelineServices { db: Arc, openai_client: Arc>, config: AppConfig, + reranker_pool: Option>, ) -> Self { Self { db, openai_client, config, + reranker_pool, } } @@ -151,7 +156,19 @@ impl PipelineServices for DefaultPipelineServices { content.text, content.category, content.context ); - retrieve_entities(&self.db, &self.openai_client, &input_text, &content.user_id).await + let rerank_lease = match &self.reranker_pool { + Some(pool) => Some(pool.checkout().await), + None => None, + }; + + retrieve_entities( + &self.db, + &self.openai_client, + &input_text, + &content.user_id, + rerank_lease, + ) + .await } async fn run_enrichment( diff --git a/main/Cargo.toml b/main/Cargo.toml index 7b4ef22..d06f430 100644 --- a/main/Cargo.toml +++ b/main/Cargo.toml @@ -25,6 +25,7 @@ ingestion-pipeline = { path = "../ingestion-pipeline" } api-router = { path = "../api-router" } html-router = { path = "../html-router" } common = { path = "../common" } +composite-retrieval = { path = "../composite-retrieval" } [dev-dependencies] tower = "0.5" diff --git a/main/src/main.rs b/main/src/main.rs index 6c77a6f..ccf161a 100644 --- a/main/src/main.rs +++ b/main/src/main.rs @@ -1,6 +1,7 @@ use api_router::{api_routes_v1, api_state::ApiState}; use axum::{extract::FromRef, Router}; use common::{storage::db::SurrealDbClient, utils::config::get_config}; +use composite_retrieval::reranking::RerankerPool; use html_router::{html_routes, html_state::HtmlState}; use ingestion_pipeline::{pipeline::IngestionPipeline, run_worker_loop}; use std::sync::Arc; @@ -43,8 +44,15 @@ async fn main() -> Result<(), Box> { .with_api_base(&config.openai_base_url), )); - let html_state = - HtmlState::new_with_resources(db, openai_client, session_store, config.clone())?; + let reranker_pool = RerankerPool::maybe_from_config(&config)?; + + let html_state = HtmlState::new_with_resources( + db, + openai_client, + session_store, + config.clone(), + reranker_pool.clone(), + )?; let api_state = ApiState { db: html_state.db.clone(), @@ -102,9 +110,14 @@ async fn main() -> Result<(), Box> { .with_api_base(&config.openai_base_url), )); let ingestion_pipeline = Arc::new( - IngestionPipeline::new(worker_db.clone(), openai_client.clone(), config.clone()) - .await - .unwrap(), + IngestionPipeline::new( + worker_db.clone(), + openai_client.clone(), + config.clone(), + reranker_pool.clone(), + ) + .await + .unwrap(), ); info!("Starting worker process"); @@ -152,6 +165,7 @@ mod tests { openai_base_url: "https://example.com".into(), storage: StorageKind::Local, pdf_ingest_mode: PdfIngestMode::LlmFirst, + ..Default::default() } } @@ -181,9 +195,14 @@ mod tests { .with_api_base(&config.openai_base_url), )); - let html_state = - HtmlState::new_with_resources(db.clone(), openai_client, session_store, config.clone()) - .expect("failed to build html state"); + let html_state = HtmlState::new_with_resources( + db.clone(), + openai_client, + session_store, + config.clone(), + None, + ) + .expect("failed to build html state"); let api_state = ApiState { db: html_state.db.clone(), diff --git a/main/src/server.rs b/main/src/server.rs index 51ac8c4..280d659 100644 --- a/main/src/server.rs +++ b/main/src/server.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use api_router::{api_routes_v1, api_state::ApiState}; use axum::{extract::FromRef, Router}; use common::{storage::db::SurrealDbClient, utils::config::get_config}; +use composite_retrieval::reranking::RerankerPool; use html_router::{html_routes, html_state::HtmlState}; use tracing::info; use tracing_subscriber::{fmt, prelude::*, EnvFilter}; @@ -41,8 +42,15 @@ async fn main() -> Result<(), Box> { .with_api_base(&config.openai_base_url), )); - let html_state = - HtmlState::new_with_resources(db, openai_client, session_store, config.clone())?; + let reranker_pool = RerankerPool::maybe_from_config(&config)?; + + let html_state = HtmlState::new_with_resources( + db, + openai_client, + session_store, + config.clone(), + reranker_pool, + )?; let api_state = ApiState { db: html_state.db.clone(), diff --git a/main/src/worker.rs b/main/src/worker.rs index 5951b1c..9f7c050 100644 --- a/main/src/worker.rs +++ b/main/src/worker.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use common::{storage::db::SurrealDbClient, utils::config::get_config}; +use composite_retrieval::reranking::RerankerPool; use ingestion_pipeline::{pipeline::IngestionPipeline, run_worker_loop}; use tracing_subscriber::{fmt, prelude::*, EnvFilter}; @@ -32,8 +33,11 @@ async fn main() -> Result<(), Box> { .with_api_base(&config.openai_base_url), )); - let ingestion_pipeline = - Arc::new(IngestionPipeline::new(db.clone(), openai_client.clone(), config).await?); + let reranker_pool = RerankerPool::maybe_from_config(&config)?; + + let ingestion_pipeline = Arc::new( + IngestionPipeline::new(db.clone(), openai_client.clone(), config, reranker_pool).await?, + ); run_worker_loop(db, ingestion_pipeline).await }