diff --git a/.gitignore b/.gitignore index 22d74cdf..c1d2267b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ target/ +wit/ +uqbar .vscode .app-signing .DS_Store diff --git a/Cargo.lock b/Cargo.lock index bce5c000..dc38e2ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,7 +179,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -189,7 +189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -200,9 +200,9 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arbitrary" -version = "1.3.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" [[package]] name = "array-init" @@ -234,17 +234,6 @@ dependencies = [ "term", ] -[[package]] -name = "async-recursion" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] - [[package]] name = "async-trait" version = "0.1.73" @@ -339,6 +328,27 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.32", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -384,7 +394,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -398,16 +408,7 @@ dependencies = [ "cc", "cfg-if", "constant_time_eq 0.3.0", - "digest 0.10.7", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", + "digest", ] [[package]] @@ -425,7 +426,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ - "sha2 0.10.7", + "sha2", "tinyvec", ] @@ -495,7 +496,7 @@ dependencies = [ "cap-primitives", "cap-std", "io-lifetimes 2.0.2", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -506,7 +507,7 @@ checksum = "6ffc30dee200c20b4dcb80572226f42658e1d9c4b668656d7cc59c33d50e396e" dependencies = [ "cap-primitives", "cap-std", - "rustix 0.38.13", + "rustix 0.38.27", "smallvec 1.11.0", ] @@ -522,8 +523,8 @@ dependencies = [ "io-lifetimes 2.0.2", "ipnet", "maybe-owned", - "rustix 0.38.13", - "windows-sys", + "rustix 0.38.27", + "windows-sys 0.48.0", "winx", ] @@ -546,7 +547,7 @@ dependencies = [ "cap-primitives", "io-extras", "io-lifetimes 2.0.2", - "rustix 0.38.13", + "rustix 0.38.27", ] [[package]] @@ -557,7 +558,7 @@ checksum = "f8f52b3c8f4abfe3252fd0a071f3004aaa3b18936ec97bdbd8763ce03aff6247" dependencies = [ "cap-primitives", "once_cell", - "rustix 0.38.13", + "rustix 0.38.27", "winx", ] @@ -594,6 +595,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -659,9 +669,8 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", - "serde", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -684,6 +693,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.4.10" @@ -732,11 +752,11 @@ checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" dependencies = [ "bs58", "coins-core", - "digest 0.10.7", - "hmac 0.12.1", + "digest", + "hmac", "k256", "serde", - "sha2 0.10.7", + "sha2", "thiserror", ] @@ -748,11 +768,11 @@ checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" dependencies = [ "bitvec", "coins-bip32", - "hmac 0.12.1", + "hmac", "once_cell", "pbkdf2 0.12.2", "rand", - "sha2 0.10.7", + "sha2", "thiserror", ] @@ -765,13 +785,13 @@ dependencies = [ "base64 0.21.4", "bech32", "bs58", - "digest 0.10.7", + "digest", "generic-array", "hex", "ripemd", "serde", "serde_derive", - "sha2 0.10.7", + "sha2", "sha3", "thiserror", ] @@ -848,18 +868,18 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b5bb9245ec7dcc04d03110e538d31f0969d301c9d673145f4b4d5c3478539a3" +checksum = "8e7e56668d2263f92b691cb9e4a2fcb186ca0384941fe420484322fa559c3329" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb18d10e5ddac43ba4ca8fd4e310938569c3e484cc01b6372b27dc5bb4dfd28" +checksum = "2a9ff61938bf11615f55b80361288c68865318025632ea73c65c0b44fa16283c" dependencies = [ "bumpalo", "cranelift-bforest", @@ -878,33 +898,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3ce6d22982c1b9b6b012654258bab1a13947bb12703518bef06b1a4867c3d6" +checksum = "50656bf19e3d4a153b404ff835b8b59e924cfa3682ebe0d3df408994f37983f6" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47220fd4f9a0ce23541652b6f16f83868d282602c600d14934b2a4c166b4bd80" +checksum = "388041deeb26109f1ea73c1812ea26bfd406c94cbce0bb5230aa44277e43b209" [[package]] name = "cranelift-control" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed5a4c42672aea9b6e820046b52e47a1c05d3394a6cdf4cb3c3c4b702f954bd2" +checksum = "b39b7c512ffac527e5b5df9beae3d67ab85d07dca6d88942c16195439fedd1d3" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b4e9a3296fc827f9d35135dc2c0c8dd8d8359eb1ef904bae2d55d5bcb0c9f94" +checksum = "fdb25f573701284fe2bcf88209d405342125df00764b396c923e11eafc94d892" dependencies = [ "serde", "serde_derive", @@ -912,9 +932,9 @@ dependencies = [ [[package]] name = "cranelift-frontend" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ec537d0f0b8e084517f3e7bfa1d89af343d7c7df455573fca9f272d4e01267" +checksum = "e57374fd11d72cf9ffb85ff64506ed831440818318f58d09f45b4185e5e9c376" dependencies = [ "cranelift-codegen", "log", @@ -924,15 +944,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45bab6d69919d210a50331d35cc6ce111567bc040aebac63a8ae130d0400a075" +checksum = "ae769b235f6ea2f86623a3ff157cc04a4ff131dc9fe782c2ebd35f272043581e" [[package]] name = "cranelift-native" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32e81605f352cf37af5463f11cd7deec7b6572741931a8d372f7fdd4a744f5d" +checksum = "3dc7bfb8f13a0526fe20db338711d9354729b861c336978380bb10f7f17dd207" dependencies = [ "cranelift-codegen", "libc", @@ -941,9 +961,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.101.4" +version = "0.102.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0edaa4cbec1bc787395c074233df2652dd62f3e29d3ee60329514a0a51e6b045" +checksum = "2c5f41a4af931b756be05af0dd374ce200aae2d52cea16b0beb07e8b52732c35" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -951,7 +971,7 @@ dependencies = [ "itertools 0.10.5", "log", "smallvec 1.11.0", - "wasmparser 0.115.0", + "wasmparser 0.116.0", "wasmtime-types", ] @@ -1062,16 +1082,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "ctr" version = "0.8.0" @@ -1187,7 +1197,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", - "pem-rfc7468", "zeroize", ] @@ -1239,22 +1248,13 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "const-oid", "crypto-common", "subtle", @@ -1318,7 +1318,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1344,12 +1344,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - [[package]] name = "dunce" version = "1.0.4" @@ -1363,7 +1357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", - "digest 0.10.7", + "digest", "elliptic-curve", "rfc6979", "signature", @@ -1384,7 +1378,7 @@ checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" dependencies = [ "base16ct", "crypto-bigint", - "digest 0.10.7", + "digest", "ff", "generic-array", "group", @@ -1459,23 +1453,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -1486,15 +1469,15 @@ checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" dependencies = [ "aes 0.8.3", "ctr 0.9.2", - "digest 0.10.7", + "digest", "hex", - "hmac 0.12.1", + "hmac", "pbkdf2 0.11.0", "rand", "scrypt", "serde", "serde_json", - "sha2 0.10.7", + "sha2", "sha3", "thiserror", "uuid 0.8.2", @@ -1725,7 +1708,7 @@ dependencies = [ "futures-timer", "futures-util", "hashers", - "http 0.2.9", + "http", "instant", "jsonwebtoken", "once_cell", @@ -1759,7 +1742,7 @@ dependencies = [ "eth-keystore", "ethers-core", "rand", - "sha2 0.10.7", + "sha2", "thiserror", "tracing", ] @@ -1777,7 +1760,7 @@ dependencies = [ "ethers-core", "glob", "home", - "md-5 0.10.5", + "md-5", "num_cpus", "once_cell", "path-slash", @@ -1812,6 +1795,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "2.0.0" @@ -1825,8 +1814,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b0377f1edc77dbd1118507bc7a66e4ab64d2b90c66f90726dc801e73a8c68f9" dependencies = [ "cfg-if", - "rustix 0.38.13", - "windows-sys", + "rustix 0.38.27", + "windows-sys 0.48.0", ] [[package]] @@ -1910,8 +1899,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd738b84894214045e8414eaded76359b4a5773f0a0a56b16575110739cdcf39" dependencies = [ "io-lifetimes 2.0.2", - "rustix 0.38.13", - "windows-sys", + "rustix 0.38.27", + "windows-sys 0.48.0", ] [[package]] @@ -2154,7 +2143,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.9", + "http", "indexmap 1.9.3", "slab", "tokio", @@ -2196,6 +2185,15 @@ dependencies = [ "fxhash", ] +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.0", +] + [[package]] name = "headers" version = "0.3.9" @@ -2205,7 +2203,7 @@ dependencies = [ "base64 0.21.4", "bytes", "headers-core", - "http 0.2.9", + "http", "httpdate", "mime", "sha1", @@ -2217,7 +2215,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http 0.2.9", + "http", ] [[package]] @@ -2225,9 +2223,6 @@ name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", -] [[package]] name = "hermit-abi" @@ -2247,17 +2242,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" dependencies = [ - "hmac 0.12.1", -] - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest 0.9.0", + "hmac", ] [[package]] @@ -2266,7 +2251,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -2275,7 +2260,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2289,17 +2274,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http-body" version = "0.4.5" @@ -2307,7 +2281,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http 0.2.9", + "http", "pin-project-lite", ] @@ -2334,7 +2308,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.9", + "http", "http-body", "httparse", "httpdate", @@ -2354,7 +2328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ "futures-util", - "http 0.2.9", + "http", "hyper", "rustls", "tokio", @@ -2534,7 +2508,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d3c230ee517ee76b1cc593b52939ff68deda3fae9e41eca426c6b4993df51c4" dependencies = [ "io-lifetimes 2.0.2", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2545,7 +2519,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2576,8 +2550,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.13", - "windows-sys", + "rustix 0.38.27", + "windows-sys 0.48.0", ] [[package]] @@ -2616,9 +2590,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "ittapi" -version = "0.3.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e0d0b7b3b53d92a7e8b80ede3400112a6b8b4c98d1f5b8b16bb787c780582c" +checksum = "6b996fe614c41395cdaedf3cf408a9534851090959d90d54a535f675550b64b1" dependencies = [ "anyhow", "ittapi-sys", @@ -2627,9 +2601,9 @@ dependencies = [ [[package]] name = "ittapi-sys" -version = "0.3.4" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f8763c96e54e6d6a0dccc2990d8b5e33e3313aaeae6185921a3f4c1614a77c" +checksum = "52f5385394064fa2c886205dba02598013ce83d3e92d33dbdc0c52fe0e7bf4fc" dependencies = [ "cc", ] @@ -2674,11 +2648,11 @@ checksum = "6204285f77fe7d9784db3fdc449ecce1a0114927a51d5a41c4c7a292011c015f" dependencies = [ "base64 0.13.1", "crypto-common", - "digest 0.10.7", - "hmac 0.12.1", + "digest", + "hmac", "serde", "serde_json", - "sha2 0.10.7", + "sha2", ] [[package]] @@ -2691,7 +2665,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.7", + "sha2", "signature", ] @@ -2737,9 +2711,12 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin 0.5.2", -] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "leb128" @@ -2749,15 +2726,57 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libm" -version = "0.2.7" +name = "libloading" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "librocksdb-sys" +version = "0.11.0+8.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "lz4-sys", + "zstd-sys", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] [[package]] name = "linux-raw-sys" @@ -2767,9 +2786,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lock_api" @@ -2788,12 +2807,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] -name = "lru-mem" -version = "0.3.0" +name = "lz4-sys" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf5c8c26d903a41c80d4cc171940a57a4d1bc51139ebd6aad87e2f9ae3774780" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" dependencies = [ - "hashbrown 0.14.0", + "cc", + "libc", ] [[package]] @@ -2823,24 +2843,13 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -[[package]] -name = "md-5" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "md-5" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -2883,6 +2892,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -2901,7 +2916,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2913,7 +2928,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http 0.2.9", + "http", "httparse", "log", "memchr", @@ -2967,6 +2982,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -2978,23 +3003,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-bigint-dig" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" -dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand", - "smallvec 1.11.0", - "zeroize", -] - [[package]] name = "num-integer" version = "0.1.45" @@ -3005,17 +3013,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.16" @@ -3023,7 +3020,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -3213,7 +3209,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec 1.11.0", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -3251,10 +3247,10 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "digest 0.10.7", - "hmac 0.12.1", + "digest", + "hmac", "password-hash", - "sha2 0.10.7", + "sha2", ] [[package]] @@ -3263,10 +3259,16 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest 0.10.7", - "hmac 0.12.1", + "digest", + "hmac", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "pem" version = "1.1.1" @@ -3276,15 +3278,6 @@ dependencies = [ "base64 0.13.1", ] -[[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.0" @@ -3394,17 +3387,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - [[package]] name = "pkcs8" version = "0.10.2" @@ -3570,7 +3552,7 @@ dependencies = [ "dns-lookup", "futures-core", "futures-util", - "http 0.2.9", + "http", "hyper", "hyper-system-resolver", "pin-project-lite", @@ -3690,9 +3672,9 @@ dependencies = [ [[package]] name = "regalloc2" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b4dcbd3a2ae7fb94b5813fa0e957c6ab51bf5d0a8ee1b69e0c2d0f1e6eb8485" +checksum = "ad156d539c879b7a24a363a2016d77961786e71f48f2e2fc8302a92abd2429a6" dependencies = [ "hashbrown 0.13.2", "log", @@ -3738,9 +3720,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ "base64 0.21.4", "bytes", @@ -3748,7 +3730,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.9", + "http", "http-body", "hyper", "hyper-rustls", @@ -3766,6 +3748,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls", @@ -3784,7 +3767,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac 0.12.1", + "hmac", "subtle", ] @@ -3809,7 +3792,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -3856,6 +3839,16 @@ dependencies = [ "serde", ] +[[package]] +name = "rocksdb" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +dependencies = [ + "libc", + "librocksdb-sys", +] + [[package]] name = "route-recognizer" version = "0.3.1" @@ -3863,107 +3856,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" [[package]] -name = "rsa" -version = "0.9.2" +name = "rusqlite" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +checksum = "a78046161564f5e7cd9008aff3b2990b3850dc8e0349119b98e8f251e099f24d" dependencies = [ - "byteorder", - "const-oid", - "digest 0.10.7", - "num-bigint-dig", - "num-integer", - "num-iter", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core", - "signature", - "spki", - "subtle", - "zeroize", -] - -[[package]] -name = "rusoto_core" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db30db44ea73551326269adcf7a2169428a054f14faf9e1768f2163494f2fa2" -dependencies = [ - "async-trait", - "base64 0.13.1", - "bytes", - "crc32fast", - "futures", - "http 0.2.9", - "hyper", - "hyper-tls", - "lazy_static", - "log", - "rusoto_credential", - "rusoto_signature", - "rustc_version", - "serde", - "serde_json", - "tokio", - "xml-rs", -] - -[[package]] -name = "rusoto_credential" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee0a6c13db5aad6047b6a44ef023dbbc21a056b6dab5be3b79ce4283d5c02d05" -dependencies = [ - "async-trait", - "chrono", - "dirs-next", - "futures", - "hyper", - "serde", - "serde_json", - "shlex", - "tokio", - "zeroize", -] - -[[package]] -name = "rusoto_s3" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aae4677183411f6b0b412d66194ef5403293917d66e70ab118f07cc24c5b14d" -dependencies = [ - "async-trait", - "bytes", - "futures", - "rusoto_core", - "xml-rs", -] - -[[package]] -name = "rusoto_signature" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ae95491c8b4847931e291b151127eccd6ff8ca13f33603eb3d0035ecb05272" -dependencies = [ - "base64 0.13.1", - "bytes", - "chrono", - "digest 0.9.0", - "futures", - "hex", - "hmac 0.11.0", - "http 0.2.9", - "hyper", - "log", - "md-5 0.9.1", - "percent-encoding", - "pin-project-lite", - "rusoto_credential", - "rustc_version", - "serde", - "sha2 0.9.9", - "tokio", + "bitflags 2.4.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec 1.11.0", ] [[package]] @@ -4004,22 +3907,22 @@ dependencies = [ "io-lifetimes 1.0.11", "libc", "linux-raw-sys 0.3.8", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "rustix" -version = "0.38.13" +version = "0.38.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +checksum = "bfeae074e687625746172d639330f1de242a178bf3189b51e35a7a21573513ac" dependencies = [ "bitflags 2.4.0", "errno", "itoa", "libc", - "linux-raw-sys 0.4.7", + "linux-raw-sys 0.4.12", "once_cell", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -4113,7 +4016,7 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4134,10 +4037,10 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" dependencies = [ - "hmac 0.12.1", + "hmac", "pbkdf2 0.11.0", "salsa20", - "sha2 0.10.7", + "sha2", ] [[package]] @@ -4279,20 +4182,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "digest", ] [[package]] @@ -4303,7 +4193,7 @@ checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -4312,7 +4202,7 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.7", + "digest", "keccak", ] @@ -4367,7 +4257,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.7", + "digest", "rand_core", ] @@ -4432,7 +4322,7 @@ dependencies = [ "rand_core", "ring", "rustc_version", - "sha2 0.10.7", + "sha2", "subtle", ] @@ -4453,7 +4343,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4470,15 +4360,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "spdx" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b19b32ed6d899ab23174302ff105c1577e45a06b08d4fe0a9dd13ce804bbbf71" -dependencies = [ - "smallvec 1.11.0", -] - [[package]] name = "spin" version = "0.5.2" @@ -4586,7 +4467,7 @@ dependencies = [ "semver", "serde", "serde_json", - "sha2 0.10.7", + "sha2", "thiserror", "url", "zip", @@ -4614,6 +4495,27 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-interface" version = "0.26.0" @@ -4625,8 +4527,8 @@ dependencies = [ "cap-std", "fd-lock", "io-lifetimes 2.0.2", - "rustix 0.38.13", - "windows-sys", + "rustix 0.38.27", + "windows-sys 0.48.0", "winx", ] @@ -4638,9 +4540,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "tempfile" @@ -4651,8 +4553,8 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.38.13", - "windows-sys", + "rustix 0.38.27", + "windows-sys 0.48.0", ] [[package]] @@ -4750,10 +4652,9 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "signal-hook-registry", "socket2 0.5.4", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4993,7 +4894,7 @@ dependencies = [ "base64 0.13.1", "byteorder", "bytes", - "http 0.2.9", + "http", "httparse", "log", "rand", @@ -5012,7 +4913,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 0.2.9", + "http", "httparse", "log", "rand", @@ -5071,12 +4972,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - [[package]] name = "unicode-width" version = "0.1.10" @@ -5121,7 +5016,6 @@ version = "0.4.0" dependencies = [ "aes-gcm 0.10.2", "anyhow", - "async-recursion", "async-trait", "base64 0.13.1", "bincode", @@ -5133,8 +5027,7 @@ dependencies = [ "clap", "crossterm", "dashmap", - "digest 0.10.7", - "dotenv", + "digest", "elliptic-curve", "ethers", "ethers-providers", @@ -5144,12 +5037,11 @@ dependencies = [ "getrandom", "hex", "hkdf", - "hmac 0.12.1", - "http 0.2.9", + "hmac", + "http", "jwt", "lazy_static", "log", - "lru-mem", "nohash-hasher", "num-traits", "open", @@ -5158,20 +5050,17 @@ dependencies = [ "reqwest", "ring", "rmp-serde", + "rocksdb", "route-recognizer", - "rsa", - "rusoto_core", - "rusoto_credential", - "rusoto_s3", + "rusqlite", "serde", "serde_json", "serde_urlencoded", - "sha2 0.10.7", + "sha2", "snow", "thiserror", "tokio", "tokio-tungstenite 0.20.1", - "uqbar_process_lib", "url", "uuid 1.4.1", "walkdir", @@ -5181,22 +5070,6 @@ dependencies = [ "zip", ] -[[package]] -name = "uqbar_process_lib" -version = "0.3.0" -source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" -dependencies = [ - "anyhow", - "bincode", - "http 1.0.0", - "rand", - "serde", - "serde_json", - "thiserror", - "url", - "wit-bindgen", -] - [[package]] name = "url" version = "2.4.1" @@ -5281,7 +5154,7 @@ dependencies = [ "futures-channel", "futures-util", "headers", - "http 0.2.9", + "http", "hyper", "log", "mime", @@ -5310,9 +5183,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi-cap-std-sync" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd94e147b273348ec68ae412b8bc17a4d372b9e070535b98e3e2c5a3ffd8e83" +checksum = "a4328de5cf2a0debfc48216fe9c2747badc64957837641f5836cd8b3d48d73f0" dependencies = [ "anyhow", "async-trait", @@ -5324,18 +5197,18 @@ dependencies = [ "io-extras", "io-lifetimes 2.0.2", "once_cell", - "rustix 0.38.13", + "rustix 0.38.27", "system-interface", "tracing", "wasi-common", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "wasi-common" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d5166f7432ee36d06aa9f9bd7990a00330401fdbc75be7887ea952a299b9a19" +checksum = "84f6774ec9e464b7373f683bc57ff87fcca5fd26a7d6bdb7438fb2f56a545aa6" dependencies = [ "anyhow", "bitflags 2.4.0", @@ -5343,12 +5216,12 @@ dependencies = [ "cap-std", "io-extras", "log", - "rustix 0.38.13", + "rustix 0.38.27", "thiserror", "tracing", "wasmtime", "wiggle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -5419,48 +5292,22 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-encoder" -version = "0.35.0" +version = "0.36.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca90ba1b5b0a70d3d49473c5579951f3bddc78d47b59256d2f9d4922b150aca" +checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" dependencies = [ "leb128", ] [[package]] name = "wasm-encoder" -version = "0.36.1" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53ae0be20bf87918df4fa831bfbbd0b491d24aee407ed86360eae4c2c5608d38" +checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" dependencies = [ "leb128", ] -[[package]] -name = "wasm-metadata" -version = "0.10.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5621910462c61a8efc3248fdfb1739bf649bb335b0df935c27b340418105f9d8" -dependencies = [ - "anyhow", - "indexmap 2.0.0", - "serde", - "serde_derive", - "serde_json", - "spdx", - "wasm-encoder 0.36.1", - "wasmparser 0.116.0", -] - -[[package]] -name = "wasmparser" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e06c0641a4add879ba71ccb3a1e4278fd546f76f1eafb21d8f7b07733b547cd5" -dependencies = [ - "indexmap 2.0.0", - "semver", -] - [[package]] name = "wasmparser" version = "0.116.0" @@ -5472,20 +5319,30 @@ dependencies = [ ] [[package]] -name = "wasmprinter" -version = "0.2.71" +name = "wasmparser" +version = "0.118.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f98260aa20f939518bcec1fac32c78898d5c68872e7363a4651f21f791b6c7e" +checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" +dependencies = [ + "indexmap 2.0.0", + "semver", +] + +[[package]] +name = "wasmprinter" +version = "0.2.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d027eb8294904fc715ac0870cebe6b0271e96b90605ee21511e7565c4ce568c" dependencies = [ "anyhow", - "wasmparser 0.116.0", + "wasmparser 0.118.1", ] [[package]] name = "wasmtime" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca54f6090ce46973f33a79f265924b204f248f91aec09229bce53d19d567c1a6" +checksum = "642e12d108e800215263e3b95972977f473957923103029d7d617db701d67ba4" dependencies = [ "anyhow", "async-trait", @@ -5506,8 +5363,8 @@ dependencies = [ "serde_derive", "serde_json", "target-lexicon", - "wasm-encoder 0.35.0", - "wasmparser 0.115.0", + "wasm-encoder 0.36.2", + "wasmparser 0.116.0", "wasmtime-cache", "wasmtime-component-macro", "wasmtime-component-util", @@ -5518,43 +5375,43 @@ dependencies = [ "wasmtime-runtime", "wasmtime-winch", "wat", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-asm-macros" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54984bc0b5689da87a43d7c181d23092b4d5cfcbb7ae3eb6b917dd55865d95e6" +checksum = "beada8bb15df52503de0a4c58de4357bfd2f96d9a44a6e547bad11efdd988b47" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-cache" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4df7655bb73b592189033ab046aa47c1da486d70bc9c1ebf45e55ac030bdf4" +checksum = "aba5bf44d044d25892c03fb3534373936ee204141ff92bac8297787ac7f22318" dependencies = [ "anyhow", "base64 0.21.4", "bincode", "directories-next", "log", - "rustix 0.38.13", + "rustix 0.38.27", "serde", "serde_derive", - "sha2 0.10.7", + "sha2", "toml 0.5.11", - "windows-sys", + "windows-sys 0.48.0", "zstd", ] [[package]] name = "wasmtime-component-macro" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64de99fb7c4c383832b85efcaae95f7094a5c505d80146227ce97ab436cbac68" +checksum = "56ccba556991465cca68d5a54769684bcf489fb532059da55105f851642d52c1" dependencies = [ "anyhow", "proc-macro2", @@ -5567,15 +5424,15 @@ dependencies = [ [[package]] name = "wasmtime-component-util" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9141a8df069e106eee0c3a8173c0809cf1a4b5630628cfb1f25ab114720093" +checksum = "05492a177a6006cb73f034d6e9a6fad6da55b23c4398835cb0012b5fa51ecf67" [[package]] name = "wasmtime-cranelift" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cf3cee8be02f5006d21b773ffd6802f96a0b7d661ff2ad8a01fb93df458b1aa" +checksum = "fe2e7532f1d6adbcc57e69bb6a7c503f0859076d07a9b4b6aabe8021ff8a05fd" dependencies = [ "anyhow", "cfg-if", @@ -5590,7 +5447,7 @@ dependencies = [ "object", "target-lexicon", "thiserror", - "wasmparser 0.115.0", + "wasmparser 0.116.0", "wasmtime-cranelift-shared", "wasmtime-environ", "wasmtime-versioned-export-macros", @@ -5598,9 +5455,9 @@ dependencies = [ [[package]] name = "wasmtime-cranelift-shared" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420fd2a69bc162957f4c94f21c7fa08ecf60d916f4e87b56332507c555da381d" +checksum = "8c98d5378a856cbf058d36278627dfabf0ed68a888142958c7ae8e6af507dafa" dependencies = [ "anyhow", "cranelift-codegen", @@ -5614,9 +5471,9 @@ dependencies = [ [[package]] name = "wasmtime-environ" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb6a445ce2b2810127caee6c1b79b8da4ae57712b05556a674592c18b7500a14" +checksum = "a6d33a9f421da810a070cd56add9bc51f852bd66afbb8b920489d6242f15b70e" dependencies = [ "anyhow", "cranelift-entity", @@ -5628,8 +5485,8 @@ dependencies = [ "serde_derive", "target-lexicon", "thiserror", - "wasm-encoder 0.35.0", - "wasmparser 0.115.0", + "wasm-encoder 0.36.2", + "wasmparser 0.116.0", "wasmprinter", "wasmtime-component-util", "wasmtime-types", @@ -5637,23 +5494,24 @@ dependencies = [ [[package]] name = "wasmtime-fiber" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345a8b061c9eab459e10b9112df9fc357d5a9e8b5b1004bc5fc674fba9be6d2a" +checksum = "404741f4c6d7f4e043be2e8b466406a2aee289ccdba22bf9eba6399921121b97" dependencies = [ + "anyhow", "cc", "cfg-if", - "rustix 0.38.13", + "rustix 0.38.27", "wasmtime-asm-macros", "wasmtime-versioned-export-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-jit" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f0f6586c61125fbfc13c3108c3dd565d21f314dd5bac823b9a5b7ab576d21f1" +checksum = "8d0994a86d6dca5f7d9740d7f2bd0568be06d2014a550361dc1c397d289d81ef" dependencies = [ "addr2line", "anyhow", @@ -5665,7 +5523,7 @@ dependencies = [ "log", "object", "rustc-demangle", - "rustix 0.38.13", + "rustix 0.38.27", "serde", "serde_derive", "target-lexicon", @@ -5673,37 +5531,37 @@ dependencies = [ "wasmtime-jit-debug", "wasmtime-jit-icache-coherence", "wasmtime-runtime", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-jit-debug" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109a9e46afe33580b952b14a4207354355f19bcdf0b47485b397b68409eaf553" +checksum = "4e0c4b74e606d1462d648631d5bc328e3d5b14e7f9d3ff93bc6db062fb8c5cd8" dependencies = [ "object", "once_cell", - "rustix 0.38.13", + "rustix 0.38.27", "wasmtime-versioned-export-macros", ] [[package]] name = "wasmtime-jit-icache-coherence" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f67e6be36375c39cff57ed3b137ab691afbf2d9ba8ee1c01f77888413f218749" +checksum = "3090a69ba1476979e090aa7ed4bc759178bafdb65b22f98b9ba24fc6e7e578d5" dependencies = [ "cfg-if", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-runtime" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d07986b2327b5e7f535ed638fbde25990fc8f85400194fda0d26db71c7b685e" +checksum = "b993ac8380385ed67bf71b51b9553edcf1ab0801b78a805a067de581b9a3e88a" dependencies = [ "anyhow", "cc", @@ -5717,36 +5575,36 @@ dependencies = [ "memoffset", "paste", "rand", - "rustix 0.38.13", + "rustix 0.38.27", "sptr", - "wasm-encoder 0.35.0", + "wasm-encoder 0.36.2", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-fiber", "wasmtime-jit-debug", "wasmtime-versioned-export-macros", "wasmtime-wmemcheck", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-types" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e810a0d2e869abd1cb42bd232990f6bd211672b3d202d2ae7e70ffb97ed70ea3" +checksum = "8b5778112fcab2dc3d4371f4203ab8facf0c453dd94312b0a88dd662955e64e0" dependencies = [ "cranelift-entity", "serde", "serde_derive", "thiserror", - "wasmparser 0.115.0", + "wasmparser 0.116.0", ] [[package]] name = "wasmtime-versioned-export-macros" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b5575a75e711ca6c36bb9ad647c93541cdc8e34218031acba5da3f35919dd3" +checksum = "f50f51f8d79bfd2aa8e9d9a0ae7c2d02b45fe412e62ff1b87c0c81b07c738231" dependencies = [ "proc-macro2", "quote", @@ -5755,9 +5613,9 @@ dependencies = [ [[package]] name = "wasmtime-wasi" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6730a2853226292cee755a36549dd1a443b324cf99319cb390af1afed6cb8a" +checksum = "eff3f4ad191a5e6d002bb5bffa3e2931a58984da9b30e57b48f353848748cf80" dependencies = [ "anyhow", "async-trait", @@ -5775,7 +5633,7 @@ dependencies = [ "libc", "log", "once_cell", - "rustix 0.38.13", + "rustix 0.38.27", "system-interface", "thiserror", "tokio", @@ -5785,21 +5643,21 @@ dependencies = [ "wasi-common", "wasmtime", "wiggle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "wasmtime-winch" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c1b6abbba5a01739bef9f00a87b419414a7dd99b795823d93fb12fc2bf994a" +checksum = "d638e7c72447253485fe131523e7465ca318c0455c826eb4f5f612fb67b7de90" dependencies = [ "anyhow", "cranelift-codegen", "gimli", "object", "target-lexicon", - "wasmparser 0.115.0", + "wasmparser 0.116.0", "wasmtime-cranelift-shared", "wasmtime-environ", "winch-codegen", @@ -5807,9 +5665,9 @@ dependencies = [ [[package]] name = "wasmtime-wit-bindgen" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d214ca7513d76af2872ad5bba4b0dcc0225821931745fdcb4fc30dd34bc3bf7" +checksum = "4b804dfd3d0c0d6d37aa21026fe7772ba1a769c89ee4f5c4f13b82d91d75216f" dependencies = [ "anyhow", "heck", @@ -5819,9 +5677,9 @@ dependencies = [ [[package]] name = "wasmtime-wmemcheck" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dafab2db172a53e23940e0fa3078c202f567ee5f13f4b42f66b694fab43c658" +checksum = "9b6060bc082cc32d9a45587c7640e29e3c7b89ada82677ac25d87850aaccb368" [[package]] name = "wast" @@ -5834,23 +5692,23 @@ dependencies = [ [[package]] name = "wast" -version = "67.0.0" +version = "69.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c2933efd77ff2398b83817a98984ffe4b67aefd9aa1d2c8e68e19b553f1c38" +checksum = "c1ee37317321afde358e4d7593745942c48d6d17e0e6e943704de9bbee121e7a" dependencies = [ "leb128", "memchr", "unicode-width", - "wasm-encoder 0.36.1", + "wasm-encoder 0.38.1", ] [[package]] name = "wat" -version = "1.0.78" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02905d13751dcb18f4e19f489d37a1bf139f519feaeef28d072a41a78e69a74" +checksum = "aeb338ee8dee4d4cd05e6426683f21c5087dc7cfc8903e839ccf48d43332da3c" dependencies = [ - "wast 67.0.0", + "wast 69.0.1", ] [[package]] @@ -5871,9 +5729,9 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "wiggle" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6ce56a4019ce3d8592c298029a75abe6887d1c95a078a4c53ec77a0628262d" +checksum = "f91028b241e692fdf30627ac10ba9d5ac378353ea4119b4f904ac95177057a44" dependencies = [ "anyhow", "async-trait", @@ -5886,9 +5744,9 @@ dependencies = [ [[package]] name = "wiggle-generate" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e585a4b1e84195031c77d8484af99cd93f129f45d519e83cb8cc75e9a420cfd3" +checksum = "5e8b3d76531994513671b2ec3b29fd342bf041e2282945bb6c52eebe6aa9e7da" dependencies = [ "anyhow", "heck", @@ -5901,9 +5759,9 @@ dependencies = [ [[package]] name = "wiggle-macro" -version = "14.0.4" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f321dbce722989d65c3082dba479fa392c7b7a1a4c3adc2a39545dd5aa452f" +checksum = "c189fe00c67f61bb330827f2abab1af9b5925c7929535cd13a68d265ec20b02d" dependencies = [ "proc-macro2", "quote", @@ -5944,9 +5802,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "winch-codegen" -version = "0.12.4" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f112bebb367a544d20c254083798087f22ceeb426168a970b955e8436f749dca" +checksum = "0c792487f4dc42733d182a72e75d718b1a563cedcc1599ff0a9ed683c33e8bb7" dependencies = [ "anyhow", "cranelift-codegen", @@ -5954,7 +5812,7 @@ dependencies = [ "regalloc2", "smallvec 1.11.0", "target-lexicon", - "wasmparser 0.115.0", + "wasmparser 0.116.0", "wasmtime-environ", ] @@ -5964,7 +5822,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -5973,7 +5831,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -5982,13 +5849,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -5997,42 +5879,84 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" version = "0.5.15" @@ -6049,7 +5973,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -6059,78 +5983,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357bb8e2932df531f83b052264b050b81ba0df90ee5a59b2d1d3949f344f81e5" dependencies = [ "bitflags 2.4.0", - "windows-sys", -] - -[[package]] -name = "wit-bindgen" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" -dependencies = [ - "bitflags 2.4.0", - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" -dependencies = [ - "anyhow", - "wit-component", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.13.2" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" -dependencies = [ - "anyhow", - "heck", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" -dependencies = [ - "anyhow", - "proc-macro2", - "quote", - "syn 2.0.32", - "wit-bindgen-core", - "wit-bindgen-rust", - "wit-component", -] - -[[package]] -name = "wit-component" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" -dependencies = [ - "anyhow", - "bitflags 2.4.0", - "indexmap 2.0.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder 0.36.1", - "wasm-metadata", - "wasmparser 0.116.0", - "wit-parser", + "windows-sys 0.48.0", ] [[package]] name = "wit-parser" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" +checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" dependencies = [ "anyhow", "id-arena", @@ -6183,12 +6043,6 @@ dependencies = [ "tap", ] -[[package]] -name = "xml-rs" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" - [[package]] name = "yansi" version = "0.5.1" @@ -6214,7 +6068,7 @@ dependencies = [ "crc32fast", "crossbeam-utils", "flate2", - "hmac 0.12.1", + "hmac", "pbkdf2 0.11.0", "sha1", "time", diff --git a/Cargo.toml b/Cargo.toml index 2dfeeb92..583b2a56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,18 +10,17 @@ repository = "https://github.com/uqbar-dao/uqbar" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] +reqwest = { version = "0.11.22", features = ["blocking"] } sha2 = "0.10" walkdir = "2.4" zip = "0.6" [features] -llm = [] simulation-mode = [] [dependencies] aes-gcm = "0.10.2" anyhow = "1.0.71" -async-recursion = "1.0.4" async-trait = "0.1.71" base64 = "0.13" bincode = "1.3.3" @@ -34,7 +33,6 @@ clap = { version = "4.4", features = ["derive"] } crossterm = { version = "0.26.1", features = ["event-stream", "bracketed-paste"] } dashmap = "5.5.3" digest = "0.10" -dotenv = "0.15.0" elliptic-curve = { version = "0.13.5", features = ["ecdh"] } ethers = "2.0" ethers-providers = "2.0.9" @@ -49,7 +47,6 @@ http = "0.2.9" jwt = "0.16" lazy_static = "1.4.0" log = "*" -lru-mem = "0.3.0" nohash-hasher = "0.2.0" num-traits = "0.2" open = "5.0.0" @@ -59,11 +56,7 @@ reqwest = "0.11.18" ring = "0.16.20" rmp-serde = "1.1.2" route-recognizer = "0.3.1" -rsa = "0.9" -rusoto_core = "0.48.0" -rusoto_s3 = "0.48.0" -rusoto_credential = "0.48.0" -serde = {version = "1.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_urlencoded = "0.7" sha2 = "0.10" @@ -72,9 +65,10 @@ thiserror = "1.0" tokio = { version = "1.28", features = ["fs", "macros", "rt-multi-thread", "sync"] } tokio-tungstenite = "0.20.1" url = "2.4.1" -uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } uuid = { version = "1.1.2", features = ["serde", "v4"] } warp = "0.3.5" -wasmtime = "14.0.4" -wasmtime-wasi = "14.0.4" +wasmtime = "15.0.1" +wasmtime-wasi = "15.0.1" zip = "0.6" +rocksdb = { version = "0.21.0", features = ["multi-threaded-cf"] } +rusqlite = { version = "0.30.0", features = ["bundled"] } diff --git a/README.md b/README.md index 0c63b4a9..4076f859 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Get an eth-sepolia-rpc API key and pass that as an argument. You can get one for Make sure not to use the same home directory for two nodes at once! You can use any name for the home directory: here we just use `home`. The `--` here separates cargo arguments from binary arguments. -TODO: document feature flags here, `--llm` and `--simulation-mode` +TODO: document feature flags `--simulation-mode` ```bash cargo +nightly run --release -- home --rpc wss://eth-sepolia.g.alchemy.com/v2/ ``` @@ -73,6 +73,6 @@ On boot you will be prompted to navigate to `localhost:8080`. Make sure your ETH Download and install an app: ``` -!m our@main:app_store:uqbar {"Download": {"package": {"package_name": "", "publisher_node": ""}, "install_from": ""}} -!m our@main:app_store:uqbar {"Install": {"package_name": "", "publisher_node": ""}} +/m our@main:app_store:uqbar {"Download": {"package": {"package_name": "", "publisher_node": ""}, "install_from": ""}} +/m our@main:app_store:uqbar {"Install": {"package_name": "", "publisher_node": ""}} ``` diff --git a/build-release.py b/build-release.py new file mode 100755 index 00000000..e4138495 --- /dev/null +++ b/build-release.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +import os +import shutil +import subprocess + +def build_and_move(feature, tmp_dir): + print("\n" + "=" * 50) + print(f"BUILDING {feature if feature else 'default'}") + print("=" * 50 + "\n") + + if feature: + subprocess.run(["cargo", "+nightly", "build", "--release", "--features", feature], check=True) + binary_name = f"uqbar-{feature}" + else: + subprocess.run(["cargo", "+nightly", "build", "--release"], check=True) + binary_name = "uqbar" + + # Move and rename the binary + source_path = "target/release/uqbar" + dest_path = os.path.join(tmp_dir, binary_name) + shutil.move(source_path, dest_path) + +def main(): + # Features to compile with + features = ["", "simulation-mode"] # Add more features as needed + + # Ensure the tmp directory is clean + tmp_dir = "/tmp/uqbar-release" + if os.path.exists(tmp_dir): + shutil.rmtree(tmp_dir) + os.makedirs(tmp_dir) + + # Loop through the features and build + for feature in features: + build_and_move(feature, tmp_dir) + + print("Build and move process completed.\nFind release in {tmp_dir}.") + +if __name__ == "__main__": + main() + diff --git a/build.rs b/build.rs index e0efecd0..1a5b7c48 100644 --- a/build.rs +++ b/build.rs @@ -135,6 +135,17 @@ fn main() { let pwd = std::env::current_dir().unwrap(); + // Pull wit from git repo + let wit_dir = pwd.join("wit"); + fs::create_dir_all(&wit_dir).unwrap(); + let wit_file = wit_dir.join("uqbar.wit"); + if !wit_file.exists() { + let mut wit_file = std::fs::File::create(&wit_file).unwrap(); + let uqbar_wit_url = "https://raw.githubusercontent.com/uqbar-dao/uqwit/master/uqbar.wit"; + let mut response = reqwest::blocking::get(uqbar_wit_url).unwrap(); + io::copy(&mut response, &mut wit_file).unwrap(); + } + // Create target.wasm (compiled .wit) & world run_command(Command::new("wasm-tools").args([ "component", diff --git a/modules/app_store/app_store/Cargo.lock b/modules/app_store/app_store/Cargo.lock index 8ea7f076..2f3eea92 100644 --- a/modules/app_store/app_store/Cargo.lock +++ b/modules/app_store/app_store/Cargo.lock @@ -120,9 +120,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -184,9 +184,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "leb128" @@ -196,9 +196,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "log" @@ -220,9 +220,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -268,9 +268,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "semver" @@ -280,18 +280,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.191" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.191" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -322,9 +322,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "spdx" @@ -337,9 +337,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" dependencies = [ "proc-macro2", "quote", @@ -389,9 +389,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -422,8 +422,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "uqbar_process_lib" -version = "0.3.0" -source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" +version = "0.4.0" +source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=8342b1a#8342b1a131401fb5d141dab8c90e79aa6d2bc909" dependencies = [ "anyhow", "bincode", @@ -461,18 +461,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-encoder" -version = "0.36.2" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" +checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" dependencies = [ "leb128", ] [[package]] name = "wasm-metadata" -version = "0.10.11" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" +checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a" dependencies = [ "anyhow", "indexmap", @@ -486,9 +486,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.116.1" +version = "0.118.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" +checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" dependencies = [ "indexmap", "semver", @@ -496,8 +496,8 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "bitflags", "wit-bindgen-rust-macro", @@ -505,8 +505,8 @@ dependencies = [ [[package]] name = "wit-bindgen-core" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "wit-component", @@ -515,8 +515,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.13.2" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "heck", @@ -527,8 +527,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "proc-macro2", @@ -541,9 +541,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.17.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" +checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2" dependencies = [ "anyhow", "bitflags", @@ -560,9 +560,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" +checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" dependencies = [ "anyhow", "id-arena", diff --git a/modules/app_store/app_store/Cargo.toml b/modules/app_store/app_store/Cargo.toml index ba0aecbc..ab087fb2 100644 --- a/modules/app_store/app_store/Cargo.toml +++ b/modules/app_store/app_store/Cargo.toml @@ -14,11 +14,11 @@ lto = true anyhow = "1.0" bincode = "1.3.3" rand = "0.8" -serde = {version = "1.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sha2 = "0.10.8" -uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } -wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } +uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "8342b1a" } +wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" } [lib] crate-type = ["cdylib"] diff --git a/modules/app_store/app_store/src/lib.rs b/modules/app_store/app_store/src/lib.rs index 2ba67f13..3d6ee781 100644 --- a/modules/app_store/app_store/src/lib.rs +++ b/modules/app_store/app_store/src/lib.rs @@ -2,10 +2,9 @@ use serde::{Deserialize, Serialize}; use sha2::Digest; use std::collections::{HashMap, HashSet}; use uqbar_process_lib::kernel_types as kt; -use uqbar_process_lib::uqbar::process::standard as wit; use uqbar_process_lib::{ - get_capability, get_payload, get_typed_state, grant_messaging, println, receive, set_state, - share_capability, Address, Message, NodeId, PackageId, ProcessId, Request, Response, + await_message, get_capability, get_payload, get_typed_state, grant_messaging, println, + set_state, share_capability, Address, Message, NodeId, PackageId, ProcessId, Request, Response, }; wit_bindgen::generate!({ @@ -182,36 +181,34 @@ impl Guest for Component { // active the main messaging loop: handle requests and responses loop { - let (source, message) = match receive() { - Ok((source, message)) => (source, message), - Err((error, _context)) => { - // TODO handle net errors more usefully based on their context - println!("net error: {:?}", error.kind); + match await_message() { + Err(send_error) => { + println!("{our}: got network error: {send_error:?}"); continue; } - }; - match handle_message(&our, &source, &mut state, &message) { - Ok(()) => {} - Err(e) => println!("app-store: error handling message: {:?}", e), + Ok(message) => match handle_message(&our, &mut state, &message) { + Ok(()) => {} + Err(e) => println!("app-store: error handling message: {:?}", e), + }, } } } } -fn handle_message( - our: &Address, - source: &Address, - mut state: &mut State, - message: &Message, -) -> anyhow::Result<()> { +fn handle_message(our: &Address, mut state: &mut State, message: &Message) -> anyhow::Result<()> { match message { - Message::Request(req) => { - match &serde_json::from_slice::(&req.ipc) { + Message::Request { + source, + expects_response, + ipc, + .. + } => { + match &serde_json::from_slice::(&ipc) { Ok(Req::LocalRequest(local_request)) => { match handle_local_request(&our, &source, local_request, &mut state) { Ok(None) => return Ok(()), Ok(Some(resp)) => { - if req.expects_response.is_some() { + if expects_response.is_some() { Response::new().ipc(serde_json::to_vec(&resp)?).send()?; } } @@ -224,7 +221,7 @@ fn handle_message( match handle_remote_request(&our, &source, remote_request, &mut state) { Ok(None) => return Ok(()), Ok(Some(resp)) => { - if req.expects_response.is_some() { + if expects_response.is_some() { Response::new().ipc(serde_json::to_vec(&resp)?).send()?; } } @@ -259,50 +256,48 @@ fn handle_message( } } Ok(Req::FTWorkerCommand(_)) => { - spawn_receive_transfer(&our, &req.ipc); + spawn_receive_transfer(&our, &ipc); } e => { return Err(anyhow::anyhow!( "app store bad request: {:?}, error {:?}", - req.ipc, + ipc, e )) } } } - Message::Response((response, context)) => { - match &serde_json::from_slice::(&response.ipc) { - Ok(Resp::RemoteResponse(remote_response)) => match remote_response { - RemoteResponse::DownloadApproved => { - println!("app store: download approved, should be starting"); - } - RemoteResponse::DownloadDenied => { - println!("app store: could not download package from that node!"); - } - }, - Ok(Resp::FTWorkerResult(ft_worker_result)) => { - let Ok(context) = - serde_json::from_slice::(&context.as_ref().unwrap()) - else { - return Err(anyhow::anyhow!("file_transfer: got weird local request")); - }; - match ft_worker_result { - FTWorkerResult::SendSuccess => { - println!( - "file_transfer: successfully shared app {} in {:.4}s", - context.file_name, - std::time::SystemTime::now() - .duration_since(context.start_time) - .unwrap() - .as_secs_f64(), - ); - } - e => return Err(anyhow::anyhow!("file_transfer: {:?}", e)), - } + Message::Response { ipc, context, .. } => match &serde_json::from_slice::(&ipc) { + Ok(Resp::RemoteResponse(remote_response)) => match remote_response { + RemoteResponse::DownloadApproved => { + println!("app store: download approved, should be starting"); + } + RemoteResponse::DownloadDenied => { + println!("app store: could not download package from that node!"); + } + }, + Ok(Resp::FTWorkerResult(ft_worker_result)) => { + let Ok(context) = + serde_json::from_slice::(&context.as_ref().unwrap()) + else { + return Err(anyhow::anyhow!("file_transfer: got weird local request")); + }; + match ft_worker_result { + FTWorkerResult::SendSuccess => { + println!( + "file_transfer: successfully shared app {} in {:.4}s", + context.file_name, + std::time::SystemTime::now() + .duration_since(context.start_time) + .unwrap() + .as_secs_f64(), + ); + } + e => return Err(anyhow::anyhow!("file_transfer: {:?}", e)), } - _ => return Err(anyhow::anyhow!("bad response from file transfer worker")), } - } + _ => return Err(anyhow::anyhow!("bad response from file transfer worker")), + }, } Ok(()) } @@ -321,14 +316,16 @@ fn handle_local_request( let Some(mut payload) = get_payload() else { return Err(anyhow::anyhow!("no payload")); }; + let drive = format!("/{}/pkg", package); Request::new() .target(Address::from_str("our@vfs:sys:uqbar")?) .ipc(serde_json::to_vec(&kt::VfsRequest { - drive: package.to_string(), - action: kt::VfsAction::New, + path: drive.clone(), + action: kt::VfsAction::CreateDrive, })?) - .send_and_await_response(5)??; + .send_and_await_response(5)? + .unwrap(); // produce the version hash for this new package let mut hasher = sha2::Sha256::new(); @@ -337,42 +334,49 @@ fn handle_local_request( // add zip bytes payload.mime = Some("application/zip".to_string()); - Request::new() + let response = Request::new() .target(Address::from_str("our@vfs:sys:uqbar")?) .ipc(serde_json::to_vec(&kt::VfsRequest { - drive: package.to_string(), - action: kt::VfsAction::Add { - full_path: package.to_string(), - entry_type: kt::AddEntryType::ZipArchive, - }, + path: drive.clone(), + action: kt::VfsAction::AddZip, })?) .payload(payload.clone()) - .send_and_await_response(5)??; + .send_and_await_response(5)?.unwrap(); + let Message::Response { ipc: ref vfs_ipc, .. } = response else { + panic!("app_store: send_and_await_response must return Response"); + }; + let vfs_ipc = serde_json::from_slice::(vfs_ipc)?; + if vfs_ipc == serde_json::json!({"Err": "NoCap"}) { + return Err(anyhow::anyhow!("cannot add NewPackage: do not have capability to access vfs")); + } // save the zip file itself in VFS for sharing with other nodes // call it .zip + let zip_path = format!("{}/{}.zip", drive.clone(), package); Request::new() .target(Address::from_str("our@vfs:sys:uqbar")?) .inherit(true) .ipc(serde_json::to_vec(&kt::VfsRequest { - drive: package.to_string(), - action: kt::VfsAction::Add { - full_path: format!("/{}.zip", package.to_string()), - entry_type: kt::AddEntryType::NewFile, - }, + path: zip_path, + action: kt::VfsAction::ReWrite, })?) .payload(payload) - .send_and_await_response(5)??; + .send_and_await_response(5)? + .unwrap(); + let metadata_path = format!("{}/metadata.json", drive.clone()); + Request::new() .target(Address::from_str("our@vfs:sys:uqbar")?) .ipc(serde_json::to_vec(&kt::VfsRequest { - drive: package.to_string(), - action: kt::VfsAction::GetEntry("/metadata.json".into()), + path: metadata_path, + action: kt::VfsAction::Read, })?) - .send_and_await_response(5)??; + .send_and_await_response(5)? + .unwrap(); let Some(payload) = get_payload() else { return Err(anyhow::anyhow!("no metadata found!")); }; + let metadata = String::from_utf8(payload.bytes)?; let metadata = serde_json::from_str::(&metadata)?; @@ -406,8 +410,8 @@ fn handle_local_request( ))?) .send_and_await_response(5) { - Ok(Ok((_source, Message::Response((resp, _context))))) => { - let resp = serde_json::from_slice::(&resp.ipc)?; + Ok(Ok(Message::Response { ipc, .. })) => { + let resp = serde_json::from_slice::(&ipc)?; match resp { Resp::RemoteResponse(RemoteResponse::DownloadApproved) => { state.requested_packages.insert(package.clone()); @@ -421,13 +425,15 @@ fn handle_local_request( }, ))), LocalRequest::Install(package) => { + let drive_path = format!("/{}/pkg", package); Request::new() .target(Address::from_str("our@vfs:sys:uqbar")?) .ipc(serde_json::to_vec(&kt::VfsRequest { - drive: package.to_string(), - action: kt::VfsAction::GetEntry("/manifest.json".into()), + path: format!("{}/manifest.json", drive_path), + action: kt::VfsAction::Read, })?) - .send_and_await_response(5)??; + .send_and_await_response(5)? + .unwrap(); let Some(payload) = get_payload() else { return Err(anyhow::anyhow!("no payload")); }; @@ -438,7 +444,7 @@ fn handle_local_request( &Address::new(&our.node, ("vfs", "sys", "uqbar")), &serde_json::to_string(&serde_json::json!({ "kind": "read", - "drive": package.to_string(), + "drive": drive_path, }))?, ) else { return Err(anyhow::anyhow!("app-store: no read cap")); @@ -447,7 +453,7 @@ fn handle_local_request( &Address::new(&our.node, ("vfs", "sys", "uqbar")), &serde_json::to_string(&serde_json::json!({ "kind": "write", - "drive": package.to_string(), + "drive": drive_path, }))?, ) else { return Err(anyhow::anyhow!("app-store: no write cap")); @@ -462,33 +468,21 @@ fn handle_local_request( // then, once all have been initialized, grant them requested caps // and finally start them. for entry in &manifest { - let path = if entry.process_wasm_path.starts_with("/") { + let wasm_path = if entry.process_wasm_path.starts_with("/") { entry.process_wasm_path.clone() } else { format!("/{}", entry.process_wasm_path) }; - let (_, hash_response) = Request::new() - .target(Address::from_str("our@vfs:sys:uqbar")?) - .ipc(serde_json::to_vec(&kt::VfsRequest { - drive: package.to_string(), - action: kt::VfsAction::GetHash(path.clone()), - })?) - .send_and_await_response(5)??; - - let Message::Response((wit::Response { ipc, .. }, _)) = hash_response else { - return Err(anyhow::anyhow!("bad vfs response")); - }; - let kt::VfsResponse::GetHash(Some(hash)) = serde_json::from_slice(&ipc)? else { - return Err(anyhow::anyhow!("no hash in vfs")); - }; + let wasm_path = format!("{}{}", drive_path, wasm_path); // build initial caps let mut initial_capabilities: HashSet = HashSet::new(); if entry.request_networking { - initial_capabilities.insert(kt::de_wit_signed_capability(networking_cap.clone())); + initial_capabilities + .insert(kt::de_wit_signed_capability(networking_cap.clone())); } initial_capabilities.insert(kt::de_wit_signed_capability(read_cap.clone())); initial_capabilities.insert(kt::de_wit_signed_capability(write_cap.clone())); - let process_id = format!("{}:{}", entry.process_name, package.to_string()); + let process_id = format!("{}:{}", entry.process_name, package); let Ok(parsed_new_process_id) = ProcessId::from_str(&process_id) else { return Err(anyhow::anyhow!("app-store: invalid process id!")); }; @@ -500,24 +494,26 @@ fn handle_local_request( ))?) .send()?; - let (_, _bytes_response) = Request::new() + let _bytes_response = Request::new() .target(Address::from_str("our@vfs:sys:uqbar")?) .ipc(serde_json::to_vec(&kt::VfsRequest { - drive: package.to_string(), - action: kt::VfsAction::GetEntry(path), + path: wasm_path.clone(), + action: kt::VfsAction::Read, })?) - .send_and_await_response(5)??; + .send_and_await_response(5)? + .unwrap(); Request::new() .target(Address::from_str("our@kernel:sys:uqbar")?) .ipc(serde_json::to_vec(&kt::KernelCommand::InitializeProcess { id: parsed_new_process_id, - wasm_bytes_handle: hash, - on_panic: entry.on_panic.clone(), + wasm_bytes_handle: wasm_path, + on_exit: entry.on_exit.clone(), initial_capabilities, public: entry.public, })?) .inherit(true) - .send_and_await_response(5)?; + .send_and_await_response(5)? + .unwrap(); } for entry in &manifest { let process_id = ProcessId::new( @@ -526,41 +522,93 @@ fn handle_local_request( package.publisher(), ); if let Some(to_request) = &entry.request_messaging { - for process_name in to_request { - let Ok(parsed_process_id) = ProcessId::from_str(&process_name) else { - // TODO handle arbitrary caps here - continue; - }; - let Some(messaging_cap) = get_capability( - &Address { - node: our.node.clone(), - process: parsed_process_id.clone(), - }, - &"\"messaging\"".into(), - ) else { - println!("app-store: no cap for {} to give away!", process_name); - continue; - }; - share_capability(&process_id, &messaging_cap); + for value in to_request { + let mut capability = None; + match value { + serde_json::Value::String(process_name) => { + if let Ok(parsed_process_id) = ProcessId::from_str(process_name) { + capability = get_capability( + &Address { + node: our.node.clone(), + process: parsed_process_id.clone(), + }, + &"\"messaging\"".into(), + ); + } + } + serde_json::Value::Object(map) => { + if let Some(process_name) = map.get("process") { + if let Ok(parsed_process_id) = + ProcessId::from_str(&process_name.to_string()) + { + if let Some(params) = map.get("params") { + capability = get_capability( + &Address { + node: our.node.clone(), + process: parsed_process_id.clone(), + }, + ¶ms.to_string(), + ); + } + } + } + } + _ => { + continue; + } + } + if let Some(cap) = capability { + share_capability(&process_id, &cap); + } else { + println!("app-store: no cap: {}, for {} to request!", value.to_string(), process_id); + } } } if let Some(to_grant) = &entry.grant_messaging { - let Some(messaging_cap) = get_capability( - &Address { - node: our.node.clone(), - process: process_id.clone(), - }, - &"\"messaging\"".into(), - ) else { - println!("app-store: no cap for {} to give away!", process_id); - continue; - }; - for process_name in to_grant { - let Ok(parsed_process_id) = ProcessId::from_str(&process_name) else { - // TODO handle arbitrary caps here - continue; - }; - share_capability(&parsed_process_id, &messaging_cap); + for value in to_grant { + let mut capability = None; + let mut to_process = None; + match value { + serde_json::Value::String(process_name) => { + if let Ok(parsed_process_id) = ProcessId::from_str(process_name) { + capability = get_capability( + &Address { + node: our.node.clone(), + process: process_id.clone(), + }, + &"\"messaging\"".into(), + ); + to_process = Some(parsed_process_id); + } + } + serde_json::Value::Object(map) => { + if let Some(process_name) = map.get("process") { + if let Ok(parsed_process_id) = + ProcessId::from_str(&process_name.to_string()) + { + if let Some(params) = map.get("params") { + capability = get_capability( + &Address { + node: our.node.clone(), + process: process_id.clone(), + }, + ¶ms.to_string(), + ); + to_process = Some(parsed_process_id); + } + } + } + } + _ => { + continue; + } + } + + if let Some(cap) = capability { + share_capability(&to_process.unwrap(), &cap); + } else { + println!("app-store: no cap: {}, for {} to grant!", value.to_string(), process_id); + } } } Request::new() @@ -568,7 +616,8 @@ fn handle_local_request( .ipc(serde_json::to_vec(&kt::KernelCommand::RunProcess( process_id, ))?) - .send_and_await_response(5)?; + .send_and_await_response(5)? + .unwrap(); } Ok(Some(Resp::InstallResponse(InstallResponse::Success))) } @@ -598,15 +647,18 @@ fn handle_remote_request( return Ok(Some(Resp::RemoteResponse(RemoteResponse::DownloadDenied))); } // get the .zip from VFS and attach as payload to response - let file_name = format!("/{}.zip", package.to_string()); + let drive_name = format!("/{}/pkg", package); + let file_path = format!("/{}.zip", drive_name); Request::new() .target(Address::from_str("our@vfs:sys:uqbar")?) .ipc(serde_json::to_vec(&kt::VfsRequest { - drive: package.to_string(), - action: kt::VfsAction::GetEntry(file_name.clone()), + path: file_path, + action: kt::VfsAction::Read, })?) - .send_and_await_response(5)?; + .send_and_await_response(5)? + .unwrap(); // transfer will inherit the payload bytes we receive from VFS + let file_name = format!("/{}.zip", package); spawn_transfer(&our, &file_name, None, &source); Ok(Some(Resp::RemoteResponse(RemoteResponse::DownloadApproved))) } diff --git a/modules/app_store/ft_worker/Cargo.lock b/modules/app_store/ft_worker/Cargo.lock index 00f36f50..eed55456 100644 --- a/modules/app_store/ft_worker/Cargo.lock +++ b/modules/app_store/ft_worker/Cargo.lock @@ -71,9 +71,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -82,9 +82,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -135,9 +135,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "leb128" @@ -147,9 +147,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "log" @@ -171,9 +171,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -219,9 +219,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "semver" @@ -231,18 +231,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.191" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.191" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -262,9 +262,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "spdx" @@ -277,9 +277,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" dependencies = [ "proc-macro2", "quote", @@ -323,9 +323,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -356,8 +356,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "uqbar_process_lib" -version = "0.3.0" -source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" +version = "0.4.0" +source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=b09d987#b09d9875edce1a230549cf56cf088f95e38d4abd" dependencies = [ "anyhow", "bincode", @@ -389,18 +389,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-encoder" -version = "0.36.2" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" +checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" dependencies = [ "leb128", ] [[package]] name = "wasm-metadata" -version = "0.10.11" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" +checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a" dependencies = [ "anyhow", "indexmap", @@ -414,9 +414,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.116.1" +version = "0.118.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" +checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" dependencies = [ "indexmap", "semver", @@ -424,8 +424,8 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "bitflags", "wit-bindgen-rust-macro", @@ -433,8 +433,8 @@ dependencies = [ [[package]] name = "wit-bindgen-core" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "wit-component", @@ -443,8 +443,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.13.2" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "heck", @@ -455,8 +455,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "proc-macro2", @@ -469,9 +469,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.17.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" +checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2" dependencies = [ "anyhow", "bitflags", @@ -488,9 +488,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" +checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" dependencies = [ "anyhow", "id-arena", diff --git a/modules/app_store/ft_worker/Cargo.toml b/modules/app_store/ft_worker/Cargo.toml index 66a2235a..6df59ad9 100644 --- a/modules/app_store/ft_worker/Cargo.toml +++ b/modules/app_store/ft_worker/Cargo.toml @@ -14,10 +14,10 @@ lto = true anyhow = "1.0" bincode = "1.3.3" rand = "0.8" -serde = {version = "1.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } -wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } +uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "b09d987" } +wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" } [lib] crate-type = ["cdylib"] diff --git a/modules/app_store/ft_worker/src/ft_worker_lib.rs b/modules/app_store/ft_worker/src/ft_worker_lib.rs index 70b9c9e5..4bf6db56 100644 --- a/modules/app_store/ft_worker/src/ft_worker_lib.rs +++ b/modules/app_store/ft_worker/src/ft_worker_lib.rs @@ -55,7 +55,7 @@ pub fn spawn_transfer( let Ok(worker_process_id) = spawn( Some(&transfer_id.to_string()), "/ft_worker.wasm".into(), - &OnPanic::None, // can set message-on-panic here + &OnExit::None, // can set message-on-panic here &Capabilities::All, false, // not public ) else { @@ -106,7 +106,7 @@ pub fn spawn_receive_transfer(our: &Address, ipc: &[u8]) { let Ok(worker_process_id) = spawn( Some(&transfer_id.to_string()), "/ft_worker.wasm".into(), - &OnPanic::None, // can set message-on-panic here + &OnExit::None, // can set message-on-panic here &Capabilities::All, false, // not public ) else { diff --git a/modules/app_store/ft_worker/src/lib.rs b/modules/app_store/ft_worker/src/lib.rs index b1d33254..0c533ed1 100644 --- a/modules/app_store/ft_worker/src/lib.rs +++ b/modules/app_store/ft_worker/src/lib.rs @@ -1,5 +1,8 @@ use serde::{Deserialize, Serialize}; -use uqbar_process_lib::uqbar::process::standard::*; +//use uqbar_process_lib::uqbar::process::standard::*; + +use uqbar_process_lib::uqbar::process::standard::{Message as StdMessage, Request as StdRequest, Response as StdResponse, SendErrorKind}; +use uqbar_process_lib::{await_message, get_payload, print_to_terminal, send_and_await_response, send_request, send_response, Address, Message, Payload}; mod ft_worker_lib; use ft_worker_lib::*; @@ -25,11 +28,11 @@ impl Guest for Component { let our = Address::from_str(&our).unwrap(); print_to_terminal(1, &format!("{}: start", our.process)); - let Ok((parent_process, Message::Request(req))) = receive() else { + let Ok(Message::Request { source: parent_process, ipc, .. }) = await_message() else { panic!("ft_worker: got bad init message"); }; - let command = serde_json::from_slice::(&req.ipc) + let command = serde_json::from_slice::(&ipc) .expect("ft_worker: got unparseable init message"); match command { @@ -55,7 +58,7 @@ impl Guest for Component { // acknowledgement. match send_and_await_response( &Address::from_str(&target).unwrap(), - &Request { + &StdRequest { inherit: false, expects_response: Some(timeout), ipc: serde_json::to_vec(&FTWorkerCommand::Receive { @@ -76,7 +79,7 @@ impl Guest for Component { SendErrorKind::Timeout => TransferError::TargetTimeout, })) } - Ok((opp_worker, Message::Response((response, _)))) => { + Ok((opp_worker, StdMessage::Response((response, _)))) => { let Ok(FTWorkerProtocol::Ready) = serde_json::from_slice(&response.ipc) else { respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected)); return; @@ -94,7 +97,7 @@ impl Guest for Component { }; send_request( &opp_worker, - &Request { + &StdRequest { inherit: false, expects_response: Some(timeout), ipc: vec![], @@ -113,7 +116,7 @@ impl Guest for Component { }; send_request( &opp_worker, - &Request { + &StdRequest { inherit: false, expects_response: None, ipc: vec![], @@ -126,11 +129,11 @@ impl Guest for Component { offset += chunk_size; } // now wait for Finished response - let Ok((receiving_worker, Message::Response((resp, _)))) = receive() else { + let Ok(Message::Response { ipc, .. }) = await_message() else { respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected)); return; }; - let Ok(FTWorkerProtocol::Finished) = serde_json::from_slice(&resp.ipc) else { + let Ok(FTWorkerProtocol::Finished) = serde_json::from_slice(&ipc) else { respond_to_parent(FTWorkerResult::Err(TransferError::TargetRejected)); return; }; @@ -141,15 +144,14 @@ impl Guest for Component { } } FTWorkerCommand::Receive { - transfer_id, file_name, - file_size, total_chunks, timeout, + .. } => { // send Ready response to counterparty send_response( - &Response { + &StdResponse { inherit: false, ipc: serde_json::to_vec(&FTWorkerProtocol::Ready).unwrap(), metadata: None, @@ -163,7 +165,7 @@ impl Guest for Component { let mut chunks_received = 0; let start_time = std::time::Instant::now(); loop { - let Ok((source, Message::Request(req))) = receive() else { + let Ok(Message::Request { .. }) = await_message() else { respond_to_parent(FTWorkerResult::Err(TransferError::SourceFailed)); return; }; @@ -183,7 +185,7 @@ impl Guest for Component { } // send Finished message to sender send_response( - &Response { + &StdResponse { inherit: false, ipc: serde_json::to_vec(&FTWorkerProtocol::Finished).unwrap(), metadata: None, @@ -193,7 +195,7 @@ impl Guest for Component { // send Success message to parent send_request( &parent_process, - &Request { + &StdRequest { inherit: false, expects_response: None, ipc: serde_json::to_vec(&FTWorkerResult::ReceiveSuccess(file_name)) @@ -213,7 +215,7 @@ impl Guest for Component { fn respond_to_parent(result: FTWorkerResult) { send_response( - &Response { + &StdResponse { inherit: false, ipc: serde_json::to_vec(&result).unwrap(), metadata: None, diff --git a/modules/app_store/pkg/manifest.json b/modules/app_store/pkg/manifest.json index a3d11081..be26398f 100644 --- a/modules/app_store/pkg/manifest.json +++ b/modules/app_store/pkg/manifest.json @@ -2,7 +2,7 @@ { "process_name": "main", "process_wasm_path": "/app_store.wasm", - "on_panic": "Restart", + "on_exit": "Restart", "request_networking": true, "request_messaging": [ "terminal:terminal:uqbar", @@ -13,7 +13,13 @@ "net:sys:uqbar", "vfs:sys:uqbar", "kernel:sys:uqbar", - "eth_rpc:sys:uqbar" + "eth_rpc:sys:uqbar", + { + "process": "vfs:sys:uqbar", + "params": { + "root": true + } + } ], "public": false } diff --git a/modules/chess/Cargo.lock b/modules/chess/Cargo.lock index 7d81cfb2..b319e6d8 100644 --- a/modules/chess/Cargo.lock +++ b/modules/chess/Cargo.lock @@ -64,7 +64,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chess" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "base64", @@ -73,6 +73,7 @@ dependencies = [ "serde", "serde_json", "uqbar_process_lib", + "url", "wit-bindgen", ] @@ -138,9 +139,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -153,9 +154,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -164,9 +165,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -202,9 +203,9 @@ checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -223,9 +224,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "lazy_static" @@ -241,9 +242,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "log" @@ -278,9 +279,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pleco" @@ -304,9 +305,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -487,9 +488,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "scopeguard" @@ -505,18 +506,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.191" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.191" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -536,9 +537,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "spdx" @@ -551,9 +552,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ "proc-macro2", "quote", @@ -597,9 +598,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -630,8 +631,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "uqbar_process_lib" -version = "0.3.0" -source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" +version = "0.4.0" +source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=65e07e4#65e07e49553a5fa3340ff7c3d9cf3340a53610c8" dependencies = [ "anyhow", "bincode", @@ -646,9 +647,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -663,18 +664,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-encoder" -version = "0.36.2" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" +checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" dependencies = [ "leb128", ] [[package]] name = "wasm-metadata" -version = "0.10.11" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" +checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a" dependencies = [ "anyhow", "indexmap", @@ -688,9 +689,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.116.1" +version = "0.118.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" +checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" dependencies = [ "indexmap", "semver", @@ -720,8 +721,8 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "wit-bindgen" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "bitflags 2.4.1", "wit-bindgen-rust-macro", @@ -729,8 +730,8 @@ dependencies = [ [[package]] name = "wit-bindgen-core" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "wit-component", @@ -739,8 +740,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.13.2" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "heck", @@ -751,8 +752,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "proc-macro2", @@ -765,9 +766,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.17.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" +checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2" dependencies = [ "anyhow", "bitflags 2.4.1", @@ -784,9 +785,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" +checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" dependencies = [ "anyhow", "id-arena", diff --git a/modules/chess/Cargo.toml b/modules/chess/Cargo.toml index 2876527a..94863750 100644 --- a/modules/chess/Cargo.toml +++ b/modules/chess/Cargo.toml @@ -1,10 +1,8 @@ [package] name = "chess" -version = "0.1.0" +version = "0.2.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [profile.release] panic = "abort" opt-level = "s" @@ -15,10 +13,11 @@ anyhow = "1.0" base64 = "0.13" bincode = "1.3.3" pleco = "0.5" -serde = {version = "1.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } -wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } +url = "*" +uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "65e07e4" } +wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" } [lib] crate-type = ["cdylib"] diff --git a/modules/chess/pkg/chess.html b/modules/chess/pkg/chess.html index d2196de7..96f3bdcc 100644 --- a/modules/chess/pkg/chess.html +++ b/modules/chess/pkg/chess.html @@ -4,6 +4,7 @@ + Chess @@ -11,7 +12,6 @@
- - + diff --git a/modules/chess/pkg/index.js b/modules/chess/pkg/index.js index 679aa4d4..8f2b4d61 100644 --- a/modules/chess/pkg/index.js +++ b/modules/chess/pkg/index.js @@ -1,4 +1,4 @@ -var fv=Object.defineProperty;var dv=(e,t,r)=>t in e?fv(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var ft=(e,t,r)=>(dv(e,typeof t!="symbol"?t+"":t,r),r);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const a of i)if(a.type==="childList")for(const s of a.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&n(s)}).observe(document,{childList:!0,subtree:!0});function r(i){const a={};return i.integrity&&(a.integrity=i.integrity),i.referrerPolicy&&(a.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?a.credentials="include":i.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function n(i){if(i.ep)return;i.ep=!0;const a=r(i);fetch(i.href,a)}})();var hv=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Qc(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function pv(e){if(e.__esModule)return e;var t=e.default;if(typeof t=="function"){var r=function n(){if(this instanceof n){var i=[null];i.push.apply(i,arguments);var a=Function.bind.apply(t,i);return new a}return t.apply(this,arguments)};r.prototype=t.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(e).forEach(function(n){var i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,i.get?i:{enumerable:!0,get:function(){return e[n]}})}),r}var Lh={exports:{}},il={},Oh={exports:{}},we={};/** +var vh=Object.defineProperty;var yh=(e,t,n)=>t in e?vh(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ee=(e,t,n)=>(yh(e,typeof t!="symbol"?t+"":t,n),n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))r(o);new MutationObserver(o=>{for(const i of o)if(i.type==="childList")for(const s of i.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&r(s)}).observe(document,{childList:!0,subtree:!0});function n(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(o){if(o.ep)return;o.ep=!0;const i=n(o);fetch(o.href,i)}})();function vc(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var yc={exports:{}},ai={},Sc={exports:{}},z={};/** * @license React * react.production.min.js * @@ -6,7 +6,7 @@ var fv=Object.defineProperty;var dv=(e,t,r)=>t in e?fv(e,t,{enumerable:!0,config * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Ts=Symbol.for("react.element"),gv=Symbol.for("react.portal"),vv=Symbol.for("react.fragment"),yv=Symbol.for("react.strict_mode"),mv=Symbol.for("react.profiler"),Cv=Symbol.for("react.provider"),Ev=Symbol.for("react.context"),Sv=Symbol.for("react.forward_ref"),xv=Symbol.for("react.suspense"),Tv=Symbol.for("react.memo"),wv=Symbol.for("react.lazy"),E0=Symbol.iterator;function Iv(e){return e===null||typeof e!="object"?null:(e=E0&&e[E0]||e["@@iterator"],typeof e=="function"?e:null)}var Ph={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Uh=Object.assign,Mh={};function ha(e,t,r){this.props=e,this.context=t,this.refs=Mh,this.updater=r||Ph}ha.prototype.isReactComponent={};ha.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};ha.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function Fh(){}Fh.prototype=ha.prototype;function Wc(e,t,r){this.props=e,this.context=t,this.refs=Mh,this.updater=r||Ph}var Yc=Wc.prototype=new Fh;Yc.constructor=Wc;Uh(Yc,ha.prototype);Yc.isPureReactComponent=!0;var S0=Array.isArray,Vh=Object.prototype.hasOwnProperty,Xc={current:null},jh={key:!0,ref:!0,__self:!0,__source:!0};function Kh(e,t,r){var n,i={},a=null,s=null;if(t!=null)for(n in t.ref!==void 0&&(s=t.ref),t.key!==void 0&&(a=""+t.key),t)Vh.call(t,n)&&!jh.hasOwnProperty(n)&&(i[n]=t[n]);var o=arguments.length-2;if(o===1)i.children=r;else if(1t in e?fv(e,t,{enumerable:!0,config * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Nv=q,Dv=Symbol.for("react.element"),Rv=Symbol.for("react.fragment"),Lv=Object.prototype.hasOwnProperty,Ov=Nv.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Pv={key:!0,ref:!0,__self:!0,__source:!0};function zh(e,t,r){var n,i={},a=null,s=null;r!==void 0&&(a=""+r),t.key!==void 0&&(a=""+t.key),t.ref!==void 0&&(s=t.ref);for(n in t)Lv.call(t,n)&&!Pv.hasOwnProperty(n)&&(i[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps,t)i[n]===void 0&&(i[n]=t[n]);return{$$typeof:Dv,type:e,key:a,ref:s,props:i,_owner:Ov.current}}il.Fragment=Rv;il.jsx=zh;il.jsxs=zh;Lh.exports=il;var D=Lh.exports,bu={},Hh={exports:{}},fr={},qh={exports:{}},$h={};/** + */var Rh=C,Ah=Symbol.for("react.element"),bh=Symbol.for("react.fragment"),zh=Object.prototype.hasOwnProperty,$h=Rh.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,Fh={key:!0,ref:!0,__self:!0,__source:!0};function Tc(e,t,n){var r,o={},i=null,s=null;n!==void 0&&(i=""+n),t.key!==void 0&&(i=""+t.key),t.ref!==void 0&&(s=t.ref);for(r in t)zh.call(t,r)&&!Fh.hasOwnProperty(r)&&(o[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps,t)o[r]===void 0&&(o[r]=t[r]);return{$$typeof:Ah,type:e,key:i,ref:s,props:o,_owner:$h.current}}ai.Fragment=bh;ai.jsx=Tc;ai.jsxs=Tc;yc.exports=ai;var S=yc.exports,Cs={},Dc={exports:{}},be={},Pc={exports:{}},Ic={};/** * @license React * scheduler.production.min.js * @@ -22,7 +22,7 @@ var fv=Object.defineProperty;var dv=(e,t,r)=>t in e?fv(e,t,{enumerable:!0,config * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */(function(e){function t(W,ae){var ne=W.length;W.push(ae);e:for(;0>>1,ie=W[ee];if(0>>1;eei(Fe,ne))Rei(ke,Fe)?(W[ee]=ke,W[Re]=ne,ee=Re):(W[ee]=Fe,W[se]=ne,ee=se);else if(Rei(ke,ne))W[ee]=ke,W[Re]=ne,ee=Re;else break e}}return ae}function i(W,ae){var ne=W.sortIndex-ae.sortIndex;return ne!==0?ne:W.id-ae.id}if(typeof performance=="object"&&typeof performance.now=="function"){var a=performance;e.unstable_now=function(){return a.now()}}else{var s=Date,o=s.now();e.unstable_now=function(){return s.now()-o}}var l=[],u=[],c=1,f=null,d=3,v=!1,g=!1,C=!1,I=typeof setTimeout=="function"?setTimeout:null,y=typeof clearTimeout=="function"?clearTimeout:null,m=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function S(W){for(var ae=r(u);ae!==null;){if(ae.callback===null)n(u);else if(ae.startTime<=W)n(u),ae.sortIndex=ae.expirationTime,t(l,ae);else break;ae=r(u)}}function B(W){if(C=!1,S(W),!g)if(r(l)!==null)g=!0,Le(R);else{var ae=r(u);ae!==null&&te(B,ae.startTime-W)}}function R(W,ae){g=!1,C&&(C=!1,y(V),V=-1),v=!0;var ne=d;try{for(S(ae),f=r(l);f!==null&&(!(f.expirationTime>ae)||W&&!ce());){var ee=f.callback;if(typeof ee=="function"){f.callback=null,d=f.priorityLevel;var ie=ee(f.expirationTime<=ae);ae=e.unstable_now(),typeof ie=="function"?f.callback=ie:f===r(l)&&n(l),S(ae)}else n(l);f=r(l)}if(f!==null)var Oe=!0;else{var se=r(u);se!==null&&te(B,se.startTime-ae),Oe=!1}return Oe}finally{f=null,d=ne,v=!1}}var L=!1,M=null,V=-1,Q=5,G=-1;function ce(){return!(e.unstable_now()-GW||125ee?(W.sortIndex=ne,t(u,W),r(l)===null&&W===r(u)&&(C?(y(V),V=-1):C=!0,te(B,ne-ee))):(W.sortIndex=ie,t(l,W),g||v||(g=!0,Le(R))),W},e.unstable_shouldYield=ce,e.unstable_wrapCallback=function(W){var ae=d;return function(){var ne=d;d=ae;try{return W.apply(this,arguments)}finally{d=ne}}}})($h);qh.exports=$h;var Uv=qh.exports;/** + */(function(e){function t(D,L){var R=D.length;D.push(L);e:for(;0>>1,Y=D[U];if(0>>1;Uo(_t,R))Jeo($e,_t)?(D[U]=$e,D[Je]=R,U=Je):(D[U]=_t,D[b]=R,U=b);else if(Jeo($e,R))D[U]=$e,D[Je]=R,U=Je;else break e}}return L}function o(D,L){var R=D.sortIndex-L.sortIndex;return R!==0?R:D.id-L.id}if(typeof performance=="object"&&typeof performance.now=="function"){var i=performance;e.unstable_now=function(){return i.now()}}else{var s=Date,l=s.now();e.unstable_now=function(){return s.now()-l}}var u=[],a=[],p=1,m=null,d=3,g=!1,v=!1,y=!1,w=typeof setTimeout=="function"?setTimeout:null,h=typeof clearTimeout=="function"?clearTimeout:null,c=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function f(D){for(var L=n(a);L!==null;){if(L.callback===null)r(a);else if(L.startTime<=D)r(a),L.sortIndex=L.expirationTime,t(u,L);else break;L=n(a)}}function k(D){if(y=!1,f(D),!v)if(n(u)!==null)v=!0,en(x);else{var L=n(a);L!==null&&tn(k,L.startTime-D)}}function x(D,L){v=!1,y&&(y=!1,h(T),T=-1),g=!0;var R=d;try{for(f(L),m=n(u);m!==null&&(!(m.expirationTime>L)||D&&!re());){var U=m.callback;if(typeof U=="function"){m.callback=null,d=m.priorityLevel;var Y=U(m.expirationTime<=L);L=e.unstable_now(),typeof Y=="function"?m.callback=Y:m===n(u)&&r(u),f(L)}else r(u);m=n(u)}if(m!==null)var lt=!0;else{var b=n(a);b!==null&&tn(k,b.startTime-L),lt=!1}return lt}finally{m=null,d=R,g=!1}}var _=!1,O=null,T=-1,j=5,I=-1;function re(){return!(e.unstable_now()-ID||125U?(D.sortIndex=R,t(a,D),n(u)===null&&D===n(a)&&(y?(h(T),T=-1):y=!0,tn(k,R-U))):(D.sortIndex=Y,t(u,D),v||g||(v=!0,en(x))),D},e.unstable_shouldYield=re,e.unstable_wrapCallback=function(D){var L=d;return function(){var R=d;d=L;try{return D.apply(this,arguments)}finally{d=R}}}})(Ic);Pc.exports=Ic;var Uh=Pc.exports;/** * @license React * react-dom.production.min.js * @@ -30,14 +30,14 @@ var fv=Object.defineProperty;var dv=(e,t,r)=>t in e?fv(e,t,{enumerable:!0,config * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Gh=q,cr=Uv;function H(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,r=1;r"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Nu=Object.prototype.hasOwnProperty,Mv=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,T0={},w0={};function Fv(e){return Nu.call(w0,e)?!0:Nu.call(T0,e)?!1:Mv.test(e)?w0[e]=!0:(T0[e]=!0,!1)}function Vv(e,t,r,n){if(r!==null&&r.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return n?!1:r!==null?!r.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function jv(e,t,r,n){if(t===null||typeof t>"u"||Vv(e,t,r,n))return!0;if(n)return!1;if(r!==null)switch(r.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function $t(e,t,r,n,i,a,s){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=n,this.attributeNamespace=i,this.mustUseProperty=r,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=s}var Rt={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){Rt[e]=new $t(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];Rt[t]=new $t(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){Rt[e]=new $t(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){Rt[e]=new $t(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){Rt[e]=new $t(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){Rt[e]=new $t(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){Rt[e]=new $t(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){Rt[e]=new $t(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){Rt[e]=new $t(e,5,!1,e.toLowerCase(),null,!1,!1)});var Jc=/[\-:]([a-z])/g;function ef(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(Jc,ef);Rt[t]=new $t(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(Jc,ef);Rt[t]=new $t(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(Jc,ef);Rt[t]=new $t(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){Rt[e]=new $t(e,1,!1,e.toLowerCase(),null,!1,!1)});Rt.xlinkHref=new $t("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){Rt[e]=new $t(e,1,!1,e.toLowerCase(),null,!0,!0)});function tf(e,t,r,n){var i=Rt.hasOwnProperty(t)?Rt[t]:null;(i!==null?i.type!==0:n||!(2o||i[s]!==a[o]){var l=` -`+i[s].replace(" at new "," at ");return e.displayName&&l.includes("")&&(l=l.replace("",e.displayName)),l}while(1<=s&&0<=o);break}}}finally{jl=!1,Error.prepareStackTrace=r}return(e=e?e.displayName||e.name:"")?Oa(e):""}function Kv(e){switch(e.tag){case 5:return Oa(e.type);case 16:return Oa("Lazy");case 13:return Oa("Suspense");case 19:return Oa("SuspenseList");case 0:case 2:case 15:return e=Kl(e.type,!1),e;case 11:return e=Kl(e.type.render,!1),e;case 1:return e=Kl(e.type,!0),e;default:return""}}function Ou(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Pi:return"Fragment";case Oi:return"Portal";case Du:return"Profiler";case rf:return"StrictMode";case Ru:return"Suspense";case Lu:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Yh:return(e.displayName||"Context")+".Consumer";case Wh:return(e._context.displayName||"Context")+".Provider";case nf:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case af:return t=e.displayName||null,t!==null?t:Ou(e.type)||"Memo";case An:t=e._payload,e=e._init;try{return Ou(e(t))}catch{}}return null}function zv(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Ou(t);case 8:return t===rf?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function Wn(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function Zh(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function Hv(e){var t=Zh(e)?"checked":"value",r=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),n=""+e[t];if(!e.hasOwnProperty(t)&&typeof r<"u"&&typeof r.get=="function"&&typeof r.set=="function"){var i=r.get,a=r.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return i.call(this)},set:function(s){n=""+s,a.call(this,s)}}),Object.defineProperty(e,t,{enumerable:r.enumerable}),{getValue:function(){return n},setValue:function(s){n=""+s},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function Os(e){e._valueTracker||(e._valueTracker=Hv(e))}function Jh(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var r=t.getValue(),n="";return e&&(n=Zh(e)?e.checked?"true":"false":e.value),e=n,e!==r?(t.setValue(e),!0):!1}function To(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Pu(e,t){var r=t.checked;return st({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:r??e._wrapperState.initialChecked})}function _0(e,t){var r=t.defaultValue==null?"":t.defaultValue,n=t.checked!=null?t.checked:t.defaultChecked;r=Wn(t.value!=null?t.value:r),e._wrapperState={initialChecked:n,initialValue:r,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function ep(e,t){t=t.checked,t!=null&&tf(e,"checked",t,!1)}function Uu(e,t){ep(e,t);var r=Wn(t.value),n=t.type;if(r!=null)n==="number"?(r===0&&e.value===""||e.value!=r)&&(e.value=""+r):e.value!==""+r&&(e.value=""+r);else if(n==="submit"||n==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?Mu(e,t.type,r):t.hasOwnProperty("defaultValue")&&Mu(e,t.type,Wn(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function A0(e,t,r){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var n=t.type;if(!(n!=="submit"&&n!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,r||t===e.value||(e.value=t),e.defaultValue=t}r=e.name,r!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,r!==""&&(e.name=r)}function Mu(e,t,r){(t!=="number"||To(e.ownerDocument)!==e)&&(r==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+r&&(e.defaultValue=""+r))}var Pa=Array.isArray;function Yi(e,t,r,n){if(e=e.options,t){t={};for(var i=0;i"+t.valueOf().toString()+"",t=Ps.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function ns(e,t){if(t){var r=e.firstChild;if(r&&r===e.lastChild&&r.nodeType===3){r.nodeValue=t;return}}e.textContent=t}var Ka={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},qv=["Webkit","ms","Moz","O"];Object.keys(Ka).forEach(function(e){qv.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Ka[t]=Ka[e]})});function ip(e,t,r){return t==null||typeof t=="boolean"||t===""?"":r||typeof t!="number"||t===0||Ka.hasOwnProperty(e)&&Ka[e]?(""+t).trim():t+"px"}function ap(e,t){e=e.style;for(var r in t)if(t.hasOwnProperty(r)){var n=r.indexOf("--")===0,i=ip(r,t[r],n);r==="float"&&(r="cssFloat"),n?e.setProperty(r,i):e[r]=i}}var $v=st({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ju(e,t){if(t){if($v[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(H(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(H(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(H(61))}if(t.style!=null&&typeof t.style!="object")throw Error(H(62))}}function Ku(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var zu=null;function sf(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Hu=null,Xi=null,Zi=null;function b0(e){if(e=_s(e)){if(typeof Hu!="function")throw Error(H(280));var t=e.stateNode;t&&(t=ul(t),Hu(e.stateNode,e.type,t))}}function sp(e){Xi?Zi?Zi.push(e):Zi=[e]:Xi=e}function op(){if(Xi){var e=Xi,t=Zi;if(Zi=Xi=null,b0(e),t)for(e=0;e>>=0,e===0?32:31-(ny(e)/iy|0)|0}var Us=64,Ms=4194304;function Ua(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Ao(e,t){var r=e.pendingLanes;if(r===0)return 0;var n=0,i=e.suspendedLanes,a=e.pingedLanes,s=r&268435455;if(s!==0){var o=s&~i;o!==0?n=Ua(o):(a&=s,a!==0&&(n=Ua(a)))}else s=r&~i,s!==0?n=Ua(s):a!==0&&(n=Ua(a));if(n===0)return 0;if(t!==0&&t!==n&&!(t&i)&&(i=n&-n,a=t&-t,i>=a||i===16&&(a&4194240)!==0))return t;if(n&4&&(n|=r&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=n;0r;r++)t.push(e);return t}function ws(e,t,r){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-Fr(t),e[t]=r}function ly(e,t){var r=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var n=e.eventTimes;for(e=e.expirationTimes;0=Ha),F0=String.fromCharCode(32),V0=!1;function Ap(e,t){switch(e){case"keyup":return Py.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Bp(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Ui=!1;function My(e,t){switch(e){case"compositionend":return Bp(t);case"keypress":return t.which!==32?null:(V0=!0,F0);case"textInput":return e=t.data,e===F0&&V0?null:e;default:return null}}function Fy(e,t){if(Ui)return e==="compositionend"||!pf&&Ap(e,t)?(e=Ip(),oo=ff=Dn=null,Ui=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=H0(r)}}function Dp(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Dp(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Rp(){for(var e=window,t=To();t instanceof e.HTMLIFrameElement;){try{var r=typeof t.contentWindow.location.href=="string"}catch{r=!1}if(r)e=t.contentWindow;else break;t=To(e.document)}return t}function gf(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function Qy(e){var t=Rp(),r=e.focusedElem,n=e.selectionRange;if(t!==r&&r&&r.ownerDocument&&Dp(r.ownerDocument.documentElement,r)){if(n!==null&&gf(r)){if(t=n.start,e=n.end,e===void 0&&(e=t),"selectionStart"in r)r.selectionStart=t,r.selectionEnd=Math.min(e,r.value.length);else if(e=(t=r.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var i=r.textContent.length,a=Math.min(n.start,i);n=n.end===void 0?a:Math.min(n.end,i),!e.extend&&a>n&&(i=n,n=a,a=i),i=q0(r,a);var s=q0(r,n);i&&s&&(e.rangeCount!==1||e.anchorNode!==i.node||e.anchorOffset!==i.offset||e.focusNode!==s.node||e.focusOffset!==s.offset)&&(t=t.createRange(),t.setStart(i.node,i.offset),e.removeAllRanges(),a>n?(e.addRange(t),e.extend(s.node,s.offset)):(t.setEnd(s.node,s.offset),e.addRange(t)))}}for(t=[],e=r;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof r.focus=="function"&&r.focus(),r=0;r=document.documentMode,Mi=null,Yu=null,$a=null,Xu=!1;function $0(e,t,r){var n=r.window===r?r.document:r.nodeType===9?r:r.ownerDocument;Xu||Mi==null||Mi!==To(n)||(n=Mi,"selectionStart"in n&&gf(n)?n={start:n.selectionStart,end:n.selectionEnd}:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection(),n={anchorNode:n.anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset}),$a&&us($a,n)||($a=n,n=bo(Yu,"onSelect"),0ji||(e.current=nc[ji],nc[ji]=null,ji--)}function Ge(e,t){ji++,nc[ji]=e.current,e.current=t}var Yn={},Mt=ei(Yn),Xt=ei(!1),vi=Yn;function na(e,t){var r=e.type.contextTypes;if(!r)return Yn;var n=e.stateNode;if(n&&n.__reactInternalMemoizedUnmaskedChildContext===t)return n.__reactInternalMemoizedMaskedChildContext;var i={},a;for(a in r)i[a]=t[a];return n&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function Zt(e){return e=e.childContextTypes,e!=null}function Do(){et(Xt),et(Mt)}function J0(e,t,r){if(Mt.current!==Yn)throw Error(H(168));Ge(Mt,t),Ge(Xt,r)}function Kp(e,t,r){var n=e.stateNode;if(t=t.childContextTypes,typeof n.getChildContext!="function")return r;n=n.getChildContext();for(var i in n)if(!(i in t))throw Error(H(108,zv(e)||"Unknown",i));return st({},r,n)}function Ro(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Yn,vi=Mt.current,Ge(Mt,e),Ge(Xt,Xt.current),!0}function ed(e,t,r){var n=e.stateNode;if(!n)throw Error(H(169));r?(e=Kp(e,t,vi),n.__reactInternalMemoizedMergedChildContext=e,et(Xt),et(Mt),Ge(Mt,e)):et(Xt),Ge(Xt,r)}var ln=null,cl=!1,ru=!1;function zp(e){ln===null?ln=[e]:ln.push(e)}function sm(e){cl=!0,zp(e)}function ti(){if(!ru&&ln!==null){ru=!0;var e=0,t=Me;try{var r=ln;for(Me=1;e>=s,i-=s,un=1<<32-Fr(t)+i|r<V?(Q=M,M=null):Q=M.sibling;var G=d(y,M,S[V],B);if(G===null){M===null&&(M=Q);break}e&&M&&G.alternate===null&&t(y,M),m=a(G,m,V),L===null?R=G:L.sibling=G,L=G,M=Q}if(V===S.length)return r(y,M),rt&&ni(y,V),R;if(M===null){for(;VV?(Q=M,M=null):Q=M.sibling;var ce=d(y,M,G.value,B);if(ce===null){M===null&&(M=Q);break}e&&M&&ce.alternate===null&&t(y,M),m=a(ce,m,V),L===null?R=ce:L.sibling=ce,L=ce,M=Q}if(G.done)return r(y,M),rt&&ni(y,V),R;if(M===null){for(;!G.done;V++,G=S.next())G=f(y,G.value,B),G!==null&&(m=a(G,m,V),L===null?R=G:L.sibling=G,L=G);return rt&&ni(y,V),R}for(M=n(y,M);!G.done;V++,G=S.next())G=v(M,y,V,G.value,B),G!==null&&(e&&G.alternate!==null&&M.delete(G.key===null?V:G.key),m=a(G,m,V),L===null?R=G:L.sibling=G,L=G);return e&&M.forEach(function(pe){return t(y,pe)}),rt&&ni(y,V),R}function I(y,m,S,B){if(typeof S=="object"&&S!==null&&S.type===Pi&&S.key===null&&(S=S.props.children),typeof S=="object"&&S!==null){switch(S.$$typeof){case Ls:e:{for(var R=S.key,L=m;L!==null;){if(L.key===R){if(R=S.type,R===Pi){if(L.tag===7){r(y,L.sibling),m=i(L,S.props.children),m.return=y,y=m;break e}}else if(L.elementType===R||typeof R=="object"&&R!==null&&R.$$typeof===An&&od(R)===L.type){r(y,L.sibling),m=i(L,S.props),m.ref=Ba(y,L,S),m.return=y,y=m;break e}r(y,L);break}else t(y,L);L=L.sibling}S.type===Pi?(m=hi(S.props.children,y.mode,B,S.key),m.return=y,y=m):(B=vo(S.type,S.key,S.props,null,y.mode,B),B.ref=Ba(y,m,S),B.return=y,y=B)}return s(y);case Oi:e:{for(L=S.key;m!==null;){if(m.key===L)if(m.tag===4&&m.stateNode.containerInfo===S.containerInfo&&m.stateNode.implementation===S.implementation){r(y,m.sibling),m=i(m,S.children||[]),m.return=y,y=m;break e}else{r(y,m);break}else t(y,m);m=m.sibling}m=cu(S,y.mode,B),m.return=y,y=m}return s(y);case An:return L=S._init,I(y,m,L(S._payload),B)}if(Pa(S))return g(y,m,S,B);if(Ta(S))return C(y,m,S,B);qs(y,S)}return typeof S=="string"&&S!==""||typeof S=="number"?(S=""+S,m!==null&&m.tag===6?(r(y,m.sibling),m=i(m,S),m.return=y,y=m):(r(y,m),m=uu(S,y.mode,B),m.return=y,y=m),s(y)):r(y,m)}return I}var aa=Xp(!0),Zp=Xp(!1),As={},tn=ei(As),hs=ei(As),ps=ei(As);function ci(e){if(e===As)throw Error(H(174));return e}function wf(e,t){switch(Ge(ps,t),Ge(hs,e),Ge(tn,As),e=t.nodeType,e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:Vu(null,"");break;default:e=e===8?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=Vu(t,e)}et(tn),Ge(tn,t)}function sa(){et(tn),et(hs),et(ps)}function Jp(e){ci(ps.current);var t=ci(tn.current),r=Vu(t,e.type);t!==r&&(Ge(hs,e),Ge(tn,r))}function If(e){hs.current===e&&(et(tn),et(hs))}var it=ei(0);function Fo(e){for(var t=e;t!==null;){if(t.tag===13){var r=t.memoizedState;if(r!==null&&(r=r.dehydrated,r===null||r.data==="$?"||r.data==="$!"))return t}else if(t.tag===19&&t.memoizedProps.revealOrder!==void 0){if(t.flags&128)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var nu=[];function _f(){for(var e=0;er?r:4,e(!0);var n=iu.transition;iu.transition={};try{e(!1),t()}finally{Me=r,iu.transition=n}}function gg(){return Nr().memoizedState}function cm(e,t,r){var n=qn(e);if(r={lane:n,action:r,hasEagerState:!1,eagerState:null,next:null},vg(e))yg(t,r);else if(r=Gp(e,t,r,n),r!==null){var i=Ht();Vr(r,e,n,i),mg(r,t,n)}}function fm(e,t,r){var n=qn(e),i={lane:n,action:r,hasEagerState:!1,eagerState:null,next:null};if(vg(e))yg(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var s=t.lastRenderedState,o=a(s,r);if(i.hasEagerState=!0,i.eagerState=o,jr(o,s)){var l=t.interleaved;l===null?(i.next=i,xf(t)):(i.next=l.next,l.next=i),t.interleaved=i;return}}catch{}finally{}r=Gp(e,t,i,n),r!==null&&(i=Ht(),Vr(r,e,n,i),mg(r,t,n))}}function vg(e){var t=e.alternate;return e===at||t!==null&&t===at}function yg(e,t){Ga=Vo=!0;var r=e.pending;r===null?t.next=t:(t.next=r.next,r.next=t),e.pending=t}function mg(e,t,r){if(r&4194240){var n=t.lanes;n&=e.pendingLanes,r|=n,t.lanes=r,lf(e,r)}}var jo={readContext:br,useCallback:Lt,useContext:Lt,useEffect:Lt,useImperativeHandle:Lt,useInsertionEffect:Lt,useLayoutEffect:Lt,useMemo:Lt,useReducer:Lt,useRef:Lt,useState:Lt,useDebugValue:Lt,useDeferredValue:Lt,useTransition:Lt,useMutableSource:Lt,useSyncExternalStore:Lt,useId:Lt,unstable_isNewReconciler:!1},dm={readContext:br,useCallback:function(e,t){return Hr().memoizedState=[e,t===void 0?null:t],e},useContext:br,useEffect:ud,useImperativeHandle:function(e,t,r){return r=r!=null?r.concat([e]):null,fo(4194308,4,cg.bind(null,t,e),r)},useLayoutEffect:function(e,t){return fo(4194308,4,e,t)},useInsertionEffect:function(e,t){return fo(4,2,e,t)},useMemo:function(e,t){var r=Hr();return t=t===void 0?null:t,e=e(),r.memoizedState=[e,t],e},useReducer:function(e,t,r){var n=Hr();return t=r!==void 0?r(t):t,n.memoizedState=n.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},n.queue=e,e=e.dispatch=cm.bind(null,at,e),[n.memoizedState,e]},useRef:function(e){var t=Hr();return e={current:e},t.memoizedState=e},useState:ld,useDebugValue:Nf,useDeferredValue:function(e){return Hr().memoizedState=e},useTransition:function(){var e=ld(!1),t=e[0];return e=um.bind(null,e[1]),Hr().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,r){var n=at,i=Hr();if(rt){if(r===void 0)throw Error(H(407));r=r()}else{if(r=t(),It===null)throw Error(H(349));mi&30||rg(n,t,r)}i.memoizedState=r;var a={value:r,getSnapshot:t};return i.queue=a,ud(ig.bind(null,n,a,e),[e]),n.flags|=2048,ys(9,ng.bind(null,n,a,r,t),void 0,null),r},useId:function(){var e=Hr(),t=It.identifierPrefix;if(rt){var r=cn,n=un;r=(n&~(1<<32-Fr(n)-1)).toString(32)+r,t=":"+t+"R"+r,r=gs++,0<\/script>",e=e.removeChild(e.firstChild)):typeof n.is=="string"?e=s.createElement(r,{is:n.is}):(e=s.createElement(r),r==="select"&&(s=e,n.multiple?s.multiple=!0:n.size&&(s.size=n.size))):e=s.createElementNS(e,r),e[Qr]=t,e[ds]=n,Ag(e,t,!1,!1),t.stateNode=e;e:{switch(s=Ku(r,n),r){case"dialog":Xe("cancel",e),Xe("close",e),i=n;break;case"iframe":case"object":case"embed":Xe("load",e),i=n;break;case"video":case"audio":for(i=0;ila&&(t.flags|=128,n=!0,ka(a,!1),t.lanes=4194304)}else{if(!n)if(e=Fo(s),e!==null){if(t.flags|=128,n=!0,r=e.updateQueue,r!==null&&(t.updateQueue=r,t.flags|=4),ka(a,!0),a.tail===null&&a.tailMode==="hidden"&&!s.alternate&&!rt)return Ot(t),null}else 2*dt()-a.renderingStartTime>la&&r!==1073741824&&(t.flags|=128,n=!0,ka(a,!1),t.lanes=4194304);a.isBackwards?(s.sibling=t.child,t.child=s):(r=a.last,r!==null?r.sibling=s:t.child=s,a.last=s)}return a.tail!==null?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=dt(),t.sibling=null,r=it.current,Ge(it,n?r&1|2:r&1),t):(Ot(t),null);case 22:case 23:return Uf(),n=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==n&&(t.flags|=8192),n&&t.mode&1?ar&1073741824&&(Ot(t),t.subtreeFlags&6&&(t.flags|=8192)):Ot(t),null;case 24:return null;case 25:return null}throw Error(H(156,t.tag))}function Em(e,t){switch(yf(t),t.tag){case 1:return Zt(t.type)&&Do(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return sa(),et(Xt),et(Mt),_f(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return If(t),null;case 13:if(et(it),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(H(340));ia()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return et(it),null;case 4:return sa(),null;case 10:return Sf(t.type._context),null;case 22:case 23:return Uf(),null;case 24:return null;default:return null}}var Gs=!1,Ut=!1,Sm=typeof WeakSet=="function"?WeakSet:Set,re=null;function qi(e,t){var r=e.ref;if(r!==null)if(typeof r=="function")try{r(null)}catch(n){lt(e,t,n)}else r.current=null}function gc(e,t,r){try{r()}catch(n){lt(e,t,n)}}var md=!1;function xm(e,t){if(Zu=Bo,e=Rp(),gf(e)){if("selectionStart"in e)var r={start:e.selectionStart,end:e.selectionEnd};else e:{r=(r=e.ownerDocument)&&r.defaultView||window;var n=r.getSelection&&r.getSelection();if(n&&n.rangeCount!==0){r=n.anchorNode;var i=n.anchorOffset,a=n.focusNode;n=n.focusOffset;try{r.nodeType,a.nodeType}catch{r=null;break e}var s=0,o=-1,l=-1,u=0,c=0,f=e,d=null;t:for(;;){for(var v;f!==r||i!==0&&f.nodeType!==3||(o=s+i),f!==a||n!==0&&f.nodeType!==3||(l=s+n),f.nodeType===3&&(s+=f.nodeValue.length),(v=f.firstChild)!==null;)d=f,f=v;for(;;){if(f===e)break t;if(d===r&&++u===i&&(o=s),d===a&&++c===n&&(l=s),(v=f.nextSibling)!==null)break;f=d,d=f.parentNode}f=v}r=o===-1||l===-1?null:{start:o,end:l}}else r=null}r=r||{start:0,end:0}}else r=null;for(Ju={focusedElem:e,selectionRange:r},Bo=!1,re=t;re!==null;)if(t=re,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,re=e;else for(;re!==null;){t=re;try{var g=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(g!==null){var C=g.memoizedProps,I=g.memoizedState,y=t.stateNode,m=y.getSnapshotBeforeUpdate(t.elementType===t.type?C:Or(t.type,C),I);y.__reactInternalSnapshotBeforeUpdate=m}break;case 3:var S=t.stateNode.containerInfo;S.nodeType===1?S.textContent="":S.nodeType===9&&S.documentElement&&S.removeChild(S.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(H(163))}}catch(B){lt(t,t.return,B)}if(e=t.sibling,e!==null){e.return=t.return,re=e;break}re=t.return}return g=md,md=!1,g}function Qa(e,t,r){var n=t.updateQueue;if(n=n!==null?n.lastEffect:null,n!==null){var i=n=n.next;do{if((i.tag&e)===e){var a=i.destroy;i.destroy=void 0,a!==void 0&&gc(t,r,a)}i=i.next}while(i!==n)}}function hl(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var r=t=t.next;do{if((r.tag&e)===e){var n=r.create;r.destroy=n()}r=r.next}while(r!==t)}}function vc(e){var t=e.ref;if(t!==null){var r=e.stateNode;switch(e.tag){case 5:e=r;break;default:e=r}typeof t=="function"?t(e):t.current=e}}function bg(e){var t=e.alternate;t!==null&&(e.alternate=null,bg(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Qr],delete t[ds],delete t[rc],delete t[im],delete t[am])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Ng(e){return e.tag===5||e.tag===3||e.tag===4}function Cd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Ng(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function yc(e,t,r){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?r.nodeType===8?r.parentNode.insertBefore(e,t):r.insertBefore(e,t):(r.nodeType===8?(t=r.parentNode,t.insertBefore(e,r)):(t=r,t.appendChild(e)),r=r._reactRootContainer,r!=null||t.onclick!==null||(t.onclick=No));else if(n!==4&&(e=e.child,e!==null))for(yc(e,t,r),e=e.sibling;e!==null;)yc(e,t,r),e=e.sibling}function mc(e,t,r){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?r.insertBefore(e,t):r.appendChild(e);else if(n!==4&&(e=e.child,e!==null))for(mc(e,t,r),e=e.sibling;e!==null;)mc(e,t,r),e=e.sibling}var Bt=null,Pr=!1;function xn(e,t,r){for(r=r.child;r!==null;)Dg(e,t,r),r=r.sibling}function Dg(e,t,r){if(en&&typeof en.onCommitFiberUnmount=="function")try{en.onCommitFiberUnmount(al,r)}catch{}switch(r.tag){case 5:Ut||qi(r,t);case 6:var n=Bt,i=Pr;Bt=null,xn(e,t,r),Bt=n,Pr=i,Bt!==null&&(Pr?(e=Bt,r=r.stateNode,e.nodeType===8?e.parentNode.removeChild(r):e.removeChild(r)):Bt.removeChild(r.stateNode));break;case 18:Bt!==null&&(Pr?(e=Bt,r=r.stateNode,e.nodeType===8?tu(e.parentNode,r):e.nodeType===1&&tu(e,r),os(e)):tu(Bt,r.stateNode));break;case 4:n=Bt,i=Pr,Bt=r.stateNode.containerInfo,Pr=!0,xn(e,t,r),Bt=n,Pr=i;break;case 0:case 11:case 14:case 15:if(!Ut&&(n=r.updateQueue,n!==null&&(n=n.lastEffect,n!==null))){i=n=n.next;do{var a=i,s=a.destroy;a=a.tag,s!==void 0&&(a&2||a&4)&&gc(r,t,s),i=i.next}while(i!==n)}xn(e,t,r);break;case 1:if(!Ut&&(qi(r,t),n=r.stateNode,typeof n.componentWillUnmount=="function"))try{n.props=r.memoizedProps,n.state=r.memoizedState,n.componentWillUnmount()}catch(o){lt(r,t,o)}xn(e,t,r);break;case 21:xn(e,t,r);break;case 22:r.mode&1?(Ut=(n=Ut)||r.memoizedState!==null,xn(e,t,r),Ut=n):xn(e,t,r);break;default:xn(e,t,r)}}function Ed(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var r=e.stateNode;r===null&&(r=e.stateNode=new Sm),t.forEach(function(n){var i=Nm.bind(null,e,n);r.has(n)||(r.add(n),n.then(i,i))})}}function Rr(e,t){var r=t.deletions;if(r!==null)for(var n=0;ni&&(i=s),n&=~a}if(n=i,n=dt()-n,n=(120>n?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*wm(n/1960))-n,10e?16:e,Rn===null)var n=!1;else{if(e=Rn,Rn=null,Ho=0,Ae&6)throw Error(H(331));var i=Ae;for(Ae|=4,re=e.current;re!==null;){var a=re,s=a.child;if(re.flags&16){var o=a.deletions;if(o!==null){for(var l=0;ldt()-Of?di(e,0):Lf|=r),Jt(e,t)}function Vg(e,t){t===0&&(e.mode&1?(t=Ms,Ms<<=1,!(Ms&130023424)&&(Ms=4194304)):t=1);var r=Ht();e=vn(e,t),e!==null&&(ws(e,t,r),Jt(e,r))}function bm(e){var t=e.memoizedState,r=0;t!==null&&(r=t.retryLane),Vg(e,r)}function Nm(e,t){var r=0;switch(e.tag){case 13:var n=e.stateNode,i=e.memoizedState;i!==null&&(r=i.retryLane);break;case 19:n=e.stateNode;break;default:throw Error(H(314))}n!==null&&n.delete(t),Vg(e,r)}var jg;jg=function(e,t,r){if(e!==null)if(e.memoizedProps!==t.pendingProps||Xt.current)Wt=!0;else{if(!(e.lanes&r)&&!(t.flags&128))return Wt=!1,mm(e,t,r);Wt=!!(e.flags&131072)}else Wt=!1,rt&&t.flags&1048576&&Hp(t,Oo,t.index);switch(t.lanes=0,t.tag){case 2:var n=t.type;ho(e,t),e=t.pendingProps;var i=na(t,Mt.current);ea(t,r),i=Bf(null,t,n,e,i,r);var a=kf();return t.flags|=1,typeof i=="object"&&i!==null&&typeof i.render=="function"&&i.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Zt(n)?(a=!0,Ro(t)):a=!1,t.memoizedState=i.state!==null&&i.state!==void 0?i.state:null,Tf(t),i.updater=fl,t.stateNode=i,i._reactInternals=t,lc(t,n,e,r),t=fc(null,t,n,!0,a,r)):(t.tag=0,rt&&a&&vf(t),jt(null,t,i,r),t=t.child),t;case 16:n=t.elementType;e:{switch(ho(e,t),e=t.pendingProps,i=n._init,n=i(n._payload),t.type=n,i=t.tag=Rm(n),e=Or(n,e),i){case 0:t=cc(null,t,n,e,r);break e;case 1:t=gd(null,t,n,e,r);break e;case 11:t=hd(null,t,n,e,r);break e;case 14:t=pd(null,t,n,Or(n.type,e),r);break e}throw Error(H(306,n,""))}return t;case 0:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Or(n,i),cc(e,t,n,i,r);case 1:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Or(n,i),gd(e,t,n,i,r);case 3:e:{if(wg(t),e===null)throw Error(H(387));n=t.pendingProps,a=t.memoizedState,i=a.element,Qp(e,t),Mo(t,n,null,r);var s=t.memoizedState;if(n=s.element,a.isDehydrated)if(a={element:n,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=a,t.memoizedState=a,t.flags&256){i=oa(Error(H(423)),t),t=vd(e,t,n,r,i);break e}else if(n!==i){i=oa(Error(H(424)),t),t=vd(e,t,n,r,i);break e}else for(lr=Kn(t.stateNode.containerInfo.firstChild),ur=t,rt=!0,Ur=null,r=Zp(t,null,n,r),t.child=r;r;)r.flags=r.flags&-3|4096,r=r.sibling;else{if(ia(),n===i){t=yn(e,t,r);break e}jt(e,t,n,r)}t=t.child}return t;case 5:return Jp(t),e===null&&ac(t),n=t.type,i=t.pendingProps,a=e!==null?e.memoizedProps:null,s=i.children,ec(n,i)?s=null:a!==null&&ec(n,a)&&(t.flags|=32),Tg(e,t),jt(e,t,s,r),t.child;case 6:return e===null&&ac(t),null;case 13:return Ig(e,t,r);case 4:return wf(t,t.stateNode.containerInfo),n=t.pendingProps,e===null?t.child=aa(t,null,n,r):jt(e,t,n,r),t.child;case 11:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Or(n,i),hd(e,t,n,i,r);case 7:return jt(e,t,t.pendingProps,r),t.child;case 8:return jt(e,t,t.pendingProps.children,r),t.child;case 12:return jt(e,t,t.pendingProps.children,r),t.child;case 10:e:{if(n=t.type._context,i=t.pendingProps,a=t.memoizedProps,s=i.value,Ge(Po,n._currentValue),n._currentValue=s,a!==null)if(jr(a.value,s)){if(a.children===i.children&&!Xt.current){t=yn(e,t,r);break e}}else for(a=t.child,a!==null&&(a.return=t);a!==null;){var o=a.dependencies;if(o!==null){s=a.child;for(var l=o.firstContext;l!==null;){if(l.context===n){if(a.tag===1){l=dn(-1,r&-r),l.tag=2;var u=a.updateQueue;if(u!==null){u=u.shared;var c=u.pending;c===null?l.next=l:(l.next=c.next,c.next=l),u.pending=l}}a.lanes|=r,l=a.alternate,l!==null&&(l.lanes|=r),sc(a.return,r,t),o.lanes|=r;break}l=l.next}}else if(a.tag===10)s=a.type===t.type?null:a.child;else if(a.tag===18){if(s=a.return,s===null)throw Error(H(341));s.lanes|=r,o=s.alternate,o!==null&&(o.lanes|=r),sc(s,r,t),s=a.sibling}else s=a.child;if(s!==null)s.return=a;else for(s=a;s!==null;){if(s===t){s=null;break}if(a=s.sibling,a!==null){a.return=s.return,s=a;break}s=s.return}a=s}jt(e,t,i.children,r),t=t.child}return t;case 9:return i=t.type,n=t.pendingProps.children,ea(t,r),i=br(i),n=n(i),t.flags|=1,jt(e,t,n,r),t.child;case 14:return n=t.type,i=Or(n,t.pendingProps),i=Or(n.type,i),pd(e,t,n,i,r);case 15:return Sg(e,t,t.type,t.pendingProps,r);case 17:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Or(n,i),ho(e,t),t.tag=1,Zt(n)?(e=!0,Ro(t)):e=!1,ea(t,r),Yp(t,n,i),lc(t,n,i,r),fc(null,t,n,!0,e,r);case 19:return _g(e,t,r);case 22:return xg(e,t,r)}throw Error(H(156,t.tag))};function Kg(e,t){return pp(e,t)}function Dm(e,t,r,n){this.tag=e,this.key=r,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=n,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function wr(e,t,r,n){return new Dm(e,t,r,n)}function Ff(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Rm(e){if(typeof e=="function")return Ff(e)?1:0;if(e!=null){if(e=e.$$typeof,e===nf)return 11;if(e===af)return 14}return 2}function $n(e,t){var r=e.alternate;return r===null?(r=wr(e.tag,t,e.key,e.mode),r.elementType=e.elementType,r.type=e.type,r.stateNode=e.stateNode,r.alternate=e,e.alternate=r):(r.pendingProps=t,r.type=e.type,r.flags=0,r.subtreeFlags=0,r.deletions=null),r.flags=e.flags&14680064,r.childLanes=e.childLanes,r.lanes=e.lanes,r.child=e.child,r.memoizedProps=e.memoizedProps,r.memoizedState=e.memoizedState,r.updateQueue=e.updateQueue,t=e.dependencies,r.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},r.sibling=e.sibling,r.index=e.index,r.ref=e.ref,r}function vo(e,t,r,n,i,a){var s=2;if(n=e,typeof e=="function")Ff(e)&&(s=1);else if(typeof e=="string")s=5;else e:switch(e){case Pi:return hi(r.children,i,a,t);case rf:s=8,i|=8;break;case Du:return e=wr(12,r,t,i|2),e.elementType=Du,e.lanes=a,e;case Ru:return e=wr(13,r,t,i),e.elementType=Ru,e.lanes=a,e;case Lu:return e=wr(19,r,t,i),e.elementType=Lu,e.lanes=a,e;case Xh:return gl(r,i,a,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case Wh:s=10;break e;case Yh:s=9;break e;case nf:s=11;break e;case af:s=14;break e;case An:s=16,n=null;break e}throw Error(H(130,e==null?e:typeof e,""))}return t=wr(s,r,t,i),t.elementType=e,t.type=n,t.lanes=a,t}function hi(e,t,r,n){return e=wr(7,e,n,t),e.lanes=r,e}function gl(e,t,r,n){return e=wr(22,e,n,t),e.elementType=Xh,e.lanes=r,e.stateNode={isHidden:!1},e}function uu(e,t,r){return e=wr(6,e,null,t),e.lanes=r,e}function cu(e,t,r){return t=wr(4,e.children!==null?e.children:[],e.key,t),t.lanes=r,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Lm(e,t,r,n,i){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Hl(0),this.expirationTimes=Hl(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Hl(0),this.identifierPrefix=n,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function Vf(e,t,r,n,i,a,s,o,l){return e=new Lm(e,t,r,o,l),t===1?(t=1,a===!0&&(t|=8)):t=0,a=wr(3,null,null,t),e.current=a,a.stateNode=e,a.memoizedState={element:n,isDehydrated:r,cache:null,transitions:null,pendingSuspenseBoundaries:null},Tf(a),e}function Om(e,t,r){var n=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE($g)}catch(e){console.error(e)}}$g(),Hh.exports=fr;var Vm=Hh.exports,Bd=Vm;bu.createRoot=Bd.createRoot,bu.hydrateRoot=Bd.hydrateRoot;/** + */var jc=C,Ae=Uh;function E(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),xs=Object.prototype.hasOwnProperty,Hh=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,Lu={},Nu={};function Bh(e){return xs.call(Nu,e)?!0:xs.call(Lu,e)?!1:Hh.test(e)?Nu[e]=!0:(Lu[e]=!0,!1)}function Wh(e,t,n,r){if(n!==null&&n.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function qh(e,t,n,r){if(t===null||typeof t>"u"||Wh(e,t,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function Ce(e,t,n,r,o,i,s){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=i,this.removeEmptyString=s}var fe={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){fe[e]=new Ce(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];fe[t]=new Ce(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){fe[e]=new Ce(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){fe[e]=new Ce(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){fe[e]=new Ce(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){fe[e]=new Ce(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){fe[e]=new Ce(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){fe[e]=new Ce(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){fe[e]=new Ce(e,5,!1,e.toLowerCase(),null,!1,!1)});var Tl=/[\-:]([a-z])/g;function Dl(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(Tl,Dl);fe[t]=new Ce(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(Tl,Dl);fe[t]=new Ce(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(Tl,Dl);fe[t]=new Ce(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){fe[e]=new Ce(e,1,!1,e.toLowerCase(),null,!1,!1)});fe.xlinkHref=new Ce("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){fe[e]=new Ce(e,1,!1,e.toLowerCase(),null,!0,!0)});function Pl(e,t,n,r){var o=fe.hasOwnProperty(t)?fe[t]:null;(o!==null?o.type!==0:r||!(2l||o[s]!==i[l]){var u=` +`+o[s].replace(" at new "," at ");return e.displayName&&u.includes("")&&(u=u.replace("",e.displayName)),u}while(1<=s&&0<=l);break}}}finally{Hi=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?cr(e):""}function Qh(e){switch(e.tag){case 5:return cr(e.type);case 16:return cr("Lazy");case 13:return cr("Suspense");case 19:return cr("SuspenseList");case 0:case 2:case 15:return e=Bi(e.type,!1),e;case 11:return e=Bi(e.type.render,!1),e;case 1:return e=Bi(e.type,!0),e;default:return""}}function Ds(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case _n:return"Fragment";case xn:return"Portal";case _s:return"Profiler";case Il:return"StrictMode";case Os:return"Suspense";case Ts:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case Mc:return(e.displayName||"Context")+".Consumer";case Nc:return(e._context.displayName||"Context")+".Provider";case jl:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case Ll:return t=e.displayName||null,t!==null?t:Ds(e.type)||"Memo";case Lt:t=e._payload,e=e._init;try{return Ds(e(t))}catch{}}return null}function Kh(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Ds(t);case 8:return t===Il?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function Vt(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function Ac(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function Vh(e){var t=Ac(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var o=n.get,i=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(s){r=""+s,i.call(this,s)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(s){r=""+s},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function oo(e){e._valueTracker||(e._valueTracker=Vh(e))}function bc(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=Ac(e)?e.checked?"true":"false":e.value),e=r,e!==n?(t.setValue(e),!0):!1}function zo(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function Ps(e,t){var n=t.checked;return G({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??e._wrapperState.initialChecked})}function Ru(e,t){var n=t.defaultValue==null?"":t.defaultValue,r=t.checked!=null?t.checked:t.defaultChecked;n=Vt(t.value!=null?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function zc(e,t){t=t.checked,t!=null&&Pl(e,"checked",t,!1)}function Is(e,t){zc(e,t);var n=Vt(t.value),r=t.type;if(n!=null)r==="number"?(n===0&&e.value===""||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if(r==="submit"||r==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?js(e,t.type,n):t.hasOwnProperty("defaultValue")&&js(e,t.type,Vt(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function Au(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!(r!=="submit"&&r!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}n=e.name,n!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,n!==""&&(e.name=n)}function js(e,t,n){(t!=="number"||zo(e.ownerDocument)!==e)&&(n==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var dr=Array.isArray;function An(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o"+t.valueOf().toString()+"",t=io.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Tr(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&n.nodeType===3){n.nodeValue=t;return}}e.textContent=t}var gr={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},Gh=["Webkit","ms","Moz","O"];Object.keys(gr).forEach(function(e){Gh.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),gr[t]=gr[e]})});function Hc(e,t,n){return t==null||typeof t=="boolean"||t===""?"":n||typeof t!="number"||t===0||gr.hasOwnProperty(e)&&gr[e]?(""+t).trim():t+"px"}function Bc(e,t){e=e.style;for(var n in t)if(t.hasOwnProperty(n)){var r=n.indexOf("--")===0,o=Hc(n,t[n],r);n==="float"&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}var Yh=G({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ms(e,t){if(t){if(Yh[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(E(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(E(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(E(61))}if(t.style!=null&&typeof t.style!="object")throw Error(E(62))}}function Rs(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var As=null;function Nl(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var bs=null,bn=null,zn=null;function $u(e){if(e=Gr(e)){if(typeof bs!="function")throw Error(E(280));var t=e.stateNode;t&&(t=pi(t),bs(e.stateNode,e.type,t))}}function Wc(e){bn?zn?zn.push(e):zn=[e]:bn=e}function qc(){if(bn){var e=bn,t=zn;if(zn=bn=null,$u(e),t)for(e=0;e>>=0,e===0?32:31-(lp(e)/up|0)|0}var so=64,lo=4194304;function fr(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Ho(e,t){var n=e.pendingLanes;if(n===0)return 0;var r=0,o=e.suspendedLanes,i=e.pingedLanes,s=n&268435455;if(s!==0){var l=s&~o;l!==0?r=fr(l):(i&=s,i!==0&&(r=fr(i)))}else s=n&~o,s!==0?r=fr(s):i!==0&&(r=fr(i));if(r===0)return 0;if(t!==0&&t!==r&&!(t&o)&&(o=r&-r,i=t&-t,o>=i||o===16&&(i&4194240)!==0))return t;if(r&4&&(r|=n&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=r;0n;n++)t.push(e);return t}function Kr(e,t,n){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-ot(t),e[t]=n}function fp(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0=vr),Vu=String.fromCharCode(32),Gu=!1;function dd(e,t){switch(e){case"keyup":return Fp.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function fd(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var On=!1;function Hp(e,t){switch(e){case"compositionend":return fd(t);case"keypress":return t.which!==32?null:(Gu=!0,Vu);case"textInput":return e=t.data,e===Vu&&Gu?null:e;default:return null}}function Bp(e,t){if(On)return e==="compositionend"||!Ul&&dd(e,t)?(e=ad(),To=zl=bt=null,On=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=Zu(n)}}function md(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?md(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function vd(){for(var e=window,t=zo();t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=zo(e.document)}return t}function Hl(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function Jp(e){var t=vd(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&md(n.ownerDocument.documentElement,n)){if(r!==null&&Hl(n)){if(t=r.start,e=r.end,e===void 0&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if(e=(t=n.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var o=n.textContent.length,i=Math.min(r.start,o);r=r.end===void 0?i:Math.min(r.end,o),!e.extend&&i>r&&(o=r,r=i,i=o),o=ea(n,i);var s=ea(n,r);o&&s&&(e.rangeCount!==1||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==s.node||e.focusOffset!==s.offset)&&(t=t.createRange(),t.setStart(o.node,o.offset),e.removeAllRanges(),i>r?(e.addRange(t),e.extend(s.node,s.offset)):(t.setEnd(s.node,s.offset),e.addRange(t)))}}for(t=[],e=n;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,Tn=null,Bs=null,Sr=null,Ws=!1;function ta(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Ws||Tn==null||Tn!==zo(r)||(r=Tn,"selectionStart"in r&&Hl(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Sr&&Nr(Sr,r)||(Sr=r,r=qo(Bs,"onSelect"),0In||(e.current=Ys[In],Ys[In]=null,In--)}function H(e,t){In++,Ys[In]=e.current,e.current=t}var Gt={},ye=Xt(Gt),Oe=Xt(!1),dn=Gt;function Bn(e,t){var n=e.type.contextTypes;if(!n)return Gt;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o={},i;for(i in n)o[i]=t[i];return r&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function Te(e){return e=e.childContextTypes,e!=null}function Ko(){q(Oe),q(ye)}function ua(e,t,n){if(ye.current!==Gt)throw Error(E(168));H(ye,t),H(Oe,n)}function Od(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var o in r)if(!(o in t))throw Error(E(108,Kh(e)||"Unknown",o));return G({},n,r)}function Vo(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Gt,dn=ye.current,H(ye,e),H(Oe,Oe.current),!0}function aa(e,t,n){var r=e.stateNode;if(!r)throw Error(E(169));n?(e=Od(e,t,dn),r.__reactInternalMemoizedMergedChildContext=e,q(Oe),q(ye),H(ye,e)):q(Oe),H(Oe,n)}var gt=null,gi=!1,rs=!1;function Td(e){gt===null?gt=[e]:gt.push(e)}function c0(e){gi=!0,Td(e)}function Jt(){if(!rs&>!==null){rs=!0;var e=0,t=F;try{var n=gt;for(F=1;e>=s,o-=s,mt=1<<32-ot(t)+o|n<T?(j=O,O=null):j=O.sibling;var I=d(h,O,f[T],k);if(I===null){O===null&&(O=j);break}e&&O&&I.alternate===null&&t(h,O),c=i(I,c,T),_===null?x=I:_.sibling=I,_=I,O=j}if(T===f.length)return n(h,O),Q&&nn(h,T),x;if(O===null){for(;TT?(j=O,O=null):j=O.sibling;var re=d(h,O,I.value,k);if(re===null){O===null&&(O=j);break}e&&O&&re.alternate===null&&t(h,O),c=i(re,c,T),_===null?x=re:_.sibling=re,_=re,O=j}if(I.done)return n(h,O),Q&&nn(h,T),x;if(O===null){for(;!I.done;T++,I=f.next())I=m(h,I.value,k),I!==null&&(c=i(I,c,T),_===null?x=I:_.sibling=I,_=I);return Q&&nn(h,T),x}for(O=r(h,O);!I.done;T++,I=f.next())I=g(O,h,T,I.value,k),I!==null&&(e&&I.alternate!==null&&O.delete(I.key===null?T:I.key),c=i(I,c,T),_===null?x=I:_.sibling=I,_=I);return e&&O.forEach(function(he){return t(h,he)}),Q&&nn(h,T),x}function w(h,c,f,k){if(typeof f=="object"&&f!==null&&f.type===_n&&f.key===null&&(f=f.props.children),typeof f=="object"&&f!==null){switch(f.$$typeof){case ro:e:{for(var x=f.key,_=c;_!==null;){if(_.key===x){if(x=f.type,x===_n){if(_.tag===7){n(h,_.sibling),c=o(_,f.props.children),c.return=h,h=c;break e}}else if(_.elementType===x||typeof x=="object"&&x!==null&&x.$$typeof===Lt&&ma(x)===_.type){n(h,_.sibling),c=o(_,f.props),c.ref=ir(h,_,f),c.return=h,h=c;break e}n(h,_);break}else t(h,_);_=_.sibling}f.type===_n?(c=an(f.props.children,h.mode,k,f.key),c.return=h,h=c):(k=Ro(f.type,f.key,f.props,null,h.mode,k),k.ref=ir(h,c,f),k.return=h,h=k)}return s(h);case xn:e:{for(_=f.key;c!==null;){if(c.key===_)if(c.tag===4&&c.stateNode.containerInfo===f.containerInfo&&c.stateNode.implementation===f.implementation){n(h,c.sibling),c=o(c,f.children||[]),c.return=h,h=c;break e}else{n(h,c);break}else t(h,c);c=c.sibling}c=ds(f,h.mode,k),c.return=h,h=c}return s(h);case Lt:return _=f._init,w(h,c,_(f._payload),k)}if(dr(f))return v(h,c,f,k);if(er(f))return y(h,c,f,k);go(h,f)}return typeof f=="string"&&f!==""||typeof f=="number"?(f=""+f,c!==null&&c.tag===6?(n(h,c.sibling),c=o(c,f),c.return=h,h=c):(n(h,c),c=cs(f,h.mode,k),c.return=h,h=c),s(h)):n(h,c)}return w}var qn=Rd(!0),Ad=Rd(!1),Yr={},ft=Xt(Yr),br=Xt(Yr),zr=Xt(Yr);function ln(e){if(e===Yr)throw Error(E(174));return e}function Xl(e,t){switch(H(zr,t),H(br,e),H(ft,Yr),e=t.nodeType,e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:Ns(null,"");break;default:e=e===8?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=Ns(t,e)}q(ft),H(ft,t)}function Qn(){q(ft),q(br),q(zr)}function bd(e){ln(zr.current);var t=ln(ft.current),n=Ns(t,e.type);t!==n&&(H(br,e),H(ft,n))}function Jl(e){br.current===e&&(q(ft),q(br))}var K=Xt(0);function ei(e){for(var t=e;t!==null;){if(t.tag===13){var n=t.memoizedState;if(n!==null&&(n=n.dehydrated,n===null||n.data==="$?"||n.data==="$!"))return t}else if(t.tag===19&&t.memoizedProps.revealOrder!==void 0){if(t.flags&128)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var os=[];function Zl(){for(var e=0;en?n:4,e(!0);var r=is.transition;is.transition={};try{e(!1),t()}finally{F=n,is.transition=r}}function Zd(){return Xe().memoizedState}function p0(e,t,n){var r=qt(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},ef(e))tf(t,n);else if(n=jd(e,t,n,r),n!==null){var o=ke();it(n,e,r,o),nf(n,t,r)}}function g0(e,t,n){var r=qt(e),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(ef(e))tf(t,o);else{var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var s=t.lastRenderedState,l=i(s,n);if(o.hasEagerState=!0,o.eagerState=l,st(l,s)){var u=t.interleaved;u===null?(o.next=o,Gl(t)):(o.next=u.next,u.next=o),t.interleaved=o;return}}catch{}finally{}n=jd(e,t,o,r),n!==null&&(o=ke(),it(n,e,r,o),nf(n,t,r))}}function ef(e){var t=e.alternate;return e===V||t!==null&&t===V}function tf(e,t){wr=ti=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function nf(e,t,n){if(n&4194240){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Rl(e,n)}}var ni={readContext:Ye,useCallback:pe,useContext:pe,useEffect:pe,useImperativeHandle:pe,useInsertionEffect:pe,useLayoutEffect:pe,useMemo:pe,useReducer:pe,useRef:pe,useState:pe,useDebugValue:pe,useDeferredValue:pe,useTransition:pe,useMutableSource:pe,useSyncExternalStore:pe,useId:pe,unstable_isNewReconciler:!1},m0={readContext:Ye,useCallback:function(e,t){return at().memoizedState=[e,t===void 0?null:t],e},useContext:Ye,useEffect:ya,useImperativeHandle:function(e,t,n){return n=n!=null?n.concat([e]):null,jo(4194308,4,Vd.bind(null,t,e),n)},useLayoutEffect:function(e,t){return jo(4194308,4,e,t)},useInsertionEffect:function(e,t){return jo(4,2,e,t)},useMemo:function(e,t){var n=at();return t=t===void 0?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=at();return t=n!==void 0?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=p0.bind(null,V,e),[r.memoizedState,e]},useRef:function(e){var t=at();return e={current:e},t.memoizedState=e},useState:va,useDebugValue:ou,useDeferredValue:function(e){return at().memoizedState=e},useTransition:function(){var e=va(!1),t=e[0];return e=h0.bind(null,e[1]),at().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=V,o=at();if(Q){if(n===void 0)throw Error(E(407));n=n()}else{if(n=t(),ue===null)throw Error(E(349));hn&30||Fd(r,t,n)}o.memoizedState=n;var i={value:n,getSnapshot:t};return o.queue=i,ya(Hd.bind(null,r,i,e),[e]),r.flags|=2048,Ur(9,Ud.bind(null,r,i,n,t),void 0,null),n},useId:function(){var e=at(),t=ue.identifierPrefix;if(Q){var n=vt,r=mt;n=(r&~(1<<32-ot(r)-1)).toString(32)+n,t=":"+t+"R"+n,n=$r++,0<\/script>",e=e.removeChild(e.firstChild)):typeof r.is=="string"?e=s.createElement(n,{is:r.is}):(e=s.createElement(n),n==="select"&&(s=e,r.multiple?s.multiple=!0:r.size&&(s.size=r.size))):e=s.createElementNS(e,n),e[ct]=t,e[Ar]=r,ff(e,t,!1,!1),t.stateNode=e;e:{switch(s=Rs(n,r),n){case"dialog":W("cancel",e),W("close",e),o=r;break;case"iframe":case"object":case"embed":W("load",e),o=r;break;case"video":case"audio":for(o=0;oVn&&(t.flags|=128,r=!0,sr(i,!1),t.lanes=4194304)}else{if(!r)if(e=ei(s),e!==null){if(t.flags|=128,r=!0,n=e.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),sr(i,!0),i.tail===null&&i.tailMode==="hidden"&&!s.alternate&&!Q)return ge(t),null}else 2*J()-i.renderingStartTime>Vn&&n!==1073741824&&(t.flags|=128,r=!0,sr(i,!1),t.lanes=4194304);i.isBackwards?(s.sibling=t.child,t.child=s):(n=i.last,n!==null?n.sibling=s:t.child=s,i.last=s)}return i.tail!==null?(t=i.tail,i.rendering=t,i.tail=t.sibling,i.renderingStartTime=J(),t.sibling=null,n=K.current,H(K,r?n&1|2:n&1),t):(ge(t),null);case 22:case 23:return cu(),r=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==r&&(t.flags|=8192),r&&t.mode&1?Ne&1073741824&&(ge(t),t.subtreeFlags&6&&(t.flags|=8192)):ge(t),null;case 24:return null;case 25:return null}throw Error(E(156,t.tag))}function x0(e,t){switch(Wl(t),t.tag){case 1:return Te(t.type)&&Ko(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Qn(),q(Oe),q(ye),Zl(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return Jl(t),null;case 13:if(q(K),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(E(340));Wn()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return q(K),null;case 4:return Qn(),null;case 10:return Vl(t.type._context),null;case 22:case 23:return cu(),null;case 24:return null;default:return null}}var vo=!1,ve=!1,_0=typeof WeakSet=="function"?WeakSet:Set,P=null;function Mn(e,t){var n=e.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){X(e,t,r)}else n.current=null}function ul(e,t,n){try{n()}catch(r){X(e,t,r)}}var Ta=!1;function O0(e,t){if(qs=Bo,e=vd(),Hl(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var o=r.anchorOffset,i=r.focusNode;r=r.focusOffset;try{n.nodeType,i.nodeType}catch{n=null;break e}var s=0,l=-1,u=-1,a=0,p=0,m=e,d=null;t:for(;;){for(var g;m!==n||o!==0&&m.nodeType!==3||(l=s+o),m!==i||r!==0&&m.nodeType!==3||(u=s+r),m.nodeType===3&&(s+=m.nodeValue.length),(g=m.firstChild)!==null;)d=m,m=g;for(;;){if(m===e)break t;if(d===n&&++a===o&&(l=s),d===i&&++p===r&&(u=s),(g=m.nextSibling)!==null)break;m=d,d=m.parentNode}m=g}n=l===-1||u===-1?null:{start:l,end:u}}else n=null}n=n||{start:0,end:0}}else n=null;for(Qs={focusedElem:e,selectionRange:n},Bo=!1,P=t;P!==null;)if(t=P,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,P=e;else for(;P!==null;){t=P;try{var v=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(v!==null){var y=v.memoizedProps,w=v.memoizedState,h=t.stateNode,c=h.getSnapshotBeforeUpdate(t.elementType===t.type?y:tt(t.type,y),w);h.__reactInternalSnapshotBeforeUpdate=c}break;case 3:var f=t.stateNode.containerInfo;f.nodeType===1?f.textContent="":f.nodeType===9&&f.documentElement&&f.removeChild(f.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(E(163))}}catch(k){X(t,t.return,k)}if(e=t.sibling,e!==null){e.return=t.return,P=e;break}P=t.return}return v=Ta,Ta=!1,v}function kr(e,t,n){var r=t.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var o=r=r.next;do{if((o.tag&e)===e){var i=o.destroy;o.destroy=void 0,i!==void 0&&ul(t,n,i)}o=o.next}while(o!==r)}}function yi(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function al(e){var t=e.ref;if(t!==null){var n=e.stateNode;switch(e.tag){case 5:e=n;break;default:e=n}typeof t=="function"?t(e):t.current=e}}function gf(e){var t=e.alternate;t!==null&&(e.alternate=null,gf(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[ct],delete t[Ar],delete t[Gs],delete t[u0],delete t[a0])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function mf(e){return e.tag===5||e.tag===3||e.tag===4}function Da(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||mf(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function cl(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.nodeType===8?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(n.nodeType===8?(t=n.parentNode,t.insertBefore(e,n)):(t=n,t.appendChild(e)),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Qo));else if(r!==4&&(e=e.child,e!==null))for(cl(e,t,n),e=e.sibling;e!==null;)cl(e,t,n),e=e.sibling}function dl(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(e=e.child,e!==null))for(dl(e,t,n),e=e.sibling;e!==null;)dl(e,t,n),e=e.sibling}var ce=null,nt=!1;function Pt(e,t,n){for(n=n.child;n!==null;)vf(e,t,n),n=n.sibling}function vf(e,t,n){if(dt&&typeof dt.onCommitFiberUnmount=="function")try{dt.onCommitFiberUnmount(ci,n)}catch{}switch(n.tag){case 5:ve||Mn(n,t);case 6:var r=ce,o=nt;ce=null,Pt(e,t,n),ce=r,nt=o,ce!==null&&(nt?(e=ce,n=n.stateNode,e.nodeType===8?e.parentNode.removeChild(n):e.removeChild(n)):ce.removeChild(n.stateNode));break;case 18:ce!==null&&(nt?(e=ce,n=n.stateNode,e.nodeType===8?ns(e.parentNode,n):e.nodeType===1&&ns(e,n),jr(e)):ns(ce,n.stateNode));break;case 4:r=ce,o=nt,ce=n.stateNode.containerInfo,nt=!0,Pt(e,t,n),ce=r,nt=o;break;case 0:case 11:case 14:case 15:if(!ve&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){o=r=r.next;do{var i=o,s=i.destroy;i=i.tag,s!==void 0&&(i&2||i&4)&&ul(n,t,s),o=o.next}while(o!==r)}Pt(e,t,n);break;case 1:if(!ve&&(Mn(n,t),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(l){X(n,t,l)}Pt(e,t,n);break;case 21:Pt(e,t,n);break;case 22:n.mode&1?(ve=(r=ve)||n.memoizedState!==null,Pt(e,t,n),ve=r):Pt(e,t,n);break;default:Pt(e,t,n)}}function Pa(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var n=e.stateNode;n===null&&(n=e.stateNode=new _0),t.forEach(function(r){var o=R0.bind(null,e,r);n.has(r)||(n.add(r),r.then(o,o))})}}function et(e,t){var n=t.deletions;if(n!==null)for(var r=0;ro&&(o=s),r&=~i}if(r=o,r=J()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*D0(r/1960))-r,10e?16:e,zt===null)var r=!1;else{if(e=zt,zt=null,ii=0,$&6)throw Error(E(331));var o=$;for($|=4,P=e.current;P!==null;){var i=P,s=i.child;if(P.flags&16){var l=i.deletions;if(l!==null){for(var u=0;uJ()-uu?un(e,0):lu|=n),De(e,t)}function _f(e,t){t===0&&(e.mode&1?(t=lo,lo<<=1,!(lo&130023424)&&(lo=4194304)):t=1);var n=ke();e=kt(e,t),e!==null&&(Kr(e,t,n),De(e,n))}function M0(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),_f(e,n)}function R0(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;o!==null&&(n=o.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(E(314))}r!==null&&r.delete(t),_f(e,n)}var Of;Of=function(e,t,n){if(e!==null)if(e.memoizedProps!==t.pendingProps||Oe.current)_e=!0;else{if(!(e.lanes&n)&&!(t.flags&128))return _e=!1,E0(e,t,n);_e=!!(e.flags&131072)}else _e=!1,Q&&t.flags&1048576&&Dd(t,Yo,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;Lo(e,t),e=t.pendingProps;var o=Bn(t,ye.current);Fn(t,n),o=tu(null,t,r,e,o,n);var i=nu();return t.flags|=1,typeof o=="object"&&o!==null&&typeof o.render=="function"&&o.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Te(r)?(i=!0,Vo(t)):i=!1,t.memoizedState=o.state!==null&&o.state!==void 0?o.state:null,Yl(t),o.updater=mi,t.stateNode=o,o._reactInternals=t,tl(t,r,e,n),t=ol(null,t,r,!0,i,n)):(t.tag=0,Q&&i&&Bl(t),we(null,t,o,n),t=t.child),t;case 16:r=t.elementType;e:{switch(Lo(e,t),e=t.pendingProps,o=r._init,r=o(r._payload),t.type=r,o=t.tag=b0(r),e=tt(r,e),o){case 0:t=rl(null,t,r,e,n);break e;case 1:t=xa(null,t,r,e,n);break e;case 11:t=Ea(null,t,r,e,n);break e;case 14:t=Ca(null,t,r,tt(r.type,e),n);break e}throw Error(E(306,r,""))}return t;case 0:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:tt(r,o),rl(e,t,r,o,n);case 1:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:tt(r,o),xa(e,t,r,o,n);case 3:e:{if(af(t),e===null)throw Error(E(387));r=t.pendingProps,i=t.memoizedState,o=i.element,Ld(e,t),Zo(t,r,null,n);var s=t.memoizedState;if(r=s.element,i.isDehydrated)if(i={element:r,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=i,t.memoizedState=i,t.flags&256){o=Kn(Error(E(423)),t),t=_a(e,t,r,n,o);break e}else if(r!==o){o=Kn(Error(E(424)),t),t=_a(e,t,r,n,o);break e}else for(Me=Ht(t.stateNode.containerInfo.firstChild),Re=t,Q=!0,rt=null,n=Ad(t,null,r,n),t.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(Wn(),r===o){t=Et(e,t,n);break e}we(e,t,r,n)}t=t.child}return t;case 5:return bd(t),e===null&&Js(t),r=t.type,o=t.pendingProps,i=e!==null?e.memoizedProps:null,s=o.children,Ks(r,o)?s=null:i!==null&&Ks(r,i)&&(t.flags|=32),uf(e,t),we(e,t,s,n),t.child;case 6:return e===null&&Js(t),null;case 13:return cf(e,t,n);case 4:return Xl(t,t.stateNode.containerInfo),r=t.pendingProps,e===null?t.child=qn(t,null,r,n):we(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:tt(r,o),Ea(e,t,r,o,n);case 7:return we(e,t,t.pendingProps,n),t.child;case 8:return we(e,t,t.pendingProps.children,n),t.child;case 12:return we(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,o=t.pendingProps,i=t.memoizedProps,s=o.value,H(Xo,r._currentValue),r._currentValue=s,i!==null)if(st(i.value,s)){if(i.children===o.children&&!Oe.current){t=Et(e,t,n);break e}}else for(i=t.child,i!==null&&(i.return=t);i!==null;){var l=i.dependencies;if(l!==null){s=i.child;for(var u=l.firstContext;u!==null;){if(u.context===r){if(i.tag===1){u=yt(-1,n&-n),u.tag=2;var a=i.updateQueue;if(a!==null){a=a.shared;var p=a.pending;p===null?u.next=u:(u.next=p.next,p.next=u),a.pending=u}}i.lanes|=n,u=i.alternate,u!==null&&(u.lanes|=n),Zs(i.return,n,t),l.lanes|=n;break}u=u.next}}else if(i.tag===10)s=i.type===t.type?null:i.child;else if(i.tag===18){if(s=i.return,s===null)throw Error(E(341));s.lanes|=n,l=s.alternate,l!==null&&(l.lanes|=n),Zs(s,n,t),s=i.sibling}else s=i.child;if(s!==null)s.return=i;else for(s=i;s!==null;){if(s===t){s=null;break}if(i=s.sibling,i!==null){i.return=s.return,s=i;break}s=s.return}i=s}we(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=t.pendingProps.children,Fn(t,n),o=Ye(o),r=r(o),t.flags|=1,we(e,t,r,n),t.child;case 14:return r=t.type,o=tt(r,t.pendingProps),o=tt(r.type,o),Ca(e,t,r,o,n);case 15:return sf(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:tt(r,o),Lo(e,t),t.tag=1,Te(r)?(e=!0,Vo(t)):e=!1,Fn(t,n),Md(t,r,o),tl(t,r,o,n),ol(null,t,r,!0,e,n);case 19:return df(e,t,n);case 22:return lf(e,t,n)}throw Error(E(156,t.tag))};function Tf(e,t){return Jc(e,t)}function A0(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Ve(e,t,n,r){return new A0(e,t,n,r)}function fu(e){return e=e.prototype,!(!e||!e.isReactComponent)}function b0(e){if(typeof e=="function")return fu(e)?1:0;if(e!=null){if(e=e.$$typeof,e===jl)return 11;if(e===Ll)return 14}return 2}function Qt(e,t){var n=e.alternate;return n===null?(n=Ve(e.tag,t,e.key,e.mode),n.elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=e.flags&14680064,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Ro(e,t,n,r,o,i){var s=2;if(r=e,typeof e=="function")fu(e)&&(s=1);else if(typeof e=="string")s=5;else e:switch(e){case _n:return an(n.children,o,i,t);case Il:s=8,o|=8;break;case _s:return e=Ve(12,n,t,o|2),e.elementType=_s,e.lanes=i,e;case Os:return e=Ve(13,n,t,o),e.elementType=Os,e.lanes=i,e;case Ts:return e=Ve(19,n,t,o),e.elementType=Ts,e.lanes=i,e;case Rc:return wi(n,o,i,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case Nc:s=10;break e;case Mc:s=9;break e;case jl:s=11;break e;case Ll:s=14;break e;case Lt:s=16,r=null;break e}throw Error(E(130,e==null?e:typeof e,""))}return t=Ve(s,n,t,o),t.elementType=e,t.type=r,t.lanes=i,t}function an(e,t,n,r){return e=Ve(7,e,r,t),e.lanes=n,e}function wi(e,t,n,r){return e=Ve(22,e,r,t),e.elementType=Rc,e.lanes=n,e.stateNode={isHidden:!1},e}function cs(e,t,n){return e=Ve(6,e,null,t),e.lanes=n,e}function ds(e,t,n){return t=Ve(4,e.children!==null?e.children:[],e.key,t),t.lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function z0(e,t,n,r,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=qi(0),this.expirationTimes=qi(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=qi(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function hu(e,t,n,r,o,i,s,l,u){return e=new z0(e,t,n,l,u),t===1?(t=1,i===!0&&(t|=8)):t=0,i=Ve(3,null,null,t),e.current=i,i.stateNode=e,i.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Yl(i),e}function $0(e,t,n){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(jf)}catch(e){console.error(e)}}jf(),Dc.exports=be;var W0=Dc.exports,ba=W0;Cs.createRoot=ba.createRoot,Cs.hydrateRoot=ba.hydrateRoot;/** * @license * Copyright (c) 2023, Jeff Hlywa (jhlywa@gmail.com) * All rights reserved. @@ -62,39 +62,13 @@ Error generating stack: `+a.message+` * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. - */const Pt="w",mr="b",Et="p",Tc="n",yo="b",Fa="r",kn="q",St="k",fu="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",nr=-1,jm={NORMAL:"n",CAPTURE:"c",BIG_PAWN:"b",EP_CAPTURE:"e",PROMOTION:"p",KSIDE_CASTLE:"k",QSIDE_CASTLE:"q"},fe={NORMAL:1,CAPTURE:2,BIG_PAWN:4,EP_CAPTURE:8,PROMOTION:16,KSIDE_CASTLE:32,QSIDE_CASTLE:64},ve={a8:0,b8:1,c8:2,d8:3,e8:4,f8:5,g8:6,h8:7,a7:16,b7:17,c7:18,d7:19,e7:20,f7:21,g7:22,h7:23,a6:32,b6:33,c6:34,d6:35,e6:36,f6:37,g6:38,h6:39,a5:48,b5:49,c5:50,d5:51,e5:52,f5:53,g5:54,h5:55,a4:64,b4:65,c4:66,d4:67,e4:68,f4:69,g4:70,h4:71,a3:80,b3:81,c3:82,d3:83,e3:84,f3:85,g3:86,h3:87,a2:96,b2:97,c2:98,d2:99,e2:100,f2:101,g2:102,h2:103,a1:112,b1:113,c1:114,d1:115,e1:116,f1:117,g1:118,h1:119},du={b:[16,32,17,15],w:[-16,-32,-17,-15]},kd={n:[-18,-33,-31,-14,18,33,31,14],b:[-17,-15,17,15],r:[-16,1,16,-1],q:[-17,-16,-15,1,17,16,15,-1],k:[-17,-16,-15,1,17,16,15,-1]},Km=[20,0,0,0,0,0,0,24,0,0,0,0,0,0,20,0,0,20,0,0,0,0,0,24,0,0,0,0,0,20,0,0,0,0,20,0,0,0,0,24,0,0,0,0,20,0,0,0,0,0,0,20,0,0,0,24,0,0,0,20,0,0,0,0,0,0,0,0,20,0,0,24,0,0,20,0,0,0,0,0,0,0,0,0,0,20,2,24,2,20,0,0,0,0,0,0,0,0,0,0,0,2,53,56,53,2,0,0,0,0,0,0,24,24,24,24,24,24,56,0,56,24,24,24,24,24,24,0,0,0,0,0,0,2,53,56,53,2,0,0,0,0,0,0,0,0,0,0,0,20,2,24,2,20,0,0,0,0,0,0,0,0,0,0,20,0,0,24,0,0,20,0,0,0,0,0,0,0,0,20,0,0,0,24,0,0,0,20,0,0,0,0,0,0,20,0,0,0,0,24,0,0,0,0,20,0,0,0,0,20,0,0,0,0,0,24,0,0,0,0,0,20,0,0,20,0,0,0,0,0,0,24,0,0,0,0,0,0,20],zm=[17,0,0,0,0,0,0,16,0,0,0,0,0,0,15,0,0,17,0,0,0,0,0,16,0,0,0,0,0,15,0,0,0,0,17,0,0,0,0,16,0,0,0,0,15,0,0,0,0,0,0,17,0,0,0,16,0,0,0,15,0,0,0,0,0,0,0,0,17,0,0,16,0,0,15,0,0,0,0,0,0,0,0,0,0,17,0,16,0,15,0,0,0,0,0,0,0,0,0,0,0,0,17,16,15,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,-15,-16,-17,0,0,0,0,0,0,0,0,0,0,0,0,-15,0,-16,0,-17,0,0,0,0,0,0,0,0,0,0,-15,0,0,-16,0,0,-17,0,0,0,0,0,0,0,0,-15,0,0,0,-16,0,0,0,-17,0,0,0,0,0,0,-15,0,0,0,0,-16,0,0,0,0,-17,0,0,0,0,-15,0,0,0,0,0,-16,0,0,0,0,0,-17,0,0,-15,0,0,0,0,0,0,-16,0,0,0,0,0,0,-17],Hm={p:1,n:2,b:4,r:8,q:16,k:32},qm="pnbrqkPNBRQK",bd=[Tc,yo,Fa,kn],$m=7,Gm=6,Qm=1,Wm=0,Ys={[St]:fe.KSIDE_CASTLE,[kn]:fe.QSIDE_CASTLE},Tn={w:[{square:ve.a1,flag:fe.QSIDE_CASTLE},{square:ve.h1,flag:fe.KSIDE_CASTLE}],b:[{square:ve.a8,flag:fe.QSIDE_CASTLE},{square:ve.h8,flag:fe.KSIDE_CASTLE}]},Ym={b:Qm,w:Gm},Xm=["1-0","0-1","1/2-1/2","*"];function pi(e){return e>>4}function Cs(e){return e&15}function Gg(e){return"0123456789".indexOf(e)!==-1}function ir(e){const t=Cs(e),r=pi(e);return"abcdefgh".substring(t,t+1)+"87654321".substring(r,r+1)}function Na(e){return e===Pt?mr:Pt}function Zm(e){const t=e.split(/\s+/);if(t.length!==6)return{ok:!1,error:"Invalid FEN: must contain six space-delimited fields"};const r=parseInt(t[5],10);if(isNaN(r)||r<=0)return{ok:!1,error:"Invalid FEN: move number must be a positive integer"};const n=parseInt(t[4],10);if(isNaN(n)||n<0)return{ok:!1,error:"Invalid FEN: half move counter number must be a non-negative integer"};if(!/^(-|[abcdefgh][36])$/.test(t[3]))return{ok:!1,error:"Invalid FEN: en-passant square is invalid"};if(/[^kKqQ-]/.test(t[2]))return{ok:!1,error:"Invalid FEN: castling availability is invalid"};if(!/^(w|b)$/.test(t[1]))return{ok:!1,error:"Invalid FEN: side-to-move is invalid"};const i=t[0].split("/");if(i.length!==8)return{ok:!1,error:"Invalid FEN: piece data does not contain 8 '/'-delimited rows"};for(let s=0;s1)return{ok:!1,error:`Invalid FEN: too many ${s} kings`}}return{ok:!0}}function Jm(e,t){const r=e.from,n=e.to,i=e.piece;let a=0,s=0,o=0;for(let l=0,u=t.length;l0?s>0&&o>0?ir(r):o>0?ir(r).charAt(1):ir(r).charAt(0):""}function wn(e,t,r,n,i,a=void 0,s=fe.NORMAL){const o=pi(n);if(i===Et&&(o===$m||o===Wm))for(let l=0;l="a"&&t<="h"?e.match(/[a-h]\d.*[a-h]\d/)?void 0:Et:(t=t.toLowerCase(),t==="o"?St:t)}function hu(e){return e.replace(/=/,"").replace(/[+#]?[?!]*$/,"")}class e2{constructor(t=fu){ft(this,"_board",new Array(128));ft(this,"_turn",Pt);ft(this,"_header",{});ft(this,"_kings",{w:nr,b:nr});ft(this,"_epSquare",-1);ft(this,"_halfMoves",0);ft(this,"_moveNumber",0);ft(this,"_history",[]);ft(this,"_comments",{});ft(this,"_castling",{w:0,b:0});this.load(t)}clear(t=!1){this._board=new Array(128),this._kings={w:nr,b:nr},this._turn=Pt,this._castling={w:0,b:0},this._epSquare=nr,this._halfMoves=0,this._moveNumber=1,this._history=[],this._comments={},this._header=t?this._header:{},this._updateSetup(this.fen())}removeHeader(t){t in this._header&&delete this._header[t]}load(t,r=!1){let n=t.split(/\s+/);if(n.length>=2&&n.length<6){const l=["-","-","0","1"];t=n.concat(l.slice(-(6-n.length))).join(" ")}n=t.split(/\s+/);const{ok:i,error:a}=Zm(t);if(!i)throw new Error(a);const s=n[0];let o=0;this.clear(r);for(let l=0;l-1&&(this._castling.w|=fe.KSIDE_CASTLE),n[2].indexOf("Q")>-1&&(this._castling.w|=fe.QSIDE_CASTLE),n[2].indexOf("k")>-1&&(this._castling.b|=fe.KSIDE_CASTLE),n[2].indexOf("q")>-1&&(this._castling.b|=fe.QSIDE_CASTLE),this._epSquare=n[3]==="-"?nr:ve[n[3]],this._halfMoves=parseInt(n[4],10),this._moveNumber=parseInt(n[5],10),this._updateSetup(this.fen())}fen(){var a,s;let t=0,r="";for(let o=ve.a8;o<=ve.h1;o++){if(this._board[o]){t>0&&(r+=t,t=0);const{color:l,type:u}=this._board[o];r+=l===Pt?u.toUpperCase():u.toLowerCase()}else t++;o+1&136&&(t>0&&(r+=t),o!==ve.h1&&(r+="/"),t=0,o+=8)}let n="";this._castling[Pt]&fe.KSIDE_CASTLE&&(n+="K"),this._castling[Pt]&fe.QSIDE_CASTLE&&(n+="Q"),this._castling[mr]&fe.KSIDE_CASTLE&&(n+="k"),this._castling[mr]&fe.QSIDE_CASTLE&&(n+="q"),n=n||"-";let i="-";if(this._epSquare!==nr){const o=this._epSquare+(this._turn===Pt?16:-16),l=[o+1,o-1];for(const u of l){if(u&136)continue;const c=this._turn;if(((a=this._board[u])==null?void 0:a.color)===c&&((s=this._board[u])==null?void 0:s.type)===Et){this._makeMove({color:c,from:u,to:this._epSquare,piece:Et,captured:Et,flags:fe.EP_CAPTURE});const f=!this._isKingAttacked(c);if(this._undoMove(),f){i=ir(this._epSquare);break}}}}return[r,this._turn,n,i,this._halfMoves,this._moveNumber].join(" ")}_updateSetup(t){this._history.length>0||(t!==fu?(this._header.SetUp="1",this._header.FEN=t):(delete this._header.SetUp,delete this._header.FEN))}reset(){this.load(fu)}get(t){return this._board[ve[t]]||!1}put({type:t,color:r},n){if(qm.indexOf(t.toLowerCase())===-1||!(n in ve))return!1;const i=ve[n];return t==St&&!(this._kings[r]==nr||this._kings[r]==i)?!1:(this._board[i]={type:t,color:r},t===St&&(this._kings[r]=i),this._updateCastlingRights(),this._updateEnPassantSquare(),this._updateSetup(this.fen()),!0)}remove(t){const r=this.get(t);return delete this._board[ve[t]],r&&r.type===St&&(this._kings[r.color]=nr),this._updateCastlingRights(),this._updateEnPassantSquare(),this._updateSetup(this.fen()),r}_updateCastlingRights(){var n,i,a,s,o,l,u,c,f,d,v,g;const t=((n=this._board[ve.e1])==null?void 0:n.type)===St&&((i=this._board[ve.e1])==null?void 0:i.color)===Pt,r=((a=this._board[ve.e8])==null?void 0:a.type)===St&&((s=this._board[ve.e8])==null?void 0:s.color)===mr;(!t||((o=this._board[ve.a1])==null?void 0:o.type)!==Fa||((l=this._board[ve.a1])==null?void 0:l.color)!==Pt)&&(this._castling.w&=~fe.QSIDE_CASTLE),(!t||((u=this._board[ve.h1])==null?void 0:u.type)!==Fa||((c=this._board[ve.h1])==null?void 0:c.color)!==Pt)&&(this._castling.w&=~fe.KSIDE_CASTLE),(!r||((f=this._board[ve.a8])==null?void 0:f.type)!==Fa||((d=this._board[ve.a8])==null?void 0:d.color)!==mr)&&(this._castling.b&=~fe.QSIDE_CASTLE),(!r||((v=this._board[ve.h8])==null?void 0:v.type)!==Fa||((g=this._board[ve.h8])==null?void 0:g.color)!==mr)&&(this._castling.b&=~fe.KSIDE_CASTLE)}_updateEnPassantSquare(){var a,s;if(this._epSquare===nr)return;const t=this._epSquare+(this._turn===Pt?-16:16),r=this._epSquare+(this._turn===Pt?16:-16),n=[r+1,r-1];if(this._board[t]!==null||this._board[this._epSquare]!==null||((a=this._board[r])==null?void 0:a.color)!==Na(this._turn)||((s=this._board[r])==null?void 0:s.type)!==Et){this._epSquare=nr;return}const i=o=>{var l,u;return!(o&136)&&((l=this._board[o])==null?void 0:l.color)===this._turn&&((u=this._board[o])==null?void 0:u.type)===Et};n.some(i)||(this._epSquare=nr)}_attacked(t,r){for(let n=ve.a8;n<=ve.h1;n++){if(n&136){n+=7;continue}if(this._board[n]===void 0||this._board[n].color!==t)continue;const i=this._board[n],a=n-r;if(a===0)continue;const s=a+119;if(Km[s]&Hm[i.type]){if(i.type===Et){if(a>0){if(i.color===Pt)return!0}else if(i.color===mr)return!0;continue}if(i.type==="n"||i.type==="k")return!0;const o=zm[s];let l=n+o,u=!1;for(;l!==r;){if(this._board[l]!=null){u=!0;break}l+=o}if(!u)return!0}}return!1}_isKingAttacked(t){const r=this._kings[t];return r===-1?!1:this._attacked(Na(t),r)}isAttacked(t,r){return this._attacked(r,ve[t])}isCheck(){return this._isKingAttacked(this._turn)}inCheck(){return this.isCheck()}isCheckmate(){return this.isCheck()&&this._moves().length===0}isStalemate(){return!this.isCheck()&&this._moves().length===0}isInsufficientMaterial(){const t={b:0,n:0,r:0,q:0,k:0,p:0},r=[];let n=0,i=0;for(let a=ve.a8;a<=ve.h1;a++){if(i=(i+1)%2,a&136){a+=7;continue}const s=this._board[a];s&&(t[s.type]=s.type in t?t[s.type]+1:1,s.type===yo&&r.push(i),n++)}if(n===2)return!0;if(n===3&&(t[yo]===1||t[Tc]===1))return!0;if(n===t[yo]+2){let a=0;const s=r.length;for(let o=0;o=3&&(n=!0);const a=t.pop();if(a)this._makeMove(a);else break}return n}isDraw(){return this._halfMoves>=100||this.isStalemate()||this.isInsufficientMaterial()||this.isThreefoldRepetition()}isGameOver(){return this.isCheckmate()||this.isStalemate()||this.isDraw()}moves({verbose:t=!1,square:r=void 0,piece:n=void 0}={}){const i=this._moves({square:r,piece:n});return t?i.map(a=>this._makePretty(a)):i.map(a=>this._moveToSan(a,i))}_moves({legal:t=!0,piece:r=void 0,square:n=void 0}={}){var v;const i=n?n.toLowerCase():void 0,a=r==null?void 0:r.toLowerCase(),s=[],o=this._turn,l=Na(o);let u=ve.a8,c=ve.h1,f=!1;if(i)if(i in ve)u=c=ve[i],f=!0;else return[];for(let g=u;g<=c;g++){if(g&136){g+=7;continue}if(!this._board[g]||this._board[g].color===l)continue;const{type:C}=this._board[g];let I;if(C===Et){if(a&&a!==C)continue;I=g+du[o][0],this._board[I]||(wn(s,o,g,I,Et),I=g+du[o][1],Ym[o]===pi(g)&&!this._board[I]&&wn(s,o,g,I,Et,void 0,fe.BIG_PAWN));for(let y=2;y<4;y++)I=g+du[o][y],!(I&136)&&(((v=this._board[I])==null?void 0:v.color)===l?wn(s,o,g,I,Et,this._board[I].type,fe.CAPTURE):I===this._epSquare&&wn(s,o,g,I,Et,Et,fe.EP_CAPTURE))}else{if(a&&a!==C)continue;for(let y=0,m=kd[C].length;y{const v=this._comments[this.fen()];if(typeof v<"u"){const g=d.length>0?" ":"";d=`${d}${g}{${v}}`}return d},s=[];for(;this._history.length>0;)s.push(this._undoMove());const o=[];let l="";for(s.length===0&&o.push(a(""));s.length>0;){l=a(l);const d=s.pop();if(!d)break;if(!this._history.length&&d.color==="b"){const v=`${this._moveNumber}. ...`;l=l?`${l} ${v}`:v}else d.color==="w"&&(l.length&&o.push(l),l=this._moveNumber+".");l=l+" "+this._moveToSan(d,this._moves({legal:!0})),this._makeMove(d)}if(l.length&&o.push(a(l)),typeof this._header.Result<"u"&&o.push(this._header.Result),r===0)return n.join("")+o.join(" ");const u=function(){return n.length>0&&n[n.length-1]===" "?(n.pop(),!0):!1},c=function(d,v){for(const g of v.split(" "))if(g){if(d+g.length>r){for(;u();)d--;n.push(t),d=0}n.push(g),d+=g.length,n.push(" "),d++}return u()&&d--,d};let f=0;for(let d=0;dr&&o[d].includes("{")){f=c(f,o[d]);continue}f+o[d].length>r&&d!==0?(n[n.length-1]===" "&&n.pop(),n.push(t),f=0):d!==0&&(n.push(" "),f++),n.push(o[d]),f+=o[d].length}return n.join("")}header(...t){for(let r=0;r0&&(B[L]=M)}return B}t=t.trim();const o=new RegExp("^(\\[((?:"+i(n)+")|.)*\\])((?:\\s*"+i(n)+"){2}|(?:\\s*"+i(n)+")*$)").exec(t),l=o&&o.length>=2?o[1]:"";this.reset();const u=a(l);let c="";for(const S in u)S.toLowerCase()==="fen"&&(c=u[S]),this.header(S,u[S]);if(!r)c&&this.load(c,!0);else if(u.SetUp==="1"){if(!("FEN"in u))throw new Error("Invalid PGN: FEN tag must be supplied with SetUp tag");this.load(u.FEN,!0)}function f(S){return Array.from(S).map(function(B){return B.charCodeAt(0)<128?B.charCodeAt(0).toString(16):encodeURIComponent(B).replace(/%/g,"").toLowerCase()}).join("")}function d(S){return S.length==0?"":decodeURIComponent("%"+(S.match(/.{1,2}/g)||[]).join("%"))}const v=function(S){return S=S.replace(new RegExp(i(n),"g")," "),`{${f(S.slice(1,S.length-1))}}`},g=function(S){if(S.startsWith("{")&&S.endsWith("}"))return d(S.slice(1,S.length-1))};let C=t.replace(l,"").replace(new RegExp(`({[^}]*})+?|;([^${i(n)}]*)`,"g"),function(S,B,R){return B!==void 0?v(B):" "+v(`{${R.slice(1)}}`)}).replace(new RegExp(i(n),"g")," ");const I=/(\([^()]+\))+?/g;for(;I.test(C);)C=C.replace(I,"");C=C.replace(/\d+\.(\.\.)?/g,""),C=C.replace(/\.\.\./g,""),C=C.replace(/\$\d+/g,"");let y=C.trim().split(new RegExp(/\s+/));y=y.filter(S=>S!=="");let m="";for(let S=0;S-1)m=y[S];else throw new Error(`Invalid move in PGN: ${y[S]}`);else m="",this._makeMove(R)}m&&Object.keys(this._header).length&&!this._header.Result&&this.header("Result",m)}_moveToSan(t,r){let n="";if(t.flags&fe.KSIDE_CASTLE)n="O-O";else if(t.flags&fe.QSIDE_CASTLE)n="O-O-O";else{if(t.piece!==Et){const i=Jm(t,r);n+=t.piece.toUpperCase()+i}t.flags&(fe.CAPTURE|fe.EP_CAPTURE)&&(t.piece===Et&&(n+=ir(t.from)[0]),n+="x"),n+=ir(t.to),t.promotion&&(n+="="+t.promotion.toUpperCase())}return this._makeMove(t),this.isCheck()&&(this.isCheckmate()?n+="#":n+="+"),this._undoMove(),n}_moveFromSan(t,r=!1){const n=hu(t);let i=Nd(n),a=this._moves({legal:!0,piece:i});for(let d=0,v=a.length;d0?n+=this.perft(t-1):n++),this._undoMove();return n}_makePretty(t){const{color:r,piece:n,from:i,to:a,flags:s,captured:o,promotion:l}=t;let u="";for(const v in fe)fe[v]&s&&(u+=jm[v]);const c=ir(i),f=ir(a),d={color:r,piece:n,from:c,to:f,san:this._moveToSan(t,this._moves({legal:!0})),flags:u,lan:c+f,before:this.fen(),after:""};return this._makeMove(t),d.after=this.fen(),this._undoMove(),o&&(d.captured=o),l&&(d.promotion=l,d.lan+=l),d}turn(){return this._turn}board(){const t=[];let r=[];for(let n=ve.a8;n<=ve.h1;n++)this._board[n]==null?r.push(null):r.push({square:ir(n),type:this._board[n].type,color:this._board[n].color}),n+1&136&&(t.push(r),r=[],n+=8);return t}squareColor(t){if(t in ve){const r=ve[t];return(pi(r)+Cs(r))%2===0?"light":"dark"}return null}history({verbose:t=!1}={}){const r=[],n=[];for(;this._history.length>0;)r.push(this._undoMove());for(;;){const i=r.pop();if(!i)break;t?n.push(this._makePretty(i)):n.push(this._moveToSan(i,this._moves())),this._makeMove(i)}return n}_pruneComments(){const t=[],r={},n=i=>{i in this._comments&&(r[i]=this._comments[i])};for(;this._history.length>0;)t.push(this._undoMove());for(n(this.fen());;){const i=t.pop();if(!i)break;this._makeMove(i),n(this.fen())}this._comments=r}getComment(){return this._comments[this.fen()]}setComment(t){this._comments[this.fen()]=t.replace("{","[").replace("}","]")}deleteComment(){const t=this._comments[this.fen()];return delete this._comments[this.fen()],t}getComments(){return this._pruneComments(),Object.keys(this._comments).map(t=>({fen:t,comment:this._comments[t]}))}deleteComments(){return this._pruneComments(),Object.keys(this._comments).map(t=>{const r=this._comments[t];return delete this._comments[t],{fen:t,comment:r}})}setCastlingRights(t,r){for(const i of[St,kn])r[i]!==void 0&&(r[i]?this._castling[t]|=Ys[i]:this._castling[t]&=~Ys[i]);this._updateCastlingRights();const n=this.getCastlingRights(t);return(r[St]===void 0||r[St]===n[St])&&(r[kn]===void 0||r[kn]===n[kn])}getCastlingRights(t){return{[St]:(this._castling[t]&Ys[St])!==0,[kn]:(this._castling[t]&Ys[kn])!==0}}moveNumber(){return this._moveNumber}}const Qg=q.createContext({dragDropManager:void 0});function vr(e){return"Minified Redux error #"+e+"; visit https://redux.js.org/Errors?code="+e+" for the full message or use the non-minified dev environment for full errors. "}var Dd=typeof Symbol=="function"&&Symbol.observable||"@@observable",pu=function(){return Math.random().toString(36).substring(7).split("").join(".")},Rd={INIT:"@@redux/INIT"+pu(),REPLACE:"@@redux/REPLACE"+pu(),PROBE_UNKNOWN_ACTION:function(){return"@@redux/PROBE_UNKNOWN_ACTION"+pu()}};function Wg(e,t,r){var n;if(typeof t=="function"&&typeof r=="function"||typeof r=="function"&&typeof arguments[3]=="function")throw new Error(vr(0));if(typeof t=="function"&&r===void 0&&(r=t,t=void 0),r!==void 0){if(typeof r!="function")throw new Error(vr(1));return r(Wg)(e,t)}if(typeof e!="function")throw new Error(vr(2));var i=e,a=t,s=[],o=s,l=!1;function u(){o===s&&(o=s.slice())}function c(){if(l)throw new Error(vr(3));return a}function f(v){if(typeof v!="function")throw new Error(vr(4));if(l)throw new Error(vr(5));var g=!0;return u(),o.push(v),function(){if(g){if(l)throw new Error(vr(6));g=!1,u();var C=o.indexOf(v);o.splice(C,1),s=null}}}function d(v){if(!function(I){if(typeof I!="object"||I===null)return!1;for(var y=I;Object.getPrototypeOf(y)!==null;)y=Object.getPrototypeOf(y);return Object.getPrototypeOf(I)===y}(v))throw new Error(vr(7));if(v.type===void 0)throw new Error(vr(8));if(l)throw new Error(vr(9));try{l=!0,a=i(a,v)}finally{l=!1}for(var g=s=o,C=0;C=0;C--)if(v.canDragSource(d[C])){g=d[C];break}return g}(t,s);if(l==null)return void e.dispatch(t2);let u=null;if(i){if(!a)throw new Error("getSourceClientOffset must be defined");(function(d){de(typeof d=="function","When clientOffset is provided, getSourceClientOffset must be a function.")})(a),u=a(l)}e.dispatch(Ld(i,u));const c=o.getSource(l).beginDrag(s,l);if(c==null)return;(function(d){de(Yg(d),"Item must be an object.")})(c),o.pinSource(l);const f=o.getSourceType(l);return{type:qf,payload:{itemType:f,item:c,sourceId:l,clientOffset:i||null,sourceClientOffset:u||null,isSourcePublic:!!n}}}}function n2(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i2(e){for(var t=1;t{const o=function(u,c,f,d){const v=f.getTarget(u);let g=v?v.drop(d,u):void 0;return function(C){de(C===void 0||Yg(C),"Drop result must either be an object or undefined.")}(g),g===void 0&&(g=c===0?{}:d.getDropResult()),g}(a,s,n,r),l={type:$f,payload:{dropResult:i2({},t,o)}};e.dispatch(l)})}}function s2(e){return function(){const t=e.getMonitor(),r=e.getRegistry();(function(i){de(i.isDragging(),"Cannot call endDrag while not dragging.")})(t);const n=t.getSourceId();return n!=null&&(r.getSource(n,!0).endDrag(t,n),r.unpinSource()),{type:Gf}}}function wc(e,t){return t===null?e===null:Array.isArray(e)?e.some(r=>r===t):e===t}function o2(e){return function(t,{clientOffset:r}={}){(function(s){de(Array.isArray(s),"Expected targetIds to be an array.")})(t);const n=t.slice(0),i=e.getMonitor(),a=e.getRegistry();return function(s,o,l){for(let u=s.length-1;u>=0;u--){const c=s[u];wc(o.getTargetType(c),l)||s.splice(u,1)}}(n,a,i.getItemType()),function(s,o,l){de(o.isDragging(),"Cannot call hover while not dragging."),de(!o.didDrop(),"Cannot call hover after drop.");for(let u=0;u{const s=n[a];var o;return i[a]=(o=s,(...l)=>{const u=o.apply(t,l);u!==void 0&&r(u)}),i},{})}dispatch(t){this.store.dispatch(t)}constructor(t,r){this.isSetUp=!1,this.handleRefCountChange=()=>{const n=this.store.getState().refCount>0;this.backend&&(n&&!this.isSetUp?(this.backend.setup(),this.isSetUp=!0):!n&&this.isSetUp&&(this.backend.teardown(),this.isSetUp=!1))},this.store=t,this.monitor=r,t.subscribe(this.handleRefCountChange)}}function Od(e,t){return{x:e.x-t.x,y:e.y-t.y}}const Xa=[],Qf=[];Xa.__IS_NONE__=!0,Qf.__IS_ALL__=!0;class c2{subscribeToStateChange(t,r={}){const{handlerIds:n}=r;de(typeof t=="function","listener must be a function."),de(n===void 0||Array.isArray(n),"handlerIds, when specified, must be an array of strings.");let i=this.store.getState().stateId;return this.store.subscribe(()=>{const a=this.store.getState(),s=a.stateId;try{s===i||s===i+1&&!function(l,u){return l!==Xa&&(l===Qf||u===void 0||(c=l,u.filter(f=>c.indexOf(f)>-1)).length>0);var c}(a.dirtyHandlerIds,n)||t()}finally{i=s}})}subscribeToOffsetChange(t){de(typeof t=="function","listener must be a function.");let r=this.store.getState().dragOffset;return this.store.subscribe(()=>{const n=this.store.getState().dragOffset;n!==r&&(r=n,t())})}canDragSource(t){if(!t)return!1;const r=this.registry.getSource(t);return de(r,`Expected to find a valid source. sourceId=${t}`),!this.isDragging()&&r.canDrag(this,t)}canDropOnTarget(t){if(!t)return!1;const r=this.registry.getTarget(t);return de(r,`Expected to find a valid target. targetId=${t}`),!this.isDragging()||this.didDrop()?!1:wc(this.registry.getTargetType(t),this.getItemType())&&r.canDrop(this,t)}isDragging(){return!!this.getItemType()}isDraggingSource(t){if(!t)return!1;const r=this.registry.getSource(t,!0);return de(r,`Expected to find a valid source. sourceId=${t}`),!this.isDragging()||!this.isSourcePublic()?!1:this.registry.getSourceType(t)===this.getItemType()&&r.isDragging(this,t)}isOverTarget(t,r={shallow:!1}){if(!t)return!1;const{shallow:n}=r;if(!this.isDragging())return!1;const i=this.registry.getTargetType(t),a=this.getItemType();if(a&&!wc(i,a))return!1;const s=this.getTargetIds();if(!s.length)return!1;const o=s.indexOf(t);return n?o===s.length-1:o>-1}getItemType(){return this.store.getState().dragOperation.itemType}getItem(){return this.store.getState().dragOperation.item}getSourceId(){return this.store.getState().dragOperation.sourceId}getTargetIds(){return this.store.getState().dragOperation.targetIds}getDropResult(){return this.store.getState().dragOperation.dropResult}didDrop(){return this.store.getState().dragOperation.didDrop}isSourcePublic(){return!!this.store.getState().dragOperation.isSourcePublic}getInitialClientOffset(){return this.store.getState().dragOffset.initialClientOffset}getInitialSourceClientOffset(){return this.store.getState().dragOffset.initialSourceClientOffset}getClientOffset(){return this.store.getState().dragOffset.clientOffset}getSourceClientOffset(){return function(t){const{clientOffset:r,initialClientOffset:n,initialSourceClientOffset:i}=t;return r&&n&&i?Od((s=i,{x:(a=r).x+s.x,y:a.y+s.y}),n):null;var a,s}(this.store.getState().dragOffset)}getDifferenceFromInitialOffset(){return function(t){const{clientOffset:r,initialClientOffset:n}=t;return r&&n?Od(r,n):null}(this.store.getState().dragOffset)}constructor(t,r){this.store=t,this.registry=r}}const Pd=typeof global<"u"?global:self,Ud=Pd.MutationObserver||Pd.WebKitMutationObserver;function Zg(e){return function(){const t=setTimeout(n,0),r=setInterval(n,50);function n(){clearTimeout(t),clearInterval(r),e()}}}const f2=typeof Ud=="function"?function(e){let t=1;const r=new Ud(e),n=document.createTextNode("");return r.observe(n,{characterData:!0}),function(){t=-t,n.data=t}}:Zg;let d2=class{call(){try{this.task&&this.task()}catch(t){this.onError(t)}finally{this.task=null,this.release(this)}}constructor(t,r){this.onError=t,this.release=r,this.task=null}};const Jg=new class{enqueueTask(e){const{queue:t,requestFlush:r}=this;t.length||(r(),this.flushing=!0),t[t.length]=e}constructor(){this.queue=[],this.pendingErrors=[],this.flushing=!1,this.index=0,this.capacity=1024,this.flush=()=>{const{queue:e}=this;for(;this.indexthis.capacity){for(let r=0,n=e.length-this.index;r{this.pendingErrors.push(e),this.requestErrorThrow()},this.requestFlush=f2(this.flush),this.requestErrorThrow=Zg(()=>{if(this.pendingErrors.length)throw this.pendingErrors.shift()})}},h2=new class{create(e){const t=this.freeTasks,r=t.length?t.pop():new d2(this.onError,n=>t[t.length]=n);return r.task=e,r}constructor(e){this.onError=e,this.freeTasks=[]}}(Jg.registerPendingError),Wf="dnd-core/ADD_SOURCE",Yf="dnd-core/ADD_TARGET",Xf="dnd-core/REMOVE_SOURCE",Sl="dnd-core/REMOVE_TARGET";function Ic(e,t){t&&Array.isArray(e)?e.forEach(r=>Ic(r,!1)):de(typeof e=="string"||typeof e=="symbol",t?"Type can only be a string, a symbol, or an array of either.":"Type can only be a string or a symbol.")}var Tr;(function(e){e.SOURCE="SOURCE",e.TARGET="TARGET"})(Tr||(Tr={}));let p2=0;function g2(e){const t=(p2++).toString();switch(e){case Tr.SOURCE:return`S${t}`;case Tr.TARGET:return`T${t}`;default:throw new Error(`Unknown Handler Role: ${e}`)}}function Md(e){switch(e[0]){case"S":return Tr.SOURCE;case"T":return Tr.TARGET;default:throw new Error(`Cannot parse handler ID: ${e}`)}}function Fd(e,t){const r=e.entries();let n=!1;do{const{done:i,value:[,a]}=r.next();if(a===t)return!0;n=!!i}while(!n);return!1}class v2{addSource(t,r){Ic(t),function(i){de(typeof i.canDrag=="function","Expected canDrag to be a function."),de(typeof i.beginDrag=="function","Expected beginDrag to be a function."),de(typeof i.endDrag=="function","Expected endDrag to be a function.")}(r);const n=this.addHandler(Tr.SOURCE,t,r);return this.store.dispatch(function(i){return{type:Wf,payload:{sourceId:i}}}(n)),n}addTarget(t,r){Ic(t,!0),function(i){de(typeof i.canDrop=="function","Expected canDrop to be a function."),de(typeof i.hover=="function","Expected hover to be a function."),de(typeof i.drop=="function","Expected beginDrag to be a function.")}(r);const n=this.addHandler(Tr.TARGET,t,r);return this.store.dispatch(function(i){return{type:Yf,payload:{targetId:i}}}(n)),n}containsHandler(t){return Fd(this.dragSources,t)||Fd(this.dropTargets,t)}getSource(t,r=!1){return de(this.isSourceId(t),"Expected a valid source ID."),r&&t===this.pinnedSourceId?this.pinnedSource:this.dragSources.get(t)}getTarget(t){return de(this.isTargetId(t),"Expected a valid target ID."),this.dropTargets.get(t)}getSourceType(t){return de(this.isSourceId(t),"Expected a valid source ID."),this.types.get(t)}getTargetType(t){return de(this.isTargetId(t),"Expected a valid target ID."),this.types.get(t)}isSourceId(t){return Md(t)===Tr.SOURCE}isTargetId(t){return Md(t)===Tr.TARGET}removeSource(t){var r;de(this.getSource(t),"Expected an existing source."),this.store.dispatch(function(n){return{type:Xf,payload:{sourceId:n}}}(t)),r=()=>{this.dragSources.delete(t),this.types.delete(t)},Jg.enqueueTask(h2.create(r))}removeTarget(t){de(this.getTarget(t),"Expected an existing target."),this.store.dispatch(function(r){return{type:Sl,payload:{targetId:r}}}(t)),this.dropTargets.delete(t),this.types.delete(t)}pinSource(t){const r=this.getSource(t);de(r,"Expected an existing source."),this.pinnedSourceId=t,this.pinnedSource=r}unpinSource(){de(this.pinnedSource,"No source is pinned at the time."),this.pinnedSourceId=null,this.pinnedSource=null}addHandler(t,r,n){const i=g2(t);return this.types.set(i,r),t===Tr.SOURCE?this.dragSources.set(i,n):t===Tr.TARGET&&this.dropTargets.set(i,n),i}constructor(t){this.types=new Map,this.dragSources=new Map,this.dropTargets=new Map,this.pinnedSourceId=null,this.pinnedSource=null,this.store=t}}const y2=(e,t)=>e===t;function m2(e=Xa,t){switch(t.type){case El:break;case Wf:case Yf:case Sl:case Xf:return Xa;default:return Qf}const{targetIds:r=[],prevTargetIds:n=[]}=t.payload,i=function(o,l){const u=new Map,c=d=>{u.set(d,u.has(d)?u.get(d)+1:1)};o.forEach(c),l.forEach(c);const f=[];return u.forEach((d,v)=>{d===1&&f.push(v)}),f}(r,n);if(!(i.length>0||!function(o,l,u=y2){if(o.length!==l.length)return!1;for(let c=0;ca!==i))});case $f:return bi({},e,{dropResult:r.dropResult,didDrop:!0,targetIds:[]});case Gf:return bi({},e,{itemType:null,item:null,sourceId:null,dropResult:null,didDrop:!1,isSourcePublic:null,targetIds:[]});default:return e}var n,i}function w2(e=0,t){switch(t.type){case Wf:case Yf:return e+1;case Xf:case Sl:return e-1;default:return e}}function I2(e=0){return e+1}function _2(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function A2(e){for(var t=1;ta&&a[s]?a[s]:i||null,r))})}),dragOffset:E2(e.dragOffset,t),refCount:w2(e.refCount,t),dragOperation:T2(e.dragOperation,t),stateId:I2(e.stateId)};var r,n,i}function k2(e,t=void 0,r={},n=!1){const i=function(l){const u=typeof window<"u"&&window.__REDUX_DEVTOOLS_EXTENSION__;return Wg(B2,l&&u&&u({name:"dnd-core",instanceId:"dnd-core"}))}(n),a=new c2(i,new v2(i)),s=new u2(i,a),o=e(s,t,r);return s.receiveBackend(o),s}function b2(e,t){if(e==null)return{};var r,n,i=function(s,o){if(s==null)return{};var l,u,c={},f=Object.keys(s);for(u=0;u=0||(c[l]=s[l]);return c}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}let jd=0;const Xs=Symbol.for("__REACT_DND_CONTEXT_INSTANCE__");var N2=q.memo(function(e){var{children:t}=e,r=b2(e,["children"]);const[n,i]=function(a){if("manager"in a)return[{dragDropManager:a.manager},!1];const s=function(l,u=Kd(),c,f){const d=u;return d[Xs]||(d[Xs]={dragDropManager:k2(l,u,c,f)}),d[Xs]}(a.backend,a.context,a.options,a.debugMode),o=!a.context;return[s,o]}(r);return q.useEffect(()=>{if(i){const a=Kd();return++jd,()=>{--jd==0&&(a[Xs]=null)}}},[]),D.jsx(Qg.Provider,{value:n,children:t})});function Kd(){return typeof global<"u"?global:window}var D2=function e(t,r){if(t===r)return!0;if(t&&r&&typeof t=="object"&&typeof r=="object"){if(t.constructor!==r.constructor)return!1;var n,i,a;if(Array.isArray(t)){if((n=t.length)!=r.length)return!1;for(i=n;i--!=0;)if(!e(t[i],r[i]))return!1;return!0}if(t.constructor===RegExp)return t.source===r.source&&t.flags===r.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===r.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===r.toString();if((n=(a=Object.keys(t)).length)!==Object.keys(r).length)return!1;for(i=n;i--!=0;)if(!Object.prototype.hasOwnProperty.call(r,a[i]))return!1;for(i=n;i--!=0;){var s=a[i];if(!e(t[s],r[s]))return!1}return!0}return t!=t&&r!=r};const Si=typeof window<"u"?q.useLayoutEffect:q.useEffect;function e1(e,t,r){const[n,i]=q.useState(()=>t(e)),a=q.useCallback(()=>{const s=t(e);D2(n,s)||(i(s),r&&r())},[n,e,r]);return Si(a),[n,a]}function t1(e,t,r){return function(n,i,a){const[s,o]=e1(n,i,a);return Si(function(){const l=n.getHandlerId();if(l!=null)return n.subscribeToStateChange(o,{handlerIds:[l]})},[n,o]),s}(t,e||(()=>({})),()=>r.reconnect())}function r1(e,t){const r=[...t||[]];return t==null&&typeof e!="function"&&r.push(e),q.useMemo(()=>typeof e=="function"?e():e,r)}function R2(e){return q.useMemo(()=>e.hooks.dragSource(),[e])}function L2(e){return q.useMemo(()=>e.hooks.dragPreview(),[e])}let gu=!1,vu=!1;class O2{receiveHandlerId(t){this.sourceId=t}getHandlerId(){return this.sourceId}canDrag(){de(!gu,"You may not call monitor.canDrag() inside your canDrag() implementation. Read more: http://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor");try{return gu=!0,this.internalMonitor.canDragSource(this.sourceId)}finally{gu=!1}}isDragging(){if(!this.sourceId)return!1;de(!vu,"You may not call monitor.isDragging() inside your isDragging() implementation. Read more: http://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor");try{return vu=!0,this.internalMonitor.isDraggingSource(this.sourceId)}finally{vu=!1}}subscribeToStateChange(t,r){return this.internalMonitor.subscribeToStateChange(t,r)}isDraggingSource(t){return this.internalMonitor.isDraggingSource(t)}isOverTarget(t,r){return this.internalMonitor.isOverTarget(t,r)}getTargetIds(){return this.internalMonitor.getTargetIds()}isSourcePublic(){return this.internalMonitor.isSourcePublic()}getSourceId(){return this.internalMonitor.getSourceId()}subscribeToOffsetChange(t){return this.internalMonitor.subscribeToOffsetChange(t)}canDragSource(t){return this.internalMonitor.canDragSource(t)}canDropOnTarget(t){return this.internalMonitor.canDropOnTarget(t)}getItemType(){return this.internalMonitor.getItemType()}getItem(){return this.internalMonitor.getItem()}getDropResult(){return this.internalMonitor.getDropResult()}didDrop(){return this.internalMonitor.didDrop()}getInitialClientOffset(){return this.internalMonitor.getInitialClientOffset()}getInitialSourceClientOffset(){return this.internalMonitor.getInitialSourceClientOffset()}getSourceClientOffset(){return this.internalMonitor.getSourceClientOffset()}getClientOffset(){return this.internalMonitor.getClientOffset()}getDifferenceFromInitialOffset(){return this.internalMonitor.getDifferenceFromInitialOffset()}constructor(t){this.sourceId=null,this.internalMonitor=t.getMonitor()}}let yu=!1;class P2{receiveHandlerId(t){this.targetId=t}getHandlerId(){return this.targetId}subscribeToStateChange(t,r){return this.internalMonitor.subscribeToStateChange(t,r)}canDrop(){if(!this.targetId)return!1;de(!yu,"You may not call monitor.canDrop() inside your canDrop() implementation. Read more: http://react-dnd.github.io/react-dnd/docs/api/drop-target-monitor");try{return yu=!0,this.internalMonitor.canDropOnTarget(this.targetId)}finally{yu=!1}}isOver(t){return!!this.targetId&&this.internalMonitor.isOverTarget(this.targetId,t)}getItemType(){return this.internalMonitor.getItemType()}getItem(){return this.internalMonitor.getItem()}getDropResult(){return this.internalMonitor.getDropResult()}didDrop(){return this.internalMonitor.didDrop()}getInitialClientOffset(){return this.internalMonitor.getInitialClientOffset()}getInitialSourceClientOffset(){return this.internalMonitor.getInitialSourceClientOffset()}getSourceClientOffset(){return this.internalMonitor.getSourceClientOffset()}getClientOffset(){return this.internalMonitor.getClientOffset()}getDifferenceFromInitialOffset(){return this.internalMonitor.getDifferenceFromInitialOffset()}constructor(t){this.targetId=null,this.internalMonitor=t.getMonitor()}}function _c(e,t,r,n){let i=r?r.call(n,e,t):void 0;if(i!==void 0)return!!i;if(e===t)return!0;if(typeof e!="object"||!e||typeof t!="object"||!t)return!1;const a=Object.keys(e),s=Object.keys(t);if(a.length!==s.length)return!1;const o=Object.prototype.hasOwnProperty.bind(t);for(let l=0;l{if(!q.isValidElement(t)){const i=t;return e(i,r),i}const n=t;return function(i){if(typeof i.type=="string")return;const a=i.type.displayName||i.type.name||"the component";throw new Error(`Only native element nodes can now be passed to React DnD connectors.You can either wrap ${a} into a
, or turn it into a drag source or a drop target itself.`)}(n),function(i,a){const s=i.ref;return de(typeof s!="string","Cannot connect React DnD to an element with an existing string ref. Please convert it to use a callback ref instead, or wrap it into a or
. Read more: https://reactjs.org/docs/refs-and-the-dom.html#callback-refs"),q.cloneElement(i,s?{ref:o=>{zd(s,o),zd(a,o)}}:{ref:a})}(n,r?i=>e(i,r):e)}}function n1(e){const t={};return Object.keys(e).forEach(r=>{const n=e[r];if(r.endsWith("Ref"))t[r]=e[r];else{const i=U2(n);t[r]=()=>i}}),t}function zd(e,t){typeof e=="function"?e(t):e.current=t}class M2{receiveHandlerId(t){this.handlerId!==t&&(this.handlerId=t,this.reconnect())}get connectTarget(){return this.dragSource}get dragSourceOptions(){return this.dragSourceOptionsInternal}set dragSourceOptions(t){this.dragSourceOptionsInternal=t}get dragPreviewOptions(){return this.dragPreviewOptionsInternal}set dragPreviewOptions(t){this.dragPreviewOptionsInternal=t}reconnect(){const t=this.reconnectDragSource();this.reconnectDragPreview(t)}reconnectDragSource(){const t=this.dragSource,r=this.didHandlerIdChange()||this.didConnectedDragSourceChange()||this.didDragSourceOptionsChange();return r&&this.disconnectDragSource(),this.handlerId?t?(r&&(this.lastConnectedHandlerId=this.handlerId,this.lastConnectedDragSource=t,this.lastConnectedDragSourceOptions=this.dragSourceOptions,this.dragSourceUnsubscribe=this.backend.connectDragSource(this.handlerId,t,this.dragSourceOptions)),r):(this.lastConnectedDragSource=t,r):r}reconnectDragPreview(t=!1){const r=this.dragPreview,n=t||this.didHandlerIdChange()||this.didConnectedDragPreviewChange()||this.didDragPreviewOptionsChange();n&&this.disconnectDragPreview(),this.handlerId&&(r?n&&(this.lastConnectedHandlerId=this.handlerId,this.lastConnectedDragPreview=r,this.lastConnectedDragPreviewOptions=this.dragPreviewOptions,this.dragPreviewUnsubscribe=this.backend.connectDragPreview(this.handlerId,r,this.dragPreviewOptions)):this.lastConnectedDragPreview=r)}didHandlerIdChange(){return this.lastConnectedHandlerId!==this.handlerId}didConnectedDragSourceChange(){return this.lastConnectedDragSource!==this.dragSource}didConnectedDragPreviewChange(){return this.lastConnectedDragPreview!==this.dragPreview}didDragSourceOptionsChange(){return!_c(this.lastConnectedDragSourceOptions,this.dragSourceOptions)}didDragPreviewOptionsChange(){return!_c(this.lastConnectedDragPreviewOptions,this.dragPreviewOptions)}disconnectDragSource(){this.dragSourceUnsubscribe&&(this.dragSourceUnsubscribe(),this.dragSourceUnsubscribe=void 0)}disconnectDragPreview(){this.dragPreviewUnsubscribe&&(this.dragPreviewUnsubscribe(),this.dragPreviewUnsubscribe=void 0,this.dragPreviewNode=null,this.dragPreviewRef=null)}get dragSource(){return this.dragSourceNode||this.dragSourceRef&&this.dragSourceRef.current}get dragPreview(){return this.dragPreviewNode||this.dragPreviewRef&&this.dragPreviewRef.current}clearDragSource(){this.dragSourceNode=null,this.dragSourceRef=null}clearDragPreview(){this.dragPreviewNode=null,this.dragPreviewRef=null}constructor(t){this.hooks=n1({dragSource:(r,n)=>{this.clearDragSource(),this.dragSourceOptions=n||null,Ac(r)?this.dragSourceRef=r:this.dragSourceNode=r,this.reconnectDragSource()},dragPreview:(r,n)=>{this.clearDragPreview(),this.dragPreviewOptions=n||null,Ac(r)?this.dragPreviewRef=r:this.dragPreviewNode=r,this.reconnectDragPreview()}}),this.handlerId=null,this.dragSourceRef=null,this.dragSourceOptionsInternal=null,this.dragPreviewRef=null,this.dragPreviewOptionsInternal=null,this.lastConnectedHandlerId=null,this.lastConnectedDragSource=null,this.lastConnectedDragSourceOptions=null,this.lastConnectedDragPreview=null,this.lastConnectedDragPreviewOptions=null,this.backend=t}}class F2{get connectTarget(){return this.dropTarget}reconnect(){const t=this.didHandlerIdChange()||this.didDropTargetChange()||this.didOptionsChange();t&&this.disconnectDropTarget();const r=this.dropTarget;this.handlerId&&(r?t&&(this.lastConnectedHandlerId=this.handlerId,this.lastConnectedDropTarget=r,this.lastConnectedDropTargetOptions=this.dropTargetOptions,this.unsubscribeDropTarget=this.backend.connectDropTarget(this.handlerId,r,this.dropTargetOptions)):this.lastConnectedDropTarget=r)}receiveHandlerId(t){t!==this.handlerId&&(this.handlerId=t,this.reconnect())}get dropTargetOptions(){return this.dropTargetOptionsInternal}set dropTargetOptions(t){this.dropTargetOptionsInternal=t}didHandlerIdChange(){return this.lastConnectedHandlerId!==this.handlerId}didDropTargetChange(){return this.lastConnectedDropTarget!==this.dropTarget}didOptionsChange(){return!_c(this.lastConnectedDropTargetOptions,this.dropTargetOptions)}disconnectDropTarget(){this.unsubscribeDropTarget&&(this.unsubscribeDropTarget(),this.unsubscribeDropTarget=void 0)}get dropTarget(){return this.dropTargetNode||this.dropTargetRef&&this.dropTargetRef.current}clearDropTarget(){this.dropTargetRef=null,this.dropTargetNode=null}constructor(t){this.hooks=n1({dropTarget:(r,n)=>{this.clearDropTarget(),this.dropTargetOptions=n,Ac(r)?this.dropTargetRef=r:this.dropTargetNode=r,this.reconnect()}}),this.handlerId=null,this.dropTargetRef=null,this.dropTargetOptionsInternal=null,this.lastConnectedHandlerId=null,this.lastConnectedDropTarget=null,this.lastConnectedDropTargetOptions=null,this.backend=t}}function xi(){const{dragDropManager:e}=q.useContext(Qg);return de(e!=null,"Expected drag drop context"),e}class V2{beginDrag(){const t=this.spec,r=this.monitor;let n=null;return n=typeof t.item=="object"?t.item:typeof t.item=="function"?t.item(r):{},n??null}canDrag(){const t=this.spec,r=this.monitor;return typeof t.canDrag=="boolean"?t.canDrag:typeof t.canDrag!="function"||t.canDrag(r)}isDragging(t,r){const n=this.spec,i=this.monitor,{isDragging:a}=n;return a?a(i):r===t.getSourceId()}endDrag(){const t=this.spec,r=this.monitor,n=this.connector,{end:i}=t;i&&i(r.getItem(),r),n.reconnect()}constructor(t,r,n){this.spec=t,this.monitor=r,this.connector=n}}function j2(e,t,r){const n=xi(),i=function(s,o,l){const u=q.useMemo(()=>new V2(s,o,l),[o,l]);return q.useEffect(()=>{u.spec=s},[s]),u}(e,t,r),a=function(s){return q.useMemo(()=>{const o=s.type;return de(o!=null,"spec.type must be defined"),o},[s])}(e);Si(function(){if(a!=null){const[s,o]=function(l,u,c){const f=c.getRegistry(),d=f.addSource(l,u);return[d,()=>f.removeSource(d)]}(a,i,n);return t.receiveHandlerId(s),r.receiveHandlerId(s),o}},[n,t,r,i,a])}function K2(e,t){const r=r1(e,t);de(!r.begin,"useDrag::spec.begin was deprecated in v14. Replace spec.begin() with spec.item(). (see more here - https://react-dnd.github.io/react-dnd/docs/api/use-drag)");const n=function(){const a=xi();return q.useMemo(()=>new O2(a),[a])}(),i=function(a,s){const o=xi(),l=q.useMemo(()=>new M2(o.getBackend()),[o]);return Si(()=>(l.dragSourceOptions=a||null,l.reconnect(),()=>l.disconnectDragSource()),[l,a]),Si(()=>(l.dragPreviewOptions=s||null,l.reconnect(),()=>l.disconnectDragPreview()),[l,s]),l}(r.options,r.previewOptions);return j2(r,n,i),[t1(r.collect,n,i),R2(i),L2(i)]}function z2(e){return q.useMemo(()=>e.hooks.dropTarget(),[e])}class H2{canDrop(){const t=this.spec,r=this.monitor;return!t.canDrop||t.canDrop(r.getItem(),r)}hover(){const t=this.spec,r=this.monitor;t.hover&&t.hover(r.getItem(),r)}drop(){const t=this.spec,r=this.monitor;if(t.drop)return t.drop(r.getItem(),r)}constructor(t,r){this.spec=t,this.monitor=r}}function q2(e,t,r){const n=xi(),i=function(s,o){const l=q.useMemo(()=>new H2(s,o),[o]);return q.useEffect(()=>{l.spec=s},[s]),l}(e,t),a=function(s){const{accept:o}=s;return q.useMemo(()=>(de(s.accept!=null,"accept must be defined"),Array.isArray(o)?o:[o]),[o])}(e);Si(function(){const[s,o]=function(l,u,c){const f=c.getRegistry(),d=f.addTarget(l,u);return[d,()=>f.removeTarget(d)]}(a,i,n);return t.receiveHandlerId(s),r.receiveHandlerId(s),o},[n,t,i,r,a.map(s=>s.toString()).join("|")])}function $2(e,t){const r=r1(e,t),n=function(){const a=xi();return q.useMemo(()=>new P2(a),[a])}(),i=function(a){const s=xi(),o=q.useMemo(()=>new F2(s.getBackend()),[s]);return Si(()=>(o.dropTargetOptions=a||null,o.reconnect(),()=>o.disconnectDropTarget()),[a]),o}(r.options);return q2(r,n,i),[t1(r.collect,n,i),z2(i)]}function i1(e){let t=null;return()=>(t==null&&(t=e()),t)}class G2{enter(t){const r=this.entered.length;return this.entered=function(n,i){const a=new Set,s=l=>a.add(l);n.forEach(s),i.forEach(s);const o=[];return a.forEach(l=>o.push(l)),o}(this.entered.filter(n=>this.isNodeInDocument(n)&&(!n.contains||n.contains(t))),[t]),r===0&&this.entered.length>0}leave(t){const r=this.entered.length;var n,i;return this.entered=(n=this.entered.filter(this.isNodeInDocument),i=t,n.filter(a=>a!==i)),r>0&&this.entered.length===0}reset(){this.entered=[]}constructor(t){this.entered=[],this.isNodeInDocument=t}}class Q2{initializeExposedProperties(){Object.keys(this.config.exposeProperties).forEach(t=>{Object.defineProperty(this.item,t,{configurable:!0,enumerable:!0,get:()=>(console.warn(`Browser doesn't allow reading "${t}" until the drop event.`),null)})})}loadDataTransfer(t){if(t){const r={};Object.keys(this.config.exposeProperties).forEach(n=>{const i=this.config.exposeProperties[n];i!=null&&(r[n]={value:i(t,this.config.matchesTypes),configurable:!0,enumerable:!0})}),Object.defineProperties(this.item,r)}}canDrag(){return!0}beginDrag(){return this.item}isDragging(t,r){return r===t.getSourceId()}endDrag(){}constructor(t){this.config=t,this.item={},this.initializeExposedProperties()}}const a1="__NATIVE_FILE__",s1="__NATIVE_URL__",o1="__NATIVE_TEXT__",l1="__NATIVE_HTML__";var Hd=Object.freeze({__proto__:null,FILE:a1,HTML:l1,TEXT:o1,URL:s1});function mu(e,t,r){const n=t.reduce((i,a)=>i||e.getData(a),"");return n??r}const Bc={[a1]:{exposeProperties:{files:e=>Array.prototype.slice.call(e.files),items:e=>e.items,dataTransfer:e=>e},matchesTypes:["Files"]},[l1]:{exposeProperties:{html:(e,t)=>mu(e,t,""),dataTransfer:e=>e},matchesTypes:["Html","text/html"]},[s1]:{exposeProperties:{urls:(e,t)=>mu(e,t,"").split(` -`),dataTransfer:e=>e},matchesTypes:["Url","text/uri-list"]},[o1]:{exposeProperties:{text:(e,t)=>mu(e,t,""),dataTransfer:e=>e},matchesTypes:["Text","text/plain"]}};function Cu(e){if(!e)return null;const t=Array.prototype.slice.call(e.types||[]);return Object.keys(Bc).filter(r=>{const n=Bc[r];return!!(n!=null&&n.matchesTypes)&&n.matchesTypes.some(i=>t.indexOf(i)>-1)})[0]||null}const W2=i1(()=>/firefox/i.test(navigator.userAgent)),qd=i1(()=>!!window.safari);class $d{interpolate(t){const{xs:r,ys:n,c1s:i,c2s:a,c3s:s}=this;let o=r.length-1;if(t===r[o])return n[o];let l,u=0,c=s.length-1;for(;u<=c;){l=Math.floor(.5*(u+c));const v=r[l];if(vt))return n[l];c=l-1}}o=Math.max(0,c);const f=t-r[o],d=f*f;return n[o]+i[o]*f+a[o]*d+s[o]*f*d}constructor(t,r){const{length:n}=t,i=[];for(let v=0;vt[v]{let S=new $d([0,.5,1],[u.y,u.y/f*C,u.y+C-f]).interpolate(v);return qd()&&a&&(S+=(window.devicePixelRatio-1)*C),S})()}}let Js;function Z2(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function Gd(e){for(var t=1;t{this.sourcePreviewNodes.delete(t),this.sourcePreviewNodeOptions.delete(t)}}connectDragSource(t,r,n){this.sourceNodes.set(t,r),this.sourceNodeOptions.set(t,n);const i=s=>this.handleDragStart(s,t),a=s=>this.handleSelectStart(s);return r.setAttribute("draggable","true"),r.addEventListener("dragstart",i),r.addEventListener("selectstart",a),()=>{this.sourceNodes.delete(t),this.sourceNodeOptions.delete(t),r.removeEventListener("dragstart",i),r.removeEventListener("selectstart",a),r.setAttribute("draggable","false")}}connectDropTarget(t,r){const n=s=>this.handleDragEnter(s,t),i=s=>this.handleDragOver(s,t),a=s=>this.handleDrop(s,t);return r.addEventListener("dragenter",n),r.addEventListener("dragover",i),r.addEventListener("drop",a),()=>{r.removeEventListener("dragenter",n),r.removeEventListener("dragover",i),r.removeEventListener("drop",a)}}addEventListeners(t){t.addEventListener&&(t.addEventListener("dragstart",this.handleTopDragStart),t.addEventListener("dragstart",this.handleTopDragStartCapture,!0),t.addEventListener("dragend",this.handleTopDragEndCapture,!0),t.addEventListener("dragenter",this.handleTopDragEnter),t.addEventListener("dragenter",this.handleTopDragEnterCapture,!0),t.addEventListener("dragleave",this.handleTopDragLeaveCapture,!0),t.addEventListener("dragover",this.handleTopDragOver),t.addEventListener("dragover",this.handleTopDragOverCapture,!0),t.addEventListener("drop",this.handleTopDrop),t.addEventListener("drop",this.handleTopDropCapture,!0))}removeEventListeners(t){t.removeEventListener&&(t.removeEventListener("dragstart",this.handleTopDragStart),t.removeEventListener("dragstart",this.handleTopDragStartCapture,!0),t.removeEventListener("dragend",this.handleTopDragEndCapture,!0),t.removeEventListener("dragenter",this.handleTopDragEnter),t.removeEventListener("dragenter",this.handleTopDragEnterCapture,!0),t.removeEventListener("dragleave",this.handleTopDragLeaveCapture,!0),t.removeEventListener("dragover",this.handleTopDragOver),t.removeEventListener("dragover",this.handleTopDragOverCapture,!0),t.removeEventListener("drop",this.handleTopDrop),t.removeEventListener("drop",this.handleTopDropCapture,!0))}getCurrentSourceNodeOptions(){const t=this.monitor.getSourceId(),r=this.sourceNodeOptions.get(t);return Gd({dropEffect:this.altKeyPressed?"copy":"move"},r||{})}getCurrentDropEffect(){return this.isDraggingNativeItem()?"copy":this.getCurrentSourceNodeOptions().dropEffect}getCurrentSourcePreviewNodeOptions(){const t=this.monitor.getSourceId();return Gd({anchorX:.5,anchorY:.5,captureDraggingState:!1},this.sourcePreviewNodeOptions.get(t)||{})}isDraggingNativeItem(){const t=this.monitor.getItemType();return Object.keys(Hd).some(r=>Hd[r]===t)}beginDragNativeItem(t,r){this.clearCurrentDragSourceNode(),this.currentNativeSource=function(n,i){const a=Bc[n];if(!a)throw new Error(`native type ${n} has no configuration`);const s=new Q2(a);return s.loadDataTransfer(i),s}(t,r),this.currentNativeHandle=this.registry.addSource(t,this.currentNativeSource),this.actions.beginDrag([this.currentNativeHandle])}setCurrentDragSourceNode(t){this.clearCurrentDragSourceNode(),this.currentDragSourceNode=t,this.mouseMoveTimeoutTimer=setTimeout(()=>{var r;return(r=this.rootElement)===null||r===void 0?void 0:r.addEventListener("mousemove",this.endDragIfSourceWasRemovedFromDOM,!0)},1e3)}clearCurrentDragSourceNode(){if(this.currentDragSourceNode){var t;return this.currentDragSourceNode=null,this.rootElement&&((t=this.window)===null||t===void 0||t.clearTimeout(this.mouseMoveTimeoutTimer||void 0),this.rootElement.removeEventListener("mousemove",this.endDragIfSourceWasRemovedFromDOM,!0)),this.mouseMoveTimeoutTimer=null,!0}return!1}handleDragStart(t,r){t.defaultPrevented||(this.dragStartSourceIds||(this.dragStartSourceIds=[]),this.dragStartSourceIds.unshift(r))}handleDragEnter(t,r){this.dragEnterTargetIds.unshift(r)}handleDragOver(t,r){this.dragOverTargetIds===null&&(this.dragOverTargetIds=[]),this.dragOverTargetIds.unshift(r)}handleDrop(t,r){this.dropTargetIds.unshift(r)}constructor(t,r,n){this.sourcePreviewNodes=new Map,this.sourcePreviewNodeOptions=new Map,this.sourceNodes=new Map,this.sourceNodeOptions=new Map,this.dragStartSourceIds=null,this.dropTargetIds=[],this.dragEnterTargetIds=[],this.currentNativeSource=null,this.currentNativeHandle=null,this.currentDragSourceNode=null,this.altKeyPressed=!1,this.mouseMoveTimeoutTimer=null,this.asyncEndDragFrameId=null,this.dragOverTargetIds=null,this.lastClientOffset=null,this.hoverRafId=null,this.getSourceClientOffset=i=>{const a=this.sourceNodes.get(i);return a&&u1(a)||null},this.endDragNativeItem=()=>{this.isDraggingNativeItem()&&(this.actions.endDrag(),this.currentNativeHandle&&this.registry.removeSource(this.currentNativeHandle),this.currentNativeHandle=null,this.currentNativeSource=null)},this.isNodeInDocument=i=>!!(i&&this.document&&this.document.body&&this.document.body.contains(i)),this.endDragIfSourceWasRemovedFromDOM=()=>{const i=this.currentDragSourceNode;i==null||this.isNodeInDocument(i)||(this.clearCurrentDragSourceNode()&&this.monitor.isDragging()&&this.actions.endDrag(),this.cancelHover())},this.scheduleHover=i=>{this.hoverRafId===null&&typeof requestAnimationFrame<"u"&&(this.hoverRafId=requestAnimationFrame(()=>{this.monitor.isDragging()&&this.actions.hover(i||[],{clientOffset:this.lastClientOffset}),this.hoverRafId=null}))},this.cancelHover=()=>{this.hoverRafId!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(this.hoverRafId),this.hoverRafId=null)},this.handleTopDragStartCapture=()=>{this.clearCurrentDragSourceNode(),this.dragStartSourceIds=[]},this.handleTopDragStart=i=>{if(i.defaultPrevented)return;const{dragStartSourceIds:a}=this;this.dragStartSourceIds=null;const s=Zs(i);this.monitor.isDragging()&&(this.actions.endDrag(),this.cancelHover()),this.actions.beginDrag(a||[],{publishSource:!1,getSourceClientOffset:this.getSourceClientOffset,clientOffset:s});const{dataTransfer:o}=i,l=Cu(o);if(this.monitor.isDragging()){if(o&&typeof o.setDragImage=="function"){const c=this.monitor.getSourceId(),f=this.sourceNodes.get(c),d=this.sourcePreviewNodes.get(c)||f;if(d){const{anchorX:v,anchorY:g,offsetX:C,offsetY:I}=this.getCurrentSourcePreviewNodeOptions(),y=X2(f,d,s,{anchorX:v,anchorY:g},{offsetX:C,offsetY:I});o.setDragImage(d,y.x,y.y)}}try{o==null||o.setData("application/json",{})}catch{}this.setCurrentDragSourceNode(i.target);const{captureDraggingState:u}=this.getCurrentSourcePreviewNodeOptions();u?this.actions.publishDragSource():setTimeout(()=>this.actions.publishDragSource(),0)}else if(l)this.beginDragNativeItem(l);else{if(o&&!o.types&&(i.target&&!i.target.hasAttribute||!i.target.hasAttribute("draggable")))return;i.preventDefault()}},this.handleTopDragEndCapture=()=>{this.clearCurrentDragSourceNode()&&this.monitor.isDragging()&&this.actions.endDrag(),this.cancelHover()},this.handleTopDragEnterCapture=i=>{var a;if(this.dragEnterTargetIds=[],this.isDraggingNativeItem()&&((a=this.currentNativeSource)===null||a===void 0||a.loadDataTransfer(i.dataTransfer)),!this.enterLeaveCounter.enter(i.target)||this.monitor.isDragging())return;const{dataTransfer:s}=i,o=Cu(s);o&&this.beginDragNativeItem(o,s)},this.handleTopDragEnter=i=>{const{dragEnterTargetIds:a}=this;this.dragEnterTargetIds=[],this.monitor.isDragging()&&(this.altKeyPressed=i.altKey,a.length>0&&this.actions.hover(a,{clientOffset:Zs(i)}),a.some(s=>this.monitor.canDropOnTarget(s))&&(i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect=this.getCurrentDropEffect())))},this.handleTopDragOverCapture=i=>{var a;this.dragOverTargetIds=[],this.isDraggingNativeItem()&&((a=this.currentNativeSource)===null||a===void 0||a.loadDataTransfer(i.dataTransfer))},this.handleTopDragOver=i=>{const{dragOverTargetIds:a}=this;if(this.dragOverTargetIds=[],!this.monitor.isDragging())return i.preventDefault(),void(i.dataTransfer&&(i.dataTransfer.dropEffect="none"));this.altKeyPressed=i.altKey,this.lastClientOffset=Zs(i),this.scheduleHover(a),(a||[]).some(s=>this.monitor.canDropOnTarget(s))?(i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect=this.getCurrentDropEffect())):this.isDraggingNativeItem()?i.preventDefault():(i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="none"))},this.handleTopDragLeaveCapture=i=>{this.isDraggingNativeItem()&&i.preventDefault(),this.enterLeaveCounter.leave(i.target)&&(this.isDraggingNativeItem()&&setTimeout(()=>this.endDragNativeItem(),0),this.cancelHover())},this.handleTopDropCapture=i=>{var a;this.dropTargetIds=[],this.isDraggingNativeItem()?(i.preventDefault(),(a=this.currentNativeSource)===null||a===void 0||a.loadDataTransfer(i.dataTransfer)):Cu(i.dataTransfer)&&i.preventDefault(),this.enterLeaveCounter.reset()},this.handleTopDrop=i=>{const{dropTargetIds:a}=this;this.dropTargetIds=[],this.actions.hover(a,{clientOffset:Zs(i)}),this.actions.drop({dropEffect:this.getCurrentDropEffect()}),this.isDraggingNativeItem()?this.endDragNativeItem():this.monitor.isDragging()&&this.actions.endDrag(),this.cancelHover()},this.handleSelectStart=i=>{const a=i.target;typeof a.dragDrop=="function"&&(a.tagName==="INPUT"||a.tagName==="SELECT"||a.tagName==="TEXTAREA"||a.isContentEditable||(i.preventDefault(),a.dragDrop()))},this.options=new class{get window(){return this.globalContext?this.globalContext:typeof window<"u"?window:void 0}get document(){var i;return!((i=this.globalContext)===null||i===void 0)&&i.document?this.globalContext.document:this.window?this.window.document:void 0}get rootElement(){var i;return((i=this.optionsArgs)===null||i===void 0?void 0:i.rootElement)||this.window}constructor(i,a){this.ownerDocument=null,this.globalContext=i,this.optionsArgs=a}}(r,n),this.actions=t.getActions(),this.monitor=t.getMonitor(),this.registry=t.getRegistry(),this.enterLeaveCounter=new G2(this.isNodeInDocument)}}const eC=function(e,t,r){return new J2(e,t,r)};var Gn;(function(e){e.mouse="mouse",e.touch="touch",e.keyboard="keyboard"})(Gn||(Gn={}));class tC{get delay(){var t;return(t=this.args.delay)!==null&&t!==void 0?t:0}get scrollAngleRanges(){return this.args.scrollAngleRanges}get getDropTargetElementsAtPoint(){return this.args.getDropTargetElementsAtPoint}get ignoreContextMenu(){var t;return(t=this.args.ignoreContextMenu)!==null&&t!==void 0&&t}get enableHoverOutsideTarget(){var t;return(t=this.args.enableHoverOutsideTarget)!==null&&t!==void 0&&t}get enableKeyboardEvents(){var t;return(t=this.args.enableKeyboardEvents)!==null&&t!==void 0&&t}get enableMouseEvents(){var t;return(t=this.args.enableMouseEvents)!==null&&t!==void 0&&t}get enableTouchEvents(){var t;return(t=this.args.enableTouchEvents)===null||t===void 0||t}get touchSlop(){return this.args.touchSlop||0}get delayTouchStart(){var t,r,n,i;return(i=(n=(t=this.args)===null||t===void 0?void 0:t.delayTouchStart)!==null&&n!==void 0?n:(r=this.args)===null||r===void 0?void 0:r.delay)!==null&&i!==void 0?i:0}get delayMouseStart(){var t,r,n,i;return(i=(n=(t=this.args)===null||t===void 0?void 0:t.delayMouseStart)!==null&&n!==void 0?n:(r=this.args)===null||r===void 0?void 0:r.delay)!==null&&i!==void 0?i:0}get window(){return this.context&&this.context.window?this.context.window:typeof window<"u"?window:void 0}get document(){var t;return!((t=this.context)===null||t===void 0)&&t.document?this.context.document:this.window?this.window.document:void 0}get rootElement(){var t;return((t=this.args)===null||t===void 0?void 0:t.rootElement)||this.document}constructor(t,r){this.args=t,this.context=r}}const rC=1,nC=0;function Eu(e){return e.button===void 0||e.button===nC}function c1(e){return!!e.targetTouches}function Go(e,t){return c1(e)?function(r,n){return r.targetTouches.length===1?Go(r.targetTouches[0]):n&&r.touches.length===1&&r.touches[0].target===n.target?Go(r.touches[0]):void 0}(e,t):{x:e.clientX,y:e.clientY}}const Qd=(()=>{let e=!1;try{addEventListener("test",()=>{},Object.defineProperty({},"passive",{get:()=>(e=!0,!0)}))}catch{}return e})(),Da={[Gn.mouse]:{start:"mousedown",move:"mousemove",end:"mouseup",contextmenu:"contextmenu"},[Gn.touch]:{start:"touchstart",move:"touchmove",end:"touchend"},[Gn.keyboard]:{keydown:"keydown"}};class Za{profile(){var t;return{sourceNodes:this.sourceNodes.size,sourcePreviewNodes:this.sourcePreviewNodes.size,sourcePreviewNodeOptions:this.sourcePreviewNodeOptions.size,targetNodes:this.targetNodes.size,dragOverTargetIds:((t=this.dragOverTargetIds)===null||t===void 0?void 0:t.length)||0}}get document(){return this.options.document}setup(){const t=this.options.rootElement;t&&(de(!Za.isSetUp,"Cannot have two Touch backends at the same time."),Za.isSetUp=!0,this.addEventListener(t,"start",this.getTopMoveStartHandler()),this.addEventListener(t,"start",this.handleTopMoveStartCapture,!0),this.addEventListener(t,"move",this.handleTopMove),this.addEventListener(t,"move",this.handleTopMoveCapture,!0),this.addEventListener(t,"end",this.handleTopMoveEndCapture,!0),this.options.enableMouseEvents&&!this.options.ignoreContextMenu&&this.addEventListener(t,"contextmenu",this.handleTopMoveEndCapture),this.options.enableKeyboardEvents&&this.addEventListener(t,"keydown",this.handleCancelOnEscape,!0))}teardown(){const t=this.options.rootElement;t&&(Za.isSetUp=!1,this._mouseClientOffset={},this.removeEventListener(t,"start",this.handleTopMoveStartCapture,!0),this.removeEventListener(t,"start",this.handleTopMoveStart),this.removeEventListener(t,"move",this.handleTopMoveCapture,!0),this.removeEventListener(t,"move",this.handleTopMove),this.removeEventListener(t,"end",this.handleTopMoveEndCapture,!0),this.options.enableMouseEvents&&!this.options.ignoreContextMenu&&this.removeEventListener(t,"contextmenu",this.handleTopMoveEndCapture),this.options.enableKeyboardEvents&&this.removeEventListener(t,"keydown",this.handleCancelOnEscape,!0),this.uninstallSourceNodeRemovalObserver())}addEventListener(t,r,n,i=!1){const a=Qd?{capture:i,passive:!1}:i;this.listenerTypes.forEach(function(s){const o=Da[s][r];o&&t.addEventListener(o,n,a)})}removeEventListener(t,r,n,i=!1){const a=Qd?{capture:i,passive:!1}:i;this.listenerTypes.forEach(function(s){const o=Da[s][r];o&&t.removeEventListener(o,n,a)})}connectDragSource(t,r){const n=this.handleMoveStart.bind(this,t);return this.sourceNodes.set(t,r),this.addEventListener(r,"start",n),()=>{this.sourceNodes.delete(t),this.removeEventListener(r,"start",n)}}connectDragPreview(t,r,n){return this.sourcePreviewNodeOptions.set(t,n),this.sourcePreviewNodes.set(t,r),()=>{this.sourcePreviewNodes.delete(t),this.sourcePreviewNodeOptions.delete(t)}}connectDropTarget(t,r){const n=this.options.rootElement;if(!this.document||!n)return()=>{};const i=a=>{if(!this.document||!n||!this.monitor.isDragging())return;let s;switch(a.type){case Da.mouse.move:s={x:a.clientX,y:a.clientY};break;case Da.touch.move:var o,l;s={x:((o=a.touches[0])===null||o===void 0?void 0:o.clientX)||0,y:((l=a.touches[0])===null||l===void 0?void 0:l.clientY)||0}}const u=s!=null?this.document.elementFromPoint(s.x,s.y):void 0,c=u&&r.contains(u);return u===r||c?this.handleMove(a,t):void 0};return this.addEventListener(this.document.body,"move",i),this.targetNodes.set(t,r),()=>{this.document&&(this.targetNodes.delete(t),this.removeEventListener(this.document.body,"move",i))}}getTopMoveStartHandler(){return this.options.delayTouchStart||this.options.delayMouseStart?this.handleTopMoveStartDelay:this.handleTopMoveStart}installSourceNodeRemovalObserver(t){this.uninstallSourceNodeRemovalObserver(),this.draggedSourceNode=t,this.draggedSourceNodeRemovalObserver=new MutationObserver(()=>{t&&!t.parentElement&&(this.resurrectSourceNode(),this.uninstallSourceNodeRemovalObserver())}),t&&t.parentElement&&this.draggedSourceNodeRemovalObserver.observe(t.parentElement,{childList:!0})}resurrectSourceNode(){this.document&&this.draggedSourceNode&&(this.draggedSourceNode.style.display="none",this.draggedSourceNode.removeAttribute("data-reactid"),this.document.body.appendChild(this.draggedSourceNode))}uninstallSourceNodeRemovalObserver(){this.draggedSourceNodeRemovalObserver&&this.draggedSourceNodeRemovalObserver.disconnect(),this.draggedSourceNodeRemovalObserver=void 0,this.draggedSourceNode=void 0}constructor(t,r,n){this.getSourceClientOffset=i=>{const a=this.sourceNodes.get(i);return a&&function(s){const o=s.nodeType===1?s:s.parentElement;if(!o)return;const{top:l,left:u}=o.getBoundingClientRect();return{x:u,y:l}}(a)},this.handleTopMoveStartCapture=i=>{Eu(i)&&(this.moveStartSourceIds=[])},this.handleMoveStart=i=>{Array.isArray(this.moveStartSourceIds)&&this.moveStartSourceIds.unshift(i)},this.handleTopMoveStart=i=>{if(!Eu(i))return;const a=Go(i);a&&(c1(i)&&(this.lastTargetTouchFallback=i.targetTouches[0]),this._mouseClientOffset=a),this.waitingForDelay=!1},this.handleTopMoveStartDelay=i=>{if(!Eu(i))return;const a=i.type===Da.touch.start?this.options.delayTouchStart:this.options.delayMouseStart;this.timeout=setTimeout(this.handleTopMoveStart.bind(this,i),a),this.waitingForDelay=!0},this.handleTopMoveCapture=()=>{this.dragOverTargetIds=[]},this.handleMove=(i,a)=>{this.dragOverTargetIds&&this.dragOverTargetIds.unshift(a)},this.handleTopMove=i=>{if(this.timeout&&clearTimeout(this.timeout),!this.document||this.waitingForDelay)return;const{moveStartSourceIds:a,dragOverTargetIds:s}=this,o=this.options.enableHoverOutsideTarget,l=Go(i,this.lastTargetTouchFallback);if(!l)return;if(this._isScrolling||!this.monitor.isDragging()&&function(m,S,B,R,L){if(!L)return!1;const M=180*Math.atan2(R-S,B-m)/Math.PI+180;for(let V=0;V=Q.start)&&(Q.end==null||M<=Q.end))return!0}return!1}(this._mouseClientOffset.x||0,this._mouseClientOffset.y||0,l.x,l.y,this.options.scrollAngleRanges))return void(this._isScrolling=!0);var u,c,f,d;if(!this.monitor.isDragging()&&this._mouseClientOffset.hasOwnProperty("x")&&a&&(u=this._mouseClientOffset.x||0,c=this._mouseClientOffset.y||0,f=l.x,d=l.y,Math.sqrt(Math.pow(Math.abs(f-u),2)+Math.pow(Math.abs(d-c),2))>(this.options.touchSlop?this.options.touchSlop:0))&&(this.moveStartSourceIds=void 0,this.actions.beginDrag(a,{clientOffset:this._mouseClientOffset,getSourceClientOffset:this.getSourceClientOffset,publishSource:!1})),!this.monitor.isDragging())return;const v=this.sourceNodes.get(this.monitor.getSourceId());this.installSourceNodeRemovalObserver(v),this.actions.publishDragSource(),i.cancelable&&i.preventDefault();const g=(s||[]).map(m=>this.targetNodes.get(m)).filter(m=>!!m),C=this.options.getDropTargetElementsAtPoint?this.options.getDropTargetElementsAtPoint(l.x,l.y,g):this.document.elementsFromPoint(l.x,l.y),I=[];for(const m in C){if(!C.hasOwnProperty(m))continue;let S=C[m];for(S!=null&&I.push(S);S;)S=S.parentElement,S&&I.indexOf(S)===-1&&I.push(S)}const y=I.filter(m=>g.indexOf(m)>-1).map(m=>this._getDropTargetId(m)).filter(m=>!!m).filter((m,S,B)=>B.indexOf(m)===S);if(o)for(const m in this.targetNodes){const S=this.targetNodes.get(m);if(v&&S&&S.contains(v)&&y.indexOf(m)===-1){y.unshift(m);break}}y.reverse(),this.actions.hover(y,{clientOffset:l})},this._getDropTargetId=i=>{const a=this.targetNodes.keys();let s=a.next();for(;s.done===!1;){const o=s.value;if(i===this.targetNodes.get(o))return o;s=a.next()}},this.handleTopMoveEndCapture=i=>{this._isScrolling=!1,this.lastTargetTouchFallback=void 0,function(a){return a.buttons===void 0||(a.buttons&rC)==0}(i)&&(this.monitor.isDragging()&&!this.monitor.didDrop()?(i.cancelable&&i.preventDefault(),this._mouseClientOffset={},this.uninstallSourceNodeRemovalObserver(),this.actions.drop(),this.actions.endDrag()):this.moveStartSourceIds=void 0)},this.handleCancelOnEscape=i=>{i.key==="Escape"&&this.monitor.isDragging()&&(this._mouseClientOffset={},this.uninstallSourceNodeRemovalObserver(),this.actions.endDrag())},this.options=new tC(n,r),this.actions=t.getActions(),this.monitor=t.getMonitor(),this.sourceNodes=new Map,this.sourcePreviewNodes=new Map,this.sourcePreviewNodeOptions=new Map,this.targetNodes=new Map,this.listenerTypes=[],this._mouseClientOffset={},this._isScrolling=!1,this.options.enableMouseEvents&&this.listenerTypes.push(Gn.mouse),this.options.enableTouchEvents&&this.listenerTypes.push(Gn.touch),this.options.enableKeyboardEvents&&this.listenerTypes.push(Gn.keyboard)}}const iC=function(e,t={},r={}){return new Za(e,t,r)},Es="abcdefgh".split(""),mo={a8:"bR",b8:"bN",c8:"bB",d8:"bQ",e8:"bK",f8:"bB",g8:"bN",h8:"bR",a7:"bP",b7:"bP",c7:"bP",d7:"bP",e7:"bP",f7:"bP",g7:"bP",h7:"bP",a2:"wP",b2:"wP",c2:"wP",d2:"wP",e2:"wP",f2:"wP",g2:"wP",h2:"wP",a1:"wR",b1:"wN",c1:"wB",d1:"wQ",e1:"wK",f1:"wB",g1:"wN",h1:"wR"},aC={a:0,b:1,c:2,d:3,e:4,f:5,g:6,h:7},sC={a:7,b:6,c:5,d:4,e:3,f:2,g:1,h:0},oC=[7,6,5,4,3,2,1,0],lC=[0,1,2,3,4,5,6,7],Wd={wP:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsx("path",{d:"m 22.5,9 c -2.21,0 -4,1.79 -4,4 0,0.89 0.29,1.71 0.78,2.38 C 17.33,16.5 16,18.59 16,21 c 0,2.03 0.94,3.84 2.41,5.03 C 15.41,27.09 11,31.58 11,39.5 H 34 C 34,31.58 29.59,27.09 26.59,26.03 28.06,24.84 29,23.03 29,21 29,18.59 27.67,16.5 25.72,15.38 26.21,14.71 26.5,13.89 26.5,13 c 0,-2.21 -1.79,-4 -4,-4 z",style:{opacity:"1",fill:"#ffffff",fillOpacity:"1",fillRule:"nonzero",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"miter",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}})})),wR:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{opacity:"1",fill:"#ffffff",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[D.jsx("path",{d:"M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 z ",style:{strokeLinecap:"butt"}}),D.jsx("path",{d:"M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 z ",style:{strokeLinecap:"butt"}}),D.jsx("path",{d:"M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14",style:{strokeLinecap:"butt"}}),D.jsx("path",{d:"M 34,14 L 31,17 L 14,17 L 11,14"}),D.jsx("path",{d:"M 31,17 L 31,29.5 L 14,29.5 L 14,17",style:{strokeLinecap:"butt",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 31,29.5 L 32.5,32 L 12.5,32 L 14,29.5"}),D.jsx("path",{d:"M 11,14 L 34,14",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}})]}))})),wN:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{opacity:"1",fill:"none",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[D.jsx("path",{d:"M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18",style:{fill:"#ffffff",stroke:"#000000"}}),D.jsx("path",{d:"M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10",style:{fill:"#ffffff",stroke:"#000000"}}),D.jsx("path",{d:"M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z",style:{fill:"#000000",stroke:"#000000"}}),D.jsx("path",{d:"M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z",transform:"matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)",style:{fill:"#000000",stroke:"#000000"}})]}))})),wB:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{opacity:"1",fill:"none",fillRule:"evenodd",fillOpacity:"1",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[D.jsxs("g",Object.assign({style:{fill:"#ffffff",stroke:"#000000",strokeLinecap:"butt"}},{children:[D.jsx("path",{d:"M 9,36 C 12.39,35.03 19.11,36.43 22.5,34 C 25.89,36.43 32.61,35.03 36,36 C 36,36 37.65,36.54 39,38 C 38.32,38.97 37.35,38.99 36,38.5 C 32.61,37.53 25.89,38.96 22.5,37.5 C 19.11,38.96 12.39,37.53 9,38.5 C 7.65,38.99 6.68,38.97 6,38 C 7.35,36.54 9,36 9,36 z"}),D.jsx("path",{d:"M 15,32 C 17.5,34.5 27.5,34.5 30,32 C 30.5,30.5 30,30 30,30 C 30,27.5 27.5,26 27.5,26 C 33,24.5 33.5,14.5 22.5,10.5 C 11.5,14.5 12,24.5 17.5,26 C 17.5,26 15,27.5 15,30 C 15,30 14.5,30.5 15,32 z"}),D.jsx("path",{d:"M 25 8 A 2.5 2.5 0 1 1 20,8 A 2.5 2.5 0 1 1 25 8 z"})]})),D.jsx("path",{d:"M 17.5,26 L 27.5,26 M 15,30 L 30,30 M 22.5,15.5 L 22.5,20.5 M 20,18 L 25,18",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}})]}))})),wQ:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{fill:"#ffffff",stroke:"#000000",strokeWidth:"1.5",strokeLinejoin:"round"}},{children:[D.jsx("path",{d:"M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.7,10.9 L 25.5,24.5 L 22.5,10 L 19.5,24.5 L 14.3,10.9 L 14,25 L 6.5,13.5 L 9,26 z"}),D.jsx("path",{d:"M 9,26 C 9,28 10.5,28 11.5,30 C 12.5,31.5 12.5,31 12,33.5 C 10.5,34.5 11,36 11,36 C 9.5,37.5 11,38.5 11,38.5 C 17.5,39.5 27.5,39.5 34,38.5 C 34,38.5 35.5,37.5 34,36 C 34,36 34.5,34.5 33,33.5 C 32.5,31 32.5,31.5 33.5,30 C 34.5,28 36,28 36,26 C 27.5,24.5 17.5,24.5 9,26 z"}),D.jsx("path",{d:"M 11.5,30 C 15,29 30,29 33.5,30",style:{fill:"none"}}),D.jsx("path",{d:"M 12,33.5 C 18,32.5 27,32.5 33,33.5",style:{fill:"none"}}),D.jsx("circle",{cx:"6",cy:"12",r:"2"}),D.jsx("circle",{cx:"14",cy:"9",r:"2"}),D.jsx("circle",{cx:"22.5",cy:"8",r:"2"}),D.jsx("circle",{cx:"31",cy:"9",r:"2"}),D.jsx("circle",{cx:"39",cy:"12",r:"2"})]}))})),wK:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{fill:"none",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[D.jsx("path",{d:"M 22.5,11.63 L 22.5,6",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 20,8 L 25,8",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25",style:{fill:"#ffffff",stroke:"#000000",strokeLinecap:"butt",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 12.5,37 C 18,40.5 27,40.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 20,16 10.5,13 6.5,19.5 C 3.5,25.5 12.5,30 12.5,30 L 12.5,37",style:{fill:"#ffffff",stroke:"#000000"}}),D.jsx("path",{d:"M 12.5,30 C 18,27 27,27 32.5,30",style:{fill:"none",stroke:"#000000"}}),D.jsx("path",{d:"M 12.5,33.5 C 18,30.5 27,30.5 32.5,33.5",style:{fill:"none",stroke:"#000000"}}),D.jsx("path",{d:"M 12.5,37 C 18,34 27,34 32.5,37",style:{fill:"none",stroke:"#000000"}})]}))})),bP:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsx("path",{d:"m 22.5,9 c -2.21,0 -4,1.79 -4,4 0,0.89 0.29,1.71 0.78,2.38 C 17.33,16.5 16,18.59 16,21 c 0,2.03 0.94,3.84 2.41,5.03 C 15.41,27.09 11,31.58 11,39.5 H 34 C 34,31.58 29.59,27.09 26.59,26.03 28.06,24.84 29,23.03 29,21 29,18.59 27.67,16.5 25.72,15.38 26.21,14.71 26.5,13.89 26.5,13 c 0,-2.21 -1.79,-4 -4,-4 z",style:{opacity:"1",fill:"#000000",fillOpacity:"1",fillRule:"nonzero",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"miter",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}})})),bR:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{opacity:"1",fill:"#000000",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[D.jsx("path",{d:"M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 z ",style:{strokeLinecap:"butt"}}),D.jsx("path",{d:"M 12.5,32 L 14,29.5 L 31,29.5 L 32.5,32 L 12.5,32 z ",style:{strokeLinecap:"butt"}}),D.jsx("path",{d:"M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 z ",style:{strokeLinecap:"butt"}}),D.jsx("path",{d:"M 14,29.5 L 14,16.5 L 31,16.5 L 31,29.5 L 14,29.5 z ",style:{strokeLinecap:"butt",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 14,16.5 L 11,14 L 34,14 L 31,16.5 L 14,16.5 z ",style:{strokeLinecap:"butt"}}),D.jsx("path",{d:"M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14 L 11,14 z ",style:{strokeLinecap:"butt"}}),D.jsx("path",{d:"M 12,35.5 L 33,35.5 L 33,35.5",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 13,31.5 L 32,31.5",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 14,29.5 L 31,29.5",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 14,16.5 L 31,16.5",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 11,14 L 34,14",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}})]}))})),bN:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{opacity:"1",fill:"none",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[D.jsx("path",{d:"M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18",style:{fill:"#000000",stroke:"#000000"}}),D.jsx("path",{d:"M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10",style:{fill:"#000000",stroke:"#000000"}}),D.jsx("path",{d:"M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z",style:{fill:"#ffffff",stroke:"#ffffff"}}),D.jsx("path",{d:"M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z",transform:"matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)",style:{fill:"#ffffff",stroke:"#ffffff"}}),D.jsx("path",{d:"M 24.55,10.4 L 24.1,11.85 L 24.6,12 C 27.75,13 30.25,14.49 32.5,18.75 C 34.75,23.01 35.75,29.06 35.25,39 L 35.2,39.5 L 37.45,39.5 L 37.5,39 C 38,28.94 36.62,22.15 34.25,17.66 C 31.88,13.17 28.46,11.02 25.06,10.5 L 24.55,10.4 z ",style:{fill:"#ffffff",stroke:"none"}})]}))})),bB:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{opacity:"1",fill:"none",fillRule:"evenodd",fillOpacity:"1",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[D.jsxs("g",Object.assign({style:{fill:"#000000",stroke:"#000000",strokeLinecap:"butt"}},{children:[D.jsx("path",{d:"M 9,36 C 12.39,35.03 19.11,36.43 22.5,34 C 25.89,36.43 32.61,35.03 36,36 C 36,36 37.65,36.54 39,38 C 38.32,38.97 37.35,38.99 36,38.5 C 32.61,37.53 25.89,38.96 22.5,37.5 C 19.11,38.96 12.39,37.53 9,38.5 C 7.65,38.99 6.68,38.97 6,38 C 7.35,36.54 9,36 9,36 z"}),D.jsx("path",{d:"M 15,32 C 17.5,34.5 27.5,34.5 30,32 C 30.5,30.5 30,30 30,30 C 30,27.5 27.5,26 27.5,26 C 33,24.5 33.5,14.5 22.5,10.5 C 11.5,14.5 12,24.5 17.5,26 C 17.5,26 15,27.5 15,30 C 15,30 14.5,30.5 15,32 z"}),D.jsx("path",{d:"M 25 8 A 2.5 2.5 0 1 1 20,8 A 2.5 2.5 0 1 1 25 8 z"})]})),D.jsx("path",{d:"M 17.5,26 L 27.5,26 M 15,30 L 30,30 M 22.5,15.5 L 22.5,20.5 M 20,18 L 25,18",style:{fill:"none",stroke:"#ffffff",strokeLinejoin:"miter"}})]}))})),bQ:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{fill:"#000000",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}},{children:[D.jsx("path",{d:"M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.7,10.9 L 25.5,24.5 L 22.5,10 L 19.5,24.5 L 14.3,10.9 L 14,25 L 6.5,13.5 L 9,26 z",style:{strokeLinecap:"butt",fill:"#000000"}}),D.jsx("path",{d:"m 9,26 c 0,2 1.5,2 2.5,4 1,1.5 1,1 0.5,3.5 -1.5,1 -1,2.5 -1,2.5 -1.5,1.5 0,2.5 0,2.5 6.5,1 16.5,1 23,0 0,0 1.5,-1 0,-2.5 0,0 0.5,-1.5 -1,-2.5 -0.5,-2.5 -0.5,-2 0.5,-3.5 1,-2 2.5,-2 2.5,-4 -8.5,-1.5 -18.5,-1.5 -27,0 z"}),D.jsx("path",{d:"M 11.5,30 C 15,29 30,29 33.5,30"}),D.jsx("path",{d:"m 12,33.5 c 6,-1 15,-1 21,0"}),D.jsx("circle",{cx:"6",cy:"12",r:"2"}),D.jsx("circle",{cx:"14",cy:"9",r:"2"}),D.jsx("circle",{cx:"22.5",cy:"8",r:"2"}),D.jsx("circle",{cx:"31",cy:"9",r:"2"}),D.jsx("circle",{cx:"39",cy:"12",r:"2"}),D.jsx("path",{d:"M 11,38.5 A 35,35 1 0 0 34,38.5",style:{fill:"none",stroke:"#000000",strokeLinecap:"butt"}}),D.jsxs("g",Object.assign({style:{fill:"none",stroke:"#ffffff"}},{children:[D.jsx("path",{d:"M 11,29 A 35,35 1 0 1 34,29"}),D.jsx("path",{d:"M 12.5,31.5 L 32.5,31.5"}),D.jsx("path",{d:"M 11.5,34.5 A 35,35 1 0 0 33.5,34.5"}),D.jsx("path",{d:"M 10.5,37.5 A 35,35 1 0 0 34.5,37.5"})]}))]}))})),bK:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:D.jsxs("g",Object.assign({style:{fill:"none",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[D.jsx("path",{d:"M 22.5,11.63 L 22.5,6",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"},id:"path6570"}),D.jsx("path",{d:"M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25",style:{fill:"#000000",fillOpacity:"1",strokeLinecap:"butt",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 12.5,37 C 18,40.5 27,40.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 20,16 10.5,13 6.5,19.5 C 3.5,25.5 12.5,30 12.5,30 L 12.5,37",style:{fill:"#000000",stroke:"#000000"}}),D.jsx("path",{d:"M 20,8 L 25,8",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}}),D.jsx("path",{d:"M 32,29.5 C 32,29.5 40.5,25.5 38.03,19.85 C 34.15,14 25,18 22.5,24.5 L 22.5,26.6 L 22.5,24.5 C 20,18 10.85,14 6.97,19.85 C 4.5,25.5 13,29.5 13,29.5",style:{fill:"none",stroke:"#ffffff"}}),D.jsx("path",{d:"M 12.5,30 C 18,27 27,27 32.5,30 M 12.5,33.5 C 18,30.5 27,30.5 32.5,33.5 M 12.5,37 C 18,34 27,34 32.5,37",style:{fill:"none",stroke:"#ffffff"}})]}))}))};function kc(e,t,r){const n=t/8,i=e==="white"?oC:lC;return{x:(e==="white"?aC:sC)[r[0]]*n+n/2,y:i[parseInt(r[1],10)-1]*n+n/2}}function Yd(e){let t=!1;return Object.keys(mo).forEach(r=>{e[r]!==mo[r]&&(t=!0)}),Object.keys(e).forEach(r=>{mo[r]!==e[r]&&(t=!0)}),t}function Xd(e){return e==="start"?mo:typeof e=="string"?function(t){if(!function(a){a=a.replace(/ .+$/,""),a=function(o){return o.replace(/8/g,"11111111").replace(/7/g,"1111111").replace(/6/g,"111111").replace(/5/g,"11111").replace(/4/g,"1111").replace(/3/g,"111").replace(/2/g,"11")}(a);const s=a.split("/");if(s.length!==8)return!1;for(let o=0;o<8;o++)if(s[o].length!==8||s[o].search(/[^kqrnbpKQRNBP1]/)!==-1)return!1;return!0}(t))return{};const r=(t=t.replace(/ .+$/,"")).split("/"),n={};let i=8;for(let a=0;a<8;a++){const s=r[a].split("");let o=0;for(let l=0;lq.useContext(f1),cC=q.forwardRef(({animationDuration:e=300,areArrowsAllowed:t=!0,arePiecesDraggable:r=!0,arePremovesAllowed:n=!1,boardOrientation:i="white",boardWidth:a,children:s,clearPremovesOnRightClick:o=!0,customArrows:l,customArrowColor:u="rgb(255,170,0)",customBoardStyle:c,customDarkSquareStyle:f={backgroundColor:"#B58863"},customDropSquareStyle:d={boxShadow:"inset 0 0 1px 6px rgba(255,255,255,0.75)"},customLightSquareStyle:v={backgroundColor:"#F0D9B5"},customPieces:g,customPremoveDarkSquareStyle:C={backgroundColor:"#A42323"},customPremoveLightSquareStyle:I={backgroundColor:"#BD2828"},customSquare:y="div",customSquareStyles:m,dropOffBoardAction:S="snapback",id:B=0,isDraggablePiece:R=()=>!0,getPositionObject:L=()=>{},onArrowsChange:M=()=>{},onDragOverSquare:V=()=>{},onMouseOutSquare:Q=()=>{},onMouseOverSquare:G=()=>{},onPieceClick:ce=()=>{},onPieceDragBegin:pe=()=>{},onPieceDragEnd:De=()=>{},onPieceDrop:Ue=()=>!0,onPromotionCheck:Ce=(ke,be,Qe)=>(Qe==="wP"&&ke[1]==="7"&&be[1]==="8"||Qe==="bP"&&ke[1]==="2"&&be[1]==="1")&&Math.abs(ke.charCodeAt(0)-be.charCodeAt(0))<=1,onPromotionPieceSelect:Le,onSquareClick:te=()=>{},onSquareRightClick:W=()=>{},position:ae="start",promotionDialogVariant:ne="default",promotionToSquare:ee=null,showBoardNotation:ie=!0,showPromotionDialog:Oe=!1,snapToCursor:se=!0,autoPromoteToQueen:Fe=!1},Re)=>{const[ke,be]=q.useState(Xd(ae)),[Qe,ct]=q.useState({removed:{},added:{}}),[ot,je]=q.useState(void 0),[We,Ke]=q.useState(Oe&&!Fe),[ht,Ns]=q.useState(null),[Ea,Sa]=q.useState(ee),[Ds,Ai]=q.useState([]),tr=q.useRef(Ds),[Gt,En]=q.useState(),[Ll,Kr]=q.useState(Object.assign(Object.assign({},Wd),g)),[Ol,w]=q.useState(!1),[h,p]=q.useState(),[_,N]=q.useState(!1);q.useImperativeHandle(Re,()=>({clearPremoves(Ye=!0){Ne(Ye)}})),q.useEffect(()=>{Kr(Object.assign(Object.assign({},Wd),g))},[g]),q.useEffect(()=>{Ke(Oe),Sa(ee)},[ee,Oe]),q.useEffect(()=>{var Ye,mt,At;Pl();const hr=Xd(ae),Dr=function(gr,Sn){const xa={removed:{},added:{}};return Object.keys(gr).forEach(rr=>{Sn[rr]!==gr[rr]&&(xa.removed[rr]=gr[rr])}),Object.keys(Sn).forEach(rr=>{gr[rr]!==Sn[rr]&&(xa.added[rr]=Sn[rr])}),xa}(ke,hr),pr=((Ye=Object.keys(Dr.added))===null||Ye===void 0?void 0:Ye.length)<=2?(At=(mt=Object.entries(Dr.added))===null||mt===void 0?void 0:mt[0])===null||At===void 0?void 0:At[1][0]:void 0;if(_)be(hr),N(!1),n&&He(pr),h&&clearTimeout(h);else if(Ol)be(hr),N(!1),n&&He(pr);else{Yd(hr)&&ot!==void 0?je(pr):Yd(hr)?je(void 0):je("b"),ct(Dr),N(!0);const gr=setTimeout(()=>{be(hr),N(!1),n&&He(pr)},e);p(gr)}return w(!1),L(hr),ge(),()=>{clearTimeout(h)}},[ae]);const{arrows:P,newArrow:F,clearArrows:ge,drawNewArrow:tt,onArrowDrawEnd:ze}=((Ye,mt=!0,At,hr)=>{const[Dr,pr]=q.useState([]),[gr,Sn]=q.useState([]),[xa,rr]=q.useState();q.useEffect(()=>{Array.isArray(Ye)&&pr(Ye==null?void 0:Ye.filter(nn=>nn[0]!==nn[1]))},[Ye]),q.useEffect(()=>{At==null||At(gr)},[gr]);const m0=[...gr,...Dr];return{arrows:m0,newArrow:xa,clearArrows:function(){Sn([]),rr(void 0)},drawNewArrow:(nn,Bi)=>{mt&&rr([nn,Bi,hr])},setArrows:Sn,onArrowDrawEnd:(nn,Bi)=>{if(nn===Bi)return;let C0;const cv=[nn,Bi,hr];C0=m0.every(([Ul,Ml])=>!(Ul===nn&&Ml===Bi))?[...gr,cv]:gr.filter(([Ul,Ml])=>!(Ul===nn&&Ml===Bi)),rr(void 0),Sn(C0)}}})(l,t,M,u);function He(Ye){if(tr.current.length===0)return;const mt=tr.current[0];if(mt.piece[0]!==void 0&&mt.piece[0]!==Ye&&Ue.length)if(je(mt.piece[0]),w(!0),Ue(mt.sourceSq,mt.targetSq,mt.piece)){const At=[...tr.current];At.shift(),tr.current=At,Ai([...At])}else Ne()}function Ne(Ye=!0){Ye&&je(void 0),tr.current=[],Ai([])}function Pl(){Ns(null),Sa(null),Ke(!1)}const uv={animationDuration:e,arePiecesDraggable:r,arePremovesAllowed:n,boardOrientation:i,boardWidth:a,customArrowColor:u,customBoardStyle:c,customDarkSquareStyle:f,customDropSquareStyle:d,customLightSquareStyle:v,customPremoveDarkSquareStyle:C,customPremoveLightSquareStyle:I,customSquare:y,customSquareStyles:m,id:B,isDraggablePiece:R,onDragOverSquare:V,onMouseOutSquare:Q,onMouseOverSquare:G,onPieceClick:ce,onPieceDragBegin:pe,onPieceDragEnd:De,onPieceDrop:Ue,onPromotionCheck:Ce,onPromotionPieceSelect:Le,onSquareClick:te,showBoardNotation:ie,snapToCursor:se,promotionDialogVariant:ne,arrows:P,newArrow:F,onArrowDrawEnd:ze,chessPieces:Ll,clearArrows:ge,drawNewArrow:tt,clearCurrentRightClickDown:function(){En(void 0)},currentPosition:ke,handleSetPosition:function(Ye,mt,At,hr){if(Ye===mt)return;if(ge(),n&&_||n&&(ot===At[0]||tr.current.filter(pr=>pr.piece[0]===At[0]).length>0)){const pr=[...tr.current];return pr.push({sourceSq:Ye,targetSq:mt,piece:At}),tr.current=pr,Ai([...pr]),void Pl()}if(!n&&_)return;const Dr=Object.assign({},ke);w(!!hr),je(At[0]),Ue.length?Ue(Ye,mt,At)||Ne():(S!=="trash"||mt||delete Dr[Ye],delete Dr[Ye],Dr[mt]=At,be(Dr)),Pl(),L(Dr)},isWaitingForAnimation:_,lastPieceColour:ot,onRightClickDown:function(Ye){En(Ye)},onRightClickUp:function(Ye){if(Gt){if(Gt===Ye)return En(void 0),o&&Ne(!1),void W(Ye)}else En(void 0)},positionDifferences:Qe,promoteFromSquare:ht,promoteToSquare:Ea,premoves:Ds,setPromoteFromSquare:Ns,setPromoteToSquare:Sa,setShowPromoteDialog:Ke,showPromoteDialog:We,autoPromoteToQueen:Fe,currentRightClickDown:Gt};return D.jsx(f1.Provider,Object.assign({value:uv},{children:s}))});function fC({row:e,col:t}){const{boardOrientation:r,boardWidth:n,customDarkSquareStyle:i,customLightSquareStyle:a}=Cn(),s=a.backgroundColor,o=i.backgroundColor,l=t===0,u=e===7;function c(){return r==="white"?8-e:e+1}function f(){return r==="black"?Es[7-t]:Es[t]}return l&&u?D.jsxs(D.Fragment,{children:[D.jsx("div",Object.assign({style:Object.assign(Object.assign({zIndex:3,position:"absolute"},{color:s}),Jd(n))},{children:c()})),D.jsx("div",Object.assign({style:Object.assign(Object.assign({zIndex:3,position:"absolute"},{color:s}),Zd(n))},{children:f()}))]}):u?D.jsx("div",Object.assign({style:Object.assign(Object.assign({userSelect:"none",zIndex:3,position:"absolute"},{color:t%2!=0?o:s}),Zd(n))},{children:f()})):l?D.jsx("div",Object.assign({style:Object.assign(Object.assign({userSelect:"none",zIndex:3,position:"absolute"},{color:e%2==0?o:s}),Jd(n))},{children:c()})):null}const Zd=e=>({alignSelf:"flex-end",paddingLeft:e/8-e/48,fontSize:e/48}),Jd=e=>({alignSelf:"flex-start",paddingRight:e/8-e/48,fontSize:e/48});function eh({isPremovedPiece:e=!1,piece:t,square:r,squares:n}){const{animationDuration:i,arePiecesDraggable:a,arePremovesAllowed:s,boardWidth:o,boardOrientation:l,chessPieces:u,currentPosition:c,id:f,isDraggablePiece:d,isWaitingForAnimation:v,onPieceClick:g,onPieceDragBegin:C,onPieceDragEnd:I,positionDifferences:y,premoves:m}=Cn(),[S,B]=q.useState({opacity:1,zIndex:5,touchAction:"none",cursor:a&&d({piece:t,sourceSquare:r})?"-webkit-grab":"default"}),[{canDrag:R,isDragging:L},M,V]=K2(()=>({type:"piece",item:()=>(C(t,r),{piece:t,square:r,id:f}),end:()=>I(t,r),collect:Q=>({canDrag:d({piece:t,sourceSquare:r}),isDragging:!!Q.isDragging()})}),[t,r,c,f]);return V((Js||(Js=new Image,Js.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="),Js),{captureDraggingState:!0}),q.useEffect(()=>{B(Q=>Object.assign(Object.assign({},Q),{opacity:L?0:1}))},[L]),q.useEffect(()=>{if(!s)return;let Q=!1;!e&&m.find(G=>G.targetSq===r)&&(Q=!0),m.find(G=>G.sourceSq===r&&G.piece===t)&&(Q=!0),B(G=>Object.assign(Object.assign({},G),{display:Q?"none":"unset"}))},[c,m]),q.useEffect(()=>{var Q;const G=(Q=y.removed)===null||Q===void 0?void 0:Q[r];if(!y.added)return;const ce=Object.entries(y.added).find(([pe,De])=>De===G||(G==null?void 0:G[1])==="P"&&(pe[1]==="1"||pe[1]==="8"));if(v&&G&&ce&&!e){const pe=r,De=ce[0];if(pe&&De){const Ue=o/8;B(Ce=>Object.assign(Object.assign({},Ce),{transform:`translate(${(l==="black"?-1:1)*(De.charCodeAt(0)-pe.charCodeAt(0))*Ue}px, ${(l==="black"?-1:1)*(Number(pe[1])-Number(De[1]))*Ue}px)`,transition:`transform ${i}ms`,zIndex:6}))}}},[y]),q.useEffect(()=>{const{sourceSq:Q}={sourceSq:n[r]};Q&&B(G=>Object.assign(Object.assign({},G),{transform:"translate(0px, 0px)",transition:"transform 0ms"}))},[c]),q.useEffect(()=>{B(Q=>Object.assign(Object.assign({},Q),{cursor:a&&d({piece:t,sourceSquare:r})?"-webkit-grab":"default"}))},[r,c,a]),D.jsx("div",Object.assign({ref:a&&R?M:null,onClick:()=>g(t),"data-piece":t,style:S},{children:typeof u[t]=="function"?u[t]({squareWidth:o/8,isDragging:L,square:r}):D.jsx("svg",Object.assign({viewBox:"1 1 43 43",width:o/8,height:o/8},{children:D.jsx("g",{children:u[t]})}))}))}function dC({square:e,squareColor:t,setSquares:r,squareHasPremove:n,children:i}){const a=q.useRef(null),{autoPromoteToQueen:s,boardWidth:o,boardOrientation:l,clearArrows:u,currentPosition:c,currentRightClickDown:f,customBoardStyle:d,customDarkSquareStyle:v,customDropSquareStyle:g,customLightSquareStyle:C,customPremoveDarkSquareStyle:I,customPremoveLightSquareStyle:y,customSquare:m,customSquareStyles:S,drawNewArrow:B,handleSetPosition:R,isWaitingForAnimation:L,lastPieceColour:M,onArrowDrawEnd:V,onDragOverSquare:Q,onMouseOutSquare:G,onMouseOverSquare:ce,onPieceDrop:pe,onPromotionCheck:De,onRightClickDown:Ue,onRightClickUp:Ce,onSquareClick:Le,setPromoteFromSquare:te,setPromoteToSquare:W,setShowPromoteDialog:ae}=Cn(),[{isOver:ne},ee]=$2(()=>({accept:"piece",drop:ie,collect:se=>({isOver:!!se.isOver()})}),[e,c,pe,L,M]);function ie(se){De(se.square,e,se.piece)?s?R(se.square,e,se.piece[0]==="w"?"wQ":"bQ"):(te(se.square),W(e),ae(!0)):R(se.square,e,se.piece,!0)}q.useEffect(()=>{if(a.current){const{x:se,y:Fe}=a.current.getBoundingClientRect();r(Re=>Object.assign(Object.assign({},Re),{[e]:{x:se,y:Fe}}))}},[o,l]);const Oe=Object.assign(Object.assign(Object.assign(Object.assign({},hC(e,l,d)),t==="black"?v:C),n&&(t==="black"?I:y)),ne&&g);return D.jsx("div",Object.assign({ref:ee,style:Oe,"data-square-color":t,"data-square":e,onMouseOver:se=>{se.buttons===2&&f&&B(f,e),se.relatedTarget&&se.currentTarget.contains(se.relatedTarget)||ce(e)},onMouseOut:se=>{se.relatedTarget&&se.currentTarget.contains(se.relatedTarget)||G(e)},onMouseDown:se=>{se.button===2&&Ue(e)},onMouseUp:se=>{se.button===2&&(f&&V(f,e),Ce(e))},onDragEnter:()=>Q(e),onClick:()=>{Le(e),u()},onContextMenu:se=>{se.preventDefault()}},{children:D.jsx(m,typeof m=="string"?Object.assign({ref:a,style:Object.assign(Object.assign(Object.assign({},rh(o)),th),!n&&(S==null?void 0:S[e]))},{children:i}):Object.assign({ref:a,square:e,squareColor:t,style:Object.assign(Object.assign(Object.assign({},rh(o)),th),!n&&(S==null?void 0:S[e]))},{children:i}))}))}const th={display:"flex",justifyContent:"center"},rh=e=>({width:e/8,height:e/8}),hC=(e,t,r)=>r!=null&&r.borderRadius?e==="a1"?t==="white"?{borderBottomLeftRadius:r.borderRadius}:{borderTopRightRadius:r.borderRadius}:e==="a8"?t==="white"?{borderTopLeftRadius:r.borderRadius}:{borderBottomRightRadius:r.borderRadius}:e==="h1"?t==="white"?{borderBottomRightRadius:r.borderRadius}:{borderTopLeftRadius:r.borderRadius}:e==="h8"?t==="white"?{borderTopRightRadius:r.borderRadius}:{borderBottomLeftRadius:r.borderRadius}:{}:{};function pC(){const[e,t]=q.useState({}),{boardOrientation:r,boardWidth:n,currentPosition:i,id:a,premoves:s,showBoardNotation:o}=Cn();return D.jsx("div",Object.assign({"data-boardid":a},{children:[...Array(8)].map((l,u)=>D.jsx("div",Object.assign({style:{display:"flex",flexWrap:"nowrap",width:n}},{children:[...Array(8)].map((c,f)=>{const d=r==="black"?Es[7-f]+(u+1):Es[f]+(8-u),v=f%2==u%2?"white":"black",g=s.find(I=>I.sourceSq===d||I.targetSq===d),C=s.find(I=>I.targetSq===d);return D.jsxs(dC,Object.assign({square:d,squareColor:v,setSquares:t,squareHasPremove:!!g},{children:[i[d]&&D.jsx(eh,{piece:i[d],square:d,squares:e}),C&&D.jsx(eh,{isPremovedPiece:!0,piece:C.piece,square:d,squares:e}),o&&D.jsx(fC,{row:u,col:f})]}),`${f}${u}`)})}),u.toString()))}))}const gC=()=>{const{arrows:e,newArrow:t,boardOrientation:r,boardWidth:n,customArrowColor:i}=Cn(),a=[...e,t].filter(Boolean);return D.jsx("svg",Object.assign({width:n,height:n,style:{position:"absolute",top:"0",left:"0",pointerEvents:"none",zIndex:"10"}},{children:a.map((s,o)=>{const[l,u,c]=s;if(l===u)return null;const f=kc(r,n,l),d=kc(r,n,u);let v=n/32;const g=o===e.length;e.some(S=>S[0]!==l&&S[1]===u)&&!g&&(v=n/16);const C=d.x-f.x,I=d.y-f.y,y=Math.hypot(I,C),m={x:f.x+C*(y-v)/y,y:f.y+I*(y-v)/y};return D.jsxs(q.Fragment,{children:[D.jsx("marker",Object.assign({id:`arrowhead-${o}`,markerWidth:"2",markerHeight:"2.5",refX:"1.25",refY:"1.25",orient:"auto"},{children:D.jsx("polygon",{points:"0.3 0, 2 1.25, 0.3 2.5",fill:c??i})})),D.jsx("line",{x1:f.x,y1:f.y,x2:m.x,y2:m.y,opacity:g?"0.5":"0.65",stroke:c??i,strokeWidth:g?.9*n/40:n/40,markerEnd:`url(#arrowhead-${o})`})]},`${l}-${u}${g?"-active":""}`)})}))};function vC({option:e}){const[t,r]=q.useState(!1),{boardWidth:n,chessPieces:i,customDarkSquareStyle:a,customLightSquareStyle:s,handleSetPosition:o,onPromotionPieceSelect:l,promoteFromSquare:u,promoteToSquare:c,promotionDialogVariant:f}=Cn(),d=()=>{switch(e[1]){case"Q":return a.backgroundColor;case"R":return s.backgroundColor;case"N":return f==="default"?s.backgroundColor:a.backgroundColor;case"B":return f==="default"?a.backgroundColor:s.backgroundColor}};return D.jsx("div",Object.assign({onClick:()=>{l!=null&&l.length?l(e):o(u,c,e,!0)},onMouseOver:()=>r(!0),onMouseOut:()=>r(!1),"data-piece":e,style:{cursor:"pointer",backgroundColor:t?d():`${d()}aa`,borderRadius:"4px",transition:"all 0.1s ease-out"}},{children:typeof i[e]=="function"?D.jsx("div",Object.assign({style:{transition:"all 0.1s ease-out",transform:t?"scale(1)":"scale(0.85)"}},{children:i[e]({squareWidth:n/8,isDragging:!1})})):D.jsx("svg",Object.assign({viewBox:"1 1 43 43",width:n/8,height:n/8,style:{transition:"all 0.1s ease-out",transform:t?"scale(1)":"scale(0.85)"}},{children:D.jsx("g",{children:i[e]})}))}))}function yC(){const{boardOrientation:e,boardWidth:t,promotionDialogVariant:r,promoteToSquare:n}=Cn(),i=(n==null?void 0:n[1])==="1"?"b":"w",a=[`${i??"w"}Q`,`${i??"w"}R`,`${i??"w"}N`,`${i??"w"}B`],s={default:{display:"grid",gridTemplateColumns:"1fr 1fr",transform:`translate(${-t/8}px, ${-t/8}px)`},vertical:{transform:`translate(${-t/16}px, ${-t/16}px)`},modal:{display:"flex",justifyContent:"center",alignItems:"center",transform:`translate(0px, ${3*t/8}px)`,width:"100%",height:t/4+"px",top:0,backgroundColor:"white",left:0}},o=kc(e,t,n||"a8");return D.jsx("div",Object.assign({style:Object.assign({position:"absolute",top:`${o==null?void 0:o.y}px`,left:`${o==null?void 0:o.x}px`,zIndex:1e3},s[r]),title:"Choose promotion piece"},{children:a.map(l=>D.jsx(vC,{option:l},l))}))}const mC={whiteKing:D.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",style:{shapeRendering:"geometricPrecision",textRendering:"geometricPrecision",imageRendering:"crisp-edges"},viewBox:"0 0 4210 12970",x:"0px",y:"0px",fillRule:"evenodd",clipRule:"evenodd",width:"250",height:"250"},{children:D.jsx("g",{children:D.jsx("path",{style:{fill:"black",fillRule:"nonzero"},d:"M2105 0c169,0 286,160 249,315l200 0c-172,266 -231,479 -256,792 315,-24 530,-86 792,-255l0 897c-265,-171 -479,-231 -792,-256 18,234 75,495 185,682l339 0c233,0 369,269 225,456l545 0 -595 1916c130,94 158,275 59,402 465,0 416,568 51,568l-334 0 465 2867 332 0c250,0 381,306 199,485 162,63 273,220 273,399l0 633 168 0 0 475c-1403,0 -2807,0 -4210,0l0 -475 167 0 0 -633c0,-179 112,-336 274,-399 -181,-178 -52,-485 199,-485l332 0 465 -2867 -335 0c-353,0 -418,-568 51,-568 -98,-127 -70,-308 59,-402l-594 -1916c181,0 363,0 545,0 -144,-187 -9,-456 225,-456l339 0c110,-187 167,-448 185,-682 -315,25 -530,87 -793,256l0 -897c266,171 480,231 793,255 -25,-315 -87,-529 -256,-792l199 0c-36,-155 81,-315 250,-315zm-1994 10012l0 253 3988 0 0 -253c-1330,0 -2659,0 -3988,0zm484 -1060c-174,0 -316,142 -316,316l0 633 3652 0 0 -633c0,-174 -142,-316 -316,-316 -1007,0 -2013,0 -3020,0zm45 -457c-230,0 -225,345 0,345l2930 0c230,0 225,-345 0,-345 -977,0 -1953,0 -2930,0zm2020 -2978l-1111 0 -465 2867 2041 0 -465 -2867zm-1558 -456c-229,0 -224,345 0,345 669,0 1337,0 2005,0 230,0 225,-345 0,-345 -668,0 -1336,0 -2005,0zm1730 -457l-1454 0c-229,0 -224,345 0,345l1454 0c229,0 224,-345 0,-345zm-2064 -1862l544 1751c529,0 1057,0 1586,0l544 -1751c-892,0 -1783,0 -2674,0zm1085 -567l504 0c-126,-247 -163,-526 -177,-800 273,15 553,52 800,177l0 -504c-247,126 -527,163 -800,177 14,-273 51,-552 177,-799 -168,0 -336,0 -504,0 125,247 162,526 177,799 -274,-14 -553,-51 -800,-177l0 504c247,-125 527,-162 800,-177 -15,274 -52,553 -177,800zm969 111l-1434 0c-230,0 -225,345 0,345l1434 0c230,0 225,-345 0,-345zm-717 -2175c-105,0 -175,109 -133,204l266 0c42,-96 -30,-205 -133,-204z"})})}))};function CC({children:e}){try{return D.jsx(D.Fragment,{children:e})}catch(t){return console.log(t),D.jsx(d1,{showError:!0})}}function d1({showError:e=!1}){return D.jsxs("div",Object.assign({style:{display:"flex",justifyContent:"center",alignItems:"center",flexDirection:"column"}},{children:[D.jsx("div",Object.assign({style:{width:250,height:250,transform:"rotate(90deg)"}},{children:mC.whiteKing})),e&&D.jsx("h1",{children:"Something went wrong"})]}))}function EC(){const e=q.useRef(null),{boardWidth:t,clearCurrentRightClickDown:r,onPromotionPieceSelect:n,setShowPromoteDialog:i,showPromoteDialog:a,customBoardStyle:s}=Cn();return q.useEffect(()=>{function o(l){e.current&&!e.current.contains(l.target)&&r()}return document.addEventListener("mouseup",o),()=>{document.removeEventListener("mouseup",o)}},[]),t?D.jsx("div",Object.assign({style:{perspective:"1000px"}},{children:D.jsxs("div",Object.assign({ref:e,style:Object.assign(Object.assign({position:"relative"},SC(t)),s)},{children:[D.jsx(pC,{}),D.jsx(gC,{}),a&&D.jsxs(D.Fragment,{children:[D.jsx("div",{onClick:()=>{i(!1),n==null||n()},style:{position:"absolute",top:"0",left:"0",zIndex:"100",backgroundColor:"rgba(22,21,18,.7)",width:t,height:t}}),D.jsx(yC,{})]})]}))})):D.jsx(d1,{})}const SC=e=>({cursor:"default",height:e,width:e});function xC(){const{boardWidth:e,chessPieces:t,id:r,snapToCursor:n}=Cn(),i=function(c){const f=xi().getMonitor(),[d,v]=e1(f,c);return q.useEffect(()=>f.subscribeToOffsetChange(v)),q.useEffect(()=>f.subscribeToStateChange(v)),d}(c=>({item:c.getItem(),clientOffset:c.getClientOffset(),sourceClientOffset:c.getSourceClientOffset(),isDragging:c.isDragging()})),{isDragging:a,item:s,clientOffset:o,sourceClientOffset:l}=i,u=q.useCallback((c,f)=>{if(!c||!f)return{display:"none"};let{x:d,y:v}=n?c:f;if(n){const C=e/8/2;d-=C,v-=C}const g=`translate(${d}px, ${v}px)`;return{transform:g,WebkitTransform:g,touchAction:"none"}},[e,n]);return a&&s.id===r?D.jsx("div",Object.assign({style:{position:"fixed",pointerEvents:"none",zIndex:10,left:0,top:0}},{children:D.jsx("div",Object.assign({style:u(o,l)},{children:typeof t[s.piece]=="function"?t[s.piece]({squareWidth:e/8,isDragging:!0}):D.jsx("svg",Object.assign({viewBox:"1 1 43 43",width:e/8,height:e/8},{children:D.jsx("g",{children:t[s.piece]})}))}))})):null}const TC=q.forwardRef((e,t)=>{const{customDndBackend:r,customDndBackendOptions:n}=e,i=function(C,I){var y={};for(var m in C)Object.prototype.hasOwnProperty.call(C,m)&&I.indexOf(m)<0&&(y[m]=C[m]);if(C!=null&&typeof Object.getOwnPropertySymbols=="function"){var S=0;for(m=Object.getOwnPropertySymbols(C);S{c("ontouchstart"in window),l(!0),s(window)},[]),q.useEffect(()=>{var C;if(e.boardWidth===void 0&&(!((C=v.current)===null||C===void 0)&&C.offsetWidth)){const I=new ResizeObserver(()=>{var y;d((y=v.current)===null||y===void 0?void 0:y.offsetWidth)});return I.observe(v.current),()=>{I.disconnect()}}},[v.current,a]);const g=r||(u?iC:eC);return o&&a?D.jsx(CC,{children:D.jsxs("div",Object.assign({style:{display:"flex",flexDirection:"column",width:"100%"}},{children:[D.jsx("div",{ref:v,style:{width:"100%"}}),D.jsx(N2,Object.assign({backend:g,context:a,options:r?n:void 0},{children:f&&D.jsxs(cC,Object.assign({boardWidth:f},i,{ref:t},{children:[D.jsx(xC,{}),D.jsx(EC,{})]}))}))]}))}):null});var me={options:{usePureJavaScript:!1}},Zf={},wC=Zf,nh={};Zf.encode=function(e,t,r){if(typeof t!="string")throw new TypeError('"alphabet" must be a string.');if(r!==void 0&&typeof r!="number")throw new TypeError('"maxline" must be a number.');var n="";if(!(e instanceof Uint8Array))n=IC(e,t);else{var i=0,a=t.length,s=t.charAt(0),o=[0];for(i=0;i0;)o.push(u%a),u=u/a|0}for(i=0;e[i]===0&&i=0;--i)n+=t[o[i]]}if(r){var c=new RegExp(".{1,"+r+"}","g");n=n.match(c).join(`\r -`)}return n};Zf.decode=function(e,t){if(typeof e!="string")throw new TypeError('"input" must be a string.');if(typeof t!="string")throw new TypeError('"alphabet" must be a string.');var r=nh[t];if(!r){r=nh[t]=[];for(var n=0;n>=8;for(;u>0;)s.push(u&255),u>>=8}for(var c=0;e[c]===a&&c0;)a.push(o%n),o=o/n|0}var l="";for(r=0;e.at(r)===0&&r=0;--r)l+=t[a[r]];return l}var ih=me,ah=wC,b=ih.util=ih.util||{};(function(){if(typeof process<"u"&&process.nextTick&&!process.browser){b.nextTick=process.nextTick,typeof setImmediate=="function"?b.setImmediate=setImmediate:b.setImmediate=b.nextTick;return}if(typeof setImmediate=="function"){b.setImmediate=function(){return setImmediate.apply(void 0,arguments)},b.nextTick=function(o){return setImmediate(o)};return}if(b.setImmediate=function(o){setTimeout(o,0)},typeof window<"u"&&typeof window.postMessage=="function"){let o=function(l){if(l.source===window&&l.data===e){l.stopPropagation();var u=t.slice();t.length=0,u.forEach(function(c){c()})}};var s=o,e="forge.setImmediate",t=[];b.setImmediate=function(l){t.push(l),t.length===1&&window.postMessage(e,"*")},window.addEventListener("message",o,!0)}if(typeof MutationObserver<"u"){var r=Date.now(),n=!0,i=document.createElement("div"),t=[];new MutationObserver(function(){var l=t.slice();t.length=0,l.forEach(function(u){u()})}).observe(i,{attributes:!0});var a=b.setImmediate;b.setImmediate=function(l){Date.now()-r>15?(r=Date.now(),a(l)):(t.push(l),t.length===1&&i.setAttribute("a",n=!n))}}b.nextTick=b.setImmediate})();b.isNodejs=typeof process<"u"&&process.versions&&process.versions.node;b.globalScope=function(){return b.isNodejs?hv:typeof self>"u"?window:self}();b.isArray=Array.isArray||function(e){return Object.prototype.toString.call(e)==="[object Array]"};b.isArrayBuffer=function(e){return typeof ArrayBuffer<"u"&&e instanceof ArrayBuffer};b.isArrayBufferView=function(e){return e&&b.isArrayBuffer(e.buffer)&&e.byteLength!==void 0};function Bs(e){if(!(e===8||e===16||e===24||e===32))throw new Error("Only 8, 16, 24, or 32 bits supported: "+e)}b.ByteBuffer=Jf;function Jf(e){if(this.data="",this.read=0,typeof e=="string")this.data=e;else if(b.isArrayBuffer(e)||b.isArrayBufferView(e))if(typeof Buffer<"u"&&e instanceof Buffer)this.data=e.toString("binary");else{var t=new Uint8Array(e);try{this.data=String.fromCharCode.apply(null,t)}catch{for(var r=0;r_C&&(this.data.substr(0,1),this._constructedStringLength=0)};b.ByteStringBuffer.prototype.length=function(){return this.data.length-this.read};b.ByteStringBuffer.prototype.isEmpty=function(){return this.length()<=0};b.ByteStringBuffer.prototype.putByte=function(e){return this.putBytes(String.fromCharCode(e))};b.ByteStringBuffer.prototype.fillWithByte=function(e,t){e=String.fromCharCode(e);for(var r=this.data;t>0;)t&1&&(r+=e),t>>>=1,t>0&&(e+=e);return this.data=r,this._optimizeConstructedString(t),this};b.ByteStringBuffer.prototype.putBytes=function(e){return this.data+=e,this._optimizeConstructedString(e.length),this};b.ByteStringBuffer.prototype.putString=function(e){return this.putBytes(b.encodeUtf8(e))};b.ByteStringBuffer.prototype.putInt16=function(e){return this.putBytes(String.fromCharCode(e>>8&255)+String.fromCharCode(e&255))};b.ByteStringBuffer.prototype.putInt24=function(e){return this.putBytes(String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255))};b.ByteStringBuffer.prototype.putInt32=function(e){return this.putBytes(String.fromCharCode(e>>24&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255))};b.ByteStringBuffer.prototype.putInt16Le=function(e){return this.putBytes(String.fromCharCode(e&255)+String.fromCharCode(e>>8&255))};b.ByteStringBuffer.prototype.putInt24Le=function(e){return this.putBytes(String.fromCharCode(e&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e>>16&255))};b.ByteStringBuffer.prototype.putInt32Le=function(e){return this.putBytes(String.fromCharCode(e&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>24&255))};b.ByteStringBuffer.prototype.putInt=function(e,t){Bs(t);var r="";do t-=8,r+=String.fromCharCode(e>>t&255);while(t>0);return this.putBytes(r)};b.ByteStringBuffer.prototype.putSignedInt=function(e,t){return e<0&&(e+=2<0);return t};b.ByteStringBuffer.prototype.getSignedInt=function(e){var t=this.getInt(e),r=2<=r&&(t-=r<<1),t};b.ByteStringBuffer.prototype.getBytes=function(e){var t;return e?(e=Math.min(this.length(),e),t=this.data.slice(this.read,this.read+e),this.read+=e):e===0?t="":(t=this.read===0?this.data:this.data.slice(this.read),this.clear()),t};b.ByteStringBuffer.prototype.bytes=function(e){return typeof e>"u"?this.data.slice(this.read):this.data.slice(this.read,this.read+e)};b.ByteStringBuffer.prototype.at=function(e){return this.data.charCodeAt(this.read+e)};b.ByteStringBuffer.prototype.setAt=function(e,t){return this.data=this.data.substr(0,this.read+e)+String.fromCharCode(t)+this.data.substr(this.read+e+1),this};b.ByteStringBuffer.prototype.last=function(){return this.data.charCodeAt(this.data.length-1)};b.ByteStringBuffer.prototype.copy=function(){var e=b.createBuffer(this.data);return e.read=this.read,e};b.ByteStringBuffer.prototype.compact=function(){return this.read>0&&(this.data=this.data.slice(this.read),this.read=0),this};b.ByteStringBuffer.prototype.clear=function(){return this.data="",this.read=0,this};b.ByteStringBuffer.prototype.truncate=function(e){var t=Math.max(0,this.length()-e);return this.data=this.data.substr(this.read,t),this.read=0,this};b.ByteStringBuffer.prototype.toHex=function(){for(var e="",t=this.read;t=e)return this;t=Math.max(t||this.growSize,e);var r=new Uint8Array(this.data.buffer,this.data.byteOffset,this.data.byteLength),n=new Uint8Array(this.length()+t);return n.set(r),this.data=new DataView(n.buffer),this};b.DataBuffer.prototype.putByte=function(e){return this.accommodate(1),this.data.setUint8(this.write++,e),this};b.DataBuffer.prototype.fillWithByte=function(e,t){this.accommodate(t);for(var r=0;r>8&65535),this.data.setInt8(this.write,e>>16&255),this.write+=3,this};b.DataBuffer.prototype.putInt32=function(e){return this.accommodate(4),this.data.setInt32(this.write,e),this.write+=4,this};b.DataBuffer.prototype.putInt16Le=function(e){return this.accommodate(2),this.data.setInt16(this.write,e,!0),this.write+=2,this};b.DataBuffer.prototype.putInt24Le=function(e){return this.accommodate(3),this.data.setInt8(this.write,e>>16&255),this.data.setInt16(this.write,e>>8&65535,!0),this.write+=3,this};b.DataBuffer.prototype.putInt32Le=function(e){return this.accommodate(4),this.data.setInt32(this.write,e,!0),this.write+=4,this};b.DataBuffer.prototype.putInt=function(e,t){Bs(t),this.accommodate(t/8);do t-=8,this.data.setInt8(this.write++,e>>t&255);while(t>0);return this};b.DataBuffer.prototype.putSignedInt=function(e,t){return Bs(t),this.accommodate(t/8),e<0&&(e+=2<0);return t};b.DataBuffer.prototype.getSignedInt=function(e){var t=this.getInt(e),r=2<=r&&(t-=r<<1),t};b.DataBuffer.prototype.getBytes=function(e){var t;return e?(e=Math.min(this.length(),e),t=this.data.slice(this.read,this.read+e),this.read+=e):e===0?t="":(t=this.read===0?this.data:this.data.slice(this.read),this.clear()),t};b.DataBuffer.prototype.bytes=function(e){return typeof e>"u"?this.data.slice(this.read):this.data.slice(this.read,this.read+e)};b.DataBuffer.prototype.at=function(e){return this.data.getUint8(this.read+e)};b.DataBuffer.prototype.setAt=function(e,t){return this.data.setUint8(e,t),this};b.DataBuffer.prototype.last=function(){return this.data.getUint8(this.write-1)};b.DataBuffer.prototype.copy=function(){return new b.DataBuffer(this)};b.DataBuffer.prototype.compact=function(){if(this.read>0){var e=new Uint8Array(this.data.buffer,this.read),t=new Uint8Array(e.byteLength);t.set(e),this.data=new DataView(t),this.write-=this.read,this.read=0}return this};b.DataBuffer.prototype.clear=function(){return this.data=new DataView(new ArrayBuffer(0)),this.read=this.write=0,this};b.DataBuffer.prototype.truncate=function(e){return this.write=Math.max(0,this.length()-e),this.read=Math.min(this.read,this.write),this};b.DataBuffer.prototype.toHex=function(){for(var e="",t=this.read;t0;)t&1&&(r+=e),t>>>=1,t>0&&(e+=e);return r};b.xorBytes=function(e,t,r){for(var n="",i="",a="",s=0,o=0;r>0;--r,++s)i=e.charCodeAt(s)^t.charCodeAt(s),o>=10&&(n+=a,a="",o=0),a+=String.fromCharCode(i),++o;return n+=a,n};b.hexToBytes=function(e){var t="",r=0;for(e.length&!0&&(r=1,t+=String.fromCharCode(parseInt(e[0],16)));r>24&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255)};var Ln="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",On=[62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],h1="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";b.encode64=function(e,t){for(var r="",n="",i,a,s,o=0;o>2),r+=Ln.charAt((i&3)<<4|a>>4),isNaN(a)?r+="==":(r+=Ln.charAt((a&15)<<2|s>>6),r+=isNaN(s)?"=":Ln.charAt(s&63)),t&&r.length>t&&(n+=r.substr(0,t)+`\r -`,r=r.substr(t));return n+=r,n};b.decode64=function(e){e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var t="",r,n,i,a,s=0;s>4),i!==64&&(t+=String.fromCharCode((n&15)<<4|i>>2),a!==64&&(t+=String.fromCharCode((i&3)<<6|a)));return t};b.encodeUtf8=function(e){return unescape(encodeURIComponent(e))};b.decodeUtf8=function(e){return decodeURIComponent(escape(e))};b.binary={raw:{},hex:{},base64:{},base58:{},baseN:{encode:ah.encode,decode:ah.decode}};b.binary.raw.encode=function(e){return String.fromCharCode.apply(null,e)};b.binary.raw.decode=function(e,t,r){var n=t;n||(n=new Uint8Array(e.length)),r=r||0;for(var i=r,a=0;a>2),r+=Ln.charAt((i&3)<<4|a>>4),isNaN(a)?r+="==":(r+=Ln.charAt((a&15)<<2|s>>6),r+=isNaN(s)?"=":Ln.charAt(s&63)),t&&r.length>t&&(n+=r.substr(0,t)+`\r -`,r=r.substr(t));return n+=r,n};b.binary.base64.decode=function(e,t,r){var n=t;n||(n=new Uint8Array(Math.ceil(e.length/4)*3)),e=e.replace(/[^A-Za-z0-9\+\/\=]/g,""),r=r||0;for(var i,a,s,o,l=0,u=r;l>4,s!==64&&(n[u++]=(a&15)<<4|s>>2,o!==64&&(n[u++]=(s&3)<<6|o));return t?u-r:n.subarray(0,u)};b.binary.base58.encode=function(e,t){return b.binary.baseN.encode(e,h1,t)};b.binary.base58.decode=function(e,t){return b.binary.baseN.decode(e,h1,t)};b.text={utf8:{},utf16:{}};b.text.utf8.encode=function(e,t,r){e=b.encodeUtf8(e);var n=t;n||(n=new Uint8Array(e.length)),r=r||0;for(var i=r,a=0;a"u"&&(r=["web","flash"]);var i,a=!1,s=null;for(var o in r){i=r[o];try{if(i==="flash"||i==="both"){if(t[0]===null)throw new Error("Flash local storage not available.");n=e.apply(this,t),a=i==="flash"}(i==="web"||i==="both")&&(t[0]=localStorage,n=e.apply(this,t),a=!0)}catch(l){s=l}if(a)break}if(!a)throw s;return n};b.setItem=function(e,t,r,n,i){xl(BC,arguments,i)};b.getItem=function(e,t,r,n){return xl(kC,arguments,n)};b.removeItem=function(e,t,r,n){xl(bC,arguments,n)};b.clearItems=function(e,t,r){xl(NC,arguments,r)};b.isEmpty=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0};b.format=function(e){for(var t=/%./g,r,n,i=0,a=[],s=0;r=t.exec(e);){n=e.substring(s,t.lastIndex-2),n.length>0&&a.push(n),s=t.lastIndex;var o=r[0][1];switch(o){case"s":case"o":i");break;case"%":a.push("%");break;default:a.push("<%"+o+"?>")}}return a.push(e.substring(s)),a.join("")};b.formatNumber=function(e,t,r,n){var i=e,a=isNaN(t=Math.abs(t))?2:t,s=r===void 0?",":r,o=n===void 0?".":n,l=i<0?"-":"",u=parseInt(i=Math.abs(+i||0).toFixed(a),10)+"",c=u.length>3?u.length%3:0;return l+(c?u.substr(0,c)+o:"")+u.substr(c).replace(/(\d{3})(?=\d)/g,"$1"+o)+(a?s+Math.abs(i-u).toFixed(a).slice(2):"")};b.formatSize=function(e){return e>=1073741824?e=b.formatNumber(e/1073741824,2,".","")+" GiB":e>=1048576?e=b.formatNumber(e/1048576,2,".","")+" MiB":e>=1024?e=b.formatNumber(e/1024,0)+" KiB":e=b.formatNumber(e,0)+" bytes",e};b.bytesFromIP=function(e){return e.indexOf(".")!==-1?b.bytesFromIPv4(e):e.indexOf(":")!==-1?b.bytesFromIPv6(e):null};b.bytesFromIPv4=function(e){if(e=e.split("."),e.length!==4)return null;for(var t=b.createBuffer(),r=0;rr[n].end-r[n].start&&(n=r.length-1))}t.push(a)}if(r.length>0){var l=r[n];l.end-l.start>0&&(t.splice(l.start,l.end-l.start+1,""),l.start===0&&t.unshift(""),l.end===7&&t.push(""))}return t.join(":")};b.estimateCores=function(e,t){if(typeof e=="function"&&(t=e,e={}),e=e||{},"cores"in b&&!e.update)return t(null,b.cores);if(typeof navigator<"u"&&"hardwareConcurrency"in navigator&&navigator.hardwareConcurrency>0)return b.cores=navigator.hardwareConcurrency,t(null,b.cores);if(typeof Worker>"u")return b.cores=1,t(null,b.cores);if(typeof Blob>"u")return b.cores=2,t(null,b.cores);var r=URL.createObjectURL(new Blob(["(",(function(){self.addEventListener("message",function(s){var o=Date.now(),l=o+4;self.postMessage({st:o,et:l})})}).toString(),")()"],{type:"application/javascript"}));n([],5,16);function n(s,o,l){if(o===0){var u=Math.floor(s.reduce(function(c,f){return c+f},0)/s.length);return b.cores=Math.max(1,u),URL.revokeObjectURL(r),t(null,b.cores)}i(l,function(c,f){s.push(a(l,f)),n(s,o-1,l)})}function i(s,o){for(var l=[],u=[],c=0;cv.st&&c.stc.st&&v.st0))return!0;for(var n=0;n0))return!0;for(var n=0;n0)return!1;var r=e.length(),n=e.at(r-1);return n>this.blockSize<<2?!1:(e.truncate(n),!0)};xe.cbc=function(e){e=e||{},this.name="CBC",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._ints=this.blockSize/4,this._inBlock=new Array(this._ints),this._outBlock=new Array(this._ints)};xe.cbc.prototype.start=function(e){if(e.iv===null){if(!this._prev)throw new Error("Invalid IV parameter.");this._iv=this._prev.slice(0)}else if("iv"in e)this._iv=Tl(e.iv,this.blockSize),this._prev=this._iv.slice(0);else throw new Error("Invalid IV parameter.")};xe.cbc.prototype.encrypt=function(e,t,r){if(e.length()0))return!0;for(var n=0;n0))return!0;for(var n=0;n0)return!1;var r=e.length(),n=e.at(r-1);return n>this.blockSize<<2?!1:(e.truncate(n),!0)};xe.cfb=function(e){e=e||{},this.name="CFB",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._ints=this.blockSize/4,this._inBlock=null,this._outBlock=new Array(this._ints),this._partialBlock=new Array(this._ints),this._partialOutput=wt.util.createBuffer(),this._partialBytes=0};xe.cfb.prototype.start=function(e){if(!("iv"in e))throw new Error("Invalid IV parameter.");this._iv=Tl(e.iv,this.blockSize),this._inBlock=this._iv.slice(0),this._partialBytes=0};xe.cfb.prototype.encrypt=function(e,t,r){var n=e.length();if(n===0)return!0;if(this.cipher.encrypt(this._inBlock,this._outBlock),this._partialBytes===0&&n>=this.blockSize){for(var i=0;i0&&(a=this.blockSize-a),this._partialOutput.clear();for(var i=0;i0)e.read-=this.blockSize;else for(var i=0;i0&&this._partialOutput.getBytes(this._partialBytes),a>0&&!r)return t.putBytes(this._partialOutput.getBytes(a-this._partialBytes)),this._partialBytes=a,!0;t.putBytes(this._partialOutput.getBytes(n-this._partialBytes)),this._partialBytes=0};xe.cfb.prototype.decrypt=function(e,t,r){var n=e.length();if(n===0)return!0;if(this.cipher.encrypt(this._inBlock,this._outBlock),this._partialBytes===0&&n>=this.blockSize){for(var i=0;i0&&(a=this.blockSize-a),this._partialOutput.clear();for(var i=0;i0)e.read-=this.blockSize;else for(var i=0;i0&&this._partialOutput.getBytes(this._partialBytes),a>0&&!r)return t.putBytes(this._partialOutput.getBytes(a-this._partialBytes)),this._partialBytes=a,!0;t.putBytes(this._partialOutput.getBytes(n-this._partialBytes)),this._partialBytes=0};xe.ofb=function(e){e=e||{},this.name="OFB",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._ints=this.blockSize/4,this._inBlock=null,this._outBlock=new Array(this._ints),this._partialOutput=wt.util.createBuffer(),this._partialBytes=0};xe.ofb.prototype.start=function(e){if(!("iv"in e))throw new Error("Invalid IV parameter.");this._iv=Tl(e.iv,this.blockSize),this._inBlock=this._iv.slice(0),this._partialBytes=0};xe.ofb.prototype.encrypt=function(e,t,r){var n=e.length();if(e.length()===0)return!0;if(this.cipher.encrypt(this._inBlock,this._outBlock),this._partialBytes===0&&n>=this.blockSize){for(var i=0;i0&&(a=this.blockSize-a),this._partialOutput.clear();for(var i=0;i0)e.read-=this.blockSize;else for(var i=0;i0&&this._partialOutput.getBytes(this._partialBytes),a>0&&!r)return t.putBytes(this._partialOutput.getBytes(a-this._partialBytes)),this._partialBytes=a,!0;t.putBytes(this._partialOutput.getBytes(n-this._partialBytes)),this._partialBytes=0};xe.ofb.prototype.decrypt=xe.ofb.prototype.encrypt;xe.ctr=function(e){e=e||{},this.name="CTR",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._ints=this.blockSize/4,this._inBlock=null,this._outBlock=new Array(this._ints),this._partialOutput=wt.util.createBuffer(),this._partialBytes=0};xe.ctr.prototype.start=function(e){if(!("iv"in e))throw new Error("Invalid IV parameter.");this._iv=Tl(e.iv,this.blockSize),this._inBlock=this._iv.slice(0),this._partialBytes=0};xe.ctr.prototype.encrypt=function(e,t,r){var n=e.length();if(n===0)return!0;if(this.cipher.encrypt(this._inBlock,this._outBlock),this._partialBytes===0&&n>=this.blockSize)for(var i=0;i0&&(a=this.blockSize-a),this._partialOutput.clear();for(var i=0;i0&&(e.read-=this.blockSize),this._partialBytes>0&&this._partialOutput.getBytes(this._partialBytes),a>0&&!r)return t.putBytes(this._partialOutput.getBytes(a-this._partialBytes)),this._partialBytes=a,!0;t.putBytes(this._partialOutput.getBytes(n-this._partialBytes)),this._partialBytes=0}wl(this._inBlock)};xe.ctr.prototype.decrypt=xe.ctr.prototype.encrypt;xe.gcm=function(e){e=e||{},this.name="GCM",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._ints=this.blockSize/4,this._inBlock=new Array(this._ints),this._outBlock=new Array(this._ints),this._partialOutput=wt.util.createBuffer(),this._partialBytes=0,this._R=3774873600};xe.gcm.prototype.start=function(e){if(!("iv"in e))throw new Error("Invalid IV parameter.");var t=wt.util.createBuffer(e.iv);this._cipherLength=0;var r;if("additionalData"in e?r=wt.util.createBuffer(e.additionalData):r=wt.util.createBuffer(),"tagLength"in e?this._tagLength=e.tagLength:this._tagLength=128,this._tag=null,e.decrypt&&(this._tag=wt.util.createBuffer(e.tag).getBytes(),this._tag.length!==this._tagLength/8))throw new Error("Authentication tag does not match tag length.");this._hashBlock=new Array(this._ints),this.tag=null,this._hashSubkey=new Array(this._ints),this.cipher.encrypt([0,0,0,0],this._hashSubkey),this.componentBits=4,this._m=this.generateHashTable(this._hashSubkey,this.componentBits);var n=t.length();if(n===12)this._j0=[t.getInt32(),t.getInt32(),t.getInt32(),1];else{for(this._j0=[0,0,0,0];t.length()>0;)this._j0=this.ghash(this._hashSubkey,this._j0,[t.getInt32(),t.getInt32(),t.getInt32(),t.getInt32()]);this._j0=this.ghash(this._hashSubkey,this._j0,[0,0].concat(bc(n*8)))}this._inBlock=this._j0.slice(0),wl(this._inBlock),this._partialBytes=0,r=wt.util.createBuffer(r),this._aDataLength=bc(r.length()*8);var i=r.length()%this.blockSize;for(i&&r.fillWithByte(0,this.blockSize-i),this._s=[0,0,0,0];r.length()>0;)this._s=this.ghash(this._hashSubkey,this._s,[r.getInt32(),r.getInt32(),r.getInt32(),r.getInt32()])};xe.gcm.prototype.encrypt=function(e,t,r){var n=e.length();if(n===0)return!0;if(this.cipher.encrypt(this._inBlock,this._outBlock),this._partialBytes===0&&n>=this.blockSize){for(var i=0;i0&&(a=this.blockSize-a),this._partialOutput.clear();for(var i=0;i0&&this._partialOutput.getBytes(this._partialBytes),a>0&&!r)return e.read-=this.blockSize,t.putBytes(this._partialOutput.getBytes(a-this._partialBytes)),this._partialBytes=a,!0;t.putBytes(this._partialOutput.getBytes(n-this._partialBytes)),this._partialBytes=0}this._s=this.ghash(this._hashSubkey,this._s,this._outBlock),wl(this._inBlock)};xe.gcm.prototype.decrypt=function(e,t,r){var n=e.length();if(n0))return!0;this.cipher.encrypt(this._inBlock,this._outBlock),wl(this._inBlock),this._hashBlock[0]=e.getInt32(),this._hashBlock[1]=e.getInt32(),this._hashBlock[2]=e.getInt32(),this._hashBlock[3]=e.getInt32(),this._s=this.ghash(this._hashSubkey,this._s,this._hashBlock);for(var i=0;i0;--n)t[n]=e[n]>>>1|(e[n-1]&1)<<31;t[0]=e[0]>>>1,r&&(t[0]^=this._R)};xe.gcm.prototype.tableMultiply=function(e){for(var t=[0,0,0,0],r=0;r<32;++r){var n=r/8|0,i=e[n]>>>(7-r%8)*4&15,a=this._m[r][i];t[0]^=a[0],t[1]^=a[1],t[2]^=a[2],t[3]^=a[3]}return t};xe.gcm.prototype.ghash=function(e,t,r){return t[0]^=r[0],t[1]^=r[1],t[2]^=r[2],t[3]^=r[3],this.tableMultiply(t)};xe.gcm.prototype.generateHashTable=function(e,t){for(var r=8/t,n=4*r,i=16*r,a=new Array(i),s=0;s>>1,i=new Array(r);i[n]=e.slice(0);for(var a=n>>>1;a>0;)this.pow(i[2*a],i[a]=[]),a>>=1;for(a=2;a4){var r=e;e=wt.util.createBuffer();for(var n=0;n>>2;for(var n=0;n>8^o&255^99,Ft[r]=o,Nc[o]=r,l=e[o],i=e[r],a=e[i],s=e[a],u=l<<24^o<<16^o<<8^(o^l),c=(i^a^s)<<24^(r^s)<<16^(r^a^s)<<8^(r^i^s);for(var f=0;f<4;++f)fi[f][r]=u,Mr[f][o]=c,u=u<<24|u>>>8,c=c<<24|c>>>8;r===0?r=n=1:(r=i^e[e[e[i^s]]],n^=e[e[n]])}}function v1(e,t){for(var r=e.slice(0),n,i=1,a=r.length,s=a+6+1,o=Ni*s,l=a;l>>16&255]<<24^Ft[n>>>8&255]<<16^Ft[n&255]<<8^Ft[n>>>24]^p1[i]<<24,i++):a>6&&l%a===4&&(n=Ft[n>>>24]<<24^Ft[n>>>16&255]<<16^Ft[n>>>8&255]<<8^Ft[n&255]),r[l]=r[l-a]^n;if(t){var u,c=Mr[0],f=Mr[1],d=Mr[2],v=Mr[3],g=r.slice(0);o=r.length;for(var l=0,C=o-Ni;l>>24]]^f[Ft[u>>>16&255]]^d[Ft[u>>>8&255]]^v[Ft[u&255]];r=g}return r}function Dc(e,t,r,n){var i=e.length/4-1,a,s,o,l,u;n?(a=Mr[0],s=Mr[1],o=Mr[2],l=Mr[3],u=Nc):(a=fi[0],s=fi[1],o=fi[2],l=fi[3],u=Ft);var c,f,d,v,g,C,I;c=t[0]^e[0],f=t[n?3:1]^e[1],d=t[2]^e[2],v=t[n?1:3]^e[3];for(var y=3,m=1;m>>24]^s[f>>>16&255]^o[d>>>8&255]^l[v&255]^e[++y],C=a[f>>>24]^s[d>>>16&255]^o[v>>>8&255]^l[c&255]^e[++y],I=a[d>>>24]^s[v>>>16&255]^o[c>>>8&255]^l[f&255]^e[++y],v=a[v>>>24]^s[c>>>16&255]^o[f>>>8&255]^l[d&255]^e[++y],c=g,f=C,d=I;r[0]=u[c>>>24]<<24^u[f>>>16&255]<<16^u[d>>>8&255]<<8^u[v&255]^e[++y],r[n?3:1]=u[f>>>24]<<24^u[d>>>16&255]<<16^u[v>>>8&255]<<8^u[c&255]^e[++y],r[2]=u[d>>>24]<<24^u[v>>>16&255]<<16^u[c>>>8&255]<<8^u[f&255]^e[++y],r[n?1:3]=u[v>>>24]<<24^u[c>>>16&255]<<16^u[f>>>8&255]<<8^u[d&255]^e[++y]}function Il(e){e=e||{};var t=(e.mode||"CBC").toUpperCase(),r="AES-"+t,n;e.decrypt?n=$e.cipher.createDecipher(r,e.key):n=$e.cipher.createCipher(r,e.key);var i=n.start;return n.start=function(a,s){var o=null;s instanceof $e.util.ByteBuffer&&(o=s,s={}),s=s||{},s.output=o,s.iv=a,i.call(n,s)},n}var Ja=me;Ja.pki=Ja.pki||{};var Rc=Ja.pki.oids=Ja.oids=Ja.oids||{};function z(e,t){Rc[e]=t,Rc[t]=e}function Pe(e,t){Rc[e]=t}z("1.2.840.113549.1.1.1","rsaEncryption");z("1.2.840.113549.1.1.4","md5WithRSAEncryption");z("1.2.840.113549.1.1.5","sha1WithRSAEncryption");z("1.2.840.113549.1.1.7","RSAES-OAEP");z("1.2.840.113549.1.1.8","mgf1");z("1.2.840.113549.1.1.9","pSpecified");z("1.2.840.113549.1.1.10","RSASSA-PSS");z("1.2.840.113549.1.1.11","sha256WithRSAEncryption");z("1.2.840.113549.1.1.12","sha384WithRSAEncryption");z("1.2.840.113549.1.1.13","sha512WithRSAEncryption");z("1.3.101.112","EdDSA25519");z("1.2.840.10040.4.3","dsa-with-sha1");z("1.3.14.3.2.7","desCBC");z("1.3.14.3.2.26","sha1");z("1.3.14.3.2.29","sha1WithRSASignature");z("2.16.840.1.101.3.4.2.1","sha256");z("2.16.840.1.101.3.4.2.2","sha384");z("2.16.840.1.101.3.4.2.3","sha512");z("2.16.840.1.101.3.4.2.4","sha224");z("2.16.840.1.101.3.4.2.5","sha512-224");z("2.16.840.1.101.3.4.2.6","sha512-256");z("1.2.840.113549.2.2","md2");z("1.2.840.113549.2.5","md5");z("1.2.840.113549.1.7.1","data");z("1.2.840.113549.1.7.2","signedData");z("1.2.840.113549.1.7.3","envelopedData");z("1.2.840.113549.1.7.4","signedAndEnvelopedData");z("1.2.840.113549.1.7.5","digestedData");z("1.2.840.113549.1.7.6","encryptedData");z("1.2.840.113549.1.9.1","emailAddress");z("1.2.840.113549.1.9.2","unstructuredName");z("1.2.840.113549.1.9.3","contentType");z("1.2.840.113549.1.9.4","messageDigest");z("1.2.840.113549.1.9.5","signingTime");z("1.2.840.113549.1.9.6","counterSignature");z("1.2.840.113549.1.9.7","challengePassword");z("1.2.840.113549.1.9.8","unstructuredAddress");z("1.2.840.113549.1.9.14","extensionRequest");z("1.2.840.113549.1.9.20","friendlyName");z("1.2.840.113549.1.9.21","localKeyId");z("1.2.840.113549.1.9.22.1","x509Certificate");z("1.2.840.113549.1.12.10.1.1","keyBag");z("1.2.840.113549.1.12.10.1.2","pkcs8ShroudedKeyBag");z("1.2.840.113549.1.12.10.1.3","certBag");z("1.2.840.113549.1.12.10.1.4","crlBag");z("1.2.840.113549.1.12.10.1.5","secretBag");z("1.2.840.113549.1.12.10.1.6","safeContentsBag");z("1.2.840.113549.1.5.13","pkcs5PBES2");z("1.2.840.113549.1.5.12","pkcs5PBKDF2");z("1.2.840.113549.1.12.1.1","pbeWithSHAAnd128BitRC4");z("1.2.840.113549.1.12.1.2","pbeWithSHAAnd40BitRC4");z("1.2.840.113549.1.12.1.3","pbeWithSHAAnd3-KeyTripleDES-CBC");z("1.2.840.113549.1.12.1.4","pbeWithSHAAnd2-KeyTripleDES-CBC");z("1.2.840.113549.1.12.1.5","pbeWithSHAAnd128BitRC2-CBC");z("1.2.840.113549.1.12.1.6","pbewithSHAAnd40BitRC2-CBC");z("1.2.840.113549.2.7","hmacWithSHA1");z("1.2.840.113549.2.8","hmacWithSHA224");z("1.2.840.113549.2.9","hmacWithSHA256");z("1.2.840.113549.2.10","hmacWithSHA384");z("1.2.840.113549.2.11","hmacWithSHA512");z("1.2.840.113549.3.7","des-EDE3-CBC");z("2.16.840.1.101.3.4.1.2","aes128-CBC");z("2.16.840.1.101.3.4.1.22","aes192-CBC");z("2.16.840.1.101.3.4.1.42","aes256-CBC");z("2.5.4.3","commonName");z("2.5.4.4","surname");z("2.5.4.5","serialNumber");z("2.5.4.6","countryName");z("2.5.4.7","localityName");z("2.5.4.8","stateOrProvinceName");z("2.5.4.9","streetAddress");z("2.5.4.10","organizationName");z("2.5.4.11","organizationalUnitName");z("2.5.4.12","title");z("2.5.4.13","description");z("2.5.4.15","businessCategory");z("2.5.4.17","postalCode");z("2.5.4.42","givenName");z("1.3.6.1.4.1.311.60.2.1.2","jurisdictionOfIncorporationStateOrProvinceName");z("1.3.6.1.4.1.311.60.2.1.3","jurisdictionOfIncorporationCountryName");z("2.16.840.1.113730.1.1","nsCertType");z("2.16.840.1.113730.1.13","nsComment");Pe("2.5.29.1","authorityKeyIdentifier");Pe("2.5.29.2","keyAttributes");Pe("2.5.29.3","certificatePolicies");Pe("2.5.29.4","keyUsageRestriction");Pe("2.5.29.5","policyMapping");Pe("2.5.29.6","subtreesConstraint");Pe("2.5.29.7","subjectAltName");Pe("2.5.29.8","issuerAltName");Pe("2.5.29.9","subjectDirectoryAttributes");Pe("2.5.29.10","basicConstraints");Pe("2.5.29.11","nameConstraints");Pe("2.5.29.12","policyConstraints");Pe("2.5.29.13","basicConstraints");z("2.5.29.14","subjectKeyIdentifier");z("2.5.29.15","keyUsage");Pe("2.5.29.16","privateKeyUsagePeriod");z("2.5.29.17","subjectAltName");z("2.5.29.18","issuerAltName");z("2.5.29.19","basicConstraints");Pe("2.5.29.20","cRLNumber");Pe("2.5.29.21","cRLReason");Pe("2.5.29.22","expirationDate");Pe("2.5.29.23","instructionCode");Pe("2.5.29.24","invalidityDate");Pe("2.5.29.25","cRLDistributionPoints");Pe("2.5.29.26","issuingDistributionPoint");Pe("2.5.29.27","deltaCRLIndicator");Pe("2.5.29.28","issuingDistributionPoint");Pe("2.5.29.29","certificateIssuer");Pe("2.5.29.30","nameConstraints");z("2.5.29.31","cRLDistributionPoints");z("2.5.29.32","certificatePolicies");Pe("2.5.29.33","policyMappings");Pe("2.5.29.34","policyConstraints");z("2.5.29.35","authorityKeyIdentifier");Pe("2.5.29.36","policyConstraints");z("2.5.29.37","extKeyUsage");Pe("2.5.29.46","freshestCRL");Pe("2.5.29.54","inhibitAnyPolicy");z("1.3.6.1.4.1.11129.2.4.2","timestampList");z("1.3.6.1.5.5.7.1.1","authorityInfoAccess");z("1.3.6.1.5.5.7.3.1","serverAuth");z("1.3.6.1.5.5.7.3.2","clientAuth");z("1.3.6.1.5.5.7.3.3","codeSigning");z("1.3.6.1.5.5.7.3.4","emailProtection");z("1.3.6.1.5.5.7.3.8","timeStamping");var Ze=me,X=Ze.asn1=Ze.asn1||{};X.Class={UNIVERSAL:0,APPLICATION:64,CONTEXT_SPECIFIC:128,PRIVATE:192};X.Type={NONE:0,BOOLEAN:1,INTEGER:2,BITSTRING:3,OCTETSTRING:4,NULL:5,OID:6,ODESC:7,EXTERNAL:8,REAL:9,ENUMERATED:10,EMBEDDED:11,UTF8:12,ROID:13,SEQUENCE:16,SET:17,PRINTABLESTRING:19,IA5STRING:22,UTCTIME:23,GENERALIZEDTIME:24,BMPSTRING:30};X.create=function(e,t,r,n,i){if(Ze.util.isArray(n)){for(var a=[],s=0;st){var n=new Error("Too few bytes to parse DER.");throw n.available=e.length(),n.remaining=t,n.requested=r,n}}var DC=function(e,t){var r=e.getByte();if(t--,r!==128){var n,i=r&128;if(!i)n=r;else{var a=r&127;Va(e,t,a),n=e.getInt(a<<3)}if(n<0)throw new Error("Negative length: "+n);return n}};X.fromDer=function(e,t){t===void 0&&(t={strict:!0,parseAllBytes:!0,decodeBitStrings:!0}),typeof t=="boolean"&&(t={strict:t,parseAllBytes:!0,decodeBitStrings:!0}),"strict"in t||(t.strict=!0),"parseAllBytes"in t||(t.parseAllBytes=!0),"decodeBitStrings"in t||(t.decodeBitStrings=!0),typeof e=="string"&&(e=Ze.util.createBuffer(e));var r=e.length(),n=Co(e,e.length(),0,t);if(t.parseAllBytes&&e.length()!==0){var i=new Error("Unparsed DER bytes remain after ASN.1 parsing.");throw i.byteCount=r,i.remaining=e.length(),i}return n};function Co(e,t,r,n){var i;Va(e,t,2);var a=e.getByte();t--;var s=a&192,o=a&31;i=e.length();var l=DC(e,t);if(t-=i-e.length(),l!==void 0&&l>t){if(n.strict){var u=new Error("Too few bytes to read ASN.1 value.");throw u.available=e.length(),u.remaining=t,u.requested=l,u}l=t}var c,f,d=(a&32)===32;if(d)if(c=[],l===void 0)for(;;){if(Va(e,t,2),e.bytes(2)===String.fromCharCode(0,0)){e.getBytes(2),t-=2;break}i=e.length(),c.push(Co(e,t,r+1,n)),t-=i-e.length()}else for(;l>0;)i=e.length(),c.push(Co(e,l,r+1,n)),t-=i-e.length(),l-=i-e.length();if(c===void 0&&s===X.Class.UNIVERSAL&&o===X.Type.BITSTRING&&(f=e.bytes(l)),c===void 0&&n.decodeBitStrings&&s===X.Class.UNIVERSAL&&o===X.Type.BITSTRING&&l>1){var v=e.read,g=t,C=0;if(o===X.Type.BITSTRING&&(Va(e,t,1),C=e.getByte(),t--),C===0)try{i=e.length();var I={strict:!0,decodeBitStrings:!0},y=Co(e,t,r+1,I),m=i-e.length();t-=m,o==X.Type.BITSTRING&&m++;var S=y.tagClass;m===l&&(S===X.Class.UNIVERSAL||S===X.Class.CONTEXT_SPECIFIC)&&(c=[y])}catch{}c===void 0&&(e.read=v,t=g)}if(c===void 0){if(l===void 0){if(n.strict)throw new Error("Non-constructed ASN.1 object of indefinite length.");l=t}if(o===X.Type.BMPSTRING)for(c="";l>0;l-=2)Va(e,t,2),c+=String.fromCharCode(e.getInt16()),t-=2;else c=e.getBytes(l),t-=l}var B=f===void 0?null:{bitStringContents:f};return X.create(s,o,d,c,B)}X.toDer=function(e){var t=Ze.util.createBuffer(),r=e.tagClass|e.type,n=Ze.util.createBuffer(),i=!1;if("bitStringContents"in e&&(i=!0,e.original&&(i=X.equals(e,e.original))),i)n.putBytes(e.bitStringContents);else if(e.composed){e.constructed?r|=32:n.putByte(0);for(var a=0;a1&&(e.value.charCodeAt(0)===0&&!(e.value.charCodeAt(1)&128)||e.value.charCodeAt(0)===255&&(e.value.charCodeAt(1)&128)===128)?n.putBytes(e.value.substr(1)):n.putBytes(e.value);if(t.putByte(r),n.length()<=127)t.putByte(n.length()&127);else{var s=n.length(),o="";do o+=String.fromCharCode(s&255),s=s>>>8;while(s>0);t.putByte(o.length|128);for(var a=o.length-1;a>=0;--a)t.putByte(o.charCodeAt(a))}return t.putBuffer(n),t};X.oidToDer=function(e){var t=e.split("."),r=Ze.util.createBuffer();r.putByte(40*parseInt(t[0],10)+parseInt(t[1],10));for(var n,i,a,s,o=2;o>>7,n||(s|=128),i.push(s),n=!1;while(a>0);for(var l=i.length-1;l>=0;--l)r.putByte(i[l])}return r};X.derToOid=function(e){var t;typeof e=="string"&&(e=Ze.util.createBuffer(e));var r=e.getByte();t=Math.floor(r/40)+"."+r%40;for(var n=0;e.length()>0;)r=e.getByte(),n=n<<7,r&128?n+=r&127:(t+="."+(n+r),n=0);return t};X.utcTimeToDate=function(e){var t=new Date,r=parseInt(e.substr(0,2),10);r=r>=50?1900+r:2e3+r;var n=parseInt(e.substr(2,2),10)-1,i=parseInt(e.substr(4,2),10),a=parseInt(e.substr(6,2),10),s=parseInt(e.substr(8,2),10),o=0;if(e.length>11){var l=e.charAt(10),u=10;l!=="+"&&l!=="-"&&(o=parseInt(e.substr(10,2),10),u+=2)}if(t.setUTCFullYear(r,n,i),t.setUTCHours(a,s,o,0),u&&(l=e.charAt(u),l==="+"||l==="-")){var c=parseInt(e.substr(u+1,2),10),f=parseInt(e.substr(u+4,2),10),d=c*60+f;d*=6e4,l==="+"?t.setTime(+t-d):t.setTime(+t+d)}return t};X.generalizedTimeToDate=function(e){var t=new Date,r=parseInt(e.substr(0,4),10),n=parseInt(e.substr(4,2),10)-1,i=parseInt(e.substr(6,2),10),a=parseInt(e.substr(8,2),10),s=parseInt(e.substr(10,2),10),o=parseInt(e.substr(12,2),10),l=0,u=0,c=!1;e.charAt(e.length-1)==="Z"&&(c=!0);var f=e.length-5,d=e.charAt(f);if(d==="+"||d==="-"){var v=parseInt(e.substr(f+1,2),10),g=parseInt(e.substr(f+4,2),10);u=v*60+g,u*=6e4,d==="+"&&(u*=-1),c=!0}return e.charAt(14)==="."&&(l=parseFloat(e.substr(14),10)*1e3),c?(t.setUTCFullYear(r,n,i),t.setUTCHours(a,s,o,l),t.setTime(+t+u)):(t.setFullYear(r,n,i),t.setHours(a,s,o,l)),t};X.dateToUtcTime=function(e){if(typeof e=="string")return e;var t="",r=[];r.push((""+e.getUTCFullYear()).substr(2)),r.push(""+(e.getUTCMonth()+1)),r.push(""+e.getUTCDate()),r.push(""+e.getUTCHours()),r.push(""+e.getUTCMinutes()),r.push(""+e.getUTCSeconds());for(var n=0;n=-128&&e<128)return t.putSignedInt(e,8);if(e>=-32768&&e<32768)return t.putSignedInt(e,16);if(e>=-8388608&&e<8388608)return t.putSignedInt(e,24);if(e>=-2147483648&&e<2147483648)return t.putSignedInt(e,32);var r=new Error("Integer too large; max is 32-bits.");throw r.integer=e,r};X.derToInteger=function(e){typeof e=="string"&&(e=Ze.util.createBuffer(e));var t=e.length()*8;if(t>32)throw new Error("Integer too large; max is 32-bits.");return e.getSignedInt(t)};X.validate=function(e,t,r,n){var i=!1;if((e.tagClass===t.tagClass||typeof t.tagClass>"u")&&(e.type===t.type||typeof t.type>"u"))if(e.constructed===t.constructed||typeof t.constructed>"u"){if(i=!0,t.value&&Ze.util.isArray(t.value))for(var a=0,s=0;i&&s0&&(n+=` -`);for(var i="",a=0;a1?n+="0x"+Ze.util.bytesToHex(e.value.slice(1)):n+="(none)",e.value.length>0){var u=e.value.charCodeAt(0);u==1?n+=" (1 unused bit shown)":u>1&&(n+=" ("+u+" unused bits shown)")}}else if(e.type===X.Type.OCTETSTRING)sh.test(e.value)||(n+="("+e.value+") "),n+="0x"+Ze.util.bytesToHex(e.value);else if(e.type===X.Type.UTF8)try{n+=Ze.util.decodeUtf8(e.value)}catch(c){if(c.message==="URI malformed")n+="0x"+Ze.util.bytesToHex(e.value)+" (malformed UTF8)";else throw c}else e.type===X.Type.PRINTABLESTRING||e.type===X.Type.IA5String?n+=e.value:sh.test(e.value)?n+="0x"+Ze.util.bytesToHex(e.value):e.value.length===0?n+="[null]":n+=e.value}return n};var Qo=me;Qo.md=Qo.md||{};Qo.md.algorithms=Qo.md.algorithms||{};var on=me,RC=on.hmac=on.hmac||{};RC.create=function(){var e=null,t=null,r=null,n=null,i={};return i.start=function(a,s){if(a!==null)if(typeof a=="string")if(a=a.toLowerCase(),a in on.md.algorithms)t=on.md.algorithms[a].create();else throw new Error('Unknown hash algorithm "'+a+'"');else t=a;if(s===null)s=e;else{if(typeof s=="string")s=on.util.createBuffer(s);else if(on.util.isArray(s)){var o=s;s=on.util.createBuffer();for(var l=0;lt.blockLength&&(t.start(),t.update(s.bytes()),s=t.digest()),r=on.util.createBuffer(),n=on.util.createBuffer(),u=s.length();for(var l=0;l>>0,s>>>0];for(var o=n.fullMessageLength.length-1;o>=0;--o)n.fullMessageLength[o]+=s[1],s[1]=s[0]+(n.fullMessageLength[o]/4294967296>>>0),n.fullMessageLength[o]=n.fullMessageLength[o]>>>0,s[0]=s[1]/4294967296>>>0;return t.putBytes(i),oh(e,r,t),(t.read>2048||t.length()===0)&&t.compact(),n},n.digest=function(){var i=Wr.util.createBuffer();i.putBytes(t.bytes());var a=n.fullMessageLength[n.fullMessageLength.length-1]+n.messageLengthSize,s=a&n.blockLength-1;i.putBytes(Lc.substr(0,n.blockLength-s));for(var o,l=0,u=n.fullMessageLength.length-1;u>=0;--u)o=n.fullMessageLength[u]*8+l,l=o/4294967296>>>0,i.putInt32Le(o>>>0);var c={h0:e.h0,h1:e.h1,h2:e.h2,h3:e.h3};oh(c,r,i);var f=Wr.util.createBuffer();return f.putInt32Le(c.h0),f.putInt32Le(c.h1),f.putInt32Le(c.h2),f.putInt32Le(c.h3),f},n};var Lc=null,Eo=null,ja=null,Gi=null,m1=!1;function LC(){Lc=String.fromCharCode(128),Lc+=Wr.util.fillString(String.fromCharCode(0),64),Eo=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9],ja=[7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21],Gi=new Array(64);for(var e=0;e<64;++e)Gi[e]=Math.floor(Math.abs(Math.sin(e+1))*4294967296);m1=!0}function oh(e,t,r){for(var n,i,a,s,o,l,u,c,f=r.length();f>=64;){for(i=e.h0,a=e.h1,s=e.h2,o=e.h3,c=0;c<16;++c)t[c]=r.getInt32Le(),l=o^a&(s^o),n=i+l+Gi[c]+t[c],u=ja[c],i=o,o=s,s=a,a+=n<>>32-u;for(;c<32;++c)l=s^o&(a^s),n=i+l+Gi[c]+t[Eo[c]],u=ja[c],i=o,o=s,s=a,a+=n<>>32-u;for(;c<48;++c)l=a^s^o,n=i+l+Gi[c]+t[Eo[c]],u=ja[c],i=o,o=s,s=a,a+=n<>>32-u;for(;c<64;++c)l=s^(a|~o),n=i+l+Gi[c]+t[Eo[c]],u=ja[c],i=o,o=s,s=a,a+=n<>>32-u;e.h0=e.h0+i|0,e.h1=e.h1+a|0,e.h2=e.h2+s|0,e.h3=e.h3+o|0,f-=64}}var Wo=me,C1=Wo.pem=Wo.pem||{};C1.encode=function(e,t){t=t||{};var r="-----BEGIN "+e.type+`-----\r -`,n;if(e.procType&&(n={name:"Proc-Type",values:[String(e.procType.version),e.procType.type]},r+=eo(n)),e.contentDomain&&(n={name:"Content-Domain",values:[e.contentDomain]},r+=eo(n)),e.dekInfo&&(n={name:"DEK-Info",values:[e.dekInfo.algorithm]},e.dekInfo.parameters&&n.values.push(e.dekInfo.parameters),r+=eo(n)),e.headers)for(var i=0;i65&&s!==-1){var o=t[s];o===","?(++s,t=t.substr(0,s)+`\r - `+t.substr(s)):t=t.substr(0,s)+`\r -`+o+t.substr(s+1),a=i-s-1,s=-1,++i}else(t[i]===" "||t[i]===" "||t[i]===",")&&(s=i);return t}function OC(e){return e.replace(/^\s+/,"")}var nt=me;nt.des=nt.des||{};nt.des.startEncrypting=function(e,t,r,n){var i=_l({key:e,output:r,decrypt:!1,mode:n||(t===null?"ECB":"CBC")});return i.start(t),i};nt.des.createEncryptionCipher=function(e,t){return _l({key:e,output:null,decrypt:!1,mode:t})};nt.des.startDecrypting=function(e,t,r,n){var i=_l({key:e,output:r,decrypt:!0,mode:n||(t===null?"ECB":"CBC")});return i.start(t),i};nt.des.createDecryptionCipher=function(e,t){return _l({key:e,output:null,decrypt:!0,mode:t})};nt.des.Algorithm=function(e,t){var r=this;r.name=e,r.mode=new t({blockSize:8,cipher:{encrypt:function(n,i){return lh(r._keys,n,i,!1)},decrypt:function(n,i){return lh(r._keys,n,i,!0)}}}),r._init=!1};nt.des.Algorithm.prototype.initialize=function(e){if(!this._init){var t=nt.util.createBuffer(e.key);if(this.name.indexOf("3DES")===0&&t.length()!==24)throw new Error("Invalid Triple-DES key size: "+t.length()*8);this._keys=HC(t),this._init=!0}};rn("DES-ECB",nt.cipher.modes.ecb);rn("DES-CBC",nt.cipher.modes.cbc);rn("DES-CFB",nt.cipher.modes.cfb);rn("DES-OFB",nt.cipher.modes.ofb);rn("DES-CTR",nt.cipher.modes.ctr);rn("3DES-ECB",nt.cipher.modes.ecb);rn("3DES-CBC",nt.cipher.modes.cbc);rn("3DES-CFB",nt.cipher.modes.cfb);rn("3DES-OFB",nt.cipher.modes.ofb);rn("3DES-CTR",nt.cipher.modes.ctr);function rn(e,t){var r=function(){return new nt.des.Algorithm(e,t)};nt.cipher.registerAlgorithm(e,r)}var PC=[16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028,16778240,16778240,0,65540,66560,0,16842756],UC=[-2146402272,-2147450880,32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576,-2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880,32800,-2147483648,-2146435040,-2146402272,1081344],MC=[520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072,134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800,131592,8,134348808,131584],FC=[8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928],VC=[256,34078976,34078720,1107296512,524288,256,1073741824,34078720,1074266368,524288,33554688,1074266368,1107296512,1107820544,524544,1073741824,33554432,1074266112,1074266112,0,1073742080,1107820800,1107820800,33554688,1107820544,1073742080,0,1107296256,34078976,33554432,1107296256,524544,524288,1107296512,256,33554432,1073741824,34078720,1107296512,1074266368,33554688,1073741824,1107820544,34078976,1074266368,256,33554432,1107820544,1107820800,524544,1107296256,1107820800,34078720,0,1074266112,1107296256,524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080],jC=[536870928,541065216,16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384,541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312],KC=[2097152,69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066,0,2099202,69206016,2048,67108866,67110912,2048,2097154],zC=[268439616,4096,262144,268701760,268435456,268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240,266240,4160,4160,262208,268435456,268701696];function HC(e){for(var t=[0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964],r=[0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697],n=[0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272],i=[0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144],a=[0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256],s=[0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488],o=[0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746],l=[0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568],u=[0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578],c=[0,268435456,8,268435464,0,268435456,8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488],f=[0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800],d=[0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744],v=[0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128],g=[0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261],C=e.length()>8?3:1,I=[],y=[0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0],m=0,S,B=0;B>>4^L)&252645135,L^=S,R^=S<<4,S=(L>>>-16^R)&65535,R^=S,L^=S<<-16,S=(R>>>2^L)&858993459,L^=S,R^=S<<2,S=(L>>>-16^R)&65535,R^=S,L^=S<<-16,S=(R>>>1^L)&1431655765,L^=S,R^=S<<1,S=(L>>>8^R)&16711935,R^=S,L^=S<<8,S=(R>>>1^L)&1431655765,L^=S,R^=S<<1,S=R<<8|L>>>20&240,R=L<<24|L<<8&16711680|L>>>8&65280|L>>>24&240,L=S;for(var M=0;M>>26,L=L<<2|L>>>26):(R=R<<1|R>>>27,L=L<<1|L>>>27),R&=-15,L&=-15;var V=t[R>>>28]|r[R>>>24&15]|n[R>>>20&15]|i[R>>>16&15]|a[R>>>12&15]|s[R>>>8&15]|o[R>>>4&15],Q=l[L>>>28]|u[L>>>24&15]|c[L>>>20&15]|f[L>>>16&15]|d[L>>>12&15]|v[L>>>8&15]|g[L>>>4&15];S=(Q>>>16^V)&65535,I[m++]=V^S,I[m++]=Q^S<<16}}return I}function lh(e,t,r,n){var i=e.length===32?3:9,a;i===3?a=n?[30,-2,-2]:[0,32,2]:a=n?[94,62,-2,32,64,2,30,-2,-2]:[0,32,2,62,30,-2,64,96,2];var s,o=t[0],l=t[1];s=(o>>>4^l)&252645135,l^=s,o^=s<<4,s=(o>>>16^l)&65535,l^=s,o^=s<<16,s=(l>>>2^o)&858993459,o^=s,l^=s<<2,s=(l>>>8^o)&16711935,o^=s,l^=s<<8,s=(o>>>1^l)&1431655765,l^=s,o^=s<<1,o=o<<1|o>>>31,l=l<<1|l>>>31;for(var u=0;u>>4|l<<28)^e[d+1];s=o,o=l,l=s^(UC[v>>>24&63]|FC[v>>>16&63]|jC[v>>>8&63]|zC[v&63]|PC[g>>>24&63]|MC[g>>>16&63]|VC[g>>>8&63]|KC[g&63])}s=o,o=l,l=s}o=o>>>1|o<<31,l=l>>>1|l<<31,s=(o>>>1^l)&1431655765,l^=s,o^=s<<1,s=(l>>>8^o)&16711935,o^=s,l^=s<<8,s=(l>>>2^o)&858993459,o^=s,l^=s<<2,s=(o>>>16^l)&65535,l^=s,o^=s<<16,s=(o>>>4^l)&252645135,l^=s,o^=s<<4,r[0]=o,r[1]=l}function _l(e){e=e||{};var t=(e.mode||"CBC").toUpperCase(),r="DES-"+t,n;e.decrypt?n=nt.cipher.createDecipher(r,e.key):n=nt.cipher.createCipher(r,e.key);var i=n.start;return n.start=function(a,s){var o=null;s instanceof nt.util.ByteBuffer&&(o=s,s={}),s=s||{},s.output=o,s.iv=a,i.call(n,s)},n}const qC={},$C=Object.freeze(Object.defineProperty({__proto__:null,default:qC},Symbol.toStringTag,{value:"Module"})),i0=pv($C);var Vt=me,GC=Vt.pkcs5=Vt.pkcs5||{},an;Vt.util.isNodejs&&!Vt.options.usePureJavaScript&&(an=i0);Vt.pbkdf2=GC.pbkdf2=function(e,t,r,n,i,a){if(typeof i=="function"&&(a=i,i=null),Vt.util.isNodejs&&!Vt.options.usePureJavaScript&&an.pbkdf2&&(i===null||typeof i!="object")&&(an.pbkdf2Sync.length>4||!i||i==="sha1"))return typeof i!="string"&&(i="sha1"),e=Buffer.from(e,"binary"),t=Buffer.from(t,"binary"),a?an.pbkdf2Sync.length===4?an.pbkdf2(e,t,r,n,function(S,B){if(S)return a(S);a(null,B.toString("binary"))}):an.pbkdf2(e,t,r,n,i,function(S,B){if(S)return a(S);a(null,B.toString("binary"))}):an.pbkdf2Sync.length===4?an.pbkdf2Sync(e,t,r,n).toString("binary"):an.pbkdf2Sync(e,t,r,n,i).toString("binary");if((typeof i>"u"||i===null)&&(i="sha1"),typeof i=="string"){if(!(i in Vt.md.algorithms))throw new Error("Unknown hash algorithm: "+i);i=Vt.md[i].create()}var s=i.digestLength;if(n>4294967295*s){var o=new Error("Derived key is too long.");if(a)return a(o);throw o}var l=Math.ceil(n/s),u=n-(l-1)*s,c=Vt.hmac.create();c.start(i,e);var f="",d,v,g;if(!a){for(var C=1;C<=l;++C){c.start(null,null),c.update(t),c.update(Vt.util.int32ToBytes(C)),d=g=c.digest().getBytes();for(var I=2;I<=r;++I)c.start(null,null),c.update(g),v=c.digest().getBytes(),d=Vt.util.xorBytes(d,v,s),g=v;f+=Cl)return a(null,f);c.start(null,null),c.update(t),c.update(Vt.util.int32ToBytes(C)),d=g=c.digest().getBytes(),I=2,m()}function m(){if(I<=r)return c.start(null,null),c.update(g),v=c.digest().getBytes(),d=Vt.util.xorBytes(d,v,s),g=v,++I,Vt.util.setImmediate(m);f+=C>>0,s>>>0];for(var o=n.fullMessageLength.length-1;o>=0;--o)n.fullMessageLength[o]+=s[1],s[1]=s[0]+(n.fullMessageLength[o]/4294967296>>>0),n.fullMessageLength[o]=n.fullMessageLength[o]>>>0,s[0]=s[1]/4294967296>>>0;return t.putBytes(i),uh(e,r,t),(t.read>2048||t.length()===0)&&t.compact(),n},n.digest=function(){var i=Yr.util.createBuffer();i.putBytes(t.bytes());var a=n.fullMessageLength[n.fullMessageLength.length-1]+n.messageLengthSize,s=a&n.blockLength-1;i.putBytes(Oc.substr(0,n.blockLength-s));for(var o,l,u=n.fullMessageLength[0]*8,c=0;c>>0,u+=l,i.putInt32(u>>>0),u=o>>>0;i.putInt32(u);var f={h0:e.h0,h1:e.h1,h2:e.h2,h3:e.h3,h4:e.h4,h5:e.h5,h6:e.h6,h7:e.h7};uh(f,r,i);var d=Yr.util.createBuffer();return d.putInt32(f.h0),d.putInt32(f.h1),d.putInt32(f.h2),d.putInt32(f.h3),d.putInt32(f.h4),d.putInt32(f.h5),d.putInt32(f.h6),d.putInt32(f.h7),d},n};var Oc=null,S1=!1,x1=null;function QC(){Oc=String.fromCharCode(128),Oc+=Yr.util.fillString(String.fromCharCode(0),64),x1=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],S1=!0}function uh(e,t,r){for(var n,i,a,s,o,l,u,c,f,d,v,g,C,I,y,m=r.length();m>=64;){for(u=0;u<16;++u)t[u]=r.getInt32();for(;u<64;++u)n=t[u-2],n=(n>>>17|n<<15)^(n>>>19|n<<13)^n>>>10,i=t[u-15],i=(i>>>7|i<<25)^(i>>>18|i<<14)^i>>>3,t[u]=n+t[u-7]+i+t[u-16]|0;for(c=e.h0,f=e.h1,d=e.h2,v=e.h3,g=e.h4,C=e.h5,I=e.h6,y=e.h7,u=0;u<64;++u)s=(g>>>6|g<<26)^(g>>>11|g<<21)^(g>>>25|g<<7),o=I^g&(C^I),a=(c>>>2|c<<30)^(c>>>13|c<<19)^(c>>>22|c<<10),l=c&f|d&(c^f),n=y+s+o+x1[u]+t[u],i=a+l,y=I,I=C,C=g,g=v+n>>>0,v=d,d=f,f=c,c=n+i>>>0;e.h0=e.h0+c|0,e.h1=e.h1+f|0,e.h2=e.h2+d|0,e.h3=e.h3+v|0,e.h4=e.h4+g|0,e.h5=e.h5+C|0,e.h6=e.h6+I|0,e.h7=e.h7+y|0,m-=64}}var $r=me,So=null;$r.util.isNodejs&&!$r.options.usePureJavaScript&&!process.versions["node-webkit"]&&(So=i0);var WC=$r.prng=$r.prng||{};WC.create=function(e){for(var t={plugin:e,key:null,seed:null,time:null,reseeds:0,generated:0,keyBytes:""},r=e.md,n=new Array(32),i=0;i<32;++i)n[i]=r.create();t.pools=n,t.pool=0,t.generate=function(u,c){if(!c)return t.generateSync(u);var f=t.plugin.cipher,d=t.plugin.increment,v=t.plugin.formatKey,g=t.plugin.formatSeed,C=$r.util.createBuffer();t.key=null,I();function I(y){if(y)return c(y);if(C.length()>=u)return c(null,C.getBytes(u));if(t.generated>1048575&&(t.key=null),t.key===null)return $r.util.nextTick(function(){a(I)});var m=f(t.key,t.seed);t.generated+=m.length,C.putBytes(m),t.key=v(f(t.key,d(t.seed))),t.seed=g(f(t.key,t.seed)),$r.util.setImmediate(I)}},t.generateSync=function(u){var c=t.plugin.cipher,f=t.plugin.increment,d=t.plugin.formatKey,v=t.plugin.formatSeed;t.key=null;for(var g=$r.util.createBuffer();g.length()1048575&&(t.key=null),t.key===null&&s();var C=c(t.key,t.seed);t.generated+=C.length,g.putBytes(C),t.key=d(c(t.key,f(t.seed))),t.seed=v(c(t.key,t.seed))}return g.getBytes(u)};function a(u){if(t.pools[0].messageLength>=32)return o(),u();var c=32-t.pools[0].messageLength<<5;t.seedFile(c,function(f,d){if(f)return u(f);t.collect(d),o(),u()})}function s(){if(t.pools[0].messageLength>=32)return o();var u=32-t.pools[0].messageLength<<5;t.collect(t.seedFileSync(u)),o()}function o(){t.reseeds=t.reseeds===4294967295?0:t.reseeds+1;var u=t.plugin.md.create();u.update(t.keyBytes);for(var c=1,f=0;f<32;++f)t.reseeds%c===0&&(u.update(t.pools[f].digest().getBytes()),t.pools[f].start()),c=c<<1;t.keyBytes=u.digest().getBytes(),u.start(),u.update(t.keyBytes);var d=u.digest().getBytes();t.key=t.plugin.formatKey(t.keyBytes),t.seed=t.plugin.formatSeed(d),t.generated=0}function l(u){var c=null,f=$r.util.globalScope,d=f.crypto||f.msCrypto;d&&d.getRandomValues&&(c=function(R){return d.getRandomValues(R)});var v=$r.util.createBuffer();if(c)for(;v.length()>16),m+=(y&32767)<<16,m+=y>>15,m=(m&2147483647)+(m>>31),B=m&4294967295;for(var I=0;I<3;++I)S=B>>>(I<<3),S^=Math.floor(Math.random()*256),v.putByte(S&255)}return v.getBytes(u)}return So?(t.seedFile=function(u,c){So.randomBytes(u,function(f,d){if(f)return c(f);c(null,d.toString())})},t.seedFileSync=function(u){return So.randomBytes(u).toString()}):(t.seedFile=function(u,c){try{c(null,l(u))}catch(f){c(f)}},t.seedFileSync=l),t.collect=function(u){for(var c=u.length,f=0;f>d&255);t.collect(f)},t.registerWorker=function(u){if(u===self)t.seedFile=function(f,d){function v(g){var C=g.data;C.forge&&C.forge.prng&&(self.removeEventListener("message",v),d(C.forge.prng.err,C.forge.prng.bytes))}self.addEventListener("message",v),self.postMessage({forge:{prng:{needed:f}}})};else{var c=function(f){var d=f.data;d.forge&&d.forge.prng&&t.seedFile(d.forge.prng.needed,function(v,g){u.postMessage({forge:{prng:{err:v,bytes:g}}})})};u.addEventListener("message",c)}},t};var Ct=me;(function(){if(Ct.random&&Ct.random.getBytes){Ct.random;return}(function(e){var t={},r=new Array(4),n=Ct.util.createBuffer();t.formatKey=function(f){var d=Ct.util.createBuffer(f);return f=new Array(4),f[0]=d.getInt32(),f[1]=d.getInt32(),f[2]=d.getInt32(),f[3]=d.getInt32(),Ct.aes._expandKey(f,!1)},t.formatSeed=function(f){var d=Ct.util.createBuffer(f);return f=new Array(4),f[0]=d.getInt32(),f[1]=d.getInt32(),f[2]=d.getInt32(),f[3]=d.getInt32(),f},t.cipher=function(f,d){return Ct.aes._updateBlock(f,d,r,!1),n.putInt32(r[0]),n.putInt32(r[1]),n.putInt32(r[2]),n.putInt32(r[3]),n.getBytes()},t.increment=function(f){return++f[3],f},t.md=Ct.md.sha256;function i(){var f=Ct.prng.create(t);return f.getBytes=function(d,v){return f.generate(d,v)},f.getBytesSync=function(d){return f.generate(d)},f}var a=i(),s=null,o=Ct.util.globalScope,l=o.crypto||o.msCrypto;if(l&&l.getRandomValues&&(s=function(f){return l.getRandomValues(f)}),Ct.options.usePureJavaScript||!Ct.util.isNodejs&&!s){if(a.collectInt(+new Date,32),typeof navigator<"u"){var u="";for(var c in navigator)try{typeof navigator[c]=="string"&&(u+=navigator[c])}catch{}a.collect(u),u=null}e&&(e().mousemove(function(f){a.collectInt(f.clientX,16),a.collectInt(f.clientY,16)}),e().keypress(function(f){a.collectInt(f.charCode,8)}))}if(!Ct.random)Ct.random=a;else for(var c in a)Ct.random[c]=a[c];Ct.random.createInstance=i,Ct.random})(typeof jQuery<"u"?jQuery:null)})();var Yt=me,Su=[217,120,249,196,25,221,181,237,40,233,253,121,74,160,216,157,198,126,55,131,43,118,83,142,98,76,100,136,68,139,251,162,23,154,89,245,135,179,79,19,97,69,109,141,9,129,125,50,189,143,64,235,134,183,123,11,240,149,33,34,92,107,78,130,84,214,101,147,206,96,178,28,115,86,192,20,167,140,241,220,18,117,202,31,59,190,228,209,66,61,212,48,163,60,182,38,111,191,14,218,70,105,7,87,39,242,29,155,188,148,67,3,248,17,199,246,144,239,62,231,6,195,213,47,200,102,30,215,8,232,234,222,128,82,238,247,132,170,114,172,53,77,106,42,150,26,210,113,90,21,73,116,75,159,208,94,4,24,164,236,194,224,65,110,15,81,203,204,36,145,175,80,161,244,112,57,153,124,58,133,35,184,180,122,252,2,54,91,37,85,151,49,45,93,250,152,227,138,146,174,5,223,41,16,103,108,186,201,211,0,230,207,225,158,168,44,99,22,1,63,88,226,137,169,13,56,52,27,171,51,255,176,187,72,12,95,185,177,205,46,197,243,219,71,229,165,156,119,10,166,32,104,254,127,193,173],ch=[1,2,3,5],YC=function(e,t){return e<>16-t},XC=function(e,t){return(e&65535)>>t|e<<16-t&65535};Yt.rc2=Yt.rc2||{};Yt.rc2.expandKey=function(e,t){typeof e=="string"&&(e=Yt.util.createBuffer(e)),t=t||128;var r=e,n=e.length(),i=t,a=Math.ceil(i/8),s=255>>(i&7),o;for(o=n;o<128;o++)r.putByte(Su[r.at(o-1)+r.at(o-n)&255]);for(r.setAt(128-a,Su[r.at(128-a)&s]),o=127-a;o>=0;o--)r.setAt(o,Su[r.at(o+1)^r.at(o+a)]);return r};var T1=function(e,t,r){var n=!1,i=null,a=null,s=null,o,l,u,c,f=[];for(e=Yt.rc2.expandKey(e,t),u=0;u<64;u++)f.push(e.getInt16Le());r?(o=function(g){for(u=0;u<4;u++)g[u]+=f[c]+(g[(u+3)%4]&g[(u+2)%4])+(~g[(u+3)%4]&g[(u+1)%4]),g[u]=YC(g[u],ch[u]),c++},l=function(g){for(u=0;u<4;u++)g[u]+=f[g[(u+3)%4]&63]}):(o=function(g){for(u=3;u>=0;u--)g[u]=XC(g[u],ch[u]),g[u]-=f[c]+(g[(u+3)%4]&g[(u+2)%4])+(~g[(u+3)%4]&g[(u+1)%4]),c--},l=function(g){for(u=3;u>=0;u--)g[u]-=f[g[(u+3)%4]&63]});var d=function(g){var C=[];for(u=0;u<4;u++){var I=i.getInt16Le();s!==null&&(r?I^=s.getInt16Le():s.putInt16Le(I)),C.push(I&65535)}c=r?0:63;for(var y=0;y=8;)d([[5,o],[1,l],[6,o],[1,l],[5,o]])},finish:function(g){var C=!0;if(r)if(g)C=g(8,i,!r);else{var I=i.length()===8?8:8-i.length();i.fillWithByte(I,I)}if(C&&(n=!0,v.update()),!r&&(C=i.length()===0,C))if(g)C=g(8,a,!r);else{var y=a.length(),m=a.at(y-1);m>y?C=!1:a.truncate(m)}return C}},v};Yt.rc2.startEncrypting=function(e,t,r){var n=Yt.rc2.createEncryptionCipher(e,128);return n.start(t,r),n};Yt.rc2.createEncryptionCipher=function(e,t){return T1(e,t,!0)};Yt.rc2.startDecrypting=function(e,t,r){var n=Yt.rc2.createDecryptionCipher(e,128);return n.start(t,r),n};Yt.rc2.createDecryptionCipher=function(e,t){return T1(e,t,!1)};var Pc=me;Pc.jsbn=Pc.jsbn||{};var fn;function K(e,t,r){this.data=[],e!=null&&(typeof e=="number"?this.fromNumber(e,t,r):t==null&&typeof e!="string"?this.fromString(e,256):this.fromString(e,t))}Pc.jsbn.BigInteger=K;function Be(){return new K(null)}function ZC(e,t,r,n,i,a){for(;--a>=0;){var s=t*this.data[e++]+r.data[n]+i;i=Math.floor(s/67108864),r.data[n++]=s&67108863}return i}function JC(e,t,r,n,i,a){for(var s=t&32767,o=t>>15;--a>=0;){var l=this.data[e]&32767,u=this.data[e++]>>15,c=o*l+u*s;l=s*l+((c&32767)<<15)+r.data[n]+(i&1073741823),i=(l>>>30)+(c>>>15)+o*u+(i>>>30),r.data[n++]=l&1073741823}return i}function fh(e,t,r,n,i,a){for(var s=t&16383,o=t>>14;--a>=0;){var l=this.data[e]&16383,u=this.data[e++]>>14,c=o*l+u*s;l=s*l+((c&16383)<<14)+r.data[n]+i,i=(l>>28)+(c>>14)+o*u,r.data[n++]=l&268435455}return i}typeof navigator>"u"?(K.prototype.am=fh,fn=28):navigator.appName=="Microsoft Internet Explorer"?(K.prototype.am=JC,fn=30):navigator.appName!="Netscape"?(K.prototype.am=ZC,fn=26):(K.prototype.am=fh,fn=28);K.prototype.DB=fn;K.prototype.DM=(1<=0;--t)e.data[t]=this.data[t];e.t=this.t,e.s=this.s}function rE(e){this.t=1,this.s=e<0?-1:0,e>0?this.data[0]=e:e<-1?this.data[0]=e+this.DV:this.t=0}function Pn(e){var t=Be();return t.fromInt(e),t}function nE(e,t){var r;if(t==16)r=4;else if(t==8)r=3;else if(t==256)r=8;else if(t==2)r=1;else if(t==32)r=5;else if(t==4)r=2;else{this.fromRadix(e,t);return}this.t=0,this.s=0;for(var n=e.length,i=!1,a=0;--n>=0;){var s=r==8?e[n]&255:w1(e,n);if(s<0){e.charAt(n)=="-"&&(i=!0);continue}i=!1,a==0?this.data[this.t++]=s:a+r>this.DB?(this.data[this.t-1]|=(s&(1<>this.DB-a):this.data[this.t-1]|=s<=this.DB&&(a-=this.DB)}r==8&&e[0]&128&&(this.s=-1,a>0&&(this.data[this.t-1]|=(1<0&&this.data[this.t-1]==e;)--this.t}function aE(e){if(this.s<0)return"-"+this.negate().toString(e);var t;if(e==16)t=4;else if(e==8)t=3;else if(e==2)t=1;else if(e==32)t=5;else if(e==4)t=2;else return this.toRadix(e);var r=(1<0)for(o>o)>0&&(i=!0,a=dh(n));s>=0;)o>(o+=this.DB-t)):(n=this.data[s]>>(o-=t)&r,o<=0&&(o+=this.DB,--s)),n>0&&(i=!0),i&&(a+=dh(n));return i?a:"0"}function sE(){var e=Be();return K.ZERO.subTo(this,e),e}function oE(){return this.s<0?this.negate():this}function lE(e){var t=this.s-e.s;if(t!=0)return t;var r=this.t;if(t=r-e.t,t!=0)return this.s<0?-t:t;for(;--r>=0;)if((t=this.data[r]-e.data[r])!=0)return t;return 0}function Bl(e){var t=1,r;return(r=e>>>16)!=0&&(e=r,t+=16),(r=e>>8)!=0&&(e=r,t+=8),(r=e>>4)!=0&&(e=r,t+=4),(r=e>>2)!=0&&(e=r,t+=2),(r=e>>1)!=0&&(e=r,t+=1),t}function uE(){return this.t<=0?0:this.DB*(this.t-1)+Bl(this.data[this.t-1]^this.s&this.DM)}function cE(e,t){var r;for(r=this.t-1;r>=0;--r)t.data[r+e]=this.data[r];for(r=e-1;r>=0;--r)t.data[r]=0;t.t=this.t+e,t.s=this.s}function fE(e,t){for(var r=e;r=0;--o)t.data[o+a+1]=this.data[o]>>n|s,s=(this.data[o]&i)<=0;--o)t.data[o]=0;t.data[a]=s,t.t=this.t+a+1,t.s=this.s,t.clamp()}function hE(e,t){t.s=this.s;var r=Math.floor(e/this.DB);if(r>=this.t){t.t=0;return}var n=e%this.DB,i=this.DB-n,a=(1<>n;for(var s=r+1;s>n;n>0&&(t.data[this.t-r-1]|=(this.s&a)<>=this.DB;if(e.t>=this.DB;n+=this.s}else{for(n+=this.s;r>=this.DB;n-=e.s}t.s=n<0?-1:0,n<-1?t.data[r++]=this.DV+n:n>0&&(t.data[r++]=n),t.t=r,t.clamp()}function gE(e,t){var r=this.abs(),n=e.abs(),i=r.t;for(t.t=i+n.t;--i>=0;)t.data[i]=0;for(i=0;i=0;)e.data[r]=0;for(r=0;r=t.DV&&(e.data[r+t.t]-=t.DV,e.data[r+t.t+1]=1)}e.t>0&&(e.data[e.t-1]+=t.am(r,t.data[r],e,2*r,0,1)),e.s=0,e.clamp()}function yE(e,t,r){var n=e.abs();if(!(n.t<=0)){var i=this.abs();if(i.t0?(n.lShiftTo(l,a),i.lShiftTo(l,r)):(n.copyTo(a),i.copyTo(r));var u=a.t,c=a.data[u-1];if(c!=0){var f=c*(1<1?a.data[u-2]>>this.F2:0),d=this.FV/f,v=(1<=0&&(r.data[r.t++]=1,r.subTo(y,r)),K.ONE.dlShiftTo(u,y),y.subTo(a,a);a.t=0;){var m=r.data[--C]==c?this.DM:Math.floor(r.data[C]*d+(r.data[C-1]+g)*v);if((r.data[C]+=a.am(0,m,r,I,0,u))0&&r.rShiftTo(l,r),s<0&&K.ZERO.subTo(r,r)}}}function mE(e){var t=Be();return this.abs().divRemTo(e,null,t),this.s<0&&t.compareTo(K.ZERO)>0&&e.subTo(t,t),t}function Ii(e){this.m=e}function CE(e){return e.s<0||e.compareTo(this.m)>=0?e.mod(this.m):e}function EE(e){return e}function SE(e){e.divRemTo(this.m,null,e)}function xE(e,t,r){e.multiplyTo(t,r),this.reduce(r)}function TE(e,t){e.squareTo(t),this.reduce(t)}Ii.prototype.convert=CE;Ii.prototype.revert=EE;Ii.prototype.reduce=SE;Ii.prototype.mulTo=xE;Ii.prototype.sqrTo=TE;function wE(){if(this.t<1)return 0;var e=this.data[0];if(!(e&1))return 0;var t=e&3;return t=t*(2-(e&15)*t)&15,t=t*(2-(e&255)*t)&255,t=t*(2-((e&65535)*t&65535))&65535,t=t*(2-e*t%this.DV)%this.DV,t>0?this.DV-t:-t}function _i(e){this.m=e,this.mp=e.invDigit(),this.mpl=this.mp&32767,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(t,t),t}function _E(e){var t=Be();return e.copyTo(t),this.reduce(t),t}function AE(e){for(;e.t<=this.mt2;)e.data[e.t++]=0;for(var t=0;t>15)*this.mpl&this.um)<<15)&e.DM;for(r=t+this.m.t,e.data[r]+=this.m.am(0,n,e,t,0,this.m.t);e.data[r]>=e.DV;)e.data[r]-=e.DV,e.data[++r]++}e.clamp(),e.drShiftTo(this.m.t,e),e.compareTo(this.m)>=0&&e.subTo(this.m,e)}function BE(e,t){e.squareTo(t),this.reduce(t)}function kE(e,t,r){e.multiplyTo(t,r),this.reduce(r)}_i.prototype.convert=IE;_i.prototype.revert=_E;_i.prototype.reduce=AE;_i.prototype.mulTo=kE;_i.prototype.sqrTo=BE;function bE(){return(this.t>0?this.data[0]&1:this.s)==0}function NE(e,t){if(e>4294967295||e<1)return K.ONE;var r=Be(),n=Be(),i=t.convert(this),a=Bl(e)-1;for(i.copyTo(r);--a>=0;)if(t.sqrTo(r,n),(e&1<0)t.mulTo(n,i,r);else{var s=r;r=n,n=s}return t.revert(r)}function DE(e,t){var r;return e<256||t.isEven()?r=new Ii(t):r=new _i(t),this.exp(e,r)}K.prototype.copyTo=tE;K.prototype.fromInt=rE;K.prototype.fromString=nE;K.prototype.clamp=iE;K.prototype.dlShiftTo=cE;K.prototype.drShiftTo=fE;K.prototype.lShiftTo=dE;K.prototype.rShiftTo=hE;K.prototype.subTo=pE;K.prototype.multiplyTo=gE;K.prototype.squareTo=vE;K.prototype.divRemTo=yE;K.prototype.invDigit=wE;K.prototype.isEven=bE;K.prototype.exp=NE;K.prototype.toString=aE;K.prototype.negate=sE;K.prototype.abs=oE;K.prototype.compareTo=lE;K.prototype.bitLength=uE;K.prototype.mod=mE;K.prototype.modPowInt=DE;K.ZERO=Pn(0);K.ONE=Pn(1);function RE(){var e=Be();return this.copyTo(e),e}function LE(){if(this.s<0){if(this.t==1)return this.data[0]-this.DV;if(this.t==0)return-1}else{if(this.t==1)return this.data[0];if(this.t==0)return 0}return(this.data[1]&(1<<32-this.DB)-1)<>24}function PE(){return this.t==0?this.s:this.data[0]<<16>>16}function UE(e){return Math.floor(Math.LN2*this.DB/Math.log(e))}function ME(){return this.s<0?-1:this.t<=0||this.t==1&&this.data[0]<=0?0:1}function FE(e){if(e==null&&(e=10),this.signum()==0||e<2||e>36)return"0";var t=this.chunkSize(e),r=Math.pow(e,t),n=Pn(r),i=Be(),a=Be(),s="";for(this.divRemTo(n,i,a);i.signum()>0;)s=(r+a.intValue()).toString(e).substr(1)+s,i.divRemTo(n,i,a);return a.intValue().toString(e)+s}function VE(e,t){this.fromInt(0),t==null&&(t=10);for(var r=this.chunkSize(t),n=Math.pow(t,r),i=!1,a=0,s=0,o=0;o=r&&(this.dMultiply(n),this.dAddOffset(s,0),a=0,s=0)}a>0&&(this.dMultiply(Math.pow(t,a)),this.dAddOffset(s,0)),i&&K.ZERO.subTo(this,this)}function jE(e,t,r){if(typeof t=="number")if(e<2)this.fromInt(1);else for(this.fromNumber(e,r),this.testBit(e-1)||this.bitwiseTo(K.ONE.shiftLeft(e-1),s0,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(t);)this.dAddOffset(2,0),this.bitLength()>e&&this.subTo(K.ONE.shiftLeft(e-1),this);else{var n=new Array,i=e&7;n.length=(e>>3)+1,t.nextBytes(n),i>0?n[0]&=(1<0)for(r>r)!=(this.s&this.DM)>>r&&(t[i++]=n|this.s<=0;)r<8?(n=(this.data[e]&(1<>(r+=this.DB-8)):(n=this.data[e]>>(r-=8)&255,r<=0&&(r+=this.DB,--e)),n&128&&(n|=-256),i==0&&(this.s&128)!=(n&128)&&++i,(i>0||n!=this.s)&&(t[i++]=n);return t}function zE(e){return this.compareTo(e)==0}function HE(e){return this.compareTo(e)<0?this:e}function qE(e){return this.compareTo(e)>0?this:e}function $E(e,t,r){var n,i,a=Math.min(e.t,this.t);for(n=0;n>=16,t+=16),e&255||(e>>=8,t+=8),e&15||(e>>=4,t+=4),e&3||(e>>=2,t+=2),e&1||++t,t}function rS(){for(var e=0;e=this.t?this.s!=0:(this.data[t]&1<>=this.DB;if(e.t>=this.DB;n+=this.s}else{for(n+=this.s;r>=this.DB;n+=e.s}t.s=n<0?-1:0,n>0?t.data[r++]=n:n<-1&&(t.data[r++]=this.DV+n),t.t=r,t.clamp()}function fS(e){var t=Be();return this.addTo(e,t),t}function dS(e){var t=Be();return this.subTo(e,t),t}function hS(e){var t=Be();return this.multiplyTo(e,t),t}function pS(e){var t=Be();return this.divRemTo(e,t,null),t}function gS(e){var t=Be();return this.divRemTo(e,null,t),t}function vS(e){var t=Be(),r=Be();return this.divRemTo(e,t,r),new Array(t,r)}function yS(e){this.data[this.t]=this.am(0,e-1,this,0,0,this.t),++this.t,this.clamp()}function mS(e,t){if(e!=0){for(;this.t<=t;)this.data[this.t++]=0;for(this.data[t]+=e;this.data[t]>=this.DV;)this.data[t]-=this.DV,++t>=this.t&&(this.data[this.t++]=0),++this.data[t]}}function ks(){}function A1(e){return e}function CS(e,t,r){e.multiplyTo(t,r)}function ES(e,t){e.squareTo(t)}ks.prototype.convert=A1;ks.prototype.revert=A1;ks.prototype.mulTo=CS;ks.prototype.sqrTo=ES;function SS(e){return this.exp(e,new ks)}function xS(e,t,r){var n=Math.min(this.t+e.t,t);for(r.s=0,r.t=n;n>0;)r.data[--n]=0;var i;for(i=r.t-this.t;n=0;)r.data[n]=0;for(n=Math.max(t-this.t,0);n2*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=Be();return e.copyTo(t),this.reduce(t),t}function IS(e){return e}function _S(e){for(e.drShiftTo(this.m.t-1,this.r2),e.t>this.m.t+1&&(e.t=this.m.t+1,e.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);e.compareTo(this.r2)<0;)e.dAddOffset(1,this.m.t+1);for(e.subTo(this.r2,e);e.compareTo(this.m)>=0;)e.subTo(this.m,e)}function AS(e,t){e.squareTo(t),this.reduce(t)}function BS(e,t,r){e.multiplyTo(t,r),this.reduce(r)}ma.prototype.convert=wS;ma.prototype.revert=IS;ma.prototype.reduce=_S;ma.prototype.mulTo=BS;ma.prototype.sqrTo=AS;function kS(e,t){var r=e.bitLength(),n,i=Pn(1),a;if(r<=0)return i;r<18?n=1:r<48?n=3:r<144?n=4:r<768?n=5:n=6,r<8?a=new Ii(t):t.isEven()?a=new ma(t):a=new _i(t);var s=new Array,o=3,l=n-1,u=(1<1){var c=Be();for(a.sqrTo(s[1],c);o<=u;)s[o]=Be(),a.mulTo(c,s[o-2],s[o]),o+=2}var f=e.t-1,d,v=!0,g=Be(),C;for(r=Bl(e.data[f])-1;f>=0;){for(r>=l?d=e.data[f]>>r-l&u:(d=(e.data[f]&(1<0&&(d|=e.data[f-1]>>this.DB+r-l)),o=n;!(d&1);)d>>=1,--o;if((r-=o)<0&&(r+=this.DB,--f),v)s[d].copyTo(i),v=!1;else{for(;o>1;)a.sqrTo(i,g),a.sqrTo(g,i),o-=2;o>0?a.sqrTo(i,g):(C=i,i=g,g=C),a.mulTo(g,s[d],i)}for(;f>=0&&!(e.data[f]&1<0&&(t.rShiftTo(a,t),r.rShiftTo(a,r));t.signum()>0;)(i=t.getLowestSetBit())>0&&t.rShiftTo(i,t),(i=r.getLowestSetBit())>0&&r.rShiftTo(i,r),t.compareTo(r)>=0?(t.subTo(r,t),t.rShiftTo(1,t)):(r.subTo(t,r),r.rShiftTo(1,r));return a>0&&r.lShiftTo(a,r),r}function NS(e){if(e<=0)return 0;var t=this.DV%e,r=this.s<0?e-1:0;if(this.t>0)if(t==0)r=this.data[0]%e;else for(var n=this.t-1;n>=0;--n)r=(t*r+this.data[n])%e;return r}function DS(e){var t=e.isEven();if(this.isEven()&&t||e.signum()==0)return K.ZERO;for(var r=e.clone(),n=this.clone(),i=Pn(1),a=Pn(0),s=Pn(0),o=Pn(1);r.signum()!=0;){for(;r.isEven();)r.rShiftTo(1,r),t?((!i.isEven()||!a.isEven())&&(i.addTo(this,i),a.subTo(e,a)),i.rShiftTo(1,i)):a.isEven()||a.subTo(e,a),a.rShiftTo(1,a);for(;n.isEven();)n.rShiftTo(1,n),t?((!s.isEven()||!o.isEven())&&(s.addTo(this,s),o.subTo(e,o)),s.rShiftTo(1,s)):o.isEven()||o.subTo(e,o),o.rShiftTo(1,o);r.compareTo(n)>=0?(r.subTo(n,r),t&&i.subTo(s,i),a.subTo(o,a)):(n.subTo(r,n),t&&s.subTo(i,s),o.subTo(a,o))}if(n.compareTo(K.ONE)!=0)return K.ZERO;if(o.compareTo(e)>=0)return o.subtract(e);if(o.signum()<0)o.addTo(e,o);else return o;return o.signum()<0?o.add(e):o}var Lr=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509],RS=(1<<26)/Lr[Lr.length-1];function LS(e){var t,r=this.abs();if(r.t==1&&r.data[0]<=Lr[Lr.length-1]){for(t=0;t=0);var o=a.modPow(n,this);if(o.compareTo(K.ONE)!=0&&o.compareTo(t)!=0){for(var l=1;l++>>0,s>>>0];for(var o=n.fullMessageLength.length-1;o>=0;--o)n.fullMessageLength[o]+=s[1],s[1]=s[0]+(n.fullMessageLength[o]/4294967296>>>0),n.fullMessageLength[o]=n.fullMessageLength[o]>>>0,s[0]=s[1]/4294967296>>>0;return t.putBytes(i),hh(e,r,t),(t.read>2048||t.length()===0)&&t.compact(),n},n.digest=function(){var i=Xr.util.createBuffer();i.putBytes(t.bytes());var a=n.fullMessageLength[n.fullMessageLength.length-1]+n.messageLengthSize,s=a&n.blockLength-1;i.putBytes(Uc.substr(0,n.blockLength-s));for(var o,l,u=n.fullMessageLength[0]*8,c=0;c>>0,u+=l,i.putInt32(u>>>0),u=o>>>0;i.putInt32(u);var f={h0:e.h0,h1:e.h1,h2:e.h2,h3:e.h3,h4:e.h4};hh(f,r,i);var d=Xr.util.createBuffer();return d.putInt32(f.h0),d.putInt32(f.h1),d.putInt32(f.h2),d.putInt32(f.h3),d.putInt32(f.h4),d},n};var Uc=null,k1=!1;function US(){Uc=String.fromCharCode(128),Uc+=Xr.util.fillString(String.fromCharCode(0),64),k1=!0}function hh(e,t,r){for(var n,i,a,s,o,l,u,c,f=r.length();f>=64;){for(i=e.h0,a=e.h1,s=e.h2,o=e.h3,l=e.h4,c=0;c<16;++c)n=r.getInt32(),t[c]=n,u=o^a&(s^o),n=(i<<5|i>>>27)+u+l+1518500249+n,l=o,o=s,s=(a<<30|a>>>2)>>>0,a=i,i=n;for(;c<20;++c)n=t[c-3]^t[c-8]^t[c-14]^t[c-16],n=n<<1|n>>>31,t[c]=n,u=o^a&(s^o),n=(i<<5|i>>>27)+u+l+1518500249+n,l=o,o=s,s=(a<<30|a>>>2)>>>0,a=i,i=n;for(;c<32;++c)n=t[c-3]^t[c-8]^t[c-14]^t[c-16],n=n<<1|n>>>31,t[c]=n,u=a^s^o,n=(i<<5|i>>>27)+u+l+1859775393+n,l=o,o=s,s=(a<<30|a>>>2)>>>0,a=i,i=n;for(;c<40;++c)n=t[c-6]^t[c-16]^t[c-28]^t[c-32],n=n<<2|n>>>30,t[c]=n,u=a^s^o,n=(i<<5|i>>>27)+u+l+1859775393+n,l=o,o=s,s=(a<<30|a>>>2)>>>0,a=i,i=n;for(;c<60;++c)n=t[c-6]^t[c-16]^t[c-28]^t[c-32],n=n<<2|n>>>30,t[c]=n,u=a&s|o&(a^s),n=(i<<5|i>>>27)+u+l+2400959708+n,l=o,o=s,s=(a<<30|a>>>2)>>>0,a=i,i=n;for(;c<80;++c)n=t[c-6]^t[c-16]^t[c-28]^t[c-32],n=n<<2|n>>>30,t[c]=n,u=a^s^o,n=(i<<5|i>>>27)+u+l+3395469782+n,l=o,o=s,s=(a<<30|a>>>2)>>>0,a=i,i=n;e.h0=e.h0+i|0,e.h1=e.h1+a|0,e.h2=e.h2+s|0,e.h3=e.h3+o|0,e.h4=e.h4+l|0,f-=64}}var Jr=me,b1=Jr.pkcs1=Jr.pkcs1||{};b1.encode_rsa_oaep=function(e,t,r){var n,i,a,s;typeof r=="string"?(n=r,i=arguments[3]||void 0,a=arguments[4]||void 0):r&&(n=r.label||void 0,i=r.seed||void 0,a=r.md||void 0,r.mgf1&&r.mgf1.md&&(s=r.mgf1.md)),a?a.start():a=Jr.md.sha1.create(),s||(s=a);var o=Math.ceil(e.n.bitLength()/8),l=o-2*a.digestLength-2;if(t.length>l){var u=new Error("RSAES-OAEP input message length is too long.");throw u.length=t.length,u.maxLength=l,u}n||(n=""),a.update(n,"raw");for(var c=a.digest(),f="",d=l-t.length,v=0;v>24&255,a>>16&255,a>>8&255,a&255);r.start(),r.update(e+s),n+=r.digest().getBytes()}return n.substring(0,t)}var In=me;(function(){if(In.prime){In.prime;return}var e=In.prime=In.prime||{},t=In.jsbn.BigInteger,r=[6,4,2,4,2,4,6,2],n=new t(null);n.fromInt(30);var i=function(f,d){return f|d};e.generateProbablePrime=function(f,d,v){typeof d=="function"&&(v=d,d={}),d=d||{};var g=d.algorithm||"PRIMEINC";typeof g=="string"&&(g={name:g}),g.options=g.options||{};var C=d.prng||In.random,I={nextBytes:function(y){for(var m=C.getBytesSync(y.length),S=0;Sd&&(f=u(d,v)),f.isProbablePrime(C))return y(null,f);f.dAddOffset(r[g++%8],0)}while(I<0||+new Date-m"u")return s(f,d,v,g);var C=u(f,d),I=v.workers,y=v.workLoad||100,m=y*30/8,S=v.workerScript||"forge/prime.worker.js";if(I===-1)return In.util.estimateCores(function(R,L){R&&(L=2),I=L-1,B()});B();function B(){I=Math.max(1,I);for(var R=[],L=0;Lf&&(C=u(f,d));var pe=C.toString(16);Q.target.postMessage({hex:pe,workLoad:y}),C.dAddOffset(m,0)}}}}function u(f,d){var v=new t(f,d),g=f-1;return v.testBit(g)||v.bitwiseTo(t.ONE.shiftLeft(g),i,v),v.dAddOffset(31-v.mod(n).byteValue(),0),v}function c(f){return f<=100?27:f<=150?18:f<=200?15:f<=250?12:f<=300?9:f<=350?8:f<=400?7:f<=500?6:f<=600?5:f<=800?4:f<=1250?3:2}})();var oe=me;if(typeof _e>"u")var _e=oe.jsbn.BigInteger;var Mc=oe.util.isNodejs?i0:null,O=oe.asn1,_r=oe.util;oe.pki=oe.pki||{};oe.pki.rsa=oe.rsa=oe.rsa||{};var he=oe.pki,MS=[6,4,2,4,2,4,6,2],FS={name:"PrivateKeyInfo",tagClass:O.Class.UNIVERSAL,type:O.Type.SEQUENCE,constructed:!0,value:[{name:"PrivateKeyInfo.version",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"PrivateKeyInfo.privateKeyAlgorithm",tagClass:O.Class.UNIVERSAL,type:O.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:O.Class.UNIVERSAL,type:O.Type.OID,constructed:!1,capture:"privateKeyOid"}]},{name:"PrivateKeyInfo",tagClass:O.Class.UNIVERSAL,type:O.Type.OCTETSTRING,constructed:!1,capture:"privateKey"}]},VS={name:"RSAPrivateKey",tagClass:O.Class.UNIVERSAL,type:O.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPrivateKey.version",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"RSAPrivateKey.modulus",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyModulus"},{name:"RSAPrivateKey.publicExponent",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyPublicExponent"},{name:"RSAPrivateKey.privateExponent",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyPrivateExponent"},{name:"RSAPrivateKey.prime1",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyPrime1"},{name:"RSAPrivateKey.prime2",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyPrime2"},{name:"RSAPrivateKey.exponent1",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyExponent1"},{name:"RSAPrivateKey.exponent2",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyExponent2"},{name:"RSAPrivateKey.coefficient",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"privateKeyCoefficient"}]},jS={name:"RSAPublicKey",tagClass:O.Class.UNIVERSAL,type:O.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPublicKey.modulus",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"publicKeyModulus"},{name:"RSAPublicKey.exponent",tagClass:O.Class.UNIVERSAL,type:O.Type.INTEGER,constructed:!1,capture:"publicKeyExponent"}]},KS=oe.pki.rsa.publicKeyValidator={name:"SubjectPublicKeyInfo",tagClass:O.Class.UNIVERSAL,type:O.Type.SEQUENCE,constructed:!0,captureAsn1:"subjectPublicKeyInfo",value:[{name:"SubjectPublicKeyInfo.AlgorithmIdentifier",tagClass:O.Class.UNIVERSAL,type:O.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:O.Class.UNIVERSAL,type:O.Type.OID,constructed:!1,capture:"publicKeyOid"}]},{name:"SubjectPublicKeyInfo.subjectPublicKey",tagClass:O.Class.UNIVERSAL,type:O.Type.BITSTRING,constructed:!1,value:[{name:"SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey",tagClass:O.Class.UNIVERSAL,type:O.Type.SEQUENCE,constructed:!0,optional:!0,captureAsn1:"rsaPublicKey"}]}]},zS={name:"DigestInfo",tagClass:O.Class.UNIVERSAL,type:O.Type.SEQUENCE,constructed:!0,value:[{name:"DigestInfo.DigestAlgorithm",tagClass:O.Class.UNIVERSAL,type:O.Type.SEQUENCE,constructed:!0,value:[{name:"DigestInfo.DigestAlgorithm.algorithmIdentifier",tagClass:O.Class.UNIVERSAL,type:O.Type.OID,constructed:!1,capture:"algorithmIdentifier"},{name:"DigestInfo.DigestAlgorithm.parameters",tagClass:O.Class.UNIVERSAL,type:O.Type.NULL,capture:"parameters",optional:!0,constructed:!1}]},{name:"DigestInfo.digest",tagClass:O.Class.UNIVERSAL,type:O.Type.OCTETSTRING,constructed:!1,capture:"digest"}]},HS=function(e){var t;if(e.algorithm in he.oids)t=he.oids[e.algorithm];else{var r=new Error("Unknown message digest algorithm.");throw r.algorithm=e.algorithm,r}var n=O.oidToDer(t).getBytes(),i=O.create(O.Class.UNIVERSAL,O.Type.SEQUENCE,!0,[]),a=O.create(O.Class.UNIVERSAL,O.Type.SEQUENCE,!0,[]);a.value.push(O.create(O.Class.UNIVERSAL,O.Type.OID,!1,n)),a.value.push(O.create(O.Class.UNIVERSAL,O.Type.NULL,!1,""));var s=O.create(O.Class.UNIVERSAL,O.Type.OCTETSTRING,!1,e.digest().getBytes());return i.value.push(a),i.value.push(s),O.toDer(i).getBytes()},N1=function(e,t,r){if(r)return e.modPow(t.e,t.n);if(!t.p||!t.q)return e.modPow(t.d,t.n);t.dP||(t.dP=t.d.mod(t.p.subtract(_e.ONE))),t.dQ||(t.dQ=t.d.mod(t.q.subtract(_e.ONE))),t.qInv||(t.qInv=t.q.modInverse(t.p));var n;do n=new _e(oe.util.bytesToHex(oe.random.getBytes(t.n.bitLength()/8)),16);while(n.compareTo(t.n)>=0||!n.gcd(t.n).equals(_e.ONE));e=e.multiply(n.modPow(t.e,t.n)).mod(t.n);for(var i=e.mod(t.p).modPow(t.dP,t.p),a=e.mod(t.q).modPow(t.dQ,t.q);i.compareTo(a)<0;)i=i.add(t.p);var s=i.subtract(a).multiply(t.qInv).mod(t.p).multiply(t.q).add(a);return s=s.multiply(n.modInverse(t.n)).mod(t.n),s};he.rsa.encrypt=function(e,t,r){var n=r,i,a=Math.ceil(t.n.bitLength()/8);r!==!1&&r!==!0?(n=r===2,i=D1(e,t,r)):(i=oe.util.createBuffer(),i.putBytes(e));for(var s=new _e(i.toHex(),16),o=N1(s,t,n),l=o.toString(16),u=oe.util.createBuffer(),c=a-Math.ceil(l.length/2);c>0;)u.putByte(0),--c;return u.putBytes(oe.util.hexToBytes(l)),u.getBytes()};he.rsa.decrypt=function(e,t,r,n){var i=Math.ceil(t.n.bitLength()/8);if(e.length!==i){var a=new Error("Encrypted message length is invalid.");throw a.length=e.length,a.expected=i,a}var s=new _e(oe.util.createBuffer(e).toHex(),16);if(s.compareTo(t.n)>=0)throw new Error("Encrypted message is invalid.");for(var o=N1(s,t,r),l=o.toString(16),u=oe.util.createBuffer(),c=i-Math.ceil(l.length/2);c>0;)u.putByte(0),--c;return u.putBytes(oe.util.hexToBytes(l)),n!==!1?Xo(u.getBytes(),t,r):u.getBytes()};he.rsa.createKeyPairGenerationState=function(e,t,r){typeof e=="string"&&(e=parseInt(e,10)),e=e||2048,r=r||{};var n=r.prng||oe.random,i={nextBytes:function(o){for(var l=n.getBytesSync(o.length),u=0;u>1,pBits:e-(e>>1),pqState:0,num:null,keys:null},s.e.fromInt(s.eInt);else throw new Error("Invalid key generation algorithm: "+a);return s};he.rsa.stepKeyPairGenerationState=function(e,t){"algorithm"in e||(e.algorithm="PRIMEINC");var r=new _e(null);r.fromInt(30);for(var n=0,i=function(f,d){return f|d},a=+new Date,s,o=0;e.keys===null&&(t<=0||ol?e.pqState=0:e.num.isProbablePrime($S(e.num.bitLength()))?++e.pqState:e.num.dAddOffset(MS[n++%8],0):e.pqState===2?e.pqState=e.num.subtract(_e.ONE).gcd(e.e).compareTo(_e.ONE)===0?3:0:e.pqState===3&&(e.pqState=0,e.p===null?e.p=e.num:e.q=e.num,e.p!==null&&e.q!==null&&++e.state,e.num=null)}else if(e.state===1)e.p.compareTo(e.q)<0&&(e.num=e.p,e.p=e.q,e.q=e.num),++e.state;else if(e.state===2)e.p1=e.p.subtract(_e.ONE),e.q1=e.q.subtract(_e.ONE),e.phi=e.p1.multiply(e.q1),++e.state;else if(e.state===3)e.phi.gcd(e.e).compareTo(_e.ONE)===0?++e.state:(e.p=null,e.q=null,e.state=0);else if(e.state===4)e.n=e.p.multiply(e.q),e.n.bitLength()===e.bits?++e.state:(e.q=null,e.state=0);else if(e.state===5){var c=e.e.modInverse(e.phi);e.keys={privateKey:he.rsa.setPrivateKey(e.n,e.e,c,e.p,e.q,c.mod(e.p1),c.mod(e.q1),e.q.modInverse(e.p)),publicKey:he.rsa.setPublicKey(e.n,e.e)}}s=+new Date,o+=s-a,a=s}return e.keys!==null};he.rsa.generateKeyPair=function(e,t,r,n){if(arguments.length===1?typeof e=="object"?(r=e,e=void 0):typeof e=="function"&&(n=e,e=void 0):arguments.length===2?typeof e=="number"?typeof t=="function"?(n=t,t=void 0):typeof t!="number"&&(r=t,t=void 0):(r=e,n=t,e=void 0,t=void 0):arguments.length===3&&(typeof t=="number"?typeof r=="function"&&(n=r,r=void 0):(n=r,r=t,t=void 0)),r=r||{},e===void 0&&(e=r.bits||2048),t===void 0&&(t=r.e||65537),!oe.options.usePureJavaScript&&!r.prng&&e>=256&&e<=16384&&(t===65537||t===3)){if(n){if(ph("generateKeyPair"))return Mc.generateKeyPair("rsa",{modulusLength:e,publicExponent:t,publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem"}},function(o,l,u){if(o)return n(o);n(null,{privateKey:he.privateKeyFromPem(u),publicKey:he.publicKeyFromPem(l)})});if(gh("generateKey")&&gh("exportKey"))return _r.globalScope.crypto.subtle.generateKey({name:"RSASSA-PKCS1-v1_5",modulusLength:e,publicExponent:yh(t),hash:{name:"SHA-256"}},!0,["sign","verify"]).then(function(o){return _r.globalScope.crypto.subtle.exportKey("pkcs8",o.privateKey)}).then(void 0,function(o){n(o)}).then(function(o){if(o){var l=he.privateKeyFromAsn1(O.fromDer(oe.util.createBuffer(o)));n(null,{privateKey:l,publicKey:he.setRsaPublicKey(l.n,l.e)})}});if(vh("generateKey")&&vh("exportKey")){var i=_r.globalScope.msCrypto.subtle.generateKey({name:"RSASSA-PKCS1-v1_5",modulusLength:e,publicExponent:yh(t),hash:{name:"SHA-256"}},!0,["sign","verify"]);i.oncomplete=function(o){var l=o.target.result,u=_r.globalScope.msCrypto.subtle.exportKey("pkcs8",l.privateKey);u.oncomplete=function(c){var f=c.target.result,d=he.privateKeyFromAsn1(O.fromDer(oe.util.createBuffer(f)));n(null,{privateKey:d,publicKey:he.setRsaPublicKey(d.n,d.e)})},u.onerror=function(c){n(c)}},i.onerror=function(o){n(o)};return}}else if(ph("generateKeyPairSync")){var a=Mc.generateKeyPairSync("rsa",{modulusLength:e,publicExponent:t,publicKeyEncoding:{type:"spki",format:"pem"},privateKeyEncoding:{type:"pkcs8",format:"pem"}});return{privateKey:he.privateKeyFromPem(a.privateKey),publicKey:he.publicKeyFromPem(a.publicKey)}}}var s=he.rsa.createKeyPairGenerationState(e,t,r);if(!n)return he.rsa.stepKeyPairGenerationState(s,0),s.keys;qS(s,r,n)};he.setRsaPublicKey=he.rsa.setPublicKey=function(e,t){var r={n:e,e:t};return r.encrypt=function(n,i,a){if(typeof i=="string"?i=i.toUpperCase():i===void 0&&(i="RSAES-PKCS1-V1_5"),i==="RSAES-PKCS1-V1_5")i={encode:function(o,l,u){return D1(o,l,2).getBytes()}};else if(i==="RSA-OAEP"||i==="RSAES-OAEP")i={encode:function(o,l){return oe.pkcs1.encode_rsa_oaep(l,o,a)}};else if(["RAW","NONE","NULL",null].indexOf(i)!==-1)i={encode:function(o){return o}};else if(typeof i=="string")throw new Error('Unsupported encryption scheme: "'+i+'".');var s=i.encode(n,r,!0);return he.rsa.encrypt(s,r,!0)},r.verify=function(n,i,a,s){typeof a=="string"?a=a.toUpperCase():a===void 0&&(a="RSASSA-PKCS1-V1_5"),s===void 0&&(s={_parseAllDigestBytes:!0}),"_parseAllDigestBytes"in s||(s._parseAllDigestBytes=!0),a==="RSASSA-PKCS1-V1_5"?a={verify:function(l,u){u=Xo(u,r,!0);var c=O.fromDer(u,{parseAllBytes:s._parseAllDigestBytes}),f={},d=[];if(!O.validate(c,zS,f,d)){var v=new Error("ASN.1 object does not contain a valid RSASSA-PKCS1-v1_5 DigestInfo value.");throw v.errors=d,v}var g=O.derToOid(f.algorithmIdentifier);if(!(g===oe.oids.md2||g===oe.oids.md5||g===oe.oids.sha1||g===oe.oids.sha224||g===oe.oids.sha256||g===oe.oids.sha384||g===oe.oids.sha512||g===oe.oids["sha512-224"]||g===oe.oids["sha512-256"])){var v=new Error("Unknown RSASSA-PKCS1-v1_5 DigestAlgorithm identifier.");throw v.oid=g,v}if((g===oe.oids.md2||g===oe.oids.md5)&&!("parameters"in f))throw new Error("ASN.1 object does not contain a valid RSASSA-PKCS1-v1_5 DigestInfo value. Missing algorithm identifer NULL parameters.");return l===f.digest}}:(a==="NONE"||a==="NULL"||a===null)&&(a={verify:function(l,u){return u=Xo(u,r,!0),l===u}});var o=he.rsa.decrypt(i,r,!0,!1);return a.verify(n,o,r.n.bitLength())},r};he.setRsaPrivateKey=he.rsa.setPrivateKey=function(e,t,r,n,i,a,s,o){var l={n:e,e:t,d:r,p:n,q:i,dP:a,dQ:s,qInv:o};return l.decrypt=function(u,c,f){typeof c=="string"?c=c.toUpperCase():c===void 0&&(c="RSAES-PKCS1-V1_5");var d=he.rsa.decrypt(u,l,!1,!1);if(c==="RSAES-PKCS1-V1_5")c={decode:Xo};else if(c==="RSA-OAEP"||c==="RSAES-OAEP")c={decode:function(v,g){return oe.pkcs1.decode_rsa_oaep(g,v,f)}};else if(["RAW","NONE","NULL",null].indexOf(c)!==-1)c={decode:function(v){return v}};else throw new Error('Unsupported encryption scheme: "'+c+'".');return c.decode(d,l,!1)},l.sign=function(u,c){var f=!1;typeof c=="string"&&(c=c.toUpperCase()),c===void 0||c==="RSASSA-PKCS1-V1_5"?(c={encode:HS},f=1):(c==="NONE"||c==="NULL"||c===null)&&(c={encode:function(){return u}},f=1);var d=c.encode(u,l.n.bitLength());return he.rsa.encrypt(d,l,f)},l};he.wrapRsaPrivateKey=function(e){return O.create(O.Class.UNIVERSAL,O.Type.SEQUENCE,!0,[O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,O.integerToDer(0).getBytes()),O.create(O.Class.UNIVERSAL,O.Type.SEQUENCE,!0,[O.create(O.Class.UNIVERSAL,O.Type.OID,!1,O.oidToDer(he.oids.rsaEncryption).getBytes()),O.create(O.Class.UNIVERSAL,O.Type.NULL,!1,"")]),O.create(O.Class.UNIVERSAL,O.Type.OCTETSTRING,!1,O.toDer(e).getBytes())])};he.privateKeyFromAsn1=function(e){var t={},r=[];if(O.validate(e,FS,t,r)&&(e=O.fromDer(oe.util.createBuffer(t.privateKey))),t={},r=[],!O.validate(e,VS,t,r)){var n=new Error("Cannot read private key. ASN.1 object does not contain an RSAPrivateKey.");throw n.errors=r,n}var i,a,s,o,l,u,c,f;return i=oe.util.createBuffer(t.privateKeyModulus).toHex(),a=oe.util.createBuffer(t.privateKeyPublicExponent).toHex(),s=oe.util.createBuffer(t.privateKeyPrivateExponent).toHex(),o=oe.util.createBuffer(t.privateKeyPrime1).toHex(),l=oe.util.createBuffer(t.privateKeyPrime2).toHex(),u=oe.util.createBuffer(t.privateKeyExponent1).toHex(),c=oe.util.createBuffer(t.privateKeyExponent2).toHex(),f=oe.util.createBuffer(t.privateKeyCoefficient).toHex(),he.setRsaPrivateKey(new _e(i,16),new _e(a,16),new _e(s,16),new _e(o,16),new _e(l,16),new _e(u,16),new _e(c,16),new _e(f,16))};he.privateKeyToAsn1=he.privateKeyToRSAPrivateKey=function(e){return O.create(O.Class.UNIVERSAL,O.Type.SEQUENCE,!0,[O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,O.integerToDer(0).getBytes()),O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.n)),O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.e)),O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.d)),O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.p)),O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.q)),O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.dP)),O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.dQ)),O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.qInv))])};he.publicKeyFromAsn1=function(e){var t={},r=[];if(O.validate(e,KS,t,r)){var n=O.derToOid(t.publicKeyOid);if(n!==he.oids.rsaEncryption){var i=new Error("Cannot read public key. Unknown OID.");throw i.oid=n,i}e=t.rsaPublicKey}if(r=[],!O.validate(e,jS,t,r)){var i=new Error("Cannot read public key. ASN.1 object does not contain an RSAPublicKey.");throw i.errors=r,i}var a=oe.util.createBuffer(t.publicKeyModulus).toHex(),s=oe.util.createBuffer(t.publicKeyExponent).toHex();return he.setRsaPublicKey(new _e(a,16),new _e(s,16))};he.publicKeyToAsn1=he.publicKeyToSubjectPublicKeyInfo=function(e){return O.create(O.Class.UNIVERSAL,O.Type.SEQUENCE,!0,[O.create(O.Class.UNIVERSAL,O.Type.SEQUENCE,!0,[O.create(O.Class.UNIVERSAL,O.Type.OID,!1,O.oidToDer(he.oids.rsaEncryption).getBytes()),O.create(O.Class.UNIVERSAL,O.Type.NULL,!1,"")]),O.create(O.Class.UNIVERSAL,O.Type.BITSTRING,!1,[he.publicKeyToRSAPublicKey(e)])])};he.publicKeyToRSAPublicKey=function(e){return O.create(O.Class.UNIVERSAL,O.Type.SEQUENCE,!0,[O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.n)),O.create(O.Class.UNIVERSAL,O.Type.INTEGER,!1,qr(e.e))])};function D1(e,t,r){var n=oe.util.createBuffer(),i=Math.ceil(t.n.bitLength()/8);if(e.length>i-11){var a=new Error("Message is too long for PKCS#1 v1.5 padding.");throw a.length=e.length,a.max=i-11,a}n.putByte(0),n.putByte(r);var s=i-3-e.length,o;if(r===0||r===1){o=r===0?0:255;for(var l=0;l0;){for(var u=0,c=oe.random.getBytes(s),l=0;l"u")throw new Error("Encryption block is invalid.");var l=0;if(o===0){l=i-3-n;for(var u=0;u1;){if(a.getByte()!==255){--a.read;break}++l}else if(o===2)for(l=0;a.length()>1;){if(a.getByte()===0){--a.read;break}++l}var c=a.getByte();if(c!==0||l!==i-3-a.length())throw new Error("Encryption block is invalid.");return a.getBytes()}function qS(e,t,r){typeof t=="function"&&(r=t,t={}),t=t||{};var n={algorithm:{name:t.algorithm||"PRIMEINC",options:{workers:t.workers||2,workLoad:t.workLoad||100,workerScript:t.workerScript}}};"prng"in t&&(n.prng=t.prng),i();function i(){a(e.pBits,function(o,l){if(o)return r(o);if(e.p=l,e.q!==null)return s(o,e.q);a(e.qBits,s)})}function a(o,l){oe.prime.generateProbablePrime(o,n,l)}function s(o,l){if(o)return r(o);if(e.q=l,e.p.compareTo(e.q)<0){var u=e.p;e.p=e.q,e.q=u}if(e.p.subtract(_e.ONE).gcd(e.e).compareTo(_e.ONE)!==0){e.p=null,i();return}if(e.q.subtract(_e.ONE).gcd(e.e).compareTo(_e.ONE)!==0){e.q=null,a(e.qBits,s);return}if(e.p1=e.p.subtract(_e.ONE),e.q1=e.q.subtract(_e.ONE),e.phi=e.p1.multiply(e.q1),e.phi.gcd(e.e).compareTo(_e.ONE)!==0){e.p=e.q=null,i();return}if(e.n=e.p.multiply(e.q),e.n.bitLength()!==e.bits){e.q=null,a(e.qBits,s);return}var c=e.e.modInverse(e.phi);e.keys={privateKey:he.rsa.setPrivateKey(e.n,e.e,c,e.p,e.q,c.mod(e.p1),c.mod(e.q1),e.q.modInverse(e.p)),publicKey:he.rsa.setPublicKey(e.n,e.e)},r(null,e.keys)}}function qr(e){var t=e.toString(16);t[0]>="8"&&(t="00"+t);var r=oe.util.hexToBytes(t);return r.length>1&&(r.charCodeAt(0)===0&&!(r.charCodeAt(1)&128)||r.charCodeAt(0)===255&&(r.charCodeAt(1)&128)===128)?r.substr(1):r}function $S(e){return e<=100?27:e<=150?18:e<=200?15:e<=250?12:e<=300?9:e<=350?8:e<=400?7:e<=500?6:e<=600?5:e<=800?4:e<=1250?3:2}function ph(e){return oe.util.isNodejs&&typeof Mc[e]=="function"}function gh(e){return typeof _r.globalScope<"u"&&typeof _r.globalScope.crypto=="object"&&typeof _r.globalScope.crypto.subtle=="object"&&typeof _r.globalScope.crypto.subtle[e]=="function"}function vh(e){return typeof _r.globalScope<"u"&&typeof _r.globalScope.msCrypto=="object"&&typeof _r.globalScope.msCrypto.subtle=="object"&&typeof _r.globalScope.msCrypto.subtle[e]=="function"}function yh(e){for(var t=oe.util.hexToBytes(e.toString(16)),r=new Uint8Array(t.length),n=0;n"u")var GS=J.jsbn.BigInteger;var U=J.asn1,ye=J.pki=J.pki||{};ye.pbe=J.pbe=J.pbe||{};var ri=ye.oids,QS={name:"EncryptedPrivateKeyInfo",tagClass:U.Class.UNIVERSAL,type:U.Type.SEQUENCE,constructed:!0,value:[{name:"EncryptedPrivateKeyInfo.encryptionAlgorithm",tagClass:U.Class.UNIVERSAL,type:U.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:U.Class.UNIVERSAL,type:U.Type.OID,constructed:!1,capture:"encryptionOid"},{name:"AlgorithmIdentifier.parameters",tagClass:U.Class.UNIVERSAL,type:U.Type.SEQUENCE,constructed:!0,captureAsn1:"encryptionParams"}]},{name:"EncryptedPrivateKeyInfo.encryptedData",tagClass:U.Class.UNIVERSAL,type:U.Type.OCTETSTRING,constructed:!1,capture:"encryptedData"}]},WS={name:"PBES2Algorithms",tagClass:U.Class.UNIVERSAL,type:U.Type.SEQUENCE,constructed:!0,value:[{name:"PBES2Algorithms.keyDerivationFunc",tagClass:U.Class.UNIVERSAL,type:U.Type.SEQUENCE,constructed:!0,value:[{name:"PBES2Algorithms.keyDerivationFunc.oid",tagClass:U.Class.UNIVERSAL,type:U.Type.OID,constructed:!1,capture:"kdfOid"},{name:"PBES2Algorithms.params",tagClass:U.Class.UNIVERSAL,type:U.Type.SEQUENCE,constructed:!0,value:[{name:"PBES2Algorithms.params.salt",tagClass:U.Class.UNIVERSAL,type:U.Type.OCTETSTRING,constructed:!1,capture:"kdfSalt"},{name:"PBES2Algorithms.params.iterationCount",tagClass:U.Class.UNIVERSAL,type:U.Type.INTEGER,constructed:!1,capture:"kdfIterationCount"},{name:"PBES2Algorithms.params.keyLength",tagClass:U.Class.UNIVERSAL,type:U.Type.INTEGER,constructed:!1,optional:!0,capture:"keyLength"},{name:"PBES2Algorithms.params.prf",tagClass:U.Class.UNIVERSAL,type:U.Type.SEQUENCE,constructed:!0,optional:!0,value:[{name:"PBES2Algorithms.params.prf.algorithm",tagClass:U.Class.UNIVERSAL,type:U.Type.OID,constructed:!1,capture:"prfOid"}]}]}]},{name:"PBES2Algorithms.encryptionScheme",tagClass:U.Class.UNIVERSAL,type:U.Type.SEQUENCE,constructed:!0,value:[{name:"PBES2Algorithms.encryptionScheme.oid",tagClass:U.Class.UNIVERSAL,type:U.Type.OID,constructed:!1,capture:"encOid"},{name:"PBES2Algorithms.encryptionScheme.iv",tagClass:U.Class.UNIVERSAL,type:U.Type.OCTETSTRING,constructed:!1,capture:"encIv"}]}]},YS={name:"pkcs-12PbeParams",tagClass:U.Class.UNIVERSAL,type:U.Type.SEQUENCE,constructed:!0,value:[{name:"pkcs-12PbeParams.salt",tagClass:U.Class.UNIVERSAL,type:U.Type.OCTETSTRING,constructed:!1,capture:"salt"},{name:"pkcs-12PbeParams.iterations",tagClass:U.Class.UNIVERSAL,type:U.Type.INTEGER,constructed:!1,capture:"iterations"}]};ye.encryptPrivateKeyInfo=function(e,t,r){r=r||{},r.saltSize=r.saltSize||8,r.count=r.count||2048,r.algorithm=r.algorithm||"aes128",r.prfAlgorithm=r.prfAlgorithm||"sha1";var n=J.random.getBytesSync(r.saltSize),i=r.count,a=U.integerToDer(i),s,o,l;if(r.algorithm.indexOf("aes")===0||r.algorithm==="des"){var u,c,f;switch(r.algorithm){case"aes128":s=16,u=16,c=ri["aes128-CBC"],f=J.aes.createEncryptionCipher;break;case"aes192":s=24,u=16,c=ri["aes192-CBC"],f=J.aes.createEncryptionCipher;break;case"aes256":s=32,u=16,c=ri["aes256-CBC"],f=J.aes.createEncryptionCipher;break;case"des":s=8,u=8,c=ri.desCBC,f=J.des.createEncryptionCipher;break;default:var d=new Error("Cannot encrypt private key. Unknown encryption algorithm.");throw d.algorithm=r.algorithm,d}var v="hmacWith"+r.prfAlgorithm.toUpperCase(),g=L1(v),C=J.pkcs5.pbkdf2(t,n,i,s,g),I=J.random.getBytesSync(u),y=f(C);y.start(I),y.update(U.toDer(e)),y.finish(),l=y.output.getBytes();var m=XS(n,a,s,v);o=U.create(U.Class.UNIVERSAL,U.Type.SEQUENCE,!0,[U.create(U.Class.UNIVERSAL,U.Type.OID,!1,U.oidToDer(ri.pkcs5PBES2).getBytes()),U.create(U.Class.UNIVERSAL,U.Type.SEQUENCE,!0,[U.create(U.Class.UNIVERSAL,U.Type.SEQUENCE,!0,[U.create(U.Class.UNIVERSAL,U.Type.OID,!1,U.oidToDer(ri.pkcs5PBKDF2).getBytes()),m]),U.create(U.Class.UNIVERSAL,U.Type.SEQUENCE,!0,[U.create(U.Class.UNIVERSAL,U.Type.OID,!1,U.oidToDer(c).getBytes()),U.create(U.Class.UNIVERSAL,U.Type.OCTETSTRING,!1,I)])])])}else if(r.algorithm==="3des"){s=24;var S=new J.util.ByteBuffer(n),C=ye.pbe.generatePkcs12Key(t,S,1,i,s),I=ye.pbe.generatePkcs12Key(t,S,2,i,s),y=J.des.createEncryptionCipher(C);y.start(I),y.update(U.toDer(e)),y.finish(),l=y.output.getBytes(),o=U.create(U.Class.UNIVERSAL,U.Type.SEQUENCE,!0,[U.create(U.Class.UNIVERSAL,U.Type.OID,!1,U.oidToDer(ri["pbeWithSHAAnd3-KeyTripleDES-CBC"]).getBytes()),U.create(U.Class.UNIVERSAL,U.Type.SEQUENCE,!0,[U.create(U.Class.UNIVERSAL,U.Type.OCTETSTRING,!1,n),U.create(U.Class.UNIVERSAL,U.Type.INTEGER,!1,a.getBytes())])])}else{var d=new Error("Cannot encrypt private key. Unknown encryption algorithm.");throw d.algorithm=r.algorithm,d}var B=U.create(U.Class.UNIVERSAL,U.Type.SEQUENCE,!0,[o,U.create(U.Class.UNIVERSAL,U.Type.OCTETSTRING,!1,l)]);return B};ye.decryptPrivateKeyInfo=function(e,t){var r=null,n={},i=[];if(!U.validate(e,QS,n,i)){var a=new Error("Cannot read encrypted private key. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");throw a.errors=i,a}var s=U.derToOid(n.encryptionOid),o=ye.pbe.getCipher(s,n.encryptionParams,t),l=J.util.createBuffer(n.encryptedData);return o.update(l),o.finish()&&(r=U.fromDer(o.output)),r};ye.encryptedPrivateKeyToPem=function(e,t){var r={type:"ENCRYPTED PRIVATE KEY",body:U.toDer(e).getBytes()};return J.pem.encode(r,{maxline:t})};ye.encryptedPrivateKeyFromPem=function(e){var t=J.pem.decode(e)[0];if(t.type!=="ENCRYPTED PRIVATE KEY"){var r=new Error('Could not convert encrypted private key from PEM; PEM header type is "ENCRYPTED PRIVATE KEY".');throw r.headerType=t.type,r}if(t.procType&&t.procType.type==="ENCRYPTED")throw new Error("Could not convert encrypted private key from PEM; PEM is encrypted.");return U.fromDer(t.body)};ye.encryptRsaPrivateKey=function(e,t,r){if(r=r||{},!r.legacy){var n=ye.wrapRsaPrivateKey(ye.privateKeyToAsn1(e));return n=ye.encryptPrivateKeyInfo(n,t,r),ye.encryptedPrivateKeyToPem(n)}var i,a,s,o;switch(r.algorithm){case"aes128":i="AES-128-CBC",s=16,a=J.random.getBytesSync(16),o=J.aes.createEncryptionCipher;break;case"aes192":i="AES-192-CBC",s=24,a=J.random.getBytesSync(16),o=J.aes.createEncryptionCipher;break;case"aes256":i="AES-256-CBC",s=32,a=J.random.getBytesSync(16),o=J.aes.createEncryptionCipher;break;case"3des":i="DES-EDE3-CBC",s=24,a=J.random.getBytesSync(8),o=J.des.createEncryptionCipher;break;case"des":i="DES-CBC",s=8,a=J.random.getBytesSync(8),o=J.des.createEncryptionCipher;break;default:var l=new Error('Could not encrypt RSA private key; unsupported encryption algorithm "'+r.algorithm+'".');throw l.algorithm=r.algorithm,l}var u=J.pbe.opensslDeriveBytes(t,a.substr(0,8),s),c=o(u);c.start(a),c.update(U.toDer(ye.privateKeyToAsn1(e))),c.finish();var f={type:"RSA PRIVATE KEY",procType:{version:"4",type:"ENCRYPTED"},dekInfo:{algorithm:i,parameters:J.util.bytesToHex(a).toUpperCase()},body:c.output.getBytes()};return J.pem.encode(f)};ye.decryptRsaPrivateKey=function(e,t){var r=null,n=J.pem.decode(e)[0];if(n.type!=="ENCRYPTED PRIVATE KEY"&&n.type!=="PRIVATE KEY"&&n.type!=="RSA PRIVATE KEY"){var i=new Error('Could not convert private key from PEM; PEM header type is not "ENCRYPTED PRIVATE KEY", "PRIVATE KEY", or "RSA PRIVATE KEY".');throw i.headerType=i,i}if(n.procType&&n.procType.type==="ENCRYPTED"){var a,s;switch(n.dekInfo.algorithm){case"DES-CBC":a=8,s=J.des.createDecryptionCipher;break;case"DES-EDE3-CBC":a=24,s=J.des.createDecryptionCipher;break;case"AES-128-CBC":a=16,s=J.aes.createDecryptionCipher;break;case"AES-192-CBC":a=24,s=J.aes.createDecryptionCipher;break;case"AES-256-CBC":a=32,s=J.aes.createDecryptionCipher;break;case"RC2-40-CBC":a=5,s=function(f){return J.rc2.createDecryptionCipher(f,40)};break;case"RC2-64-CBC":a=8,s=function(f){return J.rc2.createDecryptionCipher(f,64)};break;case"RC2-128-CBC":a=16,s=function(f){return J.rc2.createDecryptionCipher(f,128)};break;default:var i=new Error('Could not decrypt private key; unsupported encryption algorithm "'+n.dekInfo.algorithm+'".');throw i.algorithm=n.dekInfo.algorithm,i}var o=J.util.hexToBytes(n.dekInfo.parameters),l=J.pbe.opensslDeriveBytes(t,o.substr(0,8),a),u=s(l);if(u.start(o),u.update(J.util.createBuffer(n.body)),u.finish())r=u.output.getBytes();else return r}else r=n.body;return n.type==="ENCRYPTED PRIVATE KEY"?r=ye.decryptPrivateKeyInfo(U.fromDer(r),t):r=U.fromDer(r),r!==null&&(r=ye.privateKeyFromAsn1(r)),r};ye.pbe.generatePkcs12Key=function(e,t,r,n,i,a){var s,o;if(typeof a>"u"||a===null){if(!("sha1"in J.md))throw new Error('"sha1" hash algorithm unavailable.');a=J.md.sha1.create()}var l=a.digestLength,u=a.blockLength,c=new J.util.ByteBuffer,f=new J.util.ByteBuffer;if(e!=null){for(o=0;o=0;o--)pe=pe>>8,pe+=V.at(o)+ce.at(o),ce.setAt(o,pe&255);G.putBuffer(ce)}S=G,c.putBuffer(L)}return c.truncate(c.length()-i),c};ye.pbe.getCipher=function(e,t,r){switch(e){case ye.oids.pkcs5PBES2:return ye.pbe.getCipherForPBES2(e,t,r);case ye.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:case ye.oids["pbewithSHAAnd40BitRC2-CBC"]:return ye.pbe.getCipherForPKCS12PBE(e,t,r);default:var n=new Error("Cannot read encrypted PBE data block. Unsupported OID.");throw n.oid=e,n.supportedOids=["pkcs5PBES2","pbeWithSHAAnd3-KeyTripleDES-CBC","pbewithSHAAnd40BitRC2-CBC"],n}};ye.pbe.getCipherForPBES2=function(e,t,r){var n={},i=[];if(!U.validate(t,WS,n,i)){var a=new Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");throw a.errors=i,a}if(e=U.derToOid(n.kdfOid),e!==ye.oids.pkcs5PBKDF2){var a=new Error("Cannot read encrypted private key. Unsupported key derivation function OID.");throw a.oid=e,a.supportedOids=["pkcs5PBKDF2"],a}if(e=U.derToOid(n.encOid),e!==ye.oids["aes128-CBC"]&&e!==ye.oids["aes192-CBC"]&&e!==ye.oids["aes256-CBC"]&&e!==ye.oids["des-EDE3-CBC"]&&e!==ye.oids.desCBC){var a=new Error("Cannot read encrypted private key. Unsupported encryption scheme OID.");throw a.oid=e,a.supportedOids=["aes128-CBC","aes192-CBC","aes256-CBC","des-EDE3-CBC","desCBC"],a}var s=n.kdfSalt,o=J.util.createBuffer(n.kdfIterationCount);o=o.getInt(o.length()<<3);var l,u;switch(ye.oids[e]){case"aes128-CBC":l=16,u=J.aes.createDecryptionCipher;break;case"aes192-CBC":l=24,u=J.aes.createDecryptionCipher;break;case"aes256-CBC":l=32,u=J.aes.createDecryptionCipher;break;case"des-EDE3-CBC":l=24,u=J.des.createDecryptionCipher;break;case"desCBC":l=8,u=J.des.createDecryptionCipher;break}var c=R1(n.prfOid),f=J.pkcs5.pbkdf2(r,s,o,l,c),d=n.encIv,v=u(f);return v.start(d),v};ye.pbe.getCipherForPKCS12PBE=function(e,t,r){var n={},i=[];if(!U.validate(t,YS,n,i)){var a=new Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");throw a.errors=i,a}var s=J.util.createBuffer(n.salt),o=J.util.createBuffer(n.iterations);o=o.getInt(o.length()<<3);var l,u,c;switch(e){case ye.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:l=24,u=8,c=J.des.startDecrypting;break;case ye.oids["pbewithSHAAnd40BitRC2-CBC"]:l=5,u=8,c=function(C,I){var y=J.rc2.createDecryptionCipher(C,40);return y.start(I,null),y};break;default:var a=new Error("Cannot read PKCS #12 PBE data block. Unsupported OID.");throw a.oid=e,a}var f=R1(n.prfOid),d=ye.pbe.generatePkcs12Key(r,s,1,o,l,f);f.start();var v=ye.pbe.generatePkcs12Key(r,s,2,o,u,f);return c(d,v)};ye.pbe.opensslDeriveBytes=function(e,t,r,n){if(typeof n>"u"||n===null){if(!("md5"in J.md))throw new Error('"md5" hash algorithm unavailable.');n=J.md.md5.create()}t===null&&(t="");for(var i=[mh(n,e+t)],a=16,s=1;a>8*d-f&255;return R=String.fromCharCode(R.charCodeAt(0)&~L)+R.substr(1),R+I+String.fromCharCode(188)},o.verify=function(l,u,c){var f,d=c-1,v=Math.ceil(d/8);if(u=u.substr(-v),v>8*v-d&255;if(C.charCodeAt(0)&y)throw new Error("Bits beyond keysize not zero as expected.");var m=r.generate(I,g),S="";for(f=0;f2)throw new Error("Cannot read notBefore/notAfter validity times; more than two times were provided in the certificate.");if(l.length<2)throw new Error("Cannot read notBefore/notAfter validity times; they were not provided as either UTCTime or GeneralizedTime.");if(s.validity.notBefore=l[0],s.validity.notAfter=l[1],s.tbsCertificate=r.tbsCertificate,t){s.md=kl({signatureOid:s.signatureOid,type:"certificate"});var u=E.toDer(s.tbsCertificate);s.md.update(u.getBytes())}var c=le.md.sha1.create(),f=E.toDer(r.certIssuer);c.update(f.getBytes()),s.issuer.getField=function(g){return Xn(s.issuer,g)},s.issuer.addField=function(g){Ar([g]),s.issuer.attributes.push(g)},s.issuer.attributes=$.RDNAttributesAsArray(r.certIssuer),r.certIssuerUniqueId&&(s.issuer.uniqueId=r.certIssuerUniqueId),s.issuer.hash=c.digest().toHex();var d=le.md.sha1.create(),v=E.toDer(r.certSubject);return d.update(v.getBytes()),s.subject.getField=function(g){return Xn(s.subject,g)},s.subject.addField=function(g){Ar([g]),s.subject.attributes.push(g)},s.subject.attributes=$.RDNAttributesAsArray(r.certSubject),r.certSubjectUniqueId&&(s.subject.uniqueId=r.certSubjectUniqueId),s.subject.hash=d.digest().toHex(),r.certExtensions?s.extensions=$.certificateExtensionsFromAsn1(r.certExtensions):s.extensions=[],s.publicKey=$.publicKeyFromAsn1(r.subjectPublicKeyInfo),s};$.certificateExtensionsFromAsn1=function(e){for(var t=[],r=0;r1&&(n=r.value.charCodeAt(1),i=r.value.length>2?r.value.charCodeAt(2):0),t.digitalSignature=(n&128)===128,t.nonRepudiation=(n&64)===64,t.keyEncipherment=(n&32)===32,t.dataEncipherment=(n&16)===16,t.keyAgreement=(n&8)===8,t.keyCertSign=(n&4)===4,t.cRLSign=(n&2)===2,t.encipherOnly=(n&1)===1,t.decipherOnly=(i&128)===128}else if(t.name==="basicConstraints"){var r=E.fromDer(t.value);r.value.length>0&&r.value[0].type===E.Type.BOOLEAN?t.cA=r.value[0].value.charCodeAt(0)!==0:t.cA=!1;var a=null;r.value.length>0&&r.value[0].type===E.Type.INTEGER?a=r.value[0].value:r.value.length>1&&(a=r.value[1].value),a!==null&&(t.pathLenConstraint=E.derToInteger(a))}else if(t.name==="extKeyUsage")for(var r=E.fromDer(t.value),s=0;s1&&(n=r.value.charCodeAt(1)),t.client=(n&128)===128,t.server=(n&64)===64,t.email=(n&32)===32,t.objsign=(n&16)===16,t.reserved=(n&8)===8,t.sslCA=(n&4)===4,t.emailCA=(n&2)===2,t.objCA=(n&1)===1}else if(t.name==="subjectAltName"||t.name==="issuerAltName"){t.altNames=[];for(var l,r=E.fromDer(t.value),u=0;u"u"&&(t.type&&t.type in $.oids?t.name=$.oids[t.type]:t.shortName&&t.shortName in ut&&(t.name=$.oids[ut[t.shortName]])),typeof t.type>"u")if(t.name&&t.name in $.oids)t.type=$.oids[t.name];else{var n=new Error("Attribute type not specified.");throw n.attribute=t,n}if(typeof t.shortName>"u"&&t.name&&t.name in ut&&(t.shortName=ut[t.name]),t.type===Ie.extensionRequest&&(t.valueConstructed=!0,t.valueTagClass=E.Type.SEQUENCE,!t.value&&t.extensions)){t.value=[];for(var i=0;i"u"){var n=new Error("Attribute value not specified.");throw n.attribute=t,n}}}function F1(e,t){if(t=t||{},typeof e.name>"u"&&e.id&&e.id in $.oids&&(e.name=$.oids[e.id]),typeof e.id>"u")if(e.name&&e.name in $.oids)e.id=$.oids[e.name];else{var r=new Error("Extension ID not specified.");throw r.extension=e,r}if(typeof e.value<"u")return e;if(e.name==="keyUsage"){var n=0,i=0,a=0;e.digitalSignature&&(i|=128,n=7),e.nonRepudiation&&(i|=64,n=6),e.keyEncipherment&&(i|=32,n=5),e.dataEncipherment&&(i|=16,n=4),e.keyAgreement&&(i|=8,n=3),e.keyCertSign&&(i|=4,n=2),e.cRLSign&&(i|=2,n=1),e.encipherOnly&&(i|=1,n=0),e.decipherOnly&&(a|=128,n=7);var s=String.fromCharCode(n);a!==0?s+=String.fromCharCode(i)+String.fromCharCode(a):i!==0&&(s+=String.fromCharCode(i)),e.value=E.create(E.Class.UNIVERSAL,E.Type.BITSTRING,!1,s)}else if(e.name==="basicConstraints")e.value=E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[]),e.cA&&e.value.value.push(E.create(E.Class.UNIVERSAL,E.Type.BOOLEAN,!1,String.fromCharCode(255))),"pathLenConstraint"in e&&e.value.value.push(E.create(E.Class.UNIVERSAL,E.Type.INTEGER,!1,E.integerToDer(e.pathLenConstraint).getBytes()));else if(e.name==="extKeyUsage"){e.value=E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[]);var o=e.value.value;for(var l in e)e[l]===!0&&(l in Ie?o.push(E.create(E.Class.UNIVERSAL,E.Type.OID,!1,E.oidToDer(Ie[l]).getBytes())):l.indexOf(".")!==-1&&o.push(E.create(E.Class.UNIVERSAL,E.Type.OID,!1,E.oidToDer(l).getBytes())))}else if(e.name==="nsCertType"){var n=0,i=0;e.client&&(i|=128,n=7),e.server&&(i|=64,n=6),e.email&&(i|=32,n=5),e.objsign&&(i|=16,n=4),e.reserved&&(i|=8,n=3),e.sslCA&&(i|=4,n=2),e.emailCA&&(i|=2,n=1),e.objCA&&(i|=1,n=0);var s=String.fromCharCode(n);i!==0&&(s+=String.fromCharCode(i)),e.value=E.create(E.Class.UNIVERSAL,E.Type.BITSTRING,!1,s)}else if(e.name==="subjectAltName"||e.name==="issuerAltName"){e.value=E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[]);for(var u,c=0;c128)throw new Error('Invalid "nsComment" content.');e.value=E.create(E.Class.UNIVERSAL,E.Type.IA5STRING,!1,e.comment)}else if(e.name==="subjectKeyIdentifier"&&t.cert){var f=t.cert.generateSubjectKeyIdentifier();e.subjectKeyIdentifier=f.toHex(),e.value=E.create(E.Class.UNIVERSAL,E.Type.OCTETSTRING,!1,f.getBytes())}else if(e.name==="authorityKeyIdentifier"&&t.cert){e.value=E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[]);var o=e.value.value;if(e.keyIdentifier){var d=e.keyIdentifier===!0?t.cert.generateSubjectKeyIdentifier().getBytes():e.keyIdentifier;o.push(E.create(E.Class.CONTEXT_SPECIFIC,0,!1,d))}if(e.authorityCertIssuer){var v=[E.create(E.Class.CONTEXT_SPECIFIC,4,!0,[ca(e.authorityCertIssuer===!0?t.cert.issuer:e.authorityCertIssuer)])];o.push(E.create(E.Class.CONTEXT_SPECIFIC,1,!0,v))}if(e.serialNumber){var g=le.util.hexToBytes(e.serialNumber===!0?t.cert.serialNumber:e.serialNumber);o.push(E.create(E.Class.CONTEXT_SPECIFIC,2,!1,g))}}else if(e.name==="cRLDistributionPoints"){e.value=E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[]);for(var o=e.value.value,C=E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[]),I=E.create(E.Class.CONTEXT_SPECIFIC,0,!0,[]),u,c=0;c"u"){var r=new Error("Extension value not specified.");throw r.extension=e,r}return e}function o0(e,t){switch(e){case Ie["RSASSA-PSS"]:var r=[];return t.hash.algorithmOid!==void 0&&r.push(E.create(E.Class.CONTEXT_SPECIFIC,0,!0,[E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[E.create(E.Class.UNIVERSAL,E.Type.OID,!1,E.oidToDer(t.hash.algorithmOid).getBytes()),E.create(E.Class.UNIVERSAL,E.Type.NULL,!1,"")])])),t.mgf.algorithmOid!==void 0&&r.push(E.create(E.Class.CONTEXT_SPECIFIC,1,!0,[E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[E.create(E.Class.UNIVERSAL,E.Type.OID,!1,E.oidToDer(t.mgf.algorithmOid).getBytes()),E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[E.create(E.Class.UNIVERSAL,E.Type.OID,!1,E.oidToDer(t.mgf.hash.algorithmOid).getBytes()),E.create(E.Class.UNIVERSAL,E.Type.NULL,!1,"")])])])),t.saltLength!==void 0&&r.push(E.create(E.Class.CONTEXT_SPECIFIC,2,!0,[E.create(E.Class.UNIVERSAL,E.Type.INTEGER,!1,E.integerToDer(t.saltLength).getBytes())])),E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,r);default:return E.create(E.Class.UNIVERSAL,E.Type.NULL,!1,"")}}function ax(e){var t=E.create(E.Class.CONTEXT_SPECIFIC,0,!0,[]);if(e.attributes.length===0)return t;for(var r=e.attributes,n=0;n=sx&&e0&&n.value.push($.certificateExtensionsToAsn1(e.extensions)),n};$.getCertificationRequestInfo=function(e){var t=E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[E.create(E.Class.UNIVERSAL,E.Type.INTEGER,!1,E.integerToDer(e.version).getBytes()),ca(e.subject),$.publicKeyToAsn1(e.publicKey),ax(e)]);return t};$.distinguishedNameToAsn1=function(e){return ca(e)};$.certificateToAsn1=function(e){var t=e.tbsCertificate||$.getTBSCertificate(e);return E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[t,E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[E.create(E.Class.UNIVERSAL,E.Type.OID,!1,E.oidToDer(e.signatureOid).getBytes()),o0(e.signatureOid,e.signatureParameters)]),E.create(E.Class.UNIVERSAL,E.Type.BITSTRING,!1,String.fromCharCode(0)+e.signature)])};$.certificateExtensionsToAsn1=function(e){var t=E.create(E.Class.CONTEXT_SPECIFIC,3,!0,[]),r=E.create(E.Class.UNIVERSAL,E.Type.SEQUENCE,!0,[]);t.value.push(r);for(var n=0;n"u"&&(i=new Date);var a=!0,s=null,o=0;do{var l=t.shift(),u=null,c=!1;if(i&&(il.validity.notAfter)&&(s={message:"Certificate is not valid yet or has expired.",error:$.certificateError.certificate_expired,notBefore:l.validity.notBefore,notAfter:l.validity.notAfter,now:i}),s===null){if(u=t[0]||e.getIssuer(l),u===null&&l.isIssuer(l)&&(c=!0,u=l),u){var f=u;le.util.isArray(f)||(f=[f]);for(var d=!1;!d&&f.length>0;){u=f.shift();try{d=u.verify(l)}catch{}}d||(s={message:"Certificate signature is invalid.",error:$.certificateError.bad_certificate})}s===null&&(!u||c)&&!e.hasCertificate(l)&&(s={message:"Certificate is not trusted.",error:$.certificateError.unknown_ca})}if(s===null&&u&&!l.isIssuer(u)&&(s={message:"Certificate issuer is invalid.",error:$.certificateError.bad_certificate}),s===null)for(var v={keyUsage:!0,basicConstraints:!0},g=0;s===null&&gI.pathLenConstraint&&(s={message:"Certificate basicConstraints pathLenConstraint violated.",error:$.certificateError.bad_certificate})}}var S=s===null?!0:s.error,B=r.verify?r.verify(S,o,n):S;if(B===!0)s=null;else throw S===!0&&(s={message:"The application rejected the certificate.",error:$.certificateError.bad_certificate}),(B||B===0)&&(typeof B=="object"&&!le.util.isArray(B)?(B.message&&(s.message=B.message),B.error&&(s.error=B.error)):typeof B=="string"&&(s.error=B)),s;a=!1,++o}while(t.length>0);return!0};var qe=me,A=qe.asn1,Ee=qe.pki,Ss=qe.pkcs12=qe.pkcs12||{},V1={name:"ContentInfo",tagClass:A.Class.UNIVERSAL,type:A.Type.SEQUENCE,constructed:!0,value:[{name:"ContentInfo.contentType",tagClass:A.Class.UNIVERSAL,type:A.Type.OID,constructed:!1,capture:"contentType"},{name:"ContentInfo.content",tagClass:A.Class.CONTEXT_SPECIFIC,constructed:!0,captureAsn1:"content"}]},lx={name:"PFX",tagClass:A.Class.UNIVERSAL,type:A.Type.SEQUENCE,constructed:!0,value:[{name:"PFX.version",tagClass:A.Class.UNIVERSAL,type:A.Type.INTEGER,constructed:!1,capture:"version"},V1,{name:"PFX.macData",tagClass:A.Class.UNIVERSAL,type:A.Type.SEQUENCE,constructed:!0,optional:!0,captureAsn1:"mac",value:[{name:"PFX.macData.mac",tagClass:A.Class.UNIVERSAL,type:A.Type.SEQUENCE,constructed:!0,value:[{name:"PFX.macData.mac.digestAlgorithm",tagClass:A.Class.UNIVERSAL,type:A.Type.SEQUENCE,constructed:!0,value:[{name:"PFX.macData.mac.digestAlgorithm.algorithm",tagClass:A.Class.UNIVERSAL,type:A.Type.OID,constructed:!1,capture:"macAlgorithm"},{name:"PFX.macData.mac.digestAlgorithm.parameters",tagClass:A.Class.UNIVERSAL,captureAsn1:"macAlgorithmParameters"}]},{name:"PFX.macData.mac.digest",tagClass:A.Class.UNIVERSAL,type:A.Type.OCTETSTRING,constructed:!1,capture:"macDigest"}]},{name:"PFX.macData.macSalt",tagClass:A.Class.UNIVERSAL,type:A.Type.OCTETSTRING,constructed:!1,capture:"macSalt"},{name:"PFX.macData.iterations",tagClass:A.Class.UNIVERSAL,type:A.Type.INTEGER,constructed:!1,optional:!0,capture:"macIterations"}]}]},ux={name:"SafeBag",tagClass:A.Class.UNIVERSAL,type:A.Type.SEQUENCE,constructed:!0,value:[{name:"SafeBag.bagId",tagClass:A.Class.UNIVERSAL,type:A.Type.OID,constructed:!1,capture:"bagId"},{name:"SafeBag.bagValue",tagClass:A.Class.CONTEXT_SPECIFIC,constructed:!0,captureAsn1:"bagValue"},{name:"SafeBag.bagAttributes",tagClass:A.Class.UNIVERSAL,type:A.Type.SET,constructed:!0,optional:!0,capture:"bagAttributes"}]},cx={name:"Attribute",tagClass:A.Class.UNIVERSAL,type:A.Type.SEQUENCE,constructed:!0,value:[{name:"Attribute.attrId",tagClass:A.Class.UNIVERSAL,type:A.Type.OID,constructed:!1,capture:"oid"},{name:"Attribute.attrValues",tagClass:A.Class.UNIVERSAL,type:A.Type.SET,constructed:!0,capture:"values"}]},fx={name:"CertBag",tagClass:A.Class.UNIVERSAL,type:A.Type.SEQUENCE,constructed:!0,value:[{name:"CertBag.certId",tagClass:A.Class.UNIVERSAL,type:A.Type.OID,constructed:!1,capture:"certId"},{name:"CertBag.certValue",tagClass:A.Class.CONTEXT_SPECIFIC,constructed:!0,value:[{name:"CertBag.certValue[0]",tagClass:A.Class.UNIVERSAL,type:A.Class.OCTETSTRING,constructed:!1,capture:"cert"}]}]};function Ra(e,t,r,n){for(var i=[],a=0;a=0&&i.push(o)}}return i}Ss.pkcs12FromAsn1=function(e,t,r){typeof t=="string"?(r=t,t=!0):t===void 0&&(t=!0);var n={},i=[];if(!A.validate(e,lx,n,i)){var a=new Error("Cannot read PKCS#12 PFX. ASN.1 object is not an PKCS#12 PFX.");throw a.errors=a,a}var s={version:n.version.charCodeAt(0),safeContents:[],getBags:function(I){var y={},m;return"localKeyId"in I?m=I.localKeyId:"localKeyIdHex"in I&&(m=qe.util.hexToBytes(I.localKeyIdHex)),m===void 0&&!("friendlyName"in I)&&"bagType"in I&&(y[I.bagType]=Ra(s.safeContents,null,null,I.bagType)),m!==void 0&&(y.localKeyId=Ra(s.safeContents,"localKeyId",m,I.bagType)),"friendlyName"in I&&(y.friendlyName=Ra(s.safeContents,"friendlyName",I.friendlyName,I.bagType)),y},getBagsByFriendlyName:function(I,y){return Ra(s.safeContents,"friendlyName",I,y)},getBagsByLocalKeyId:function(I,y){return Ra(s.safeContents,"localKeyId",I,y)}};if(n.version.charCodeAt(0)!==3){var a=new Error("PKCS#12 PFX of version other than 3 not supported.");throw a.version=n.version.charCodeAt(0),a}if(A.derToOid(n.contentType)!==Ee.oids.data){var a=new Error("Only PKCS#12 PFX in password integrity mode supported.");throw a.oid=A.derToOid(n.contentType),a}var o=n.content.value[0];if(o.tagClass!==A.Class.UNIVERSAL||o.type!==A.Type.OCTETSTRING)throw new Error("PKCS#12 authSafe content data is not an OCTET STRING.");if(o=l0(o),n.mac){var l=null,u=0,c=A.derToOid(n.macAlgorithm);switch(c){case Ee.oids.sha1:l=qe.md.sha1.create(),u=20;break;case Ee.oids.sha256:l=qe.md.sha256.create(),u=32;break;case Ee.oids.sha384:l=qe.md.sha384.create(),u=48;break;case Ee.oids.sha512:l=qe.md.sha512.create(),u=64;break;case Ee.oids.md5:l=qe.md.md5.create(),u=16;break}if(l===null)throw new Error("PKCS#12 uses unsupported MAC algorithm: "+c);var f=new qe.util.ByteBuffer(n.macSalt),d="macIterations"in n?parseInt(qe.util.bytesToHex(n.macIterations),16):1,v=Ss.generateKey(r,f,3,d,u,l),g=qe.hmac.create();g.start(l,v),g.update(o.value);var C=g.getMac();if(C.getBytes()!==n.macDigest)throw new Error("PKCS#12 MAC could not be verified. Invalid password?")}return dx(s,o.value,t,r),s};function l0(e){if(e.composed||e.constructed){for(var t=qe.util.createBuffer(),r=0;r0&&(a=A.create(A.Class.UNIVERSAL,A.Type.SET,!0,l));var u=[],c=[];t!==null&&(qe.util.isArray(t)?c=t:c=[t]);for(var f=[],d=0;d0){var I=A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,f),y=A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[A.create(A.Class.UNIVERSAL,A.Type.OID,!1,A.oidToDer(Ee.oids.data).getBytes()),A.create(A.Class.CONTEXT_SPECIFIC,0,!0,[A.create(A.Class.UNIVERSAL,A.Type.OCTETSTRING,!1,A.toDer(I).getBytes())])]);u.push(y)}var m=null;if(e!==null){var S=Ee.wrapRsaPrivateKey(Ee.privateKeyToAsn1(e));r===null?m=A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[A.create(A.Class.UNIVERSAL,A.Type.OID,!1,A.oidToDer(Ee.oids.keyBag).getBytes()),A.create(A.Class.CONTEXT_SPECIFIC,0,!0,[S]),a]):m=A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[A.create(A.Class.UNIVERSAL,A.Type.OID,!1,A.oidToDer(Ee.oids.pkcs8ShroudedKeyBag).getBytes()),A.create(A.Class.CONTEXT_SPECIFIC,0,!0,[Ee.encryptPrivateKeyInfo(S,r,n)]),a]);var B=A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[m]),R=A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[A.create(A.Class.UNIVERSAL,A.Type.OID,!1,A.oidToDer(Ee.oids.data).getBytes()),A.create(A.Class.CONTEXT_SPECIFIC,0,!0,[A.create(A.Class.UNIVERSAL,A.Type.OCTETSTRING,!1,A.toDer(B).getBytes())])]);u.push(R)}var L=A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,u),M;if(n.useMac){var o=qe.md.sha1.create(),V=new qe.util.ByteBuffer(qe.random.getBytes(n.saltSize)),Q=n.count,e=Ss.generateKey(r,V,3,Q,20),G=qe.hmac.create();G.start(o,e),G.update(A.toDer(L).getBytes());var ce=G.getMac();M=A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[A.create(A.Class.UNIVERSAL,A.Type.OID,!1,A.oidToDer(Ee.oids.sha1).getBytes()),A.create(A.Class.UNIVERSAL,A.Type.NULL,!1,"")]),A.create(A.Class.UNIVERSAL,A.Type.OCTETSTRING,!1,ce.getBytes())]),A.create(A.Class.UNIVERSAL,A.Type.OCTETSTRING,!1,V.getBytes()),A.create(A.Class.UNIVERSAL,A.Type.INTEGER,!1,A.integerToDer(Q).getBytes())])}return A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[A.create(A.Class.UNIVERSAL,A.Type.INTEGER,!1,A.integerToDer(3).getBytes()),A.create(A.Class.UNIVERSAL,A.Type.SEQUENCE,!0,[A.create(A.Class.UNIVERSAL,A.Type.OID,!1,A.oidToDer(Ee.oids.data).getBytes()),A.create(A.Class.CONTEXT_SPECIFIC,0,!0,[A.create(A.Class.UNIVERSAL,A.Type.OCTETSTRING,!1,A.toDer(L).getBytes())])]),M])};Ss.generateKey=qe.pbe.generatePkcs12Key;var Zn=me,u0=Zn.asn1,fa=Zn.pki=Zn.pki||{};fa.pemToDer=function(e){var t=Zn.pem.decode(e)[0];if(t.procType&&t.procType.type==="ENCRYPTED")throw new Error("Could not convert PEM to DER; PEM is encrypted.");return Zn.util.createBuffer(t.body)};fa.privateKeyFromPem=function(e){var t=Zn.pem.decode(e)[0];if(t.type!=="PRIVATE KEY"&&t.type!=="RSA PRIVATE KEY"){var r=new Error('Could not convert private key from PEM; PEM header type is not "PRIVATE KEY" or "RSA PRIVATE KEY".');throw r.headerType=t.type,r}if(t.procType&&t.procType.type==="ENCRYPTED")throw new Error("Could not convert private key from PEM; PEM is encrypted.");var n=u0.fromDer(t.body);return fa.privateKeyFromAsn1(n)};fa.privateKeyToPem=function(e,t){var r={type:"RSA PRIVATE KEY",body:u0.toDer(fa.privateKeyToAsn1(e)).getBytes()};return Zn.pem.encode(r,{maxline:t})};fa.privateKeyInfoToPem=function(e,t){var r={type:"PRIVATE KEY",body:u0.toDer(e).getBytes()};return Zn.pem.encode(r,{maxline:t})};var j=me,bl=function(e,t,r,n){var i=j.util.createBuffer(),a=e.length>>1,s=a+(e.length&1),o=e.substr(0,s),l=e.substr(a,s),u=j.util.createBuffer(),c=j.hmac.create();r=t+r;var f=Math.ceil(n/16),d=Math.ceil(n/20);c.start("MD5",o);var v=j.util.createBuffer();u.putBytes(r);for(var g=0;g0&&(T.queue(e,T.createAlert(e,{level:T.Alert.Level.warning,description:T.Alert.Description.no_renegotiation})),T.flush(e)),e.process()};T.parseHelloMessage=function(e,t,r){var n=null,i=e.entity===T.ConnectionEnd.client;if(r<38)e.error(e,{message:i?"Invalid ServerHello message. Message too short.":"Invalid ClientHello message. Message too short.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.illegal_parameter}});else{var a=t.fragment,s=a.length();if(n={version:{major:a.getByte(),minor:a.getByte()},random:j.util.createBuffer(a.getBytes(32)),session_id:sr(a,1),extensions:[]},i?(n.cipher_suite=a.getBytes(2),n.compression_method=a.getByte()):(n.cipher_suites=sr(a,2),n.compression_methods=sr(a,1)),s=r-(s-a.length()),s>0){for(var o=sr(a,2);o.length()>0;)n.extensions.push({type:[o.getByte(),o.getByte()],data:sr(o,2)});if(!i)for(var l=0;l0;){var f=c.getByte();if(f!==0)break;e.session.extensions.server_name.serverNameList.push(sr(c,2).getBytes())}}}if(e.session.version&&(n.version.major!==e.session.version.major||n.version.minor!==e.session.version.minor))return e.error(e,{message:"TLS version change is disallowed during renegotiation.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.protocol_version}});if(i)e.session.cipherSuite=T.getCipherSuite(n.cipher_suite);else for(var d=j.util.createBuffer(n.cipher_suites.bytes());d.length()>0&&(e.session.cipherSuite=T.getCipherSuite(d.getBytes(2)),e.session.cipherSuite===null););if(e.session.cipherSuite===null)return e.error(e,{message:"No cipher suites in common.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.handshake_failure},cipherSuite:j.util.bytesToHex(n.cipher_suite)});i?e.session.compressionMethod=n.compression_method:e.session.compressionMethod=T.CompressionMethod.none}return n};T.createSecurityParameters=function(e,t){var r=e.entity===T.ConnectionEnd.client,n=t.random.bytes(),i=r?e.session.sp.client_random:n,a=r?n:T.createRandom().getBytes();e.session.sp={entity:e.entity,prf_algorithm:T.PRFAlgorithm.tls_prf_sha256,bulk_cipher_algorithm:null,cipher_type:null,enc_key_length:null,block_length:null,fixed_iv_length:null,record_iv_length:null,mac_algorithm:null,mac_length:null,mac_key_length:null,compression_algorithm:e.session.compressionMethod,pre_master_secret:null,master_secret:null,client_random:i,server_random:a}};T.handleServerHello=function(e,t,r){var n=T.parseHelloMessage(e,t,r);if(!e.fail){if(n.version.minor<=e.version.minor)e.version.minor=n.version.minor;else return e.error(e,{message:"Incompatible TLS version.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.protocol_version}});e.session.version=e.version;var i=n.session_id.bytes();i.length>0&&i===e.session.id?(e.expect=j1,e.session.resuming=!0,e.session.sp.server_random=n.random.bytes()):(e.expect=Ex,e.session.resuming=!1,T.createSecurityParameters(e,n)),e.session.id=i,e.process()}};T.handleClientHello=function(e,t,r){var n=T.parseHelloMessage(e,t,r);if(!e.fail){var i=n.session_id.bytes(),a=null;if(e.sessionCache&&(a=e.sessionCache.getSession(i),a===null?i="":(a.version.major!==n.version.major||a.version.minor>n.version.minor)&&(a=null,i="")),i.length===0&&(i=j.random.getBytes(32)),e.session.id=i,e.session.clientHelloVersion=n.version,e.session.sp={},a)e.version=e.session.version=a.version,e.session.sp=a.sp;else{for(var s,o=1;o0;)a=sr(i.certificate_list,3),s=j.asn1.fromDer(a),a=j.pki.certificateFromAsn1(s,!0),o.push(a)}catch(u){return e.error(e,{message:"Could not parse certificate list.",cause:u,send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.bad_certificate}})}var l=e.entity===T.ConnectionEnd.client;(l||e.verifyClient===!0)&&o.length===0?e.error(e,{message:l?"No server certificate provided.":"No client certificate provided.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.illegal_parameter}}):o.length===0?e.expect=l?Eh:Fc:(l?e.session.serverCertificate=o[0]:e.session.clientCertificate=o[0],T.verifyCertificateChain(e,o)&&(e.expect=l?Eh:Fc)),e.process()};T.handleServerKeyExchange=function(e,t,r){if(r>0)return e.error(e,{message:"Invalid key parameters. Only RSA is supported.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.unsupported_certificate}});e.expect=Sx,e.process()};T.handleClientKeyExchange=function(e,t,r){if(r<48)return e.error(e,{message:"Invalid key parameters. Only RSA is supported.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.unsupported_certificate}});var n=t.fragment,i={enc_pre_master_secret:sr(n,2).getBytes()},a=null;if(e.getPrivateKey)try{a=e.getPrivateKey(e,e.session.serverCertificate),a=j.pki.privateKeyFromPem(a)}catch(l){e.error(e,{message:"Could not get private key.",cause:l,send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.internal_error}})}if(a===null)return e.error(e,{message:"No private key set.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.internal_error}});try{var s=e.session.sp;s.pre_master_secret=a.decrypt(i.enc_pre_master_secret);var o=e.session.clientHelloVersion;if(o.major!==s.pre_master_secret.charCodeAt(0)||o.minor!==s.pre_master_secret.charCodeAt(1))throw new Error("TLS version rollback attack detected.")}catch{s.pre_master_secret=j.random.getBytes(48)}e.expect=c0,e.session.clientCertificate!==null&&(e.expect=Bx),e.process()};T.handleCertificateRequest=function(e,t,r){if(r<3)return e.error(e,{message:"Invalid CertificateRequest. Message too short.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.illegal_parameter}});var n=t.fragment,i={certificate_types:sr(n,1),certificate_authorities:sr(n,2)};e.session.certificateRequest=i,e.expect=xx,e.process()};T.handleCertificateVerify=function(e,t,r){if(r<2)return e.error(e,{message:"Invalid CertificateVerify. Message too short.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.illegal_parameter}});var n=t.fragment;n.read-=4;var i=n.bytes();n.read+=4;var a={signature:sr(n,2).getBytes()},s=j.util.createBuffer();s.putBuffer(e.session.md5.digest()),s.putBuffer(e.session.sha1.digest()),s=s.getBytes();try{var o=e.session.clientCertificate;if(!o.publicKey.verify(s,a.signature,"NONE"))throw new Error("CertificateVerify signature does not match.");e.session.md5.update(i),e.session.sha1.update(i)}catch{return e.error(e,{message:"Bad signature in CertificateVerify.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.handshake_failure}})}e.expect=c0,e.process()};T.handleServerHelloDone=function(e,t,r){if(r>0)return e.error(e,{message:"Invalid ServerHelloDone message. Invalid length.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.record_overflow}});if(e.serverCertificate===null){var n={message:"No server certificate provided. Not enough security.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.insufficient_security}},i=0,a=e.verify(e,n.alert.description,i,[]);if(a!==!0)return(a||a===0)&&(typeof a=="object"&&!j.util.isArray(a)?(a.message&&(n.message=a.message),a.alert&&(n.alert.description=a.alert)):typeof a=="number"&&(n.alert.description=a)),e.error(e,n)}e.session.certificateRequest!==null&&(t=T.createRecord(e,{type:T.ContentType.handshake,data:T.createCertificate(e)}),T.queue(e,t)),t=T.createRecord(e,{type:T.ContentType.handshake,data:T.createClientKeyExchange(e)}),T.queue(e,t),e.expect=Ix;var s=function(o,l){o.session.certificateRequest!==null&&o.session.clientCertificate!==null&&T.queue(o,T.createRecord(o,{type:T.ContentType.handshake,data:T.createCertificateVerify(o,l)})),T.queue(o,T.createRecord(o,{type:T.ContentType.change_cipher_spec,data:T.createChangeCipherSpec()})),o.state.pending=T.createConnectionState(o),o.state.current.write=o.state.pending.write,T.queue(o,T.createRecord(o,{type:T.ContentType.handshake,data:T.createFinished(o)})),o.expect=j1,T.flush(o),o.process()};if(e.session.certificateRequest===null||e.session.clientCertificate===null)return s(e,null);T.getClientSignature(e,s)};T.handleChangeCipherSpec=function(e,t){if(t.fragment.getByte()!==1)return e.error(e,{message:"Invalid ChangeCipherSpec message received.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.illegal_parameter}});var r=e.entity===T.ConnectionEnd.client;(e.session.resuming&&r||!e.session.resuming&&!r)&&(e.state.pending=T.createConnectionState(e)),e.state.current.read=e.state.pending.read,(!e.session.resuming&&r||e.session.resuming&&!r)&&(e.state.pending=null),e.expect=r?Tx:kx,e.process()};T.handleFinished=function(e,t,r){var n=t.fragment;n.read-=4;var i=n.bytes();n.read+=4;var a=t.fragment.getBytes();n=j.util.createBuffer(),n.putBuffer(e.session.md5.digest()),n.putBuffer(e.session.sha1.digest());var s=e.entity===T.ConnectionEnd.client,o=s?"server finished":"client finished",l=e.session.sp,u=12,c=bl;if(n=c(l.master_secret,o,n.getBytes(),u),n.getBytes()!==a)return e.error(e,{message:"Invalid verify_data in Finished message.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.decrypt_error}});e.session.md5.update(i),e.session.sha1.update(i),(e.session.resuming&&s||!e.session.resuming&&!s)&&(T.queue(e,T.createRecord(e,{type:T.ContentType.change_cipher_spec,data:T.createChangeCipherSpec()})),e.state.current.write=e.state.pending.write,e.state.pending=null,T.queue(e,T.createRecord(e,{type:T.ContentType.handshake,data:T.createFinished(e)}))),e.expect=s?wx:bx,e.handshaking=!1,++e.handshakes,e.peerCertificate=s?e.session.serverCertificate:e.session.clientCertificate,T.flush(e),e.isConnected=!0,e.connected(e),e.process()};T.handleAlert=function(e,t){var r=t.fragment,n={level:r.getByte(),description:r.getByte()},i;switch(n.description){case T.Alert.Description.close_notify:i="Connection closed.";break;case T.Alert.Description.unexpected_message:i="Unexpected message.";break;case T.Alert.Description.bad_record_mac:i="Bad record MAC.";break;case T.Alert.Description.decryption_failed:i="Decryption failed.";break;case T.Alert.Description.record_overflow:i="Record overflow.";break;case T.Alert.Description.decompression_failure:i="Decompression failed.";break;case T.Alert.Description.handshake_failure:i="Handshake failure.";break;case T.Alert.Description.bad_certificate:i="Bad certificate.";break;case T.Alert.Description.unsupported_certificate:i="Unsupported certificate.";break;case T.Alert.Description.certificate_revoked:i="Certificate revoked.";break;case T.Alert.Description.certificate_expired:i="Certificate expired.";break;case T.Alert.Description.certificate_unknown:i="Certificate unknown.";break;case T.Alert.Description.illegal_parameter:i="Illegal parameter.";break;case T.Alert.Description.unknown_ca:i="Unknown certificate authority.";break;case T.Alert.Description.access_denied:i="Access denied.";break;case T.Alert.Description.decode_error:i="Decode error.";break;case T.Alert.Description.decrypt_error:i="Decrypt error.";break;case T.Alert.Description.export_restriction:i="Export restriction.";break;case T.Alert.Description.protocol_version:i="Unsupported protocol version.";break;case T.Alert.Description.insufficient_security:i="Insufficient security.";break;case T.Alert.Description.internal_error:i="Internal error.";break;case T.Alert.Description.user_canceled:i="User canceled.";break;case T.Alert.Description.no_renegotiation:i="Renegotiation not supported.";break;default:i="Unknown error.";break}if(n.description===T.Alert.Description.close_notify)return e.close();e.error(e,{message:i,send:!1,origin:e.entity===T.ConnectionEnd.client?"server":"client",alert:n}),e.process()};T.handleHandshake=function(e,t){var r=t.fragment,n=r.getByte(),i=r.getInt24();if(i>r.length())return e.fragmented=t,t.fragment=j.util.createBuffer(),r.read-=4,e.process();e.fragmented=null,r.read-=4;var a=r.bytes(i+4);r.read+=4,n in el[e.entity][e.expect]?(e.entity===T.ConnectionEnd.server&&!e.open&&!e.fail&&(e.handshaking=!0,e.session={version:null,extensions:{server_name:{serverNameList:[]}},cipherSuite:null,compressionMethod:null,serverCertificate:null,clientCertificate:null,md5:j.md.md5.create(),sha1:j.md.sha1.create()}),n!==T.HandshakeType.hello_request&&n!==T.HandshakeType.certificate_verify&&n!==T.HandshakeType.finished&&(e.session.md5.update(a),e.session.sha1.update(a)),el[e.entity][e.expect][n](e,t,i)):T.handleUnexpected(e,t)};T.handleApplicationData=function(e,t){e.data.putBuffer(t.fragment),e.dataReady(e),e.process()};T.handleHeartbeat=function(e,t){var r=t.fragment,n=r.getByte(),i=r.getInt16(),a=r.getBytes(i);if(n===T.HeartbeatMessageType.heartbeat_request){if(e.handshaking||i>a.length)return e.process();T.queue(e,T.createRecord(e,{type:T.ContentType.heartbeat,data:T.createHeartbeat(T.HeartbeatMessageType.heartbeat_response,a)})),T.flush(e)}else if(n===T.HeartbeatMessageType.heartbeat_response){if(a!==e.expectedHeartbeatPayload)return e.process();e.heartbeatReceived&&e.heartbeatReceived(e,j.util.createBuffer(a))}e.process()};var Cx=0,Ex=1,Eh=2,Sx=3,xx=4,j1=5,Tx=6,wx=7,Ix=8,_x=0,Ax=1,Fc=2,Bx=3,c0=4,kx=5,bx=6,x=T.handleUnexpected,K1=T.handleChangeCipherSpec,kt=T.handleAlert,Kt=T.handleHandshake,z1=T.handleApplicationData,bt=T.handleHeartbeat,f0=[];f0[T.ConnectionEnd.client]=[[x,kt,Kt,x,bt],[x,kt,Kt,x,bt],[x,kt,Kt,x,bt],[x,kt,Kt,x,bt],[x,kt,Kt,x,bt],[K1,kt,x,x,bt],[x,kt,Kt,x,bt],[x,kt,Kt,z1,bt],[x,kt,Kt,x,bt]];f0[T.ConnectionEnd.server]=[[x,kt,Kt,x,bt],[x,kt,Kt,x,bt],[x,kt,Kt,x,bt],[x,kt,Kt,x,bt],[K1,kt,x,x,bt],[x,kt,Kt,x,bt],[x,kt,Kt,z1,bt],[x,kt,Kt,x,bt]];var _n=T.handleHelloRequest,Nx=T.handleServerHello,H1=T.handleCertificate,Sh=T.handleServerKeyExchange,xu=T.handleCertificateRequest,to=T.handleServerHelloDone,q1=T.handleFinished,el=[];el[T.ConnectionEnd.client]=[[x,x,Nx,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x],[_n,x,x,x,x,x,x,x,x,x,x,H1,Sh,xu,to,x,x,x,x,x,x],[_n,x,x,x,x,x,x,x,x,x,x,x,Sh,xu,to,x,x,x,x,x,x],[_n,x,x,x,x,x,x,x,x,x,x,x,x,xu,to,x,x,x,x,x,x],[_n,x,x,x,x,x,x,x,x,x,x,x,x,x,to,x,x,x,x,x,x],[_n,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x],[_n,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,q1],[_n,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x],[_n,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]];var Dx=T.handleClientHello,Rx=T.handleClientKeyExchange,Lx=T.handleCertificateVerify;el[T.ConnectionEnd.server]=[[x,Dx,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x],[x,x,x,x,x,x,x,x,x,x,x,H1,x,x,x,x,x,x,x,x,x],[x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,Rx,x,x,x,x],[x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,Lx,x,x,x,x,x],[x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x],[x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,q1],[x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x],[x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x]];T.generateKeys=function(e,t){var r=bl,n=t.client_random+t.server_random;e.session.resuming||(t.master_secret=r(t.pre_master_secret,"master secret",n,48).bytes(),t.pre_master_secret=null),n=t.server_random+t.client_random;var i=2*t.mac_key_length+2*t.enc_key_length,a=e.version.major===T.Versions.TLS_1_0.major&&e.version.minor===T.Versions.TLS_1_0.minor;a&&(i+=2*t.fixed_iv_length);var s=r(t.master_secret,"key expansion",n,i),o={client_write_MAC_key:s.getBytes(t.mac_key_length),server_write_MAC_key:s.getBytes(t.mac_key_length),client_write_key:s.getBytes(t.enc_key_length),server_write_key:s.getBytes(t.enc_key_length)};return a&&(o.client_write_IV=s.getBytes(t.fixed_iv_length),o.server_write_IV=s.getBytes(t.fixed_iv_length)),o};T.createConnectionState=function(e){var t=e.entity===T.ConnectionEnd.client,r=function(){var a={sequenceNumber:[0,0],macKey:null,macLength:0,macFunction:null,cipherState:null,cipherFunction:function(s){return!0},compressionState:null,compressFunction:function(s){return!0},updateSequenceNumber:function(){a.sequenceNumber[1]===4294967295?(a.sequenceNumber[1]=0,++a.sequenceNumber[0]):++a.sequenceNumber[1]}};return a},n={read:r(),write:r()};if(n.read.update=function(a,s){return n.read.cipherFunction(s,n.read)?n.read.compressFunction(a,s,n.read)||a.error(a,{message:"Could not decompress record.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.decompression_failure}}):a.error(a,{message:"Could not decrypt record or bad MAC.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.bad_record_mac}}),!a.fail},n.write.update=function(a,s){return n.write.compressFunction(a,s,n.write)?n.write.cipherFunction(s,n.write)||a.error(a,{message:"Could not encrypt record.",send:!1,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.internal_error}}):a.error(a,{message:"Could not compress record.",send:!1,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.internal_error}}),!a.fail},e.session){var i=e.session.sp;switch(e.session.cipherSuite.initSecurityParameters(i),i.keys=T.generateKeys(e,i),n.read.macKey=t?i.keys.server_write_MAC_key:i.keys.client_write_MAC_key,n.write.macKey=t?i.keys.client_write_MAC_key:i.keys.server_write_MAC_key,e.session.cipherSuite.initConnectionState(n,e,i),i.compression_algorithm){case T.CompressionMethod.none:break;case T.CompressionMethod.deflate:n.read.compressFunction=mx,n.write.compressFunction=yx;break;default:throw new Error("Unsupported compression algorithm.")}}return n};T.createRandom=function(){var e=new Date,t=+e+e.getTimezoneOffset()*6e4,r=j.util.createBuffer();return r.putInt32(t),r.putBytes(j.random.getBytes(28)),r};T.createRecord=function(e,t){if(!t.data)return null;var r={type:t.type,version:{major:e.version.major,minor:e.version.minor},length:t.data.length(),fragment:t.data};return r};T.createAlert=function(e,t){var r=j.util.createBuffer();return r.putByte(t.level),r.putByte(t.description),T.createRecord(e,{type:T.ContentType.alert,data:r})};T.createClientHello=function(e){e.session.clientHelloVersion={major:e.version.major,minor:e.version.minor};for(var t=j.util.createBuffer(),r=0;r0&&(f+=2);var d=e.session.id,v=d.length+1+2+4+28+2+i+1+s+f,g=j.util.createBuffer();return g.putByte(T.HandshakeType.client_hello),g.putInt24(v),g.putByte(e.version.major),g.putByte(e.version.minor),g.putBytes(e.session.sp.client_random),Er(g,1,j.util.createBuffer(d)),Er(g,2,t),Er(g,1,a),f>0&&Er(g,2,o),g};T.createServerHello=function(e){var t=e.session.id,r=t.length+1+2+4+28+2+1,n=j.util.createBuffer();return n.putByte(T.HandshakeType.server_hello),n.putInt24(r),n.putByte(e.version.major),n.putByte(e.version.minor),n.putBytes(e.session.sp.server_random),Er(n,1,j.util.createBuffer(t)),n.putByte(e.session.cipherSuite.id[0]),n.putByte(e.session.cipherSuite.id[1]),n.putByte(e.session.compressionMethod),n};T.createCertificate=function(e){var t=e.entity===T.ConnectionEnd.client,r=null;if(e.getCertificate){var n;t?n=e.session.certificateRequest:n=e.session.extensions.server_name.serverNameList,r=e.getCertificate(e,n)}var i=j.util.createBuffer();if(r!==null)try{j.util.isArray(r)||(r=[r]);for(var a=null,s=0;s"u"&&(r=t.length);var n=j.util.createBuffer();n.putByte(e),n.putInt16(r),n.putBytes(t);var i=n.length(),a=Math.max(16,i-r-3);return n.putBytes(j.random.getBytes(a)),n};T.queue=function(e,t){if(t&&!(t.fragment.length()===0&&(t.type===T.ContentType.handshake||t.type===T.ContentType.alert||t.type===T.ContentType.change_cipher_spec))){if(t.type===T.ContentType.handshake){var r=t.fragment.bytes();e.session.md5.update(r),e.session.sha1.update(r),r=null}var n;if(t.fragment.length()<=T.MaxFragment)n=[t];else{n=[];for(var i=t.fragment.bytes();i.length>T.MaxFragment;)n.push(T.createRecord(e,{type:t.type,data:j.util.createBuffer(i.slice(0,T.MaxFragment))})),i=i.slice(T.MaxFragment);i.length>0&&n.push(T.createRecord(e,{type:t.type,data:j.util.createBuffer(i)}))}for(var a=0;a0&&(s=r.order[0]),s!==null&&s in r.cache){a=r.cache[s],delete r.cache[s];for(var o in r.order)if(r.order[o]===s){r.order.splice(o,1);break}}return a},r.setSession=function(i,a){if(r.order.length===r.capacity){var s=r.order.shift();delete r.cache[s]}var s=j.util.bytesToHex(i);r.order.push(s),r.cache[s]=a}}return r};T.createConnection=function(e){var t=null;e.caStore?j.util.isArray(e.caStore)?t=j.pki.createCaStore(e.caStore):t=e.caStore:t=j.pki.createCaStore();var r=e.cipherSuites||null;if(r===null){r=[];for(var n in T.CipherSuites)r.push(T.CipherSuites[n])}var i=e.server?T.ConnectionEnd.server:T.ConnectionEnd.client,a=e.sessionCache?T.createSessionCache(e.sessionCache):null,s={version:{major:T.Version.major,minor:T.Version.minor},entity:i,sessionId:e.sessionId,caStore:t,sessionCache:a,cipherSuites:r,connected:e.connected,virtualHost:e.virtualHost||null,verifyClient:e.verifyClient||!1,verify:e.verify||function(c,f,d,v){return f},verifyOptions:e.verifyOptions||{},getCertificate:e.getCertificate||null,getPrivateKey:e.getPrivateKey||null,getSignature:e.getSignature||null,input:j.util.createBuffer(),tlsData:j.util.createBuffer(),data:j.util.createBuffer(),tlsDataReady:e.tlsDataReady,dataReady:e.dataReady,heartbeatReceived:e.heartbeatReceived,closed:e.closed,error:function(c,f){f.origin=f.origin||(c.entity===T.ConnectionEnd.client?"client":"server"),f.send&&(T.queue(c,T.createAlert(c,f.alert)),T.flush(c));var d=f.fatal!==!1;d&&(c.fail=!0),e.error(c,f),d&&c.close(!1)},deflate:e.deflate||null,inflate:e.inflate||null};s.reset=function(c){s.version={major:T.Version.major,minor:T.Version.minor},s.record=null,s.session=null,s.peerCertificate=null,s.state={pending:null,current:null},s.expect=s.entity===T.ConnectionEnd.client?Cx:_x,s.fragmented=null,s.records=[],s.open=!1,s.handshakes=0,s.handshaking=!1,s.isConnected=!1,s.fail=!(c||typeof c>"u"),s.input.clear(),s.tlsData.clear(),s.data.clear(),s.state.current=T.createConnectionState(s)},s.reset();var o=function(c,f){var d=f.type-T.ContentType.change_cipher_spec,v=f0[c.entity][c.expect];d in v?v[d](c,f):T.handleUnexpected(c,f)},l=function(c){var f=0,d=c.input,v=d.length();if(v<5)f=5-v;else{c.record={type:d.getByte(),version:{major:d.getByte(),minor:d.getByte()},length:d.getInt16(),fragment:j.util.createBuffer(),ready:!1};var g=c.record.version.major===c.version.major;g&&c.session&&c.session.version&&(g=c.record.version.minor===c.version.minor),g||c.error(c,{message:"Incompatible TLS version.",send:!0,alert:{level:T.Alert.Level.fatal,description:T.Alert.Description.protocol_version}})}return f},u=function(c){var f=0,d=c.input,v=d.length();if(v0&&(s.sessionCache&&(f=s.sessionCache.getSession(c)),f===null&&(c="")),c.length===0&&s.sessionCache&&(f=s.sessionCache.getSession(),f!==null&&(c=f.id)),s.session={id:c,version:null,cipherSuite:null,compressionMethod:null,serverCertificate:null,certificateRequest:null,clientCertificate:null,sp:{},md5:j.md.md5.create(),sha1:j.md.sha1.create()},f&&(s.version=f.version,s.session.sp=f.sp),s.session.sp.client_random=T.createRandom().getBytes(),s.open=!0,T.queue(s,T.createRecord(s,{type:T.ContentType.handshake,data:T.createClientHello(s)})),T.flush(s)}},s.process=function(c){var f=0;return c&&s.input.putBytes(c),s.fail||(s.record!==null&&s.record.ready&&s.record.fragment.isEmpty()&&(s.record=null),s.record===null&&(f=l(s)),!s.fail&&s.record!==null&&!s.record.ready&&(f=u(s)),!s.fail&&s.record!==null&&s.record.ready&&o(s,s.record)),f},s.prepare=function(c){return T.queue(s,T.createRecord(s,{type:T.ContentType.application_data,data:j.util.createBuffer(c)})),T.flush(s)},s.prepareHeartbeatRequest=function(c,f){return c instanceof j.util.ByteBuffer&&(c=c.bytes()),typeof f>"u"&&(f=c.length),s.expectedHeartbeatPayload=c,T.queue(s,T.createRecord(s,{type:T.ContentType.heartbeat,data:T.createHeartbeat(T.HeartbeatMessageType.heartbeat_request,c,f)})),T.flush(s)},s.close=function(c){if(!s.fail&&s.sessionCache&&s.session){var f={id:s.session.id,version:s.session.version,sp:s.session.sp};f.sp.keys=null,s.sessionCache.setSession(f.id,f)}s.open&&(s.open=!1,s.input.clear(),(s.isConnected||s.handshaking)&&(s.isConnected=s.handshaking=!1,T.queue(s,T.createAlert(s,{level:T.Alert.Level.warning,description:T.Alert.Description.close_notify})),T.flush(s)),s.closed(s)),s.reset(c)},s};j.tls=j.tls||{};for(var wu in T)typeof T[wu]!="function"&&(j.tls[wu]=T[wu]);j.tls.prf_tls1=bl;j.tls.hmac_sha1=vx;j.tls.createSessionCache=T.createSessionCache;j.tls.createConnection=T.createConnection;var Qn=me,Br=Qn.tls;Br.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA={id:[0,47],name:"TLS_RSA_WITH_AES_128_CBC_SHA",initSecurityParameters:function(e){e.bulk_cipher_algorithm=Br.BulkCipherAlgorithm.aes,e.cipher_type=Br.CipherType.block,e.enc_key_length=16,e.block_length=16,e.fixed_iv_length=16,e.record_iv_length=16,e.mac_algorithm=Br.MACAlgorithm.hmac_sha1,e.mac_length=20,e.mac_key_length=20},initConnectionState:$1};Br.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA={id:[0,53],name:"TLS_RSA_WITH_AES_256_CBC_SHA",initSecurityParameters:function(e){e.bulk_cipher_algorithm=Br.BulkCipherAlgorithm.aes,e.cipher_type=Br.CipherType.block,e.enc_key_length=32,e.block_length=16,e.fixed_iv_length=16,e.record_iv_length=16,e.mac_algorithm=Br.MACAlgorithm.hmac_sha1,e.mac_length=20,e.mac_key_length=20},initConnectionState:$1};function $1(e,t,r){var n=t.entity===Qn.tls.ConnectionEnd.client;e.read.cipherState={init:!1,cipher:Qn.cipher.createDecipher("AES-CBC",n?r.keys.server_write_key:r.keys.client_write_key),iv:n?r.keys.server_write_IV:r.keys.client_write_IV},e.write.cipherState={init:!1,cipher:Qn.cipher.createCipher("AES-CBC",n?r.keys.client_write_key:r.keys.server_write_key),iv:n?r.keys.client_write_IV:r.keys.server_write_IV},e.read.cipherFunction=Fx,e.write.cipherFunction=Px,e.read.macLength=e.write.macLength=r.mac_length,e.read.macFunction=e.write.macFunction=Br.hmac_sha1}function Px(e,t){var r=!1,n=t.macFunction(t.macKey,t.sequenceNumber,e);e.fragment.putBytes(n),t.updateSequenceNumber();var i;e.version.minor===Br.Versions.TLS_1_0.minor?i=t.cipherState.init?null:t.cipherState.iv:i=Qn.random.getBytesSync(16),t.cipherState.init=!0;var a=t.cipherState.cipher;return a.start({iv:i}),e.version.minor>=Br.Versions.TLS_1_1.minor&&a.output.putBytes(i),a.update(e.fragment),a.finish(Ux)&&(e.fragment=a.output,e.length=e.fragment.length(),r=!0),r}function Ux(e,t,r){if(!r){var n=e-t.length()%e;t.fillWithByte(n-1,n)}return!0}function Mx(e,t,r){var n=!0;if(r){for(var i=t.length(),a=t.last(),s=i-1-a;s=a?(e.fragment=i.output.getBytes(o-a),s=i.output.getBytes(a)):e.fragment=i.output.getBytes(),e.fragment=Qn.util.createBuffer(e.fragment),e.length=e.fragment.length();var l=t.macFunction(t.macKey,t.sequenceNumber,e);return t.updateSequenceNumber(),r=Vx(t.macKey,s,l)&&r,r}function Vx(e,t,r){var n=Qn.hmac.create();return n.start("SHA1",e),n.update(t),t=n.digest().getBytes(),n.start(null,null),n.update(r),r=n.digest().getBytes(),t===r}var Je=me,bs=Je.sha512=Je.sha512||{};Je.md.sha512=Je.md.algorithms.sha512=bs;var G1=Je.sha384=Je.sha512.sha384=Je.sha512.sha384||{};G1.create=function(){return bs.create("SHA-384")};Je.md.sha384=Je.md.algorithms.sha384=G1;Je.sha512.sha256=Je.sha512.sha256||{create:function(){return bs.create("SHA-512/256")}};Je.md["sha512/256"]=Je.md.algorithms["sha512/256"]=Je.sha512.sha256;Je.sha512.sha224=Je.sha512.sha224||{create:function(){return bs.create("SHA-512/224")}};Je.md["sha512/224"]=Je.md.algorithms["sha512/224"]=Je.sha512.sha224;bs.create=function(e){if(Q1||jx(),typeof e>"u"&&(e="SHA-512"),!(e in si))throw new Error("Invalid SHA-512 algorithm: "+e);for(var t=si[e],r=null,n=Je.util.createBuffer(),i=new Array(80),a=0;a<80;++a)i[a]=new Array(2);var s=64;switch(e){case"SHA-384":s=48;break;case"SHA-512/256":s=32;break;case"SHA-512/224":s=28;break}var o={algorithm:e.replace("-","").toLowerCase(),blockLength:128,digestLength:s,messageLength:0,fullMessageLength:null,messageLengthSize:16};return o.start=function(){o.messageLength=0,o.fullMessageLength=o.messageLength128=[];for(var l=o.messageLengthSize/4,u=0;u>>0,c>>>0];for(var f=o.fullMessageLength.length-1;f>=0;--f)o.fullMessageLength[f]+=c[1],c[1]=c[0]+(o.fullMessageLength[f]/4294967296>>>0),o.fullMessageLength[f]=o.fullMessageLength[f]>>>0,c[0]=c[1]/4294967296>>>0;return n.putBytes(l),xh(r,i,n),(n.read>2048||n.length()===0)&&n.compact(),o},o.digest=function(){var l=Je.util.createBuffer();l.putBytes(n.bytes());var u=o.fullMessageLength[o.fullMessageLength.length-1]+o.messageLengthSize,c=u&o.blockLength-1;l.putBytes(Vc.substr(0,o.blockLength-c));for(var f,d,v=o.fullMessageLength[0]*8,g=0;g>>0,v+=d,l.putInt32(v>>>0),v=f>>>0;l.putInt32(v);for(var C=new Array(r.length),g=0;g=128;){for(Ce=0;Ce<16;++Ce)t[Ce][0]=r.getInt32()>>>0,t[Ce][1]=r.getInt32()>>>0;for(;Ce<80;++Ce)W=t[Ce-2],Le=W[0],te=W[1],n=((Le>>>19|te<<13)^(te>>>29|Le<<3)^Le>>>6)>>>0,i=((Le<<13|te>>>19)^(te<<3|Le>>>29)^(Le<<26|te>>>6))>>>0,ne=t[Ce-15],Le=ne[0],te=ne[1],a=((Le>>>1|te<<31)^(Le>>>8|te<<24)^Le>>>7)>>>0,s=((Le<<31|te>>>1)^(Le<<24|te>>>8)^(Le<<25|te>>>7))>>>0,ae=t[Ce-7],ee=t[Ce-16],te=i+ae[1]+s+ee[1],t[Ce][0]=n+ae[0]+a+ee[0]+(te/4294967296>>>0)>>>0,t[Ce][1]=te>>>0;for(C=e[0][0],I=e[0][1],y=e[1][0],m=e[1][1],S=e[2][0],B=e[2][1],R=e[3][0],L=e[3][1],M=e[4][0],V=e[4][1],Q=e[5][0],G=e[5][1],ce=e[6][0],pe=e[6][1],De=e[7][0],Ue=e[7][1],Ce=0;Ce<80;++Ce)u=((M>>>14|V<<18)^(M>>>18|V<<14)^(V>>>9|M<<23))>>>0,c=((M<<18|V>>>14)^(M<<14|V>>>18)^(V<<23|M>>>9))>>>0,f=(ce^M&(Q^ce))>>>0,d=(pe^V&(G^pe))>>>0,o=((C>>>28|I<<4)^(I>>>2|C<<30)^(I>>>7|C<<25))>>>0,l=((C<<4|I>>>28)^(I<<30|C>>>2)^(I<<25|C>>>7))>>>0,v=(C&y|S&(C^y))>>>0,g=(I&m|B&(I^m))>>>0,te=Ue+c+d+jc[Ce][1]+t[Ce][1],n=De+u+f+jc[Ce][0]+t[Ce][0]+(te/4294967296>>>0)>>>0,i=te>>>0,te=l+g,a=o+v+(te/4294967296>>>0)>>>0,s=te>>>0,De=ce,Ue=pe,ce=Q,pe=G,Q=M,G=V,te=L+i,M=R+n+(te/4294967296>>>0)>>>0,V=te>>>0,R=S,L=B,S=y,B=m,y=C,m=I,te=i+s,C=n+a+(te/4294967296>>>0)>>>0,I=te>>>0;te=e[0][1]+I,e[0][0]=e[0][0]+C+(te/4294967296>>>0)>>>0,e[0][1]=te>>>0,te=e[1][1]+m,e[1][0]=e[1][0]+y+(te/4294967296>>>0)>>>0,e[1][1]=te>>>0,te=e[2][1]+B,e[2][0]=e[2][0]+S+(te/4294967296>>>0)>>>0,e[2][1]=te>>>0,te=e[3][1]+L,e[3][0]=e[3][0]+R+(te/4294967296>>>0)>>>0,e[3][1]=te>>>0,te=e[4][1]+V,e[4][0]=e[4][0]+M+(te/4294967296>>>0)>>>0,e[4][1]=te>>>0,te=e[5][1]+G,e[5][0]=e[5][0]+Q+(te/4294967296>>>0)>>>0,e[5][1]=te>>>0,te=e[6][1]+pe,e[6][0]=e[6][0]+ce+(te/4294967296>>>0)>>>0,e[6][1]=te>>>0,te=e[7][1]+Ue,e[7][0]=e[7][0]+De+(te/4294967296>>>0)>>>0,e[7][1]=te>>>0,ie-=128}}var d0={},Kx=me,xt=Kx.asn1;d0.privateKeyValidator={name:"PrivateKeyInfo",tagClass:xt.Class.UNIVERSAL,type:xt.Type.SEQUENCE,constructed:!0,value:[{name:"PrivateKeyInfo.version",tagClass:xt.Class.UNIVERSAL,type:xt.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"PrivateKeyInfo.privateKeyAlgorithm",tagClass:xt.Class.UNIVERSAL,type:xt.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:xt.Class.UNIVERSAL,type:xt.Type.OID,constructed:!1,capture:"privateKeyOid"}]},{name:"PrivateKeyInfo",tagClass:xt.Class.UNIVERSAL,type:xt.Type.OCTETSTRING,constructed:!1,capture:"privateKey"}]};d0.publicKeyValidator={name:"SubjectPublicKeyInfo",tagClass:xt.Class.UNIVERSAL,type:xt.Type.SEQUENCE,constructed:!0,captureAsn1:"subjectPublicKeyInfo",value:[{name:"SubjectPublicKeyInfo.AlgorithmIdentifier",tagClass:xt.Class.UNIVERSAL,type:xt.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:xt.Class.UNIVERSAL,type:xt.Type.OID,constructed:!1,capture:"publicKeyOid"}]},{tagClass:xt.Class.UNIVERSAL,type:xt.Type.BITSTRING,constructed:!1,composed:!0,captureBitStringValue:"ed25519PublicKey"}]};var Nt=me,W1=d0,zx=W1.publicKeyValidator,Hx=W1.privateKeyValidator;if(typeof qx>"u")var qx=Nt.jsbn.BigInteger;var Kc=Nt.util.ByteBuffer,er=typeof Buffer>"u"?Uint8Array:Buffer;Nt.pki=Nt.pki||{};Nt.pki.ed25519=Nt.ed25519=Nt.ed25519||{};var Se=Nt.ed25519;Se.constants={};Se.constants.PUBLIC_KEY_BYTE_LENGTH=32;Se.constants.PRIVATE_KEY_BYTE_LENGTH=64;Se.constants.SEED_BYTE_LENGTH=32;Se.constants.SIGN_BYTE_LENGTH=64;Se.constants.HASH_BYTE_LENGTH=64;Se.generateKeyPair=function(e){e=e||{};var t=e.seed;if(t===void 0)t=Nt.random.getBytesSync(Se.constants.SEED_BYTE_LENGTH);else if(typeof t=="string"){if(t.length!==Se.constants.SEED_BYTE_LENGTH)throw new TypeError('"seed" must be '+Se.constants.SEED_BYTE_LENGTH+" bytes in length.")}else if(!(t instanceof Uint8Array))throw new TypeError('"seed" must be a node.js Buffer, Uint8Array, or a binary string.');t=hn({message:t,encoding:"binary"});for(var r=new er(Se.constants.PUBLIC_KEY_BYTE_LENGTH),n=new er(Se.constants.PRIVATE_KEY_BYTE_LENGTH),i=0;i<32;++i)n[i]=t[i];return Wx(r,n),{publicKey:r,privateKey:n}};Se.privateKeyFromAsn1=function(e){var t={},r=[],n=Nt.asn1.validate(e,Hx,t,r);if(!n){var i=new Error("Invalid Key.");throw i.errors=r,i}var a=Nt.asn1.derToOid(t.privateKeyOid),s=Nt.oids.EdDSA25519;if(a!==s)throw new Error('Invalid OID "'+a+'"; OID must be "'+s+'".');var o=t.privateKey,l=hn({message:Nt.asn1.fromDer(o).value,encoding:"binary"});return{privateKeyBytes:l}};Se.publicKeyFromAsn1=function(e){var t={},r=[],n=Nt.asn1.validate(e,zx,t,r);if(!n){var i=new Error("Invalid Key.");throw i.errors=r,i}var a=Nt.asn1.derToOid(t.publicKeyOid),s=Nt.oids.EdDSA25519;if(a!==s)throw new Error('Invalid OID "'+a+'"; OID must be "'+s+'".');var o=t.ed25519PublicKey;if(o.length!==Se.constants.PUBLIC_KEY_BYTE_LENGTH)throw new Error("Key length is invalid.");return hn({message:o,encoding:"binary"})};Se.publicKeyFromPrivateKey=function(e){e=e||{};var t=hn({message:e.privateKey,encoding:"binary"});if(t.length!==Se.constants.PRIVATE_KEY_BYTE_LENGTH)throw new TypeError('"options.privateKey" must have a byte length of '+Se.constants.PRIVATE_KEY_BYTE_LENGTH);for(var r=new er(Se.constants.PUBLIC_KEY_BYTE_LENGTH),n=0;n=0};function hn(e){var t=e.message;if(t instanceof Uint8Array||t instanceof er)return t;var r=e.encoding;if(t===void 0)if(e.md)t=e.md.digest().getBytes(),r="binary";else throw new TypeError('"options.message" or "options.md" not specified.');if(typeof t=="string"&&!r)throw new TypeError('"options.encoding" must be "binary" or "utf8".');if(typeof t=="string"){if(typeof Buffer<"u")return Buffer.from(t,r);t=new Kc(t,r)}else if(!(t instanceof Kc))throw new TypeError('"options.message" must be a node.js Buffer, a Uint8Array, a forge ByteBuffer, or a string with "options.encoding" specifying its encoding.');for(var n=new er(t.length()),i=0;i=32;--n){for(r=0,i=n-32,a=n-12;i>8,t[i]-=r*256;t[i]+=r,t[n]=0}for(r=0,i=0;i<32;++i)t[i]+=r-(t[31]>>4)*Iu[i],r=t[i]>>8,t[i]&=255;for(i=0;i<32;++i)t[i]-=r*Iu[i];for(n=0;n<32;++n)t[n+1]+=t[n]>>8,e[n]=t[n]&255}function Hc(e){for(var t=new Float64Array(64),r=0;r<64;++r)t[r]=e[r],e[r]=0;Y1(e,t)}function qc(e,t){var r=ue(),n=ue(),i=ue(),a=ue(),s=ue(),o=ue(),l=ue(),u=ue(),c=ue();Qi(r,e[1],e[0]),Qi(c,t[1],t[0]),Ve(r,r,c),Li(n,e[0],e[1]),Li(c,t[0],t[1]),Ve(n,n,c),Ve(i,e[3],t[3]),Ve(i,i,Gx),Ve(a,e[2],t[2]),Li(a,a,a),Qi(s,n,r),Qi(o,a,i),Li(l,a,i),Li(u,n,r),Ve(e[0],s,o),Ve(e[1],u,l),Ve(e[2],l,o),Ve(e[3],s,u)}function Ih(e,t,r){for(var n=0;n<4;++n)ev(e[n],t[n],r)}function h0(e,t){var r=ue(),n=ue(),i=ue();rT(i,t[2]),Ve(r,t[0],i),Ve(n,t[1],i),rl(e,n),e[31]^=Z1(r)<<7}function rl(e,t){var r,n,i,a=ue(),s=ue();for(r=0;r<16;++r)s[r]=t[r];for(_u(s),_u(s),_u(s),n=0;n<2;++n){for(a[0]=s[0]-65517,r=1;r<15;++r)a[r]=s[r]-65535-(a[r-1]>>16&1),a[r-1]&=65535;a[15]=s[15]-32767-(a[14]>>16&1),i=a[15]>>16&1,a[14]&=65535,ev(s,a,1-i)}for(r=0;r<16;r++)e[2*r]=s[r]&255,e[2*r+1]=s[r]>>8}function Zx(e,t){var r=ue(),n=ue(),i=ue(),a=ue(),s=ue(),o=ue(),l=ue();return Un(e[2],tl),Jx(e[1],t),oi(i,e[1]),Ve(a,i,$x),Qi(i,i,e[2]),Li(a,e[2],a),oi(s,a),oi(o,s),Ve(l,o,s),Ve(r,l,i),Ve(r,r,a),eT(r,r),Ve(r,r,i),Ve(r,r,a),Ve(r,r,a),Ve(e[0],r,a),oi(n,e[0]),Ve(n,n,a),_h(n,i)&&Ve(e[0],e[0],Qx),oi(n,e[0]),Ve(n,n,a),_h(n,i)?-1:(Z1(e[0])===t[31]>>7&&Qi(e[0],zc,e[0]),Ve(e[3],e[0],e[1]),0)}function Jx(e,t){var r;for(r=0;r<16;++r)e[r]=t[2*r]+(t[2*r+1]<<8);e[15]&=32767}function eT(e,t){var r=ue(),n;for(n=0;n<16;++n)r[n]=t[n];for(n=250;n>=0;--n)oi(r,r),n!==1&&Ve(r,r,t);for(n=0;n<16;++n)e[n]=r[n]}function _h(e,t){var r=new er(32),n=new er(32);return rl(r,e),rl(n,t),X1(r,0,n,0)}function X1(e,t,r,n){return tT(e,t,r,n,32)}function tT(e,t,r,n,i){var a,s=0;for(a=0;a>>8)-1}function Z1(e){var t=new er(32);return rl(t,e),t[0]&1}function J1(e,t,r){var n,i;for(Un(e[0],zc),Un(e[1],tl),Un(e[2],tl),Un(e[3],zc),i=255;i>=0;--i)n=r[i/8|0]>>(i&7)&1,Ih(e,t,n),qc(t,e),qc(e,e),Ih(e,t,n)}function p0(e,t){var r=[ue(),ue(),ue(),ue()];Un(r[0],Th),Un(r[1],wh),Un(r[2],tl),Ve(r[3],Th,wh),J1(e,r,t)}function Un(e,t){var r;for(r=0;r<16;r++)e[r]=t[r]|0}function rT(e,t){var r=ue(),n;for(n=0;n<16;++n)r[n]=t[n];for(n=253;n>=0;--n)oi(r,r),n!==2&&n!==4&&Ve(r,r,t);for(n=0;n<16;++n)e[n]=r[n]}function _u(e){var t,r,n=1;for(t=0;t<16;++t)r=e[t]+n+65535,n=Math.floor(r/65536),e[t]=r-n*65536;e[0]+=n-1+37*(n-1)}function ev(e,t,r){for(var n,i=~(r-1),a=0;a<16;++a)n=i&(e[a]^t[a]),e[a]^=n,t[a]^=n}function ue(e){var t,r=new Float64Array(16);if(e)for(t=0;t0&&(o=or.util.fillString(String.fromCharCode(0),l)+o);var u=i.encrypt(o,"NONE"),c=e.generate(o,a);return{encapsulation:u,key:c}},n.decrypt=function(i,a,s){var o=i.decrypt(a,"NONE");return e.generate(o,s)},n};or.kem.kdf1=function(e,t){tv(this,e,0,t||e.digestLength)};or.kem.kdf2=function(e,t){tv(this,e,1,t||e.digestLength)};function tv(e,t,r,n){e.generate=function(i,a){for(var s=new or.util.ByteBuffer,o=Math.ceil(a/n)+r,l=new or.util.ByteBuffer,u=r;u"u"||t?e.flags|=Te.log.LEVEL_LOCKED:e.flags&=~Te.log.LEVEL_LOCKED};Te.log.addLogger=function(e){$c.push(e)};if(typeof console<"u"&&"log"in console){var La;if(console.error&&console.warn&&console.info&&console.debug){var nT={error:console.error,warning:console.warn,info:console.info,debug:console.debug,verbose:console.debug},g0=function(e,t){Te.log.prepareStandard(t);var r=nT[t.level],n=[t.standard];n=n.concat(t.arguments.slice()),r.apply(console,n)};La=Te.log.makeLogger(g0)}else{var g0=function(t,r){Te.log.prepareStandardFull(r),console.log(r.standardFull)};La=Te.log.makeLogger(g0)}Te.log.setLevel(La,"debug"),Te.log.addLogger(La),ts=La}else console={log:function(){}};if(ts!==null&&typeof window<"u"&&window.location){var ro=new URL(window.location.href).searchParams;if(ro.has("console.level")&&Te.log.setLevel(ts,ro.get("console.level").slice(-1)[0]),ro.has("console.lock")){var iT=ro.get("console.lock").slice(-1)[0];iT=="true"&&Te.log.lock(ts)}}Te.log.consoleLogger=ts;var Y=me,k=Y.asn1,zt=Y.pkcs7=Y.pkcs7||{};zt.messageFromPem=function(e){var t=Y.pem.decode(e)[0];if(t.type!=="PKCS7"){var r=new Error('Could not convert PKCS#7 message from PEM; PEM header type is not "PKCS#7".');throw r.headerType=t.type,r}if(t.procType&&t.procType.type==="ENCRYPTED")throw new Error("Could not convert PKCS#7 message from PEM; PEM is encrypted.");var n=k.fromDer(t.body);return zt.messageFromAsn1(n)};zt.messageToPem=function(e,t){var r={type:"PKCS7",body:k.toDer(e.toAsn1()).getBytes()};return Y.pem.encode(r,{maxline:t})};zt.messageFromAsn1=function(e){var t={},r=[];if(!k.validate(e,zt.asn1.contentInfoValidator,t,r)){var n=new Error("Cannot read PKCS#7 message. ASN.1 object is not an PKCS#7 ContentInfo.");throw n.errors=r,n}var i=k.derToOid(t.contentType),a;switch(i){case Y.pki.oids.envelopedData:a=zt.createEnvelopedData();break;case Y.pki.oids.encryptedData:a=zt.createEncryptedData();break;case Y.pki.oids.signedData:a=zt.createSignedData();break;default:throw new Error("Cannot read PKCS#7 message. ContentType with OID "+i+" is not (yet) supported.")}return a.fromAsn1(t.content.value[0]),a};zt.createSignedData=function(){var e=null;return e={type:Y.pki.oids.signedData,version:1,certificates:[],crls:[],signers:[],digestAlgorithmIdentifiers:[],contentInfo:null,signerInfos:[],fromAsn1:function(n){if(v0(e,n,zt.asn1.signedDataValidator),e.certificates=[],e.crls=[],e.digestAlgorithmIdentifiers=[],e.contentInfo=null,e.signerInfos=[],e.rawCapture.certificates)for(var i=e.rawCapture.certificates.value,a=0;a0&&s.value[0].value.push(k.create(k.Class.CONTEXT_SPECIFIC,0,!0,n)),a.length>0&&s.value[0].value.push(k.create(k.Class.CONTEXT_SPECIFIC,1,!0,a)),s.value[0].value.push(k.create(k.Class.UNIVERSAL,k.Type.SET,!0,e.signerInfos)),k.create(k.Class.UNIVERSAL,k.Type.SEQUENCE,!0,[k.create(k.Class.UNIVERSAL,k.Type.OID,!1,k.oidToDer(e.type).getBytes()),s])},addSigner:function(n){var i=n.issuer,a=n.serialNumber;if(n.certificate){var s=n.certificate;typeof s=="string"&&(s=Y.pki.certificateFromPem(s)),i=s.issuer.attributes,a=s.serialNumber}var o=n.key;if(!o)throw new Error("Could not add PKCS#7 signer; no private key specified.");typeof o=="string"&&(o=Y.pki.privateKeyFromPem(o));var l=n.digestAlgorithm||Y.pki.oids.sha1;switch(l){case Y.pki.oids.sha1:case Y.pki.oids.sha256:case Y.pki.oids.sha384:case Y.pki.oids.sha512:case Y.pki.oids.md5:break;default:throw new Error("Could not add PKCS#7 signer; unknown message digest algorithm: "+l)}var u=n.authenticatedAttributes||[];if(u.length>0){for(var c=!1,f=!1,d=0;d0){for(var r=k.create(k.Class.CONTEXT_SPECIFIC,1,!0,[]),n=0;n=r&&i="8"&&(r="00"+r);var n=pt.util.hexToBytes(r);e.putInt32(n.length),e.putBytes(n)}function Wi(e,t){e.putInt32(t.length),e.putString(t)}function no(){for(var e=pt.md.sha1.create(),t=arguments.length,r=0;r0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");r===-1&&(r=t);var n=r===t?0:4-r%4;return[r,n]}function gT(e){var t=nv(e),r=t[0],n=t[1];return(r+n)*3/4-n}function vT(e,t,r){return(t+r)*3/4-r}function yT(e){var t,r=nv(e),n=r[0],i=r[1],a=new hT(vT(e,n,i)),s=0,o=i>0?n-4:n,l;for(l=0;l>16&255,a[s++]=t>>8&255,a[s++]=t&255;return i===2&&(t=Cr[e.charCodeAt(l)]<<2|Cr[e.charCodeAt(l+1)]>>4,a[s++]=t&255),i===1&&(t=Cr[e.charCodeAt(l)]<<10|Cr[e.charCodeAt(l+1)]<<4|Cr[e.charCodeAt(l+2)]>>2,a[s++]=t>>8&255,a[s++]=t&255),a}function mT(e){return Zr[e>>18&63]+Zr[e>>12&63]+Zr[e>>6&63]+Zr[e&63]}function CT(e,t,r){for(var n,i=[],a=t;ao?o:s+a));return n===1?(t=e[r-1],i.push(Zr[t>>2]+Zr[t<<4&63]+"==")):n===2&&(t=(e[r-2]<<8)+e[r-1],i.push(Zr[t>>10]+Zr[t>>4&63]+Zr[t<<2&63]+"=")),i.join("")}var y0={};/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */y0.read=function(e,t,r,n,i){var a,s,o=i*8-n-1,l=(1<>1,c=-7,f=r?i-1:0,d=r?-1:1,v=e[t+f];for(f+=d,a=v&(1<<-c)-1,v>>=-c,c+=o;c>0;a=a*256+e[t+f],f+=d,c-=8);for(s=a&(1<<-c)-1,a>>=-c,c+=n;c>0;s=s*256+e[t+f],f+=d,c-=8);if(a===0)a=1-u;else{if(a===l)return s?NaN:(v?-1:1)*(1/0);s=s+Math.pow(2,n),a=a-u}return(v?-1:1)*s*Math.pow(2,a-n)};y0.write=function(e,t,r,n,i,a){var s,o,l,u=a*8-i-1,c=(1<>1,d=i===23?Math.pow(2,-24)-Math.pow(2,-77):0,v=n?0:a-1,g=n?1:-1,C=t<0||t===0&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(o=isNaN(t)?1:0,s=c):(s=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-s))<1&&(s--,l*=2),s+f>=1?t+=d/l:t+=d*Math.pow(2,1-f),t*l>=2&&(s++,l/=2),s+f>=c?(o=0,s=c):s+f>=1?(o=(t*l-1)*Math.pow(2,i),s=s+f):(o=t*Math.pow(2,f-1)*Math.pow(2,i),s=0));i>=8;e[r+v]=o&255,v+=g,o/=256,i-=8);for(s=s<0;e[r+v]=s&255,v+=g,s/=256,u-=8);e[r+v-g]|=C*128};/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */(function(e){const t=Dl,r=y0,n=typeof Symbol=="function"&&typeof Symbol.for=="function"?Symbol.for("nodejs.util.inspect.custom"):null;e.Buffer=o,e.SlowBuffer=m,e.INSPECT_MAX_BYTES=50;const i=2147483647;e.kMaxLength=i,o.TYPED_ARRAY_SUPPORT=a(),!o.TYPED_ARRAY_SUPPORT&&typeof console<"u"&&typeof console.error=="function"&&console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support.");function a(){try{const w=new Uint8Array(1),h={foo:function(){return 42}};return Object.setPrototypeOf(h,Uint8Array.prototype),Object.setPrototypeOf(w,h),w.foo()===42}catch{return!1}}Object.defineProperty(o.prototype,"parent",{enumerable:!0,get:function(){if(o.isBuffer(this))return this.buffer}}),Object.defineProperty(o.prototype,"offset",{enumerable:!0,get:function(){if(o.isBuffer(this))return this.byteOffset}});function s(w){if(w>i)throw new RangeError('The value "'+w+'" is invalid for option "size"');const h=new Uint8Array(w);return Object.setPrototypeOf(h,o.prototype),h}function o(w,h,p){if(typeof w=="number"){if(typeof h=="string")throw new TypeError('The "string" argument must be of type string. Received type number');return f(w)}return l(w,h,p)}o.poolSize=8192;function l(w,h,p){if(typeof w=="string")return d(w,h);if(ArrayBuffer.isView(w))return g(w);if(w==null)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof w);if(Gt(w,ArrayBuffer)||w&&Gt(w.buffer,ArrayBuffer)||typeof SharedArrayBuffer<"u"&&(Gt(w,SharedArrayBuffer)||w&&Gt(w.buffer,SharedArrayBuffer)))return C(w,h,p);if(typeof w=="number")throw new TypeError('The "value" argument must not be of type number. Received type number');const _=w.valueOf&&w.valueOf();if(_!=null&&_!==w)return o.from(_,h,p);const N=I(w);if(N)return N;if(typeof Symbol<"u"&&Symbol.toPrimitive!=null&&typeof w[Symbol.toPrimitive]=="function")return o.from(w[Symbol.toPrimitive]("string"),h,p);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof w)}o.from=function(w,h,p){return l(w,h,p)},Object.setPrototypeOf(o.prototype,Uint8Array.prototype),Object.setPrototypeOf(o,Uint8Array);function u(w){if(typeof w!="number")throw new TypeError('"size" argument must be of type number');if(w<0)throw new RangeError('The value "'+w+'" is invalid for option "size"')}function c(w,h,p){return u(w),w<=0?s(w):h!==void 0?typeof p=="string"?s(w).fill(h,p):s(w).fill(h):s(w)}o.alloc=function(w,h,p){return c(w,h,p)};function f(w){return u(w),s(w<0?0:y(w)|0)}o.allocUnsafe=function(w){return f(w)},o.allocUnsafeSlow=function(w){return f(w)};function d(w,h){if((typeof h!="string"||h==="")&&(h="utf8"),!o.isEncoding(h))throw new TypeError("Unknown encoding: "+h);const p=S(w,h)|0;let _=s(p);const N=_.write(w,h);return N!==p&&(_=_.slice(0,N)),_}function v(w){const h=w.length<0?0:y(w.length)|0,p=s(h);for(let _=0;_=i)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i.toString(16)+" bytes");return w|0}function m(w){return+w!=w&&(w=0),o.alloc(+w)}o.isBuffer=function(h){return h!=null&&h._isBuffer===!0&&h!==o.prototype},o.compare=function(h,p){if(Gt(h,Uint8Array)&&(h=o.from(h,h.offset,h.byteLength)),Gt(p,Uint8Array)&&(p=o.from(p,p.offset,p.byteLength)),!o.isBuffer(h)||!o.isBuffer(p))throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(h===p)return 0;let _=h.length,N=p.length;for(let P=0,F=Math.min(_,N);PN.length?(o.isBuffer(F)||(F=o.from(F)),F.copy(N,P)):Uint8Array.prototype.set.call(N,F,P);else if(o.isBuffer(F))F.copy(N,P);else throw new TypeError('"list" argument must be an Array of Buffers');P+=F.length}return N};function S(w,h){if(o.isBuffer(w))return w.length;if(ArrayBuffer.isView(w)||Gt(w,ArrayBuffer))return w.byteLength;if(typeof w!="string")throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof w);const p=w.length,_=arguments.length>2&&arguments[2]===!0;if(!_&&p===0)return 0;let N=!1;for(;;)switch(h){case"ascii":case"latin1":case"binary":return p;case"utf8":case"utf-8":return Ea(w).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return p*2;case"hex":return p>>>1;case"base64":return Ai(w).length;default:if(N)return _?-1:Ea(w).length;h=(""+h).toLowerCase(),N=!0}}o.byteLength=S;function B(w,h,p){let _=!1;if((h===void 0||h<0)&&(h=0),h>this.length||((p===void 0||p>this.length)&&(p=this.length),p<=0)||(p>>>=0,h>>>=0,p<=h))return"";for(w||(w="utf8");;)switch(w){case"hex":return ae(this,h,p);case"utf8":case"utf-8":return Ue(this,h,p);case"ascii":return te(this,h,p);case"latin1":case"binary":return W(this,h,p);case"base64":return De(this,h,p);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ne(this,h,p);default:if(_)throw new TypeError("Unknown encoding: "+w);w=(w+"").toLowerCase(),_=!0}}o.prototype._isBuffer=!0;function R(w,h,p){const _=w[h];w[h]=w[p],w[p]=_}o.prototype.swap16=function(){const h=this.length;if(h%2!==0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let p=0;pp&&(h+=" ... "),""},n&&(o.prototype[n]=o.prototype.inspect),o.prototype.compare=function(h,p,_,N,P){if(Gt(h,Uint8Array)&&(h=o.from(h,h.offset,h.byteLength)),!o.isBuffer(h))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof h);if(p===void 0&&(p=0),_===void 0&&(_=h?h.length:0),N===void 0&&(N=0),P===void 0&&(P=this.length),p<0||_>h.length||N<0||P>this.length)throw new RangeError("out of range index");if(N>=P&&p>=_)return 0;if(N>=P)return-1;if(p>=_)return 1;if(p>>>=0,_>>>=0,N>>>=0,P>>>=0,this===h)return 0;let F=P-N,ge=_-p;const tt=Math.min(F,ge),ze=this.slice(N,P),He=h.slice(p,_);for(let Ne=0;Ne2147483647?p=2147483647:p<-2147483648&&(p=-2147483648),p=+p,En(p)&&(p=N?0:w.length-1),p<0&&(p=w.length+p),p>=w.length){if(N)return-1;p=w.length-1}else if(p<0)if(N)p=0;else return-1;if(typeof h=="string"&&(h=o.from(h,_)),o.isBuffer(h))return h.length===0?-1:M(w,h,p,_,N);if(typeof h=="number")return h=h&255,typeof Uint8Array.prototype.indexOf=="function"?N?Uint8Array.prototype.indexOf.call(w,h,p):Uint8Array.prototype.lastIndexOf.call(w,h,p):M(w,[h],p,_,N);throw new TypeError("val must be string, number or Buffer")}function M(w,h,p,_,N){let P=1,F=w.length,ge=h.length;if(_!==void 0&&(_=String(_).toLowerCase(),_==="ucs2"||_==="ucs-2"||_==="utf16le"||_==="utf-16le")){if(w.length<2||h.length<2)return-1;P=2,F/=2,ge/=2,p/=2}function tt(He,Ne){return P===1?He[Ne]:He.readUInt16BE(Ne*P)}let ze;if(N){let He=-1;for(ze=p;zeF&&(p=F-ge),ze=p;ze>=0;ze--){let He=!0;for(let Ne=0;NeN&&(_=N)):_=N;const P=h.length;_>P/2&&(_=P/2);let F;for(F=0;F<_;++F){const ge=parseInt(h.substr(F*2,2),16);if(En(ge))return F;w[p+F]=ge}return F}function Q(w,h,p,_){return tr(Ea(h,w.length-p),w,p,_)}function G(w,h,p,_){return tr(Sa(h),w,p,_)}function ce(w,h,p,_){return tr(Ai(h),w,p,_)}function pe(w,h,p,_){return tr(Ds(h,w.length-p),w,p,_)}o.prototype.write=function(h,p,_,N){if(p===void 0)N="utf8",_=this.length,p=0;else if(_===void 0&&typeof p=="string")N=p,_=this.length,p=0;else if(isFinite(p))p=p>>>0,isFinite(_)?(_=_>>>0,N===void 0&&(N="utf8")):(N=_,_=void 0);else throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");const P=this.length-p;if((_===void 0||_>P)&&(_=P),h.length>0&&(_<0||p<0)||p>this.length)throw new RangeError("Attempt to write outside buffer bounds");N||(N="utf8");let F=!1;for(;;)switch(N){case"hex":return V(this,h,p,_);case"utf8":case"utf-8":return Q(this,h,p,_);case"ascii":case"latin1":case"binary":return G(this,h,p,_);case"base64":return ce(this,h,p,_);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return pe(this,h,p,_);default:if(F)throw new TypeError("Unknown encoding: "+N);N=(""+N).toLowerCase(),F=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function De(w,h,p){return h===0&&p===w.length?t.fromByteArray(w):t.fromByteArray(w.slice(h,p))}function Ue(w,h,p){p=Math.min(w.length,p);const _=[];let N=h;for(;N239?4:P>223?3:P>191?2:1;if(N+ge<=p){let tt,ze,He,Ne;switch(ge){case 1:P<128&&(F=P);break;case 2:tt=w[N+1],(tt&192)===128&&(Ne=(P&31)<<6|tt&63,Ne>127&&(F=Ne));break;case 3:tt=w[N+1],ze=w[N+2],(tt&192)===128&&(ze&192)===128&&(Ne=(P&15)<<12|(tt&63)<<6|ze&63,Ne>2047&&(Ne<55296||Ne>57343)&&(F=Ne));break;case 4:tt=w[N+1],ze=w[N+2],He=w[N+3],(tt&192)===128&&(ze&192)===128&&(He&192)===128&&(Ne=(P&15)<<18|(tt&63)<<12|(ze&63)<<6|He&63,Ne>65535&&Ne<1114112&&(F=Ne))}}F===null?(F=65533,ge=1):F>65535&&(F-=65536,_.push(F>>>10&1023|55296),F=56320|F&1023),_.push(F),N+=ge}return Le(_)}const Ce=4096;function Le(w){const h=w.length;if(h<=Ce)return String.fromCharCode.apply(String,w);let p="",_=0;for(;__)&&(p=_);let N="";for(let P=h;P_&&(h=_),p<0?(p+=_,p<0&&(p=0)):p>_&&(p=_),pp)throw new RangeError("Trying to access beyond buffer length")}o.prototype.readUintLE=o.prototype.readUIntLE=function(h,p,_){h=h>>>0,p=p>>>0,_||ee(h,p,this.length);let N=this[h],P=1,F=0;for(;++F>>0,p=p>>>0,_||ee(h,p,this.length);let N=this[h+--p],P=1;for(;p>0&&(P*=256);)N+=this[h+--p]*P;return N},o.prototype.readUint8=o.prototype.readUInt8=function(h,p){return h=h>>>0,p||ee(h,1,this.length),this[h]},o.prototype.readUint16LE=o.prototype.readUInt16LE=function(h,p){return h=h>>>0,p||ee(h,2,this.length),this[h]|this[h+1]<<8},o.prototype.readUint16BE=o.prototype.readUInt16BE=function(h,p){return h=h>>>0,p||ee(h,2,this.length),this[h]<<8|this[h+1]},o.prototype.readUint32LE=o.prototype.readUInt32LE=function(h,p){return h=h>>>0,p||ee(h,4,this.length),(this[h]|this[h+1]<<8|this[h+2]<<16)+this[h+3]*16777216},o.prototype.readUint32BE=o.prototype.readUInt32BE=function(h,p){return h=h>>>0,p||ee(h,4,this.length),this[h]*16777216+(this[h+1]<<16|this[h+2]<<8|this[h+3])},o.prototype.readBigUInt64LE=Kr(function(h){h=h>>>0,We(h,"offset");const p=this[h],_=this[h+7];(p===void 0||_===void 0)&&Ke(h,this.length-8);const N=p+this[++h]*2**8+this[++h]*2**16+this[++h]*2**24,P=this[++h]+this[++h]*2**8+this[++h]*2**16+_*2**24;return BigInt(N)+(BigInt(P)<>>0,We(h,"offset");const p=this[h],_=this[h+7];(p===void 0||_===void 0)&&Ke(h,this.length-8);const N=p*2**24+this[++h]*2**16+this[++h]*2**8+this[++h],P=this[++h]*2**24+this[++h]*2**16+this[++h]*2**8+_;return(BigInt(N)<>>0,p=p>>>0,_||ee(h,p,this.length);let N=this[h],P=1,F=0;for(;++F=P&&(N-=Math.pow(2,8*p)),N},o.prototype.readIntBE=function(h,p,_){h=h>>>0,p=p>>>0,_||ee(h,p,this.length);let N=p,P=1,F=this[h+--N];for(;N>0&&(P*=256);)F+=this[h+--N]*P;return P*=128,F>=P&&(F-=Math.pow(2,8*p)),F},o.prototype.readInt8=function(h,p){return h=h>>>0,p||ee(h,1,this.length),this[h]&128?(255-this[h]+1)*-1:this[h]},o.prototype.readInt16LE=function(h,p){h=h>>>0,p||ee(h,2,this.length);const _=this[h]|this[h+1]<<8;return _&32768?_|4294901760:_},o.prototype.readInt16BE=function(h,p){h=h>>>0,p||ee(h,2,this.length);const _=this[h+1]|this[h]<<8;return _&32768?_|4294901760:_},o.prototype.readInt32LE=function(h,p){return h=h>>>0,p||ee(h,4,this.length),this[h]|this[h+1]<<8|this[h+2]<<16|this[h+3]<<24},o.prototype.readInt32BE=function(h,p){return h=h>>>0,p||ee(h,4,this.length),this[h]<<24|this[h+1]<<16|this[h+2]<<8|this[h+3]},o.prototype.readBigInt64LE=Kr(function(h){h=h>>>0,We(h,"offset");const p=this[h],_=this[h+7];(p===void 0||_===void 0)&&Ke(h,this.length-8);const N=this[h+4]+this[h+5]*2**8+this[h+6]*2**16+(_<<24);return(BigInt(N)<>>0,We(h,"offset");const p=this[h],_=this[h+7];(p===void 0||_===void 0)&&Ke(h,this.length-8);const N=(p<<24)+this[++h]*2**16+this[++h]*2**8+this[++h];return(BigInt(N)<>>0,p||ee(h,4,this.length),r.read(this,h,!0,23,4)},o.prototype.readFloatBE=function(h,p){return h=h>>>0,p||ee(h,4,this.length),r.read(this,h,!1,23,4)},o.prototype.readDoubleLE=function(h,p){return h=h>>>0,p||ee(h,8,this.length),r.read(this,h,!0,52,8)},o.prototype.readDoubleBE=function(h,p){return h=h>>>0,p||ee(h,8,this.length),r.read(this,h,!1,52,8)};function ie(w,h,p,_,N,P){if(!o.isBuffer(w))throw new TypeError('"buffer" argument must be a Buffer instance');if(h>N||hw.length)throw new RangeError("Index out of range")}o.prototype.writeUintLE=o.prototype.writeUIntLE=function(h,p,_,N){if(h=+h,p=p>>>0,_=_>>>0,!N){const ge=Math.pow(2,8*_)-1;ie(this,h,p,_,ge,0)}let P=1,F=0;for(this[p]=h&255;++F<_&&(P*=256);)this[p+F]=h/P&255;return p+_},o.prototype.writeUintBE=o.prototype.writeUIntBE=function(h,p,_,N){if(h=+h,p=p>>>0,_=_>>>0,!N){const ge=Math.pow(2,8*_)-1;ie(this,h,p,_,ge,0)}let P=_-1,F=1;for(this[p+P]=h&255;--P>=0&&(F*=256);)this[p+P]=h/F&255;return p+_},o.prototype.writeUint8=o.prototype.writeUInt8=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,1,255,0),this[p]=h&255,p+1},o.prototype.writeUint16LE=o.prototype.writeUInt16LE=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,2,65535,0),this[p]=h&255,this[p+1]=h>>>8,p+2},o.prototype.writeUint16BE=o.prototype.writeUInt16BE=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,2,65535,0),this[p]=h>>>8,this[p+1]=h&255,p+2},o.prototype.writeUint32LE=o.prototype.writeUInt32LE=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,4,4294967295,0),this[p+3]=h>>>24,this[p+2]=h>>>16,this[p+1]=h>>>8,this[p]=h&255,p+4},o.prototype.writeUint32BE=o.prototype.writeUInt32BE=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,4,4294967295,0),this[p]=h>>>24,this[p+1]=h>>>16,this[p+2]=h>>>8,this[p+3]=h&255,p+4};function Oe(w,h,p,_,N){je(h,_,N,w,p,7);let P=Number(h&BigInt(4294967295));w[p++]=P,P=P>>8,w[p++]=P,P=P>>8,w[p++]=P,P=P>>8,w[p++]=P;let F=Number(h>>BigInt(32)&BigInt(4294967295));return w[p++]=F,F=F>>8,w[p++]=F,F=F>>8,w[p++]=F,F=F>>8,w[p++]=F,p}function se(w,h,p,_,N){je(h,_,N,w,p,7);let P=Number(h&BigInt(4294967295));w[p+7]=P,P=P>>8,w[p+6]=P,P=P>>8,w[p+5]=P,P=P>>8,w[p+4]=P;let F=Number(h>>BigInt(32)&BigInt(4294967295));return w[p+3]=F,F=F>>8,w[p+2]=F,F=F>>8,w[p+1]=F,F=F>>8,w[p]=F,p+8}o.prototype.writeBigUInt64LE=Kr(function(h,p=0){return Oe(this,h,p,BigInt(0),BigInt("0xffffffffffffffff"))}),o.prototype.writeBigUInt64BE=Kr(function(h,p=0){return se(this,h,p,BigInt(0),BigInt("0xffffffffffffffff"))}),o.prototype.writeIntLE=function(h,p,_,N){if(h=+h,p=p>>>0,!N){const tt=Math.pow(2,8*_-1);ie(this,h,p,_,tt-1,-tt)}let P=0,F=1,ge=0;for(this[p]=h&255;++P<_&&(F*=256);)h<0&&ge===0&&this[p+P-1]!==0&&(ge=1),this[p+P]=(h/F>>0)-ge&255;return p+_},o.prototype.writeIntBE=function(h,p,_,N){if(h=+h,p=p>>>0,!N){const tt=Math.pow(2,8*_-1);ie(this,h,p,_,tt-1,-tt)}let P=_-1,F=1,ge=0;for(this[p+P]=h&255;--P>=0&&(F*=256);)h<0&&ge===0&&this[p+P+1]!==0&&(ge=1),this[p+P]=(h/F>>0)-ge&255;return p+_},o.prototype.writeInt8=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,1,127,-128),h<0&&(h=255+h+1),this[p]=h&255,p+1},o.prototype.writeInt16LE=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,2,32767,-32768),this[p]=h&255,this[p+1]=h>>>8,p+2},o.prototype.writeInt16BE=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,2,32767,-32768),this[p]=h>>>8,this[p+1]=h&255,p+2},o.prototype.writeInt32LE=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,4,2147483647,-2147483648),this[p]=h&255,this[p+1]=h>>>8,this[p+2]=h>>>16,this[p+3]=h>>>24,p+4},o.prototype.writeInt32BE=function(h,p,_){return h=+h,p=p>>>0,_||ie(this,h,p,4,2147483647,-2147483648),h<0&&(h=4294967295+h+1),this[p]=h>>>24,this[p+1]=h>>>16,this[p+2]=h>>>8,this[p+3]=h&255,p+4},o.prototype.writeBigInt64LE=Kr(function(h,p=0){return Oe(this,h,p,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))}),o.prototype.writeBigInt64BE=Kr(function(h,p=0){return se(this,h,p,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))});function Fe(w,h,p,_,N,P){if(p+_>w.length)throw new RangeError("Index out of range");if(p<0)throw new RangeError("Index out of range")}function Re(w,h,p,_,N){return h=+h,p=p>>>0,N||Fe(w,h,p,4),r.write(w,h,p,_,23,4),p+4}o.prototype.writeFloatLE=function(h,p,_){return Re(this,h,p,!0,_)},o.prototype.writeFloatBE=function(h,p,_){return Re(this,h,p,!1,_)};function ke(w,h,p,_,N){return h=+h,p=p>>>0,N||Fe(w,h,p,8),r.write(w,h,p,_,52,8),p+8}o.prototype.writeDoubleLE=function(h,p,_){return ke(this,h,p,!0,_)},o.prototype.writeDoubleBE=function(h,p,_){return ke(this,h,p,!1,_)},o.prototype.copy=function(h,p,_,N){if(!o.isBuffer(h))throw new TypeError("argument should be a Buffer");if(_||(_=0),!N&&N!==0&&(N=this.length),p>=h.length&&(p=h.length),p||(p=0),N>0&&N<_&&(N=_),N===_||h.length===0||this.length===0)return 0;if(p<0)throw new RangeError("targetStart out of bounds");if(_<0||_>=this.length)throw new RangeError("Index out of range");if(N<0)throw new RangeError("sourceEnd out of bounds");N>this.length&&(N=this.length),h.length-p>>0,_=_===void 0?this.length:_>>>0,h||(h=0);let P;if(typeof h=="number")for(P=p;P<_;++P)this[P]=h;else{const F=o.isBuffer(h)?h:o.from(h,N),ge=F.length;if(ge===0)throw new TypeError('The value "'+h+'" is invalid for argument "value"');for(P=0;P<_-p;++P)this[P+p]=F[P%ge]}return this};const be={};function Qe(w,h,p){be[w]=class extends p{constructor(){super(),Object.defineProperty(this,"message",{value:h.apply(this,arguments),writable:!0,configurable:!0}),this.name=`${this.name} [${w}]`,this.stack,delete this.name}get code(){return w}set code(N){Object.defineProperty(this,"code",{configurable:!0,enumerable:!0,value:N,writable:!0})}toString(){return`${this.name} [${w}]: ${this.message}`}}}Qe("ERR_BUFFER_OUT_OF_BOUNDS",function(w){return w?`${w} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"},RangeError),Qe("ERR_INVALID_ARG_TYPE",function(w,h){return`The "${w}" argument must be of type number. Received type ${typeof h}`},TypeError),Qe("ERR_OUT_OF_RANGE",function(w,h,p){let _=`The value of "${w}" is out of range.`,N=p;return Number.isInteger(p)&&Math.abs(p)>2**32?N=ct(String(p)):typeof p=="bigint"&&(N=String(p),(p>BigInt(2)**BigInt(32)||p<-(BigInt(2)**BigInt(32)))&&(N=ct(N)),N+="n"),_+=` It must be ${h}. Received ${N}`,_},RangeError);function ct(w){let h="",p=w.length;const _=w[0]==="-"?1:0;for(;p>=_+4;p-=3)h=`_${w.slice(p-3,p)}${h}`;return`${w.slice(0,p)}${h}`}function ot(w,h,p){We(h,"offset"),(w[h]===void 0||w[h+p]===void 0)&&Ke(h,w.length-(p+1))}function je(w,h,p,_,N,P){if(w>p||w3?h===0||h===BigInt(0)?ge=`>= 0${F} and < 2${F} ** ${(P+1)*8}${F}`:ge=`>= -(2${F} ** ${(P+1)*8-1}${F}) and < 2 ** ${(P+1)*8-1}${F}`:ge=`>= ${h}${F} and <= ${p}${F}`,new be.ERR_OUT_OF_RANGE("value",ge,w)}ot(_,N,P)}function We(w,h){if(typeof w!="number")throw new be.ERR_INVALID_ARG_TYPE(h,"number",w)}function Ke(w,h,p){throw Math.floor(w)!==w?(We(w,p),new be.ERR_OUT_OF_RANGE(p||"offset","an integer",w)):h<0?new be.ERR_BUFFER_OUT_OF_BOUNDS:new be.ERR_OUT_OF_RANGE(p||"offset",`>= ${p?1:0} and <= ${h}`,w)}const ht=/[^+/0-9A-Za-z-_]/g;function Ns(w){if(w=w.split("=")[0],w=w.trim().replace(ht,""),w.length<2)return"";for(;w.length%4!==0;)w=w+"=";return w}function Ea(w,h){h=h||1/0;let p;const _=w.length;let N=null;const P=[];for(let F=0;F<_;++F){if(p=w.charCodeAt(F),p>55295&&p<57344){if(!N){if(p>56319){(h-=3)>-1&&P.push(239,191,189);continue}else if(F+1===_){(h-=3)>-1&&P.push(239,191,189);continue}N=p;continue}if(p<56320){(h-=3)>-1&&P.push(239,191,189),N=p;continue}p=(N-55296<<10|p-56320)+65536}else N&&(h-=3)>-1&&P.push(239,191,189);if(N=null,p<128){if((h-=1)<0)break;P.push(p)}else if(p<2048){if((h-=2)<0)break;P.push(p>>6|192,p&63|128)}else if(p<65536){if((h-=3)<0)break;P.push(p>>12|224,p>>6&63|128,p&63|128)}else if(p<1114112){if((h-=4)<0)break;P.push(p>>18|240,p>>12&63|128,p>>6&63|128,p&63|128)}else throw new Error("Invalid code point")}return P}function Sa(w){const h=[];for(let p=0;p>8,N=p%256,P.push(N),P.push(_);return P}function Ai(w){return t.toByteArray(Ns(w))}function tr(w,h,p,_){let N;for(N=0;N<_&&!(N+p>=h.length||N>=w.length);++N)h[N+p]=w[N];return N}function Gt(w,h){return w instanceof h||w!=null&&w.constructor!=null&&w.constructor.name!=null&&w.constructor.name===h.name}function En(w){return w!==w}const Ll=function(){const w="0123456789abcdef",h=new Array(256);for(let p=0;p<16;++p){const _=p*16;for(let N=0;N<16;++N)h[_+N]=w[p]+w[N]}return h}();function Kr(w){return typeof BigInt>"u"?Ol:w}function Ol(){throw new Error("BigInt not supported")}})(xo);const ST=e=>(window.location.pathname.includes("/http_proxy:http_proxy:uqbar/serve/")?`/http_proxy:http_proxy:uqbar/serve/${window.location.pathname.split("/")[3]}/${e}`:e).replace("//","/");function Ri(e){const t=document.cookie.split(";");for(let r=0;r{const n=new FileReader;n.onerror=r,n.onload=function(i){const a=i.target.result,s=new Uint8Array(a);t(s)},n.readAsArrayBuffer(e)})}class TT{constructor({nodeId:t,channelId:r,uri:n="ws://"+window.location.host,onMessage:i=()=>null,onOpen:a=()=>null,onClose:s=()=>null,onError:o=()=>null,onEncryptionReady:l=()=>null}){ft(this,"nodeId");ft(this,"channelId");ft(this,"_secret");ft(this,"_cipher");ft(this,"_decipher");ft(this,"_ws");ft(this,"_encrypt",t=>{if(this._cipher){const r=yr.random.getBytesSync(12);this._cipher.start({iv:r}),this._cipher.update(yr.util.createBuffer(t,"utf8")),this._cipher.finish();const n=this._cipher.output.getBytes(),i=this._cipher.mode.tag.getBytes();return{encrypted:n+i,nonce:r}}return null});ft(this,"_decrypt",t=>{if(!this._decipher)return null;const r=t.slice(0,-28),n=t.slice(-28,-12),i=t.slice(-12);return this._decipher.start({iv:yr.util.createBuffer(i),tag:yr.util.createBuffer(n)}),this._decipher.update(yr.util.createBuffer(r)),this._decipher.finish()?this._decipher.output.toString():null});ft(this,"send",({data:t,channelId:r=this.channelId,encrypted:n=!0,target:i={node:this.nodeId,process:this.channelId}})=>{const a=Ri(`uqbar-auth_${this.nodeId}`),s=Ri(`uqbar-ws-auth_${this.nodeId}`);if(n){if(!this._cipher)return console.error("No cipher, unable to encrypt");this._ws.send(Bu({EncryptedWsMessage:{auth_token:a,ws_auth_token:s,channel_id:r,target:{node:i.node,process:typeof i.process=="number"?{Id:i.process}:{Name:i.process}},...this._encrypt(JSON.stringify(t))}}))}else this._ws.send(Bu({WsMessage:{auth_token:a,ws_auth_token:s,channel_id:r,target:{node:i.node,process:typeof i.process=="number"?{Id:i.process}:{Name:i.process}},json:t}}))});ft(this,"fetchJson",async(t,r)=>(console.log("Fetching JSON:",t),await(await fetch(t,r)).json()));this._secret=void 0,this.channelId=r,this.nodeId=t,this._ws=new WebSocket(n),this._ws.onmessage=async d=>{if(typeof d.data=="string")i(d.data);else if(d.data instanceof Blob){const v=await xT(d.data),g=this._decrypt(v);if(g===null){console.log("Unable to decrypt message, passing through as-is");const C=new TextDecoder().decode(v);i(C)}else i(g)}else i(d.data)},this._ws.onopen=d=>{console.log(`${t}`,Ri(`uqbar-auth_${t}`),Ri(`uqbar-ws-auth_${t}`)),this._ws.send(Bu({WsRegister:{auth_token:Ri(`uqbar-auth_${t}`),ws_auth_token:Ri(`uqbar-ws-auth_${t}`),channel_id:r}})),a(d)},this._ws.onclose=s,this._ws.onerror=o;const c=yr.pki.rsa.generateKeyPair({bits:2048,e:65537}),f=c.publicKey.n.toString(16);fetch(ST("/encryptor:sys:uqbar"),{method:"POST",body:JSON.stringify({channel_id:r,public_key_hex:f})}).then(d=>d.json()).then(d=>{const{encrypted_secret:v,signed_public_key:g}=d;fetch(`/qns_indexer:qns_indexer:uqbar/node/${this.nodeId}`).then(C=>C.json()).then(C=>{const{public_key:I}=C,y=I.replace("0x","");if(!y)return;if(yr.pki.ed25519.verify({message:xo.Buffer.from(f,"hex"),signature:xo.Buffer.from(g,"hex"),publicKey:xo.Buffer.from(y,"hex")})){const S=yr.util.hexToBytes(v),B=c.privateKey.decrypt(S,"RSA-OAEP",{md:yr.md.sha256.create()});this._secret=yr.util.bytesToHex(B),this._cipher=yr.cipher.createCipher("AES-GCM",B),this._decipher=yr.cipher.createDecipher("AES-GCM",B),l(this)}else console.error("Unable to verify networking key")}).catch(console.error)}).catch(console.error)}}const bh=e=>{let t;const r=new Set,n=(l,u)=>{const c=typeof l=="function"?l(t):l;if(!Object.is(c,t)){const f=t;t=u??typeof c!="object"?c:Object.assign({},t,c),r.forEach(d=>d(t,f))}},i=()=>t,o={setState:n,getState:i,subscribe:l=>(r.add(l),()=>r.delete(l)),destroy:()=>{r.clear()}};return t=e(n,i,o),o},wT=e=>e?bh(e):bh;var iv={exports:{}},av={},sv={exports:{}},ov={};/** + */const me="w",We="b",ie="p",ml="n",Ao="b",pr="r",Mt="q",se="k",fs="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",je=-1,q0={NORMAL:"n",CAPTURE:"c",BIG_PAWN:"b",EP_CAPTURE:"e",PROMOTION:"p",KSIDE_CASTLE:"k",QSIDE_CASTLE:"q"},N={NORMAL:1,CAPTURE:2,BIG_PAWN:4,EP_CAPTURE:8,PROMOTION:16,KSIDE_CASTLE:32,QSIDE_CASTLE:64},A={a8:0,b8:1,c8:2,d8:3,e8:4,f8:5,g8:6,h8:7,a7:16,b7:17,c7:18,d7:19,e7:20,f7:21,g7:22,h7:23,a6:32,b6:33,c6:34,d6:35,e6:36,f6:37,g6:38,h6:39,a5:48,b5:49,c5:50,d5:51,e5:52,f5:53,g5:54,h5:55,a4:64,b4:65,c4:66,d4:67,e4:68,f4:69,g4:70,h4:71,a3:80,b3:81,c3:82,d3:83,e3:84,f3:85,g3:86,h3:87,a2:96,b2:97,c2:98,d2:99,e2:100,f2:101,g2:102,h2:103,a1:112,b1:113,c1:114,d1:115,e1:116,f1:117,g1:118,h1:119},hs={b:[16,32,17,15],w:[-16,-32,-17,-15]},za={n:[-18,-33,-31,-14,18,33,31,14],b:[-17,-15,17,15],r:[-16,1,16,-1],q:[-17,-16,-15,1,17,16,15,-1],k:[-17,-16,-15,1,17,16,15,-1]},Q0=[20,0,0,0,0,0,0,24,0,0,0,0,0,0,20,0,0,20,0,0,0,0,0,24,0,0,0,0,0,20,0,0,0,0,20,0,0,0,0,24,0,0,0,0,20,0,0,0,0,0,0,20,0,0,0,24,0,0,0,20,0,0,0,0,0,0,0,0,20,0,0,24,0,0,20,0,0,0,0,0,0,0,0,0,0,20,2,24,2,20,0,0,0,0,0,0,0,0,0,0,0,2,53,56,53,2,0,0,0,0,0,0,24,24,24,24,24,24,56,0,56,24,24,24,24,24,24,0,0,0,0,0,0,2,53,56,53,2,0,0,0,0,0,0,0,0,0,0,0,20,2,24,2,20,0,0,0,0,0,0,0,0,0,0,20,0,0,24,0,0,20,0,0,0,0,0,0,0,0,20,0,0,0,24,0,0,0,20,0,0,0,0,0,0,20,0,0,0,0,24,0,0,0,0,20,0,0,0,0,20,0,0,0,0,0,24,0,0,0,0,0,20,0,0,20,0,0,0,0,0,0,24,0,0,0,0,0,0,20],K0=[17,0,0,0,0,0,0,16,0,0,0,0,0,0,15,0,0,17,0,0,0,0,0,16,0,0,0,0,0,15,0,0,0,0,17,0,0,0,0,16,0,0,0,0,15,0,0,0,0,0,0,17,0,0,0,16,0,0,0,15,0,0,0,0,0,0,0,0,17,0,0,16,0,0,15,0,0,0,0,0,0,0,0,0,0,17,0,16,0,15,0,0,0,0,0,0,0,0,0,0,0,0,17,16,15,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,-15,-16,-17,0,0,0,0,0,0,0,0,0,0,0,0,-15,0,-16,0,-17,0,0,0,0,0,0,0,0,0,0,-15,0,0,-16,0,0,-17,0,0,0,0,0,0,0,0,-15,0,0,0,-16,0,0,0,-17,0,0,0,0,0,0,-15,0,0,0,0,-16,0,0,0,0,-17,0,0,0,0,-15,0,0,0,0,0,-16,0,0,0,0,0,-17,0,0,-15,0,0,0,0,0,0,-16,0,0,0,0,0,0,-17],V0={p:1,n:2,b:4,r:8,q:16,k:32},G0="pnbrqkPNBRQK",$a=[ml,Ao,pr,Mt],Y0=7,X0=6,J0=1,Z0=0,wo={[se]:N.KSIDE_CASTLE,[Mt]:N.QSIDE_CASTLE},It={w:[{square:A.a1,flag:N.QSIDE_CASTLE},{square:A.h1,flag:N.KSIDE_CASTLE}],b:[{square:A.a8,flag:N.QSIDE_CASTLE},{square:A.h8,flag:N.KSIDE_CASTLE}]},eg={b:J0,w:X0},tg=["1-0","0-1","1/2-1/2","*"];function cn(e){return e>>4}function Br(e){return e&15}function Lf(e){return"0123456789".indexOf(e)!==-1}function Le(e){const t=Br(e),n=cn(e);return"abcdefgh".substring(t,t+1)+"87654321".substring(n,n+1)}function ur(e){return e===me?We:me}function ng(e){const t=e.split(/\s+/);if(t.length!==6)return{ok:!1,error:"Invalid FEN: must contain six space-delimited fields"};const n=parseInt(t[5],10);if(isNaN(n)||n<=0)return{ok:!1,error:"Invalid FEN: move number must be a positive integer"};const r=parseInt(t[4],10);if(isNaN(r)||r<0)return{ok:!1,error:"Invalid FEN: half move counter number must be a non-negative integer"};if(!/^(-|[abcdefgh][36])$/.test(t[3]))return{ok:!1,error:"Invalid FEN: en-passant square is invalid"};if(/[^kKqQ-]/.test(t[2]))return{ok:!1,error:"Invalid FEN: castling availability is invalid"};if(!/^(w|b)$/.test(t[1]))return{ok:!1,error:"Invalid FEN: side-to-move is invalid"};const o=t[0].split("/");if(o.length!==8)return{ok:!1,error:"Invalid FEN: piece data does not contain 8 '/'-delimited rows"};for(let s=0;s1)return{ok:!1,error:`Invalid FEN: too many ${s} kings`}}return{ok:!0}}function rg(e,t){const n=e.from,r=e.to,o=e.piece;let i=0,s=0,l=0;for(let u=0,a=t.length;u0?s>0&&l>0?Le(n):l>0?Le(n).charAt(1):Le(n).charAt(0):""}function jt(e,t,n,r,o,i=void 0,s=N.NORMAL){const l=cn(r);if(o===ie&&(l===Y0||l===Z0))for(let u=0;u<$a.length;u++){const a=$a[u];e.push({color:t,from:n,to:r,piece:o,captured:i,promotion:a,flags:s|N.PROMOTION})}else e.push({color:t,from:n,to:r,piece:o,captured:i,flags:s})}function Fa(e){let t=e.charAt(0);return t>="a"&&t<="h"?e.match(/[a-h]\d.*[a-h]\d/)?void 0:ie:(t=t.toLowerCase(),t==="o"?se:t)}function ps(e){return e.replace(/=/,"").replace(/[+#]?[?!]*$/,"")}class og{constructor(t=fs){ee(this,"_board",new Array(128));ee(this,"_turn",me);ee(this,"_header",{});ee(this,"_kings",{w:je,b:je});ee(this,"_epSquare",-1);ee(this,"_halfMoves",0);ee(this,"_moveNumber",0);ee(this,"_history",[]);ee(this,"_comments",{});ee(this,"_castling",{w:0,b:0});this.load(t)}clear(t=!1){this._board=new Array(128),this._kings={w:je,b:je},this._turn=me,this._castling={w:0,b:0},this._epSquare=je,this._halfMoves=0,this._moveNumber=1,this._history=[],this._comments={},this._header=t?this._header:{},this._updateSetup(this.fen())}removeHeader(t){t in this._header&&delete this._header[t]}load(t,n=!1){let r=t.split(/\s+/);if(r.length>=2&&r.length<6){const u=["-","-","0","1"];t=r.concat(u.slice(-(6-r.length))).join(" ")}r=t.split(/\s+/);const{ok:o,error:i}=ng(t);if(!o)throw new Error(i);const s=r[0];let l=0;this.clear(n);for(let u=0;u-1&&(this._castling.w|=N.KSIDE_CASTLE),r[2].indexOf("Q")>-1&&(this._castling.w|=N.QSIDE_CASTLE),r[2].indexOf("k")>-1&&(this._castling.b|=N.KSIDE_CASTLE),r[2].indexOf("q")>-1&&(this._castling.b|=N.QSIDE_CASTLE),this._epSquare=r[3]==="-"?je:A[r[3]],this._halfMoves=parseInt(r[4],10),this._moveNumber=parseInt(r[5],10),this._updateSetup(this.fen())}fen(){var i,s;let t=0,n="";for(let l=A.a8;l<=A.h1;l++){if(this._board[l]){t>0&&(n+=t,t=0);const{color:u,type:a}=this._board[l];n+=u===me?a.toUpperCase():a.toLowerCase()}else t++;l+1&136&&(t>0&&(n+=t),l!==A.h1&&(n+="/"),t=0,l+=8)}let r="";this._castling[me]&N.KSIDE_CASTLE&&(r+="K"),this._castling[me]&N.QSIDE_CASTLE&&(r+="Q"),this._castling[We]&N.KSIDE_CASTLE&&(r+="k"),this._castling[We]&N.QSIDE_CASTLE&&(r+="q"),r=r||"-";let o="-";if(this._epSquare!==je){const l=this._epSquare+(this._turn===me?16:-16),u=[l+1,l-1];for(const a of u){if(a&136)continue;const p=this._turn;if(((i=this._board[a])==null?void 0:i.color)===p&&((s=this._board[a])==null?void 0:s.type)===ie){this._makeMove({color:p,from:a,to:this._epSquare,piece:ie,captured:ie,flags:N.EP_CAPTURE});const m=!this._isKingAttacked(p);if(this._undoMove(),m){o=Le(this._epSquare);break}}}}return[n,this._turn,r,o,this._halfMoves,this._moveNumber].join(" ")}_updateSetup(t){this._history.length>0||(t!==fs?(this._header.SetUp="1",this._header.FEN=t):(delete this._header.SetUp,delete this._header.FEN))}reset(){this.load(fs)}get(t){return this._board[A[t]]||!1}put({type:t,color:n},r){if(G0.indexOf(t.toLowerCase())===-1||!(r in A))return!1;const o=A[r];return t==se&&!(this._kings[n]==je||this._kings[n]==o)?!1:(this._board[o]={type:t,color:n},t===se&&(this._kings[n]=o),this._updateCastlingRights(),this._updateEnPassantSquare(),this._updateSetup(this.fen()),!0)}remove(t){const n=this.get(t);return delete this._board[A[t]],n&&n.type===se&&(this._kings[n.color]=je),this._updateCastlingRights(),this._updateEnPassantSquare(),this._updateSetup(this.fen()),n}_updateCastlingRights(){var r,o,i,s,l,u,a,p,m,d,g,v;const t=((r=this._board[A.e1])==null?void 0:r.type)===se&&((o=this._board[A.e1])==null?void 0:o.color)===me,n=((i=this._board[A.e8])==null?void 0:i.type)===se&&((s=this._board[A.e8])==null?void 0:s.color)===We;(!t||((l=this._board[A.a1])==null?void 0:l.type)!==pr||((u=this._board[A.a1])==null?void 0:u.color)!==me)&&(this._castling.w&=~N.QSIDE_CASTLE),(!t||((a=this._board[A.h1])==null?void 0:a.type)!==pr||((p=this._board[A.h1])==null?void 0:p.color)!==me)&&(this._castling.w&=~N.KSIDE_CASTLE),(!n||((m=this._board[A.a8])==null?void 0:m.type)!==pr||((d=this._board[A.a8])==null?void 0:d.color)!==We)&&(this._castling.b&=~N.QSIDE_CASTLE),(!n||((g=this._board[A.h8])==null?void 0:g.type)!==pr||((v=this._board[A.h8])==null?void 0:v.color)!==We)&&(this._castling.b&=~N.KSIDE_CASTLE)}_updateEnPassantSquare(){var i,s;if(this._epSquare===je)return;const t=this._epSquare+(this._turn===me?-16:16),n=this._epSquare+(this._turn===me?16:-16),r=[n+1,n-1];if(this._board[t]!==null||this._board[this._epSquare]!==null||((i=this._board[n])==null?void 0:i.color)!==ur(this._turn)||((s=this._board[n])==null?void 0:s.type)!==ie){this._epSquare=je;return}const o=l=>{var u,a;return!(l&136)&&((u=this._board[l])==null?void 0:u.color)===this._turn&&((a=this._board[l])==null?void 0:a.type)===ie};r.some(o)||(this._epSquare=je)}_attacked(t,n){for(let r=A.a8;r<=A.h1;r++){if(r&136){r+=7;continue}if(this._board[r]===void 0||this._board[r].color!==t)continue;const o=this._board[r],i=r-n;if(i===0)continue;const s=i+119;if(Q0[s]&V0[o.type]){if(o.type===ie){if(i>0){if(o.color===me)return!0}else if(o.color===We)return!0;continue}if(o.type==="n"||o.type==="k")return!0;const l=K0[s];let u=r+l,a=!1;for(;u!==n;){if(this._board[u]!=null){a=!0;break}u+=l}if(!a)return!0}}return!1}_isKingAttacked(t){const n=this._kings[t];return n===-1?!1:this._attacked(ur(t),n)}isAttacked(t,n){return this._attacked(n,A[t])}isCheck(){return this._isKingAttacked(this._turn)}inCheck(){return this.isCheck()}isCheckmate(){return this.isCheck()&&this._moves().length===0}isStalemate(){return!this.isCheck()&&this._moves().length===0}isInsufficientMaterial(){const t={b:0,n:0,r:0,q:0,k:0,p:0},n=[];let r=0,o=0;for(let i=A.a8;i<=A.h1;i++){if(o=(o+1)%2,i&136){i+=7;continue}const s=this._board[i];s&&(t[s.type]=s.type in t?t[s.type]+1:1,s.type===Ao&&n.push(o),r++)}if(r===2)return!0;if(r===3&&(t[Ao]===1||t[ml]===1))return!0;if(r===t[Ao]+2){let i=0;const s=n.length;for(let l=0;l=3&&(r=!0);const i=t.pop();if(i)this._makeMove(i);else break}return r}isDraw(){return this._halfMoves>=100||this.isStalemate()||this.isInsufficientMaterial()||this.isThreefoldRepetition()}isGameOver(){return this.isCheckmate()||this.isStalemate()||this.isDraw()}moves({verbose:t=!1,square:n=void 0,piece:r=void 0}={}){const o=this._moves({square:n,piece:r});return t?o.map(i=>this._makePretty(i)):o.map(i=>this._moveToSan(i,o))}_moves({legal:t=!0,piece:n=void 0,square:r=void 0}={}){var g;const o=r?r.toLowerCase():void 0,i=n==null?void 0:n.toLowerCase(),s=[],l=this._turn,u=ur(l);let a=A.a8,p=A.h1,m=!1;if(o)if(o in A)a=p=A[o],m=!0;else return[];for(let v=a;v<=p;v++){if(v&136){v+=7;continue}if(!this._board[v]||this._board[v].color===u)continue;const{type:y}=this._board[v];let w;if(y===ie){if(i&&i!==y)continue;w=v+hs[l][0],this._board[w]||(jt(s,l,v,w,ie),w=v+hs[l][1],eg[l]===cn(v)&&!this._board[w]&&jt(s,l,v,w,ie,void 0,N.BIG_PAWN));for(let h=2;h<4;h++)w=v+hs[l][h],!(w&136)&&(((g=this._board[w])==null?void 0:g.color)===u?jt(s,l,v,w,ie,this._board[w].type,N.CAPTURE):w===this._epSquare&&jt(s,l,v,w,ie,ie,N.EP_CAPTURE))}else{if(i&&i!==y)continue;for(let h=0,c=za[y].length;h{const g=this._comments[this.fen()];if(typeof g<"u"){const v=d.length>0?" ":"";d=`${d}${v}{${g}}`}return d},s=[];for(;this._history.length>0;)s.push(this._undoMove());const l=[];let u="";for(s.length===0&&l.push(i(""));s.length>0;){u=i(u);const d=s.pop();if(!d)break;if(!this._history.length&&d.color==="b"){const g=`${this._moveNumber}. ...`;u=u?`${u} ${g}`:g}else d.color==="w"&&(u.length&&l.push(u),u=this._moveNumber+".");u=u+" "+this._moveToSan(d,this._moves({legal:!0})),this._makeMove(d)}if(u.length&&l.push(i(u)),typeof this._header.Result<"u"&&l.push(this._header.Result),n===0)return r.join("")+l.join(" ");const a=function(){return r.length>0&&r[r.length-1]===" "?(r.pop(),!0):!1},p=function(d,g){for(const v of g.split(" "))if(v){if(d+v.length>n){for(;a();)d--;r.push(t),d=0}r.push(v),d+=v.length,r.push(" "),d++}return a()&&d--,d};let m=0;for(let d=0;dn&&l[d].includes("{")){m=p(m,l[d]);continue}m+l[d].length>n&&d!==0?(r[r.length-1]===" "&&r.pop(),r.push(t),m=0):d!==0&&(r.push(" "),m++),r.push(l[d]),m+=l[d].length}return r.join("")}header(...t){for(let n=0;n0&&(k[_]=O)}return k}t=t.trim();const l=new RegExp("^(\\[((?:"+o(r)+")|.)*\\])((?:\\s*"+o(r)+"){2}|(?:\\s*"+o(r)+")*$)").exec(t),u=l&&l.length>=2?l[1]:"";this.reset();const a=i(u);let p="";for(const f in a)f.toLowerCase()==="fen"&&(p=a[f]),this.header(f,a[f]);if(!n)p&&this.load(p,!0);else if(a.SetUp==="1"){if(!("FEN"in a))throw new Error("Invalid PGN: FEN tag must be supplied with SetUp tag");this.load(a.FEN,!0)}function m(f){return Array.from(f).map(function(k){return k.charCodeAt(0)<128?k.charCodeAt(0).toString(16):encodeURIComponent(k).replace(/%/g,"").toLowerCase()}).join("")}function d(f){return f.length==0?"":decodeURIComponent("%"+(f.match(/.{1,2}/g)||[]).join("%"))}const g=function(f){return f=f.replace(new RegExp(o(r),"g")," "),`{${m(f.slice(1,f.length-1))}}`},v=function(f){if(f.startsWith("{")&&f.endsWith("}"))return d(f.slice(1,f.length-1))};let y=t.replace(u,"").replace(new RegExp(`({[^}]*})+?|;([^${o(r)}]*)`,"g"),function(f,k,x){return k!==void 0?g(k):" "+g(`{${x.slice(1)}}`)}).replace(new RegExp(o(r),"g")," ");const w=/(\([^()]+\))+?/g;for(;w.test(y);)y=y.replace(w,"");y=y.replace(/\d+\.(\.\.)?/g,""),y=y.replace(/\.\.\./g,""),y=y.replace(/\$\d+/g,"");let h=y.trim().split(new RegExp(/\s+/));h=h.filter(f=>f!=="");let c="";for(let f=0;f-1)c=h[f];else throw new Error(`Invalid move in PGN: ${h[f]}`);else c="",this._makeMove(x)}c&&Object.keys(this._header).length&&!this._header.Result&&this.header("Result",c)}_moveToSan(t,n){let r="";if(t.flags&N.KSIDE_CASTLE)r="O-O";else if(t.flags&N.QSIDE_CASTLE)r="O-O-O";else{if(t.piece!==ie){const o=rg(t,n);r+=t.piece.toUpperCase()+o}t.flags&(N.CAPTURE|N.EP_CAPTURE)&&(t.piece===ie&&(r+=Le(t.from)[0]),r+="x"),r+=Le(t.to),t.promotion&&(r+="="+t.promotion.toUpperCase())}return this._makeMove(t),this.isCheck()&&(this.isCheckmate()?r+="#":r+="+"),this._undoMove(),r}_moveFromSan(t,n=!1){const r=ps(t);let o=Fa(r),i=this._moves({legal:!0,piece:o});for(let d=0,g=i.length;d0?r+=this.perft(t-1):r++),this._undoMove();return r}_makePretty(t){const{color:n,piece:r,from:o,to:i,flags:s,captured:l,promotion:u}=t;let a="";for(const g in N)N[g]&s&&(a+=q0[g]);const p=Le(o),m=Le(i),d={color:n,piece:r,from:p,to:m,san:this._moveToSan(t,this._moves({legal:!0})),flags:a,lan:p+m,before:this.fen(),after:""};return this._makeMove(t),d.after=this.fen(),this._undoMove(),l&&(d.captured=l),u&&(d.promotion=u,d.lan+=u),d}turn(){return this._turn}board(){const t=[];let n=[];for(let r=A.a8;r<=A.h1;r++)this._board[r]==null?n.push(null):n.push({square:Le(r),type:this._board[r].type,color:this._board[r].color}),r+1&136&&(t.push(n),n=[],r+=8);return t}squareColor(t){if(t in A){const n=A[t];return(cn(n)+Br(n))%2===0?"light":"dark"}return null}history({verbose:t=!1}={}){const n=[],r=[];for(;this._history.length>0;)n.push(this._undoMove());for(;;){const o=n.pop();if(!o)break;t?r.push(this._makePretty(o)):r.push(this._moveToSan(o,this._moves())),this._makeMove(o)}return r}_pruneComments(){const t=[],n={},r=o=>{o in this._comments&&(n[o]=this._comments[o])};for(;this._history.length>0;)t.push(this._undoMove());for(r(this.fen());;){const o=t.pop();if(!o)break;this._makeMove(o),r(this.fen())}this._comments=n}getComment(){return this._comments[this.fen()]}setComment(t){this._comments[this.fen()]=t.replace("{","[").replace("}","]")}deleteComment(){const t=this._comments[this.fen()];return delete this._comments[this.fen()],t}getComments(){return this._pruneComments(),Object.keys(this._comments).map(t=>({fen:t,comment:this._comments[t]}))}deleteComments(){return this._pruneComments(),Object.keys(this._comments).map(t=>{const n=this._comments[t];return delete this._comments[t],{fen:t,comment:n}})}setCastlingRights(t,n){for(const o of[se,Mt])n[o]!==void 0&&(n[o]?this._castling[t]|=wo[o]:this._castling[t]&=~wo[o]);this._updateCastlingRights();const r=this.getCastlingRights(t);return(n[se]===void 0||n[se]===r[se])&&(n[Mt]===void 0||n[Mt]===r[Mt])}getCastlingRights(t){return{[se]:(this._castling[t]&wo[se])!==0,[Mt]:(this._castling[t]&wo[Mt])!==0}}moveNumber(){return this._moveNumber}}const Nf=C.createContext({dragDropManager:void 0});function Be(e){return"Minified Redux error #"+e+"; visit https://redux.js.org/Errors?code="+e+" for the full message or use the non-minified dev environment for full errors. "}var Ua=typeof Symbol=="function"&&Symbol.observable||"@@observable",gs=function(){return Math.random().toString(36).substring(7).split("").join(".")},Ha={INIT:"@@redux/INIT"+gs(),REPLACE:"@@redux/REPLACE"+gs(),PROBE_UNKNOWN_ACTION:function(){return"@@redux/PROBE_UNKNOWN_ACTION"+gs()}};function Mf(e,t,n){var r;if(typeof t=="function"&&typeof n=="function"||typeof n=="function"&&typeof arguments[3]=="function")throw new Error(Be(0));if(typeof t=="function"&&n===void 0&&(n=t,t=void 0),n!==void 0){if(typeof n!="function")throw new Error(Be(1));return n(Mf)(e,t)}if(typeof e!="function")throw new Error(Be(2));var o=e,i=t,s=[],l=s,u=!1;function a(){l===s&&(l=s.slice())}function p(){if(u)throw new Error(Be(3));return i}function m(g){if(typeof g!="function")throw new Error(Be(4));if(u)throw new Error(Be(5));var v=!0;return a(),l.push(g),function(){if(v){if(u)throw new Error(Be(6));v=!1,a();var y=l.indexOf(g);l.splice(y,1),s=null}}}function d(g){if(!function(w){if(typeof w!="object"||w===null)return!1;for(var h=w;Object.getPrototypeOf(h)!==null;)h=Object.getPrototypeOf(h);return Object.getPrototypeOf(w)===h}(g))throw new Error(Be(7));if(g.type===void 0)throw new Error(Be(8));if(u)throw new Error(Be(9));try{u=!0,i=o(i,g)}finally{u=!1}for(var v=s=l,y=0;y=0;y--)if(g.canDragSource(d[y])){v=d[y];break}return v}(t,s);if(u==null)return void e.dispatch(ig);let a=null;if(o){if(!i)throw new Error("getSourceClientOffset must be defined");(function(d){M(typeof d=="function","When clientOffset is provided, getSourceClientOffset must be a function.")})(i),a=i(u)}e.dispatch(Ba(o,a));const p=l.getSource(u).beginDrag(s,u);if(p==null)return;(function(d){M(Rf(d),"Item must be an object.")})(p),l.pinSource(u);const m=l.getSourceType(u);return{type:yu,payload:{itemType:m,item:p,sourceId:u,clientOffset:o||null,sourceClientOffset:a||null,isSourcePublic:!!r}}}}function lg(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ug(e){for(var t=1;t{const l=function(a,p,m,d){const g=m.getTarget(a);let v=g?g.drop(d,a):void 0;return function(y){M(y===void 0||Rf(y),"Drop result must either be an object or undefined.")}(v),v===void 0&&(v=p===0?{}:d.getDropResult()),v}(i,s,r,n),u={type:Su,payload:{dropResult:ug({},t,l)}};e.dispatch(u)})}}function cg(e){return function(){const t=e.getMonitor(),n=e.getRegistry();(function(o){M(o.isDragging(),"Cannot call endDrag while not dragging.")})(t);const r=t.getSourceId();return r!=null&&(n.getSource(r,!0).endDrag(t,r),n.unpinSource()),{type:wu}}}function vl(e,t){return t===null?e===null:Array.isArray(e)?e.some(n=>n===t):e===t}function dg(e){return function(t,{clientOffset:n}={}){(function(s){M(Array.isArray(s),"Expected targetIds to be an array.")})(t);const r=t.slice(0),o=e.getMonitor(),i=e.getRegistry();return function(s,l,u){for(let a=s.length-1;a>=0;a--){const p=s[a];vl(l.getTargetType(p),u)||s.splice(a,1)}}(r,i,o.getItemType()),function(s,l,u){M(l.isDragging(),"Cannot call hover while not dragging."),M(!l.didDrop(),"Cannot call hover after drop.");for(let a=0;a{const s=r[i];var l;return o[i]=(l=s,(...u)=>{const a=l.apply(t,u);a!==void 0&&n(a)}),o},{})}dispatch(t){this.store.dispatch(t)}constructor(t,n){this.isSetUp=!1,this.handleRefCountChange=()=>{const r=this.store.getState().refCount>0;this.backend&&(r&&!this.isSetUp?(this.backend.setup(),this.isSetUp=!0):!r&&this.isSetUp&&(this.backend.teardown(),this.isSetUp=!1))},this.store=t,this.monitor=n,t.subscribe(this.handleRefCountChange)}}function Wa(e,t){return{x:e.x-t.x,y:e.y-t.y}}const xr=[],ku=[];xr.__IS_NONE__=!0,ku.__IS_ALL__=!0;class pg{subscribeToStateChange(t,n={}){const{handlerIds:r}=n;M(typeof t=="function","listener must be a function."),M(r===void 0||Array.isArray(r),"handlerIds, when specified, must be an array of strings.");let o=this.store.getState().stateId;return this.store.subscribe(()=>{const i=this.store.getState(),s=i.stateId;try{s===o||s===o+1&&!function(u,a){return u!==xr&&(u===ku||a===void 0||(p=u,a.filter(m=>p.indexOf(m)>-1)).length>0);var p}(i.dirtyHandlerIds,r)||t()}finally{o=s}})}subscribeToOffsetChange(t){M(typeof t=="function","listener must be a function.");let n=this.store.getState().dragOffset;return this.store.subscribe(()=>{const r=this.store.getState().dragOffset;r!==n&&(n=r,t())})}canDragSource(t){if(!t)return!1;const n=this.registry.getSource(t);return M(n,`Expected to find a valid source. sourceId=${t}`),!this.isDragging()&&n.canDrag(this,t)}canDropOnTarget(t){if(!t)return!1;const n=this.registry.getTarget(t);return M(n,`Expected to find a valid target. targetId=${t}`),!this.isDragging()||this.didDrop()?!1:vl(this.registry.getTargetType(t),this.getItemType())&&n.canDrop(this,t)}isDragging(){return!!this.getItemType()}isDraggingSource(t){if(!t)return!1;const n=this.registry.getSource(t,!0);return M(n,`Expected to find a valid source. sourceId=${t}`),!this.isDragging()||!this.isSourcePublic()?!1:this.registry.getSourceType(t)===this.getItemType()&&n.isDragging(this,t)}isOverTarget(t,n={shallow:!1}){if(!t)return!1;const{shallow:r}=n;if(!this.isDragging())return!1;const o=this.registry.getTargetType(t),i=this.getItemType();if(i&&!vl(o,i))return!1;const s=this.getTargetIds();if(!s.length)return!1;const l=s.indexOf(t);return r?l===s.length-1:l>-1}getItemType(){return this.store.getState().dragOperation.itemType}getItem(){return this.store.getState().dragOperation.item}getSourceId(){return this.store.getState().dragOperation.sourceId}getTargetIds(){return this.store.getState().dragOperation.targetIds}getDropResult(){return this.store.getState().dragOperation.dropResult}didDrop(){return this.store.getState().dragOperation.didDrop}isSourcePublic(){return!!this.store.getState().dragOperation.isSourcePublic}getInitialClientOffset(){return this.store.getState().dragOffset.initialClientOffset}getInitialSourceClientOffset(){return this.store.getState().dragOffset.initialSourceClientOffset}getClientOffset(){return this.store.getState().dragOffset.clientOffset}getSourceClientOffset(){return function(t){const{clientOffset:n,initialClientOffset:r,initialSourceClientOffset:o}=t;return n&&r&&o?Wa((s=o,{x:(i=n).x+s.x,y:i.y+s.y}),r):null;var i,s}(this.store.getState().dragOffset)}getDifferenceFromInitialOffset(){return function(t){const{clientOffset:n,initialClientOffset:r}=t;return n&&r?Wa(n,r):null}(this.store.getState().dragOffset)}constructor(t,n){this.store=t,this.registry=n}}const qa=typeof global<"u"?global:self,Qa=qa.MutationObserver||qa.WebKitMutationObserver;function bf(e){return function(){const t=setTimeout(r,0),n=setInterval(r,50);function r(){clearTimeout(t),clearInterval(n),e()}}}const gg=typeof Qa=="function"?function(e){let t=1;const n=new Qa(e),r=document.createTextNode("");return n.observe(r,{characterData:!0}),function(){t=-t,r.data=t}}:bf;class mg{call(){try{this.task&&this.task()}catch(t){this.onError(t)}finally{this.task=null,this.release(this)}}constructor(t,n){this.onError=t,this.release=n,this.task=null}}const zf=new class{enqueueTask(e){const{queue:t,requestFlush:n}=this;t.length||(n(),this.flushing=!0),t[t.length]=e}constructor(){this.queue=[],this.pendingErrors=[],this.flushing=!1,this.index=0,this.capacity=1024,this.flush=()=>{const{queue:e}=this;for(;this.indexthis.capacity){for(let n=0,r=e.length-this.index;n{this.pendingErrors.push(e),this.requestErrorThrow()},this.requestFlush=gg(this.flush),this.requestErrorThrow=bf(()=>{if(this.pendingErrors.length)throw this.pendingErrors.shift()})}},vg=new class{create(e){const t=this.freeTasks,n=t.length?t.pop():new mg(this.onError,r=>t[t.length]=r);return n.task=e,n}constructor(e){this.onError=e,this.freeTasks=[]}}(zf.registerPendingError),Eu="dnd-core/ADD_SOURCE",Cu="dnd-core/ADD_TARGET",xu="dnd-core/REMOVE_SOURCE",Oi="dnd-core/REMOVE_TARGET";function yl(e,t){t&&Array.isArray(e)?e.forEach(n=>yl(n,!1)):M(typeof e=="string"||typeof e=="symbol",t?"Type can only be a string, a symbol, or an array of either.":"Type can only be a string or a symbol.")}var Ke;(function(e){e.SOURCE="SOURCE",e.TARGET="TARGET"})(Ke||(Ke={}));let yg=0;function Sg(e){const t=(yg++).toString();switch(e){case Ke.SOURCE:return`S${t}`;case Ke.TARGET:return`T${t}`;default:throw new Error(`Unknown Handler Role: ${e}`)}}function Ka(e){switch(e[0]){case"S":return Ke.SOURCE;case"T":return Ke.TARGET;default:throw new Error(`Cannot parse handler ID: ${e}`)}}function Va(e,t){const n=e.entries();let r=!1;do{const{done:o,value:[,i]}=n.next();if(i===t)return!0;r=!!o}while(!r);return!1}class wg{addSource(t,n){yl(t),function(o){M(typeof o.canDrag=="function","Expected canDrag to be a function."),M(typeof o.beginDrag=="function","Expected beginDrag to be a function."),M(typeof o.endDrag=="function","Expected endDrag to be a function.")}(n);const r=this.addHandler(Ke.SOURCE,t,n);return this.store.dispatch(function(o){return{type:Eu,payload:{sourceId:o}}}(r)),r}addTarget(t,n){yl(t,!0),function(o){M(typeof o.canDrop=="function","Expected canDrop to be a function."),M(typeof o.hover=="function","Expected hover to be a function."),M(typeof o.drop=="function","Expected beginDrag to be a function.")}(n);const r=this.addHandler(Ke.TARGET,t,n);return this.store.dispatch(function(o){return{type:Cu,payload:{targetId:o}}}(r)),r}containsHandler(t){return Va(this.dragSources,t)||Va(this.dropTargets,t)}getSource(t,n=!1){return M(this.isSourceId(t),"Expected a valid source ID."),n&&t===this.pinnedSourceId?this.pinnedSource:this.dragSources.get(t)}getTarget(t){return M(this.isTargetId(t),"Expected a valid target ID."),this.dropTargets.get(t)}getSourceType(t){return M(this.isSourceId(t),"Expected a valid source ID."),this.types.get(t)}getTargetType(t){return M(this.isTargetId(t),"Expected a valid target ID."),this.types.get(t)}isSourceId(t){return Ka(t)===Ke.SOURCE}isTargetId(t){return Ka(t)===Ke.TARGET}removeSource(t){var n;M(this.getSource(t),"Expected an existing source."),this.store.dispatch(function(r){return{type:xu,payload:{sourceId:r}}}(t)),n=()=>{this.dragSources.delete(t),this.types.delete(t)},zf.enqueueTask(vg.create(n))}removeTarget(t){M(this.getTarget(t),"Expected an existing target."),this.store.dispatch(function(n){return{type:Oi,payload:{targetId:n}}}(t)),this.dropTargets.delete(t),this.types.delete(t)}pinSource(t){const n=this.getSource(t);M(n,"Expected an existing source."),this.pinnedSourceId=t,this.pinnedSource=n}unpinSource(){M(this.pinnedSource,"No source is pinned at the time."),this.pinnedSourceId=null,this.pinnedSource=null}addHandler(t,n,r){const o=Sg(t);return this.types.set(o,n),t===Ke.SOURCE?this.dragSources.set(o,r):t===Ke.TARGET&&this.dropTargets.set(o,r),o}constructor(t){this.types=new Map,this.dragSources=new Map,this.dropTargets=new Map,this.pinnedSourceId=null,this.pinnedSource=null,this.store=t}}const kg=(e,t)=>e===t;function Eg(e=xr,t){switch(t.type){case _i:break;case Eu:case Cu:case Oi:case xu:return xr;default:return ku}const{targetIds:n=[],prevTargetIds:r=[]}=t.payload,o=function(l,u){const a=new Map,p=d=>{a.set(d,a.has(d)?a.get(d)+1:1)};l.forEach(p),u.forEach(p);const m=[];return a.forEach((d,g)=>{d===1&&m.push(g)}),m}(n,r);if(!(o.length>0||!function(l,u,a=kg){if(l.length!==u.length)return!1;for(let p=0;pi!==o))});case Su:return Cn({},e,{dropResult:n.dropResult,didDrop:!0,targetIds:[]});case wu:return Cn({},e,{itemType:null,item:null,sourceId:null,dropResult:null,didDrop:!1,isSourcePublic:null,targetIds:[]});default:return e}var r,o}function Dg(e=0,t){switch(t.type){case Eu:case Cu:return e+1;case xu:case Oi:return e-1;default:return e}}function Pg(e=0){return e+1}function Ig(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function jg(e){for(var t=1;ti&&i[s]?i[s]:o||null,n))})}),dragOffset:xg(e.dragOffset,t),refCount:Dg(e.refCount,t),dragOperation:Tg(e.dragOperation,t),stateId:Pg(e.stateId)};var n,r,o}function Ng(e,t=void 0,n={},r=!1){const o=function(u){const a=typeof window<"u"&&window.__REDUX_DEVTOOLS_EXTENSION__;return Mf(Lg,u&&a&&a({name:"dnd-core",instanceId:"dnd-core"}))}(r),i=new pg(o,new wg(o)),s=new hg(o,i),l=e(s,t,n);return s.receiveBackend(l),s}function Mg(e,t){if(e==null)return{};var n,r,o=function(s,l){if(s==null)return{};var u,a,p={},m=Object.keys(s);for(a=0;a=0||(p[u]=s[u]);return p}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}let Ya=0;const ko=Symbol.for("__REACT_DND_CONTEXT_INSTANCE__");var Rg=C.memo(function(e){var{children:t}=e,n=Mg(e,["children"]);const[r,o]=function(i){if("manager"in i)return[{dragDropManager:i.manager},!1];const s=function(u,a=Xa(),p,m){const d=a;return d[ko]||(d[ko]={dragDropManager:Ng(u,a,p,m)}),d[ko]}(i.backend,i.context,i.options,i.debugMode),l=!i.context;return[s,l]}(n);return C.useEffect(()=>{if(o){const i=Xa();return++Ya,()=>{--Ya==0&&(i[ko]=null)}}},[]),S.jsx(Nf.Provider,{value:r,children:t})});function Xa(){return typeof global<"u"?global:window}var Ag=function e(t,n){if(t===n)return!0;if(t&&n&&typeof t=="object"&&typeof n=="object"){if(t.constructor!==n.constructor)return!1;var r,o,i;if(Array.isArray(t)){if((r=t.length)!=n.length)return!1;for(o=r;o--!=0;)if(!e(t[o],n[o]))return!1;return!0}if(t.constructor===RegExp)return t.source===n.source&&t.flags===n.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===n.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===n.toString();if((r=(i=Object.keys(t)).length)!==Object.keys(n).length)return!1;for(o=r;o--!=0;)if(!Object.prototype.hasOwnProperty.call(n,i[o]))return!1;for(o=r;o--!=0;){var s=i[o];if(!e(t[s],n[s]))return!1}return!0}return t!=t&&n!=n};const mn=typeof window<"u"?C.useLayoutEffect:C.useEffect;function $f(e,t,n){const[r,o]=C.useState(()=>t(e)),i=C.useCallback(()=>{const s=t(e);Ag(r,s)||(o(s),n&&n())},[r,e,n]);return mn(i),[r,i]}function Ff(e,t,n){return function(r,o,i){const[s,l]=$f(r,o,i);return mn(function(){const u=r.getHandlerId();if(u!=null)return r.subscribeToStateChange(l,{handlerIds:[u]})},[r,l]),s}(t,e||(()=>({})),()=>n.reconnect())}function Uf(e,t){const n=[...t||[]];return t==null&&typeof e!="function"&&n.push(e),C.useMemo(()=>typeof e=="function"?e():e,n)}function bg(e){return C.useMemo(()=>e.hooks.dragSource(),[e])}function zg(e){return C.useMemo(()=>e.hooks.dragPreview(),[e])}let ms=!1,vs=!1;class $g{receiveHandlerId(t){this.sourceId=t}getHandlerId(){return this.sourceId}canDrag(){M(!ms,"You may not call monitor.canDrag() inside your canDrag() implementation. Read more: http://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor");try{return ms=!0,this.internalMonitor.canDragSource(this.sourceId)}finally{ms=!1}}isDragging(){if(!this.sourceId)return!1;M(!vs,"You may not call monitor.isDragging() inside your isDragging() implementation. Read more: http://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor");try{return vs=!0,this.internalMonitor.isDraggingSource(this.sourceId)}finally{vs=!1}}subscribeToStateChange(t,n){return this.internalMonitor.subscribeToStateChange(t,n)}isDraggingSource(t){return this.internalMonitor.isDraggingSource(t)}isOverTarget(t,n){return this.internalMonitor.isOverTarget(t,n)}getTargetIds(){return this.internalMonitor.getTargetIds()}isSourcePublic(){return this.internalMonitor.isSourcePublic()}getSourceId(){return this.internalMonitor.getSourceId()}subscribeToOffsetChange(t){return this.internalMonitor.subscribeToOffsetChange(t)}canDragSource(t){return this.internalMonitor.canDragSource(t)}canDropOnTarget(t){return this.internalMonitor.canDropOnTarget(t)}getItemType(){return this.internalMonitor.getItemType()}getItem(){return this.internalMonitor.getItem()}getDropResult(){return this.internalMonitor.getDropResult()}didDrop(){return this.internalMonitor.didDrop()}getInitialClientOffset(){return this.internalMonitor.getInitialClientOffset()}getInitialSourceClientOffset(){return this.internalMonitor.getInitialSourceClientOffset()}getSourceClientOffset(){return this.internalMonitor.getSourceClientOffset()}getClientOffset(){return this.internalMonitor.getClientOffset()}getDifferenceFromInitialOffset(){return this.internalMonitor.getDifferenceFromInitialOffset()}constructor(t){this.sourceId=null,this.internalMonitor=t.getMonitor()}}let ys=!1;class Fg{receiveHandlerId(t){this.targetId=t}getHandlerId(){return this.targetId}subscribeToStateChange(t,n){return this.internalMonitor.subscribeToStateChange(t,n)}canDrop(){if(!this.targetId)return!1;M(!ys,"You may not call monitor.canDrop() inside your canDrop() implementation. Read more: http://react-dnd.github.io/react-dnd/docs/api/drop-target-monitor");try{return ys=!0,this.internalMonitor.canDropOnTarget(this.targetId)}finally{ys=!1}}isOver(t){return!!this.targetId&&this.internalMonitor.isOverTarget(this.targetId,t)}getItemType(){return this.internalMonitor.getItemType()}getItem(){return this.internalMonitor.getItem()}getDropResult(){return this.internalMonitor.getDropResult()}didDrop(){return this.internalMonitor.didDrop()}getInitialClientOffset(){return this.internalMonitor.getInitialClientOffset()}getInitialSourceClientOffset(){return this.internalMonitor.getInitialSourceClientOffset()}getSourceClientOffset(){return this.internalMonitor.getSourceClientOffset()}getClientOffset(){return this.internalMonitor.getClientOffset()}getDifferenceFromInitialOffset(){return this.internalMonitor.getDifferenceFromInitialOffset()}constructor(t){this.targetId=null,this.internalMonitor=t.getMonitor()}}function Sl(e,t,n,r){let o=n?n.call(r,e,t):void 0;if(o!==void 0)return!!o;if(e===t)return!0;if(typeof e!="object"||!e||typeof t!="object"||!t)return!1;const i=Object.keys(e),s=Object.keys(t);if(i.length!==s.length)return!1;const l=Object.prototype.hasOwnProperty.bind(t);for(let u=0;u{if(!C.isValidElement(t)){const o=t;return e(o,n),o}const r=t;return function(o){if(typeof o.type=="string")return;const i=o.type.displayName||o.type.name||"the component";throw new Error(`Only native element nodes can now be passed to React DnD connectors.You can either wrap ${i} into a
, or turn it into a drag source or a drop target itself.`)}(r),function(o,i){const s=o.ref;return M(typeof s!="string","Cannot connect React DnD to an element with an existing string ref. Please convert it to use a callback ref instead, or wrap it into a or
. Read more: https://reactjs.org/docs/refs-and-the-dom.html#callback-refs"),C.cloneElement(o,s?{ref:l=>{Ja(s,l),Ja(i,l)}}:{ref:i})}(r,n?o=>e(o,n):e)}}function Hf(e){const t={};return Object.keys(e).forEach(n=>{const r=e[n];if(n.endsWith("Ref"))t[n]=e[n];else{const o=Ug(r);t[n]=()=>o}}),t}function Ja(e,t){typeof e=="function"?e(t):e.current=t}class Hg{receiveHandlerId(t){this.handlerId!==t&&(this.handlerId=t,this.reconnect())}get connectTarget(){return this.dragSource}get dragSourceOptions(){return this.dragSourceOptionsInternal}set dragSourceOptions(t){this.dragSourceOptionsInternal=t}get dragPreviewOptions(){return this.dragPreviewOptionsInternal}set dragPreviewOptions(t){this.dragPreviewOptionsInternal=t}reconnect(){const t=this.reconnectDragSource();this.reconnectDragPreview(t)}reconnectDragSource(){const t=this.dragSource,n=this.didHandlerIdChange()||this.didConnectedDragSourceChange()||this.didDragSourceOptionsChange();return n&&this.disconnectDragSource(),this.handlerId?t?(n&&(this.lastConnectedHandlerId=this.handlerId,this.lastConnectedDragSource=t,this.lastConnectedDragSourceOptions=this.dragSourceOptions,this.dragSourceUnsubscribe=this.backend.connectDragSource(this.handlerId,t,this.dragSourceOptions)),n):(this.lastConnectedDragSource=t,n):n}reconnectDragPreview(t=!1){const n=this.dragPreview,r=t||this.didHandlerIdChange()||this.didConnectedDragPreviewChange()||this.didDragPreviewOptionsChange();r&&this.disconnectDragPreview(),this.handlerId&&(n?r&&(this.lastConnectedHandlerId=this.handlerId,this.lastConnectedDragPreview=n,this.lastConnectedDragPreviewOptions=this.dragPreviewOptions,this.dragPreviewUnsubscribe=this.backend.connectDragPreview(this.handlerId,n,this.dragPreviewOptions)):this.lastConnectedDragPreview=n)}didHandlerIdChange(){return this.lastConnectedHandlerId!==this.handlerId}didConnectedDragSourceChange(){return this.lastConnectedDragSource!==this.dragSource}didConnectedDragPreviewChange(){return this.lastConnectedDragPreview!==this.dragPreview}didDragSourceOptionsChange(){return!Sl(this.lastConnectedDragSourceOptions,this.dragSourceOptions)}didDragPreviewOptionsChange(){return!Sl(this.lastConnectedDragPreviewOptions,this.dragPreviewOptions)}disconnectDragSource(){this.dragSourceUnsubscribe&&(this.dragSourceUnsubscribe(),this.dragSourceUnsubscribe=void 0)}disconnectDragPreview(){this.dragPreviewUnsubscribe&&(this.dragPreviewUnsubscribe(),this.dragPreviewUnsubscribe=void 0,this.dragPreviewNode=null,this.dragPreviewRef=null)}get dragSource(){return this.dragSourceNode||this.dragSourceRef&&this.dragSourceRef.current}get dragPreview(){return this.dragPreviewNode||this.dragPreviewRef&&this.dragPreviewRef.current}clearDragSource(){this.dragSourceNode=null,this.dragSourceRef=null}clearDragPreview(){this.dragPreviewNode=null,this.dragPreviewRef=null}constructor(t){this.hooks=Hf({dragSource:(n,r)=>{this.clearDragSource(),this.dragSourceOptions=r||null,wl(n)?this.dragSourceRef=n:this.dragSourceNode=n,this.reconnectDragSource()},dragPreview:(n,r)=>{this.clearDragPreview(),this.dragPreviewOptions=r||null,wl(n)?this.dragPreviewRef=n:this.dragPreviewNode=n,this.reconnectDragPreview()}}),this.handlerId=null,this.dragSourceRef=null,this.dragSourceOptionsInternal=null,this.dragPreviewRef=null,this.dragPreviewOptionsInternal=null,this.lastConnectedHandlerId=null,this.lastConnectedDragSource=null,this.lastConnectedDragSourceOptions=null,this.lastConnectedDragPreview=null,this.lastConnectedDragPreviewOptions=null,this.backend=t}}class Bg{get connectTarget(){return this.dropTarget}reconnect(){const t=this.didHandlerIdChange()||this.didDropTargetChange()||this.didOptionsChange();t&&this.disconnectDropTarget();const n=this.dropTarget;this.handlerId&&(n?t&&(this.lastConnectedHandlerId=this.handlerId,this.lastConnectedDropTarget=n,this.lastConnectedDropTargetOptions=this.dropTargetOptions,this.unsubscribeDropTarget=this.backend.connectDropTarget(this.handlerId,n,this.dropTargetOptions)):this.lastConnectedDropTarget=n)}receiveHandlerId(t){t!==this.handlerId&&(this.handlerId=t,this.reconnect())}get dropTargetOptions(){return this.dropTargetOptionsInternal}set dropTargetOptions(t){this.dropTargetOptionsInternal=t}didHandlerIdChange(){return this.lastConnectedHandlerId!==this.handlerId}didDropTargetChange(){return this.lastConnectedDropTarget!==this.dropTarget}didOptionsChange(){return!Sl(this.lastConnectedDropTargetOptions,this.dropTargetOptions)}disconnectDropTarget(){this.unsubscribeDropTarget&&(this.unsubscribeDropTarget(),this.unsubscribeDropTarget=void 0)}get dropTarget(){return this.dropTargetNode||this.dropTargetRef&&this.dropTargetRef.current}clearDropTarget(){this.dropTargetRef=null,this.dropTargetNode=null}constructor(t){this.hooks=Hf({dropTarget:(n,r)=>{this.clearDropTarget(),this.dropTargetOptions=r,wl(n)?this.dropTargetRef=n:this.dropTargetNode=n,this.reconnect()}}),this.handlerId=null,this.dropTargetRef=null,this.dropTargetOptionsInternal=null,this.lastConnectedHandlerId=null,this.lastConnectedDropTarget=null,this.lastConnectedDropTargetOptions=null,this.backend=t}}function vn(){const{dragDropManager:e}=C.useContext(Nf);return M(e!=null,"Expected drag drop context"),e}class Wg{beginDrag(){const t=this.spec,n=this.monitor;let r=null;return r=typeof t.item=="object"?t.item:typeof t.item=="function"?t.item(n):{},r??null}canDrag(){const t=this.spec,n=this.monitor;return typeof t.canDrag=="boolean"?t.canDrag:typeof t.canDrag!="function"||t.canDrag(n)}isDragging(t,n){const r=this.spec,o=this.monitor,{isDragging:i}=r;return i?i(o):n===t.getSourceId()}endDrag(){const t=this.spec,n=this.monitor,r=this.connector,{end:o}=t;o&&o(n.getItem(),n),r.reconnect()}constructor(t,n,r){this.spec=t,this.monitor=n,this.connector=r}}function qg(e,t,n){const r=vn(),o=function(s,l,u){const a=C.useMemo(()=>new Wg(s,l,u),[l,u]);return C.useEffect(()=>{a.spec=s},[s]),a}(e,t,n),i=function(s){return C.useMemo(()=>{const l=s.type;return M(l!=null,"spec.type must be defined"),l},[s])}(e);mn(function(){if(i!=null){const[s,l]=function(u,a,p){const m=p.getRegistry(),d=m.addSource(u,a);return[d,()=>m.removeSource(d)]}(i,o,r);return t.receiveHandlerId(s),n.receiveHandlerId(s),l}},[r,t,n,o,i])}function Qg(e,t){const n=Uf(e,t);M(!n.begin,"useDrag::spec.begin was deprecated in v14. Replace spec.begin() with spec.item(). (see more here - https://react-dnd.github.io/react-dnd/docs/api/use-drag)");const r=function(){const i=vn();return C.useMemo(()=>new $g(i),[i])}(),o=function(i,s){const l=vn(),u=C.useMemo(()=>new Hg(l.getBackend()),[l]);return mn(()=>(u.dragSourceOptions=i||null,u.reconnect(),()=>u.disconnectDragSource()),[u,i]),mn(()=>(u.dragPreviewOptions=s||null,u.reconnect(),()=>u.disconnectDragPreview()),[u,s]),u}(n.options,n.previewOptions);return qg(n,r,o),[Ff(n.collect,r,o),bg(o),zg(o)]}function Kg(e){return C.useMemo(()=>e.hooks.dropTarget(),[e])}class Vg{canDrop(){const t=this.spec,n=this.monitor;return!t.canDrop||t.canDrop(n.getItem(),n)}hover(){const t=this.spec,n=this.monitor;t.hover&&t.hover(n.getItem(),n)}drop(){const t=this.spec,n=this.monitor;if(t.drop)return t.drop(n.getItem(),n)}constructor(t,n){this.spec=t,this.monitor=n}}function Gg(e,t,n){const r=vn(),o=function(s,l){const u=C.useMemo(()=>new Vg(s,l),[l]);return C.useEffect(()=>{u.spec=s},[s]),u}(e,t),i=function(s){const{accept:l}=s;return C.useMemo(()=>(M(s.accept!=null,"accept must be defined"),Array.isArray(l)?l:[l]),[l])}(e);mn(function(){const[s,l]=function(u,a,p){const m=p.getRegistry(),d=m.addTarget(u,a);return[d,()=>m.removeTarget(d)]}(i,o,r);return t.receiveHandlerId(s),n.receiveHandlerId(s),l},[r,t,o,n,i.map(s=>s.toString()).join("|")])}function Yg(e,t){const n=Uf(e,t),r=function(){const i=vn();return C.useMemo(()=>new Fg(i),[i])}(),o=function(i){const s=vn(),l=C.useMemo(()=>new Bg(s.getBackend()),[s]);return mn(()=>(l.dropTargetOptions=i||null,l.reconnect(),()=>l.disconnectDropTarget()),[i]),l}(n.options);return Gg(n,r,o),[Ff(n.collect,r,o),Kg(o)]}function Bf(e){let t=null;return()=>(t==null&&(t=e()),t)}class Xg{enter(t){const n=this.entered.length;return this.entered=function(r,o){const i=new Set,s=u=>i.add(u);r.forEach(s),o.forEach(s);const l=[];return i.forEach(u=>l.push(u)),l}(this.entered.filter(r=>this.isNodeInDocument(r)&&(!r.contains||r.contains(t))),[t]),n===0&&this.entered.length>0}leave(t){const n=this.entered.length;var r,o;return this.entered=(r=this.entered.filter(this.isNodeInDocument),o=t,r.filter(i=>i!==o)),n>0&&this.entered.length===0}reset(){this.entered=[]}constructor(t){this.entered=[],this.isNodeInDocument=t}}class Jg{initializeExposedProperties(){Object.keys(this.config.exposeProperties).forEach(t=>{Object.defineProperty(this.item,t,{configurable:!0,enumerable:!0,get:()=>(console.warn(`Browser doesn't allow reading "${t}" until the drop event.`),null)})})}loadDataTransfer(t){if(t){const n={};Object.keys(this.config.exposeProperties).forEach(r=>{const o=this.config.exposeProperties[r];o!=null&&(n[r]={value:o(t,this.config.matchesTypes),configurable:!0,enumerable:!0})}),Object.defineProperties(this.item,n)}}canDrag(){return!0}beginDrag(){return this.item}isDragging(t,n){return n===t.getSourceId()}endDrag(){}constructor(t){this.config=t,this.item={},this.initializeExposedProperties()}}const Wf="__NATIVE_FILE__",qf="__NATIVE_URL__",Qf="__NATIVE_TEXT__",Kf="__NATIVE_HTML__";var Za=Object.freeze({__proto__:null,FILE:Wf,HTML:Kf,TEXT:Qf,URL:qf});function Ss(e,t,n){const r=t.reduce((o,i)=>o||e.getData(i),"");return r??n}const kl={[Wf]:{exposeProperties:{files:e=>Array.prototype.slice.call(e.files),items:e=>e.items,dataTransfer:e=>e},matchesTypes:["Files"]},[Kf]:{exposeProperties:{html:(e,t)=>Ss(e,t,""),dataTransfer:e=>e},matchesTypes:["Html","text/html"]},[qf]:{exposeProperties:{urls:(e,t)=>Ss(e,t,"").split(` +`),dataTransfer:e=>e},matchesTypes:["Url","text/uri-list"]},[Qf]:{exposeProperties:{text:(e,t)=>Ss(e,t,""),dataTransfer:e=>e},matchesTypes:["Text","text/plain"]}};function ws(e){if(!e)return null;const t=Array.prototype.slice.call(e.types||[]);return Object.keys(kl).filter(n=>{const r=kl[n];return!!(r!=null&&r.matchesTypes)&&r.matchesTypes.some(o=>t.indexOf(o)>-1)})[0]||null}const Zg=Bf(()=>/firefox/i.test(navigator.userAgent)),ec=Bf(()=>!!window.safari);class tc{interpolate(t){const{xs:n,ys:r,c1s:o,c2s:i,c3s:s}=this;let l=n.length-1;if(t===n[l])return r[l];let u,a=0,p=s.length-1;for(;a<=p;){u=Math.floor(.5*(a+p));const g=n[u];if(gt))return r[u];p=u-1}}l=Math.max(0,p);const m=t-n[l],d=m*m;return r[l]+o[l]*m+i[l]*d+s[l]*m*d}constructor(t,n){const{length:r}=t,o=[];for(let g=0;gt[g]{let f=new tc([0,.5,1],[a.y,a.y/m*y,a.y+y-m]).interpolate(g);return ec()&&i&&(f+=(window.devicePixelRatio-1)*y),f})()}}let Co;function n1(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function nc(e){for(var t=1;t{this.sourcePreviewNodes.delete(t),this.sourcePreviewNodeOptions.delete(t)}}connectDragSource(t,n,r){this.sourceNodes.set(t,n),this.sourceNodeOptions.set(t,r);const o=s=>this.handleDragStart(s,t),i=s=>this.handleSelectStart(s);return n.setAttribute("draggable","true"),n.addEventListener("dragstart",o),n.addEventListener("selectstart",i),()=>{this.sourceNodes.delete(t),this.sourceNodeOptions.delete(t),n.removeEventListener("dragstart",o),n.removeEventListener("selectstart",i),n.setAttribute("draggable","false")}}connectDropTarget(t,n){const r=s=>this.handleDragEnter(s,t),o=s=>this.handleDragOver(s,t),i=s=>this.handleDrop(s,t);return n.addEventListener("dragenter",r),n.addEventListener("dragover",o),n.addEventListener("drop",i),()=>{n.removeEventListener("dragenter",r),n.removeEventListener("dragover",o),n.removeEventListener("drop",i)}}addEventListeners(t){t.addEventListener&&(t.addEventListener("dragstart",this.handleTopDragStart),t.addEventListener("dragstart",this.handleTopDragStartCapture,!0),t.addEventListener("dragend",this.handleTopDragEndCapture,!0),t.addEventListener("dragenter",this.handleTopDragEnter),t.addEventListener("dragenter",this.handleTopDragEnterCapture,!0),t.addEventListener("dragleave",this.handleTopDragLeaveCapture,!0),t.addEventListener("dragover",this.handleTopDragOver),t.addEventListener("dragover",this.handleTopDragOverCapture,!0),t.addEventListener("drop",this.handleTopDrop),t.addEventListener("drop",this.handleTopDropCapture,!0))}removeEventListeners(t){t.removeEventListener&&(t.removeEventListener("dragstart",this.handleTopDragStart),t.removeEventListener("dragstart",this.handleTopDragStartCapture,!0),t.removeEventListener("dragend",this.handleTopDragEndCapture,!0),t.removeEventListener("dragenter",this.handleTopDragEnter),t.removeEventListener("dragenter",this.handleTopDragEnterCapture,!0),t.removeEventListener("dragleave",this.handleTopDragLeaveCapture,!0),t.removeEventListener("dragover",this.handleTopDragOver),t.removeEventListener("dragover",this.handleTopDragOverCapture,!0),t.removeEventListener("drop",this.handleTopDrop),t.removeEventListener("drop",this.handleTopDropCapture,!0))}getCurrentSourceNodeOptions(){const t=this.monitor.getSourceId(),n=this.sourceNodeOptions.get(t);return nc({dropEffect:this.altKeyPressed?"copy":"move"},n||{})}getCurrentDropEffect(){return this.isDraggingNativeItem()?"copy":this.getCurrentSourceNodeOptions().dropEffect}getCurrentSourcePreviewNodeOptions(){const t=this.monitor.getSourceId();return nc({anchorX:.5,anchorY:.5,captureDraggingState:!1},this.sourcePreviewNodeOptions.get(t)||{})}isDraggingNativeItem(){const t=this.monitor.getItemType();return Object.keys(Za).some(n=>Za[n]===t)}beginDragNativeItem(t,n){this.clearCurrentDragSourceNode(),this.currentNativeSource=function(r,o){const i=kl[r];if(!i)throw new Error(`native type ${r} has no configuration`);const s=new Jg(i);return s.loadDataTransfer(o),s}(t,n),this.currentNativeHandle=this.registry.addSource(t,this.currentNativeSource),this.actions.beginDrag([this.currentNativeHandle])}setCurrentDragSourceNode(t){this.clearCurrentDragSourceNode(),this.currentDragSourceNode=t,this.mouseMoveTimeoutTimer=setTimeout(()=>{var n;return(n=this.rootElement)===null||n===void 0?void 0:n.addEventListener("mousemove",this.endDragIfSourceWasRemovedFromDOM,!0)},1e3)}clearCurrentDragSourceNode(){if(this.currentDragSourceNode){var t;return this.currentDragSourceNode=null,this.rootElement&&((t=this.window)===null||t===void 0||t.clearTimeout(this.mouseMoveTimeoutTimer||void 0),this.rootElement.removeEventListener("mousemove",this.endDragIfSourceWasRemovedFromDOM,!0)),this.mouseMoveTimeoutTimer=null,!0}return!1}handleDragStart(t,n){t.defaultPrevented||(this.dragStartSourceIds||(this.dragStartSourceIds=[]),this.dragStartSourceIds.unshift(n))}handleDragEnter(t,n){this.dragEnterTargetIds.unshift(n)}handleDragOver(t,n){this.dragOverTargetIds===null&&(this.dragOverTargetIds=[]),this.dragOverTargetIds.unshift(n)}handleDrop(t,n){this.dropTargetIds.unshift(n)}constructor(t,n,r){this.sourcePreviewNodes=new Map,this.sourcePreviewNodeOptions=new Map,this.sourceNodes=new Map,this.sourceNodeOptions=new Map,this.dragStartSourceIds=null,this.dropTargetIds=[],this.dragEnterTargetIds=[],this.currentNativeSource=null,this.currentNativeHandle=null,this.currentDragSourceNode=null,this.altKeyPressed=!1,this.mouseMoveTimeoutTimer=null,this.asyncEndDragFrameId=null,this.dragOverTargetIds=null,this.lastClientOffset=null,this.hoverRafId=null,this.getSourceClientOffset=o=>{const i=this.sourceNodes.get(o);return i&&Vf(i)||null},this.endDragNativeItem=()=>{this.isDraggingNativeItem()&&(this.actions.endDrag(),this.currentNativeHandle&&this.registry.removeSource(this.currentNativeHandle),this.currentNativeHandle=null,this.currentNativeSource=null)},this.isNodeInDocument=o=>!!(o&&this.document&&this.document.body&&this.document.body.contains(o)),this.endDragIfSourceWasRemovedFromDOM=()=>{const o=this.currentDragSourceNode;o==null||this.isNodeInDocument(o)||(this.clearCurrentDragSourceNode()&&this.monitor.isDragging()&&this.actions.endDrag(),this.cancelHover())},this.scheduleHover=o=>{this.hoverRafId===null&&typeof requestAnimationFrame<"u"&&(this.hoverRafId=requestAnimationFrame(()=>{this.monitor.isDragging()&&this.actions.hover(o||[],{clientOffset:this.lastClientOffset}),this.hoverRafId=null}))},this.cancelHover=()=>{this.hoverRafId!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(this.hoverRafId),this.hoverRafId=null)},this.handleTopDragStartCapture=()=>{this.clearCurrentDragSourceNode(),this.dragStartSourceIds=[]},this.handleTopDragStart=o=>{if(o.defaultPrevented)return;const{dragStartSourceIds:i}=this;this.dragStartSourceIds=null;const s=Eo(o);this.monitor.isDragging()&&(this.actions.endDrag(),this.cancelHover()),this.actions.beginDrag(i||[],{publishSource:!1,getSourceClientOffset:this.getSourceClientOffset,clientOffset:s});const{dataTransfer:l}=o,u=ws(l);if(this.monitor.isDragging()){if(l&&typeof l.setDragImage=="function"){const p=this.monitor.getSourceId(),m=this.sourceNodes.get(p),d=this.sourcePreviewNodes.get(p)||m;if(d){const{anchorX:g,anchorY:v,offsetX:y,offsetY:w}=this.getCurrentSourcePreviewNodeOptions(),h=t1(m,d,s,{anchorX:g,anchorY:v},{offsetX:y,offsetY:w});l.setDragImage(d,h.x,h.y)}}try{l==null||l.setData("application/json",{})}catch{}this.setCurrentDragSourceNode(o.target);const{captureDraggingState:a}=this.getCurrentSourcePreviewNodeOptions();a?this.actions.publishDragSource():setTimeout(()=>this.actions.publishDragSource(),0)}else if(u)this.beginDragNativeItem(u);else{if(l&&!l.types&&(o.target&&!o.target.hasAttribute||!o.target.hasAttribute("draggable")))return;o.preventDefault()}},this.handleTopDragEndCapture=()=>{this.clearCurrentDragSourceNode()&&this.monitor.isDragging()&&this.actions.endDrag(),this.cancelHover()},this.handleTopDragEnterCapture=o=>{var i;if(this.dragEnterTargetIds=[],this.isDraggingNativeItem()&&((i=this.currentNativeSource)===null||i===void 0||i.loadDataTransfer(o.dataTransfer)),!this.enterLeaveCounter.enter(o.target)||this.monitor.isDragging())return;const{dataTransfer:s}=o,l=ws(s);l&&this.beginDragNativeItem(l,s)},this.handleTopDragEnter=o=>{const{dragEnterTargetIds:i}=this;this.dragEnterTargetIds=[],this.monitor.isDragging()&&(this.altKeyPressed=o.altKey,i.length>0&&this.actions.hover(i,{clientOffset:Eo(o)}),i.some(s=>this.monitor.canDropOnTarget(s))&&(o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect=this.getCurrentDropEffect())))},this.handleTopDragOverCapture=o=>{var i;this.dragOverTargetIds=[],this.isDraggingNativeItem()&&((i=this.currentNativeSource)===null||i===void 0||i.loadDataTransfer(o.dataTransfer))},this.handleTopDragOver=o=>{const{dragOverTargetIds:i}=this;if(this.dragOverTargetIds=[],!this.monitor.isDragging())return o.preventDefault(),void(o.dataTransfer&&(o.dataTransfer.dropEffect="none"));this.altKeyPressed=o.altKey,this.lastClientOffset=Eo(o),this.scheduleHover(i),(i||[]).some(s=>this.monitor.canDropOnTarget(s))?(o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect=this.getCurrentDropEffect())):this.isDraggingNativeItem()?o.preventDefault():(o.preventDefault(),o.dataTransfer&&(o.dataTransfer.dropEffect="none"))},this.handleTopDragLeaveCapture=o=>{this.isDraggingNativeItem()&&o.preventDefault(),this.enterLeaveCounter.leave(o.target)&&(this.isDraggingNativeItem()&&setTimeout(()=>this.endDragNativeItem(),0),this.cancelHover())},this.handleTopDropCapture=o=>{var i;this.dropTargetIds=[],this.isDraggingNativeItem()?(o.preventDefault(),(i=this.currentNativeSource)===null||i===void 0||i.loadDataTransfer(o.dataTransfer)):ws(o.dataTransfer)&&o.preventDefault(),this.enterLeaveCounter.reset()},this.handleTopDrop=o=>{const{dropTargetIds:i}=this;this.dropTargetIds=[],this.actions.hover(i,{clientOffset:Eo(o)}),this.actions.drop({dropEffect:this.getCurrentDropEffect()}),this.isDraggingNativeItem()?this.endDragNativeItem():this.monitor.isDragging()&&this.actions.endDrag(),this.cancelHover()},this.handleSelectStart=o=>{const i=o.target;typeof i.dragDrop=="function"&&(i.tagName==="INPUT"||i.tagName==="SELECT"||i.tagName==="TEXTAREA"||i.isContentEditable||(o.preventDefault(),i.dragDrop()))},this.options=new class{get window(){return this.globalContext?this.globalContext:typeof window<"u"?window:void 0}get document(){var o;return!((o=this.globalContext)===null||o===void 0)&&o.document?this.globalContext.document:this.window?this.window.document:void 0}get rootElement(){var o;return((o=this.optionsArgs)===null||o===void 0?void 0:o.rootElement)||this.window}constructor(o,i){this.ownerDocument=null,this.globalContext=o,this.optionsArgs=i}}(n,r),this.actions=t.getActions(),this.monitor=t.getMonitor(),this.registry=t.getRegistry(),this.enterLeaveCounter=new Xg(this.isNodeInDocument)}}const o1=function(e,t,n){return new r1(e,t,n)};var Kt;(function(e){e.mouse="mouse",e.touch="touch",e.keyboard="keyboard"})(Kt||(Kt={}));class i1{get delay(){var t;return(t=this.args.delay)!==null&&t!==void 0?t:0}get scrollAngleRanges(){return this.args.scrollAngleRanges}get getDropTargetElementsAtPoint(){return this.args.getDropTargetElementsAtPoint}get ignoreContextMenu(){var t;return(t=this.args.ignoreContextMenu)!==null&&t!==void 0&&t}get enableHoverOutsideTarget(){var t;return(t=this.args.enableHoverOutsideTarget)!==null&&t!==void 0&&t}get enableKeyboardEvents(){var t;return(t=this.args.enableKeyboardEvents)!==null&&t!==void 0&&t}get enableMouseEvents(){var t;return(t=this.args.enableMouseEvents)!==null&&t!==void 0&&t}get enableTouchEvents(){var t;return(t=this.args.enableTouchEvents)===null||t===void 0||t}get touchSlop(){return this.args.touchSlop||0}get delayTouchStart(){var t,n,r,o;return(o=(r=(t=this.args)===null||t===void 0?void 0:t.delayTouchStart)!==null&&r!==void 0?r:(n=this.args)===null||n===void 0?void 0:n.delay)!==null&&o!==void 0?o:0}get delayMouseStart(){var t,n,r,o;return(o=(r=(t=this.args)===null||t===void 0?void 0:t.delayMouseStart)!==null&&r!==void 0?r:(n=this.args)===null||n===void 0?void 0:n.delay)!==null&&o!==void 0?o:0}get window(){return this.context&&this.context.window?this.context.window:typeof window<"u"?window:void 0}get document(){var t;return!((t=this.context)===null||t===void 0)&&t.document?this.context.document:this.window?this.window.document:void 0}get rootElement(){var t;return((t=this.args)===null||t===void 0?void 0:t.rootElement)||this.document}constructor(t,n){this.args=t,this.context=n}}const s1=1,l1=0;function ks(e){return e.button===void 0||e.button===l1}function Gf(e){return!!e.targetTouches}function ui(e,t){return Gf(e)?function(n,r){return n.targetTouches.length===1?ui(n.targetTouches[0]):r&&n.touches.length===1&&n.touches[0].target===r.target?ui(n.touches[0]):void 0}(e,t):{x:e.clientX,y:e.clientY}}const rc=(()=>{let e=!1;try{addEventListener("test",()=>{},Object.defineProperty({},"passive",{get:()=>(e=!0,!0)}))}catch{}return e})(),ar={[Kt.mouse]:{start:"mousedown",move:"mousemove",end:"mouseup",contextmenu:"contextmenu"},[Kt.touch]:{start:"touchstart",move:"touchmove",end:"touchend"},[Kt.keyboard]:{keydown:"keydown"}};class _r{profile(){var t;return{sourceNodes:this.sourceNodes.size,sourcePreviewNodes:this.sourcePreviewNodes.size,sourcePreviewNodeOptions:this.sourcePreviewNodeOptions.size,targetNodes:this.targetNodes.size,dragOverTargetIds:((t=this.dragOverTargetIds)===null||t===void 0?void 0:t.length)||0}}get document(){return this.options.document}setup(){const t=this.options.rootElement;t&&(M(!_r.isSetUp,"Cannot have two Touch backends at the same time."),_r.isSetUp=!0,this.addEventListener(t,"start",this.getTopMoveStartHandler()),this.addEventListener(t,"start",this.handleTopMoveStartCapture,!0),this.addEventListener(t,"move",this.handleTopMove),this.addEventListener(t,"move",this.handleTopMoveCapture,!0),this.addEventListener(t,"end",this.handleTopMoveEndCapture,!0),this.options.enableMouseEvents&&!this.options.ignoreContextMenu&&this.addEventListener(t,"contextmenu",this.handleTopMoveEndCapture),this.options.enableKeyboardEvents&&this.addEventListener(t,"keydown",this.handleCancelOnEscape,!0))}teardown(){const t=this.options.rootElement;t&&(_r.isSetUp=!1,this._mouseClientOffset={},this.removeEventListener(t,"start",this.handleTopMoveStartCapture,!0),this.removeEventListener(t,"start",this.handleTopMoveStart),this.removeEventListener(t,"move",this.handleTopMoveCapture,!0),this.removeEventListener(t,"move",this.handleTopMove),this.removeEventListener(t,"end",this.handleTopMoveEndCapture,!0),this.options.enableMouseEvents&&!this.options.ignoreContextMenu&&this.removeEventListener(t,"contextmenu",this.handleTopMoveEndCapture),this.options.enableKeyboardEvents&&this.removeEventListener(t,"keydown",this.handleCancelOnEscape,!0),this.uninstallSourceNodeRemovalObserver())}addEventListener(t,n,r,o=!1){const i=rc?{capture:o,passive:!1}:o;this.listenerTypes.forEach(function(s){const l=ar[s][n];l&&t.addEventListener(l,r,i)})}removeEventListener(t,n,r,o=!1){const i=rc?{capture:o,passive:!1}:o;this.listenerTypes.forEach(function(s){const l=ar[s][n];l&&t.removeEventListener(l,r,i)})}connectDragSource(t,n){const r=this.handleMoveStart.bind(this,t);return this.sourceNodes.set(t,n),this.addEventListener(n,"start",r),()=>{this.sourceNodes.delete(t),this.removeEventListener(n,"start",r)}}connectDragPreview(t,n,r){return this.sourcePreviewNodeOptions.set(t,r),this.sourcePreviewNodes.set(t,n),()=>{this.sourcePreviewNodes.delete(t),this.sourcePreviewNodeOptions.delete(t)}}connectDropTarget(t,n){const r=this.options.rootElement;if(!this.document||!r)return()=>{};const o=i=>{if(!this.document||!r||!this.monitor.isDragging())return;let s;switch(i.type){case ar.mouse.move:s={x:i.clientX,y:i.clientY};break;case ar.touch.move:var l,u;s={x:((l=i.touches[0])===null||l===void 0?void 0:l.clientX)||0,y:((u=i.touches[0])===null||u===void 0?void 0:u.clientY)||0}}const a=s!=null?this.document.elementFromPoint(s.x,s.y):void 0,p=a&&n.contains(a);return a===n||p?this.handleMove(i,t):void 0};return this.addEventListener(this.document.body,"move",o),this.targetNodes.set(t,n),()=>{this.document&&(this.targetNodes.delete(t),this.removeEventListener(this.document.body,"move",o))}}getTopMoveStartHandler(){return this.options.delayTouchStart||this.options.delayMouseStart?this.handleTopMoveStartDelay:this.handleTopMoveStart}installSourceNodeRemovalObserver(t){this.uninstallSourceNodeRemovalObserver(),this.draggedSourceNode=t,this.draggedSourceNodeRemovalObserver=new MutationObserver(()=>{t&&!t.parentElement&&(this.resurrectSourceNode(),this.uninstallSourceNodeRemovalObserver())}),t&&t.parentElement&&this.draggedSourceNodeRemovalObserver.observe(t.parentElement,{childList:!0})}resurrectSourceNode(){this.document&&this.draggedSourceNode&&(this.draggedSourceNode.style.display="none",this.draggedSourceNode.removeAttribute("data-reactid"),this.document.body.appendChild(this.draggedSourceNode))}uninstallSourceNodeRemovalObserver(){this.draggedSourceNodeRemovalObserver&&this.draggedSourceNodeRemovalObserver.disconnect(),this.draggedSourceNodeRemovalObserver=void 0,this.draggedSourceNode=void 0}constructor(t,n,r){this.getSourceClientOffset=o=>{const i=this.sourceNodes.get(o);return i&&function(s){const l=s.nodeType===1?s:s.parentElement;if(!l)return;const{top:u,left:a}=l.getBoundingClientRect();return{x:a,y:u}}(i)},this.handleTopMoveStartCapture=o=>{ks(o)&&(this.moveStartSourceIds=[])},this.handleMoveStart=o=>{Array.isArray(this.moveStartSourceIds)&&this.moveStartSourceIds.unshift(o)},this.handleTopMoveStart=o=>{if(!ks(o))return;const i=ui(o);i&&(Gf(o)&&(this.lastTargetTouchFallback=o.targetTouches[0]),this._mouseClientOffset=i),this.waitingForDelay=!1},this.handleTopMoveStartDelay=o=>{if(!ks(o))return;const i=o.type===ar.touch.start?this.options.delayTouchStart:this.options.delayMouseStart;this.timeout=setTimeout(this.handleTopMoveStart.bind(this,o),i),this.waitingForDelay=!0},this.handleTopMoveCapture=()=>{this.dragOverTargetIds=[]},this.handleMove=(o,i)=>{this.dragOverTargetIds&&this.dragOverTargetIds.unshift(i)},this.handleTopMove=o=>{if(this.timeout&&clearTimeout(this.timeout),!this.document||this.waitingForDelay)return;const{moveStartSourceIds:i,dragOverTargetIds:s}=this,l=this.options.enableHoverOutsideTarget,u=ui(o,this.lastTargetTouchFallback);if(!u)return;if(this._isScrolling||!this.monitor.isDragging()&&function(c,f,k,x,_){if(!_)return!1;const O=180*Math.atan2(x-f,k-c)/Math.PI+180;for(let T=0;T<_.length;++T){const j=_[T];if(j&&(j.start==null||O>=j.start)&&(j.end==null||O<=j.end))return!0}return!1}(this._mouseClientOffset.x||0,this._mouseClientOffset.y||0,u.x,u.y,this.options.scrollAngleRanges))return void(this._isScrolling=!0);var a,p,m,d;if(!this.monitor.isDragging()&&this._mouseClientOffset.hasOwnProperty("x")&&i&&(a=this._mouseClientOffset.x||0,p=this._mouseClientOffset.y||0,m=u.x,d=u.y,Math.sqrt(Math.pow(Math.abs(m-a),2)+Math.pow(Math.abs(d-p),2))>(this.options.touchSlop?this.options.touchSlop:0))&&(this.moveStartSourceIds=void 0,this.actions.beginDrag(i,{clientOffset:this._mouseClientOffset,getSourceClientOffset:this.getSourceClientOffset,publishSource:!1})),!this.monitor.isDragging())return;const g=this.sourceNodes.get(this.monitor.getSourceId());this.installSourceNodeRemovalObserver(g),this.actions.publishDragSource(),o.cancelable&&o.preventDefault();const v=(s||[]).map(c=>this.targetNodes.get(c)).filter(c=>!!c),y=this.options.getDropTargetElementsAtPoint?this.options.getDropTargetElementsAtPoint(u.x,u.y,v):this.document.elementsFromPoint(u.x,u.y),w=[];for(const c in y){if(!y.hasOwnProperty(c))continue;let f=y[c];for(f!=null&&w.push(f);f;)f=f.parentElement,f&&w.indexOf(f)===-1&&w.push(f)}const h=w.filter(c=>v.indexOf(c)>-1).map(c=>this._getDropTargetId(c)).filter(c=>!!c).filter((c,f,k)=>k.indexOf(c)===f);if(l)for(const c in this.targetNodes){const f=this.targetNodes.get(c);if(g&&f&&f.contains(g)&&h.indexOf(c)===-1){h.unshift(c);break}}h.reverse(),this.actions.hover(h,{clientOffset:u})},this._getDropTargetId=o=>{const i=this.targetNodes.keys();let s=i.next();for(;s.done===!1;){const l=s.value;if(o===this.targetNodes.get(l))return l;s=i.next()}},this.handleTopMoveEndCapture=o=>{this._isScrolling=!1,this.lastTargetTouchFallback=void 0,function(i){return i.buttons===void 0||(i.buttons&s1)==0}(o)&&(this.monitor.isDragging()&&!this.monitor.didDrop()?(o.cancelable&&o.preventDefault(),this._mouseClientOffset={},this.uninstallSourceNodeRemovalObserver(),this.actions.drop(),this.actions.endDrag()):this.moveStartSourceIds=void 0)},this.handleCancelOnEscape=o=>{o.key==="Escape"&&this.monitor.isDragging()&&(this._mouseClientOffset={},this.uninstallSourceNodeRemovalObserver(),this.actions.endDrag())},this.options=new i1(r,n),this.actions=t.getActions(),this.monitor=t.getMonitor(),this.sourceNodes=new Map,this.sourcePreviewNodes=new Map,this.sourcePreviewNodeOptions=new Map,this.targetNodes=new Map,this.listenerTypes=[],this._mouseClientOffset={},this._isScrolling=!1,this.options.enableMouseEvents&&this.listenerTypes.push(Kt.mouse),this.options.enableTouchEvents&&this.listenerTypes.push(Kt.touch),this.options.enableKeyboardEvents&&this.listenerTypes.push(Kt.keyboard)}}const u1=function(e,t={},n={}){return new _r(e,t,n)},Wr="abcdefgh".split(""),bo={a8:"bR",b8:"bN",c8:"bB",d8:"bQ",e8:"bK",f8:"bB",g8:"bN",h8:"bR",a7:"bP",b7:"bP",c7:"bP",d7:"bP",e7:"bP",f7:"bP",g7:"bP",h7:"bP",a2:"wP",b2:"wP",c2:"wP",d2:"wP",e2:"wP",f2:"wP",g2:"wP",h2:"wP",a1:"wR",b1:"wN",c1:"wB",d1:"wQ",e1:"wK",f1:"wB",g1:"wN",h1:"wR"},a1={a:0,b:1,c:2,d:3,e:4,f:5,g:6,h:7},c1={a:7,b:6,c:5,d:4,e:3,f:2,g:1,h:0},d1=[7,6,5,4,3,2,1,0],f1=[0,1,2,3,4,5,6,7],oc={wP:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsx("path",{d:"m 22.5,9 c -2.21,0 -4,1.79 -4,4 0,0.89 0.29,1.71 0.78,2.38 C 17.33,16.5 16,18.59 16,21 c 0,2.03 0.94,3.84 2.41,5.03 C 15.41,27.09 11,31.58 11,39.5 H 34 C 34,31.58 29.59,27.09 26.59,26.03 28.06,24.84 29,23.03 29,21 29,18.59 27.67,16.5 25.72,15.38 26.21,14.71 26.5,13.89 26.5,13 c 0,-2.21 -1.79,-4 -4,-4 z",style:{opacity:"1",fill:"#ffffff",fillOpacity:"1",fillRule:"nonzero",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"miter",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}})})),wR:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{opacity:"1",fill:"#ffffff",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[S.jsx("path",{d:"M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 z ",style:{strokeLinecap:"butt"}}),S.jsx("path",{d:"M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 z ",style:{strokeLinecap:"butt"}}),S.jsx("path",{d:"M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14",style:{strokeLinecap:"butt"}}),S.jsx("path",{d:"M 34,14 L 31,17 L 14,17 L 11,14"}),S.jsx("path",{d:"M 31,17 L 31,29.5 L 14,29.5 L 14,17",style:{strokeLinecap:"butt",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 31,29.5 L 32.5,32 L 12.5,32 L 14,29.5"}),S.jsx("path",{d:"M 11,14 L 34,14",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}})]}))})),wN:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{opacity:"1",fill:"none",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[S.jsx("path",{d:"M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18",style:{fill:"#ffffff",stroke:"#000000"}}),S.jsx("path",{d:"M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10",style:{fill:"#ffffff",stroke:"#000000"}}),S.jsx("path",{d:"M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z",style:{fill:"#000000",stroke:"#000000"}}),S.jsx("path",{d:"M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z",transform:"matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)",style:{fill:"#000000",stroke:"#000000"}})]}))})),wB:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{opacity:"1",fill:"none",fillRule:"evenodd",fillOpacity:"1",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[S.jsxs("g",Object.assign({style:{fill:"#ffffff",stroke:"#000000",strokeLinecap:"butt"}},{children:[S.jsx("path",{d:"M 9,36 C 12.39,35.03 19.11,36.43 22.5,34 C 25.89,36.43 32.61,35.03 36,36 C 36,36 37.65,36.54 39,38 C 38.32,38.97 37.35,38.99 36,38.5 C 32.61,37.53 25.89,38.96 22.5,37.5 C 19.11,38.96 12.39,37.53 9,38.5 C 7.65,38.99 6.68,38.97 6,38 C 7.35,36.54 9,36 9,36 z"}),S.jsx("path",{d:"M 15,32 C 17.5,34.5 27.5,34.5 30,32 C 30.5,30.5 30,30 30,30 C 30,27.5 27.5,26 27.5,26 C 33,24.5 33.5,14.5 22.5,10.5 C 11.5,14.5 12,24.5 17.5,26 C 17.5,26 15,27.5 15,30 C 15,30 14.5,30.5 15,32 z"}),S.jsx("path",{d:"M 25 8 A 2.5 2.5 0 1 1 20,8 A 2.5 2.5 0 1 1 25 8 z"})]})),S.jsx("path",{d:"M 17.5,26 L 27.5,26 M 15,30 L 30,30 M 22.5,15.5 L 22.5,20.5 M 20,18 L 25,18",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}})]}))})),wQ:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{fill:"#ffffff",stroke:"#000000",strokeWidth:"1.5",strokeLinejoin:"round"}},{children:[S.jsx("path",{d:"M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.7,10.9 L 25.5,24.5 L 22.5,10 L 19.5,24.5 L 14.3,10.9 L 14,25 L 6.5,13.5 L 9,26 z"}),S.jsx("path",{d:"M 9,26 C 9,28 10.5,28 11.5,30 C 12.5,31.5 12.5,31 12,33.5 C 10.5,34.5 11,36 11,36 C 9.5,37.5 11,38.5 11,38.5 C 17.5,39.5 27.5,39.5 34,38.5 C 34,38.5 35.5,37.5 34,36 C 34,36 34.5,34.5 33,33.5 C 32.5,31 32.5,31.5 33.5,30 C 34.5,28 36,28 36,26 C 27.5,24.5 17.5,24.5 9,26 z"}),S.jsx("path",{d:"M 11.5,30 C 15,29 30,29 33.5,30",style:{fill:"none"}}),S.jsx("path",{d:"M 12,33.5 C 18,32.5 27,32.5 33,33.5",style:{fill:"none"}}),S.jsx("circle",{cx:"6",cy:"12",r:"2"}),S.jsx("circle",{cx:"14",cy:"9",r:"2"}),S.jsx("circle",{cx:"22.5",cy:"8",r:"2"}),S.jsx("circle",{cx:"31",cy:"9",r:"2"}),S.jsx("circle",{cx:"39",cy:"12",r:"2"})]}))})),wK:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{fill:"none",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[S.jsx("path",{d:"M 22.5,11.63 L 22.5,6",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 20,8 L 25,8",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25",style:{fill:"#ffffff",stroke:"#000000",strokeLinecap:"butt",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 12.5,37 C 18,40.5 27,40.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 20,16 10.5,13 6.5,19.5 C 3.5,25.5 12.5,30 12.5,30 L 12.5,37",style:{fill:"#ffffff",stroke:"#000000"}}),S.jsx("path",{d:"M 12.5,30 C 18,27 27,27 32.5,30",style:{fill:"none",stroke:"#000000"}}),S.jsx("path",{d:"M 12.5,33.5 C 18,30.5 27,30.5 32.5,33.5",style:{fill:"none",stroke:"#000000"}}),S.jsx("path",{d:"M 12.5,37 C 18,34 27,34 32.5,37",style:{fill:"none",stroke:"#000000"}})]}))})),bP:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsx("path",{d:"m 22.5,9 c -2.21,0 -4,1.79 -4,4 0,0.89 0.29,1.71 0.78,2.38 C 17.33,16.5 16,18.59 16,21 c 0,2.03 0.94,3.84 2.41,5.03 C 15.41,27.09 11,31.58 11,39.5 H 34 C 34,31.58 29.59,27.09 26.59,26.03 28.06,24.84 29,23.03 29,21 29,18.59 27.67,16.5 25.72,15.38 26.21,14.71 26.5,13.89 26.5,13 c 0,-2.21 -1.79,-4 -4,-4 z",style:{opacity:"1",fill:"#000000",fillOpacity:"1",fillRule:"nonzero",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"miter",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}})})),bR:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{opacity:"1",fill:"#000000",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[S.jsx("path",{d:"M 9,39 L 36,39 L 36,36 L 9,36 L 9,39 z ",style:{strokeLinecap:"butt"}}),S.jsx("path",{d:"M 12.5,32 L 14,29.5 L 31,29.5 L 32.5,32 L 12.5,32 z ",style:{strokeLinecap:"butt"}}),S.jsx("path",{d:"M 12,36 L 12,32 L 33,32 L 33,36 L 12,36 z ",style:{strokeLinecap:"butt"}}),S.jsx("path",{d:"M 14,29.5 L 14,16.5 L 31,16.5 L 31,29.5 L 14,29.5 z ",style:{strokeLinecap:"butt",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 14,16.5 L 11,14 L 34,14 L 31,16.5 L 14,16.5 z ",style:{strokeLinecap:"butt"}}),S.jsx("path",{d:"M 11,14 L 11,9 L 15,9 L 15,11 L 20,11 L 20,9 L 25,9 L 25,11 L 30,11 L 30,9 L 34,9 L 34,14 L 11,14 z ",style:{strokeLinecap:"butt"}}),S.jsx("path",{d:"M 12,35.5 L 33,35.5 L 33,35.5",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 13,31.5 L 32,31.5",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 14,29.5 L 31,29.5",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 14,16.5 L 31,16.5",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 11,14 L 34,14",style:{fill:"none",stroke:"#ffffff",strokeWidth:"1",strokeLinejoin:"miter"}})]}))})),bN:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{opacity:"1",fill:"none",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[S.jsx("path",{d:"M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18",style:{fill:"#000000",stroke:"#000000"}}),S.jsx("path",{d:"M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10",style:{fill:"#000000",stroke:"#000000"}}),S.jsx("path",{d:"M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z",style:{fill:"#ffffff",stroke:"#ffffff"}}),S.jsx("path",{d:"M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z",transform:"matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)",style:{fill:"#ffffff",stroke:"#ffffff"}}),S.jsx("path",{d:"M 24.55,10.4 L 24.1,11.85 L 24.6,12 C 27.75,13 30.25,14.49 32.5,18.75 C 34.75,23.01 35.75,29.06 35.25,39 L 35.2,39.5 L 37.45,39.5 L 37.5,39 C 38,28.94 36.62,22.15 34.25,17.66 C 31.88,13.17 28.46,11.02 25.06,10.5 L 24.55,10.4 z ",style:{fill:"#ffffff",stroke:"none"}})]}))})),bB:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{opacity:"1",fill:"none",fillRule:"evenodd",fillOpacity:"1",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[S.jsxs("g",Object.assign({style:{fill:"#000000",stroke:"#000000",strokeLinecap:"butt"}},{children:[S.jsx("path",{d:"M 9,36 C 12.39,35.03 19.11,36.43 22.5,34 C 25.89,36.43 32.61,35.03 36,36 C 36,36 37.65,36.54 39,38 C 38.32,38.97 37.35,38.99 36,38.5 C 32.61,37.53 25.89,38.96 22.5,37.5 C 19.11,38.96 12.39,37.53 9,38.5 C 7.65,38.99 6.68,38.97 6,38 C 7.35,36.54 9,36 9,36 z"}),S.jsx("path",{d:"M 15,32 C 17.5,34.5 27.5,34.5 30,32 C 30.5,30.5 30,30 30,30 C 30,27.5 27.5,26 27.5,26 C 33,24.5 33.5,14.5 22.5,10.5 C 11.5,14.5 12,24.5 17.5,26 C 17.5,26 15,27.5 15,30 C 15,30 14.5,30.5 15,32 z"}),S.jsx("path",{d:"M 25 8 A 2.5 2.5 0 1 1 20,8 A 2.5 2.5 0 1 1 25 8 z"})]})),S.jsx("path",{d:"M 17.5,26 L 27.5,26 M 15,30 L 30,30 M 22.5,15.5 L 22.5,20.5 M 20,18 L 25,18",style:{fill:"none",stroke:"#ffffff",strokeLinejoin:"miter"}})]}))})),bQ:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{fill:"#000000",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"}},{children:[S.jsx("path",{d:"M 9,26 C 17.5,24.5 30,24.5 36,26 L 38.5,13.5 L 31,25 L 30.7,10.9 L 25.5,24.5 L 22.5,10 L 19.5,24.5 L 14.3,10.9 L 14,25 L 6.5,13.5 L 9,26 z",style:{strokeLinecap:"butt",fill:"#000000"}}),S.jsx("path",{d:"m 9,26 c 0,2 1.5,2 2.5,4 1,1.5 1,1 0.5,3.5 -1.5,1 -1,2.5 -1,2.5 -1.5,1.5 0,2.5 0,2.5 6.5,1 16.5,1 23,0 0,0 1.5,-1 0,-2.5 0,0 0.5,-1.5 -1,-2.5 -0.5,-2.5 -0.5,-2 0.5,-3.5 1,-2 2.5,-2 2.5,-4 -8.5,-1.5 -18.5,-1.5 -27,0 z"}),S.jsx("path",{d:"M 11.5,30 C 15,29 30,29 33.5,30"}),S.jsx("path",{d:"m 12,33.5 c 6,-1 15,-1 21,0"}),S.jsx("circle",{cx:"6",cy:"12",r:"2"}),S.jsx("circle",{cx:"14",cy:"9",r:"2"}),S.jsx("circle",{cx:"22.5",cy:"8",r:"2"}),S.jsx("circle",{cx:"31",cy:"9",r:"2"}),S.jsx("circle",{cx:"39",cy:"12",r:"2"}),S.jsx("path",{d:"M 11,38.5 A 35,35 1 0 0 34,38.5",style:{fill:"none",stroke:"#000000",strokeLinecap:"butt"}}),S.jsxs("g",Object.assign({style:{fill:"none",stroke:"#ffffff"}},{children:[S.jsx("path",{d:"M 11,29 A 35,35 1 0 1 34,29"}),S.jsx("path",{d:"M 12.5,31.5 L 32.5,31.5"}),S.jsx("path",{d:"M 11.5,34.5 A 35,35 1 0 0 33.5,34.5"}),S.jsx("path",{d:"M 10.5,37.5 A 35,35 1 0 0 34.5,37.5"})]}))]}))})),bK:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",width:"45",height:"45"},{children:S.jsxs("g",Object.assign({style:{fill:"none",fillOpacity:"1",fillRule:"evenodd",stroke:"#000000",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",strokeMiterlimit:"4",strokeDasharray:"none",strokeOpacity:"1"}},{children:[S.jsx("path",{d:"M 22.5,11.63 L 22.5,6",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"},id:"path6570"}),S.jsx("path",{d:"M 22.5,25 C 22.5,25 27,17.5 25.5,14.5 C 25.5,14.5 24.5,12 22.5,12 C 20.5,12 19.5,14.5 19.5,14.5 C 18,17.5 22.5,25 22.5,25",style:{fill:"#000000",fillOpacity:"1",strokeLinecap:"butt",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 12.5,37 C 18,40.5 27,40.5 32.5,37 L 32.5,30 C 32.5,30 41.5,25.5 38.5,19.5 C 34.5,13 25,16 22.5,23.5 L 22.5,27 L 22.5,23.5 C 20,16 10.5,13 6.5,19.5 C 3.5,25.5 12.5,30 12.5,30 L 12.5,37",style:{fill:"#000000",stroke:"#000000"}}),S.jsx("path",{d:"M 20,8 L 25,8",style:{fill:"none",stroke:"#000000",strokeLinejoin:"miter"}}),S.jsx("path",{d:"M 32,29.5 C 32,29.5 40.5,25.5 38.03,19.85 C 34.15,14 25,18 22.5,24.5 L 22.5,26.6 L 22.5,24.5 C 20,18 10.85,14 6.97,19.85 C 4.5,25.5 13,29.5 13,29.5",style:{fill:"none",stroke:"#ffffff"}}),S.jsx("path",{d:"M 12.5,30 C 18,27 27,27 32.5,30 M 12.5,33.5 C 18,30.5 27,30.5 32.5,33.5 M 12.5,37 C 18,34 27,34 32.5,37",style:{fill:"none",stroke:"#ffffff"}})]}))}))};function El(e,t,n){const r=t/8,o=e==="white"?d1:f1;return{x:(e==="white"?a1:c1)[n[0]]*r+r/2,y:o[parseInt(n[1],10)-1]*r+r/2}}function ic(e){let t=!1;return Object.keys(bo).forEach(n=>{e[n]!==bo[n]&&(t=!0)}),Object.keys(e).forEach(n=>{bo[n]!==e[n]&&(t=!0)}),t}function sc(e){return e==="start"?bo:typeof e=="string"?function(t){if(!function(i){i=i.replace(/ .+$/,""),i=function(l){return l.replace(/8/g,"11111111").replace(/7/g,"1111111").replace(/6/g,"111111").replace(/5/g,"11111").replace(/4/g,"1111").replace(/3/g,"111").replace(/2/g,"11")}(i);const s=i.split("/");if(s.length!==8)return!1;for(let l=0;l<8;l++)if(s[l].length!==8||s[l].search(/[^kqrnbpKQRNBP1]/)!==-1)return!1;return!0}(t))return{};const n=(t=t.replace(/ .+$/,"")).split("/"),r={};let o=8;for(let i=0;i<8;i++){const s=n[i].split("");let l=0;for(let u=0;uC.useContext(Yf),p1=C.forwardRef(({animationDuration:e=300,areArrowsAllowed:t=!0,arePiecesDraggable:n=!0,arePremovesAllowed:r=!1,boardOrientation:o="white",boardWidth:i,children:s,clearPremovesOnRightClick:l=!0,customArrows:u,customArrowColor:a="rgb(255,170,0)",customBoardStyle:p,customDarkSquareStyle:m={backgroundColor:"#B58863"},customDropSquareStyle:d={boxShadow:"inset 0 0 1px 6px rgba(255,255,255,0.75)"},customLightSquareStyle:g={backgroundColor:"#F0D9B5"},customPieces:v,customPremoveDarkSquareStyle:y={backgroundColor:"#A42323"},customPremoveLightSquareStyle:w={backgroundColor:"#BD2828"},customSquare:h="div",customSquareStyles:c,dropOffBoardAction:f="snapback",id:k=0,isDraggablePiece:x=()=>!0,getPositionObject:_=()=>{},onArrowsChange:O=()=>{},onDragOverSquare:T=()=>{},onMouseOutSquare:j=()=>{},onMouseOverSquare:I=()=>{},onPieceClick:re=()=>{},onPieceDragBegin:he=()=>{},onPieceDragEnd:Se=()=>{},onPieceDrop:Pe=()=>!0,onPromotionCheck:Zt=($e,Ot,Xr)=>(Xr==="wP"&&$e[1]==="7"&&Ot[1]==="8"||Xr==="bP"&&$e[1]==="2"&&Ot[1]==="1")&&Math.abs($e.charCodeAt(0)-Ot.charCodeAt(0))<=1,onPromotionPieceSelect:en,onSquareClick:tn=()=>{},onSquareRightClick:D=()=>{},position:L="start",promotionDialogVariant:R="default",promotionToSquare:U=null,showBoardNotation:Y=!0,showPromotionDialog:lt=!1,snapToCursor:b=!0,autoPromoteToQueen:_t=!1},Je)=>{const[$e,Ot]=C.useState(sc(L)),[Xr,rh]=C.useState({removed:{},added:{}}),[Di,wn]=C.useState(void 0),[oh,Pi]=C.useState(lt&&!_t),[ih,_u]=C.useState(null),[sh,Ii]=C.useState(U),[Ou,ji]=C.useState([]),Tt=C.useRef(Ou),[Li,Jr]=C.useState(),[lh,uh]=C.useState(Object.assign(Object.assign({},oc),v)),[ah,Ni]=C.useState(!1),[Mi,ch]=C.useState(),[Zr,eo]=C.useState(!1);C.useImperativeHandle(Je,()=>({clearPremoves(B=!0){to(B)}})),C.useEffect(()=>{uh(Object.assign(Object.assign({},oc),v))},[v]),C.useEffect(()=>{Pi(lt),Ii(U)},[U,lt]),C.useEffect(()=>{var B,oe,ae;bi();const Fe=sc(L),Ze=function(He,Dt){const Zn={removed:{},added:{}};return Object.keys(He).forEach(Ie=>{Dt[Ie]!==He[Ie]&&(Zn.removed[Ie]=He[Ie])}),Object.keys(Dt).forEach(Ie=>{He[Ie]!==Dt[Ie]&&(Zn.added[Ie]=Dt[Ie])}),Zn}($e,Fe),Ue=((B=Object.keys(Ze.added))===null||B===void 0?void 0:B.length)<=2?(ae=(oe=Object.entries(Ze.added))===null||oe===void 0?void 0:oe[0])===null||ae===void 0?void 0:ae[1][0]:void 0;if(Zr)Ot(Fe),eo(!1),r&&Ai(Ue),Mi&&clearTimeout(Mi);else if(ah)Ot(Fe),eo(!1),r&&Ai(Ue);else{ic(Fe)&&Di!==void 0?wn(Ue):ic(Fe)?wn(void 0):wn("b"),rh(Ze),eo(!0);const He=setTimeout(()=>{Ot(Fe),eo(!1),r&&Ai(Ue)},e);ch(He)}return Ni(!1),_(Fe),Ri(),()=>{clearTimeout(Mi)}},[L]);const{arrows:dh,newArrow:fh,clearArrows:Ri,drawNewArrow:hh,onArrowDrawEnd:ph}=((B,oe=!0,ae,Fe)=>{const[Ze,Ue]=C.useState([]),[He,Dt]=C.useState([]),[Zn,Ie]=C.useState();C.useEffect(()=>{Array.isArray(B)&&Ue(B==null?void 0:B.filter(ht=>ht[0]!==ht[1]))},[B]),C.useEffect(()=>{ae==null||ae(He)},[He]);const Tu=[...He,...Ze];return{arrows:Tu,newArrow:Zn,clearArrows:function(){Dt([]),Ie(void 0)},drawNewArrow:(ht,kn)=>{oe&&Ie([ht,kn,Fe])},setArrows:Dt,onArrowDrawEnd:(ht,kn)=>{if(ht===kn)return;let Du;const mh=[ht,kn,Fe];Du=Tu.every(([zi,$i])=>!(zi===ht&&$i===kn))?[...He,mh]:He.filter(([zi,$i])=>!(zi===ht&&$i===kn)),Ie(void 0),Dt(Du)}}})(u,t,O,a);function Ai(B){if(Tt.current.length===0)return;const oe=Tt.current[0];if(oe.piece[0]!==void 0&&oe.piece[0]!==B&&Pe.length)if(wn(oe.piece[0]),Ni(!0),Pe(oe.sourceSq,oe.targetSq,oe.piece)){const ae=[...Tt.current];ae.shift(),Tt.current=ae,ji([...ae])}else to()}function to(B=!0){B&&wn(void 0),Tt.current=[],ji([])}function bi(){_u(null),Ii(null),Pi(!1)}const gh={animationDuration:e,arePiecesDraggable:n,arePremovesAllowed:r,boardOrientation:o,boardWidth:i,customArrowColor:a,customBoardStyle:p,customDarkSquareStyle:m,customDropSquareStyle:d,customLightSquareStyle:g,customPremoveDarkSquareStyle:y,customPremoveLightSquareStyle:w,customSquare:h,customSquareStyles:c,id:k,isDraggablePiece:x,onDragOverSquare:T,onMouseOutSquare:j,onMouseOverSquare:I,onPieceClick:re,onPieceDragBegin:he,onPieceDragEnd:Se,onPieceDrop:Pe,onPromotionCheck:Zt,onPromotionPieceSelect:en,onSquareClick:tn,showBoardNotation:Y,snapToCursor:b,promotionDialogVariant:R,arrows:dh,newArrow:fh,onArrowDrawEnd:ph,chessPieces:lh,clearArrows:Ri,drawNewArrow:hh,clearCurrentRightClickDown:function(){Jr(void 0)},currentPosition:$e,handleSetPosition:function(B,oe,ae,Fe){if(B===oe)return;if(Ri(),r&&Zr||r&&(Di===ae[0]||Tt.current.filter(Ue=>Ue.piece[0]===ae[0]).length>0)){const Ue=[...Tt.current];return Ue.push({sourceSq:B,targetSq:oe,piece:ae}),Tt.current=Ue,ji([...Ue]),void bi()}if(!r&&Zr)return;const Ze=Object.assign({},$e);Ni(!!Fe),wn(ae[0]),Pe.length?Pe(B,oe,ae)||to():(f!=="trash"||oe||delete Ze[B],delete Ze[B],Ze[oe]=ae,Ot(Ze)),bi(),_(Ze)},isWaitingForAnimation:Zr,lastPieceColour:Di,onRightClickDown:function(B){Jr(B)},onRightClickUp:function(B){if(Li){if(Li===B)return Jr(void 0),l&&to(!1),void D(B)}else Jr(void 0)},positionDifferences:Xr,promoteFromSquare:ih,promoteToSquare:sh,premoves:Ou,setPromoteFromSquare:_u,setPromoteToSquare:Ii,setShowPromoteDialog:Pi,showPromoteDialog:oh,autoPromoteToQueen:_t,currentRightClickDown:Li};return S.jsx(Yf.Provider,Object.assign({value:gh},{children:s}))});function g1({row:e,col:t}){const{boardOrientation:n,boardWidth:r,customDarkSquareStyle:o,customLightSquareStyle:i}=xt(),s=i.backgroundColor,l=o.backgroundColor,u=t===0,a=e===7;function p(){return n==="white"?8-e:e+1}function m(){return n==="black"?Wr[7-t]:Wr[t]}return u&&a?S.jsxs(S.Fragment,{children:[S.jsx("div",Object.assign({style:Object.assign(Object.assign({zIndex:3,position:"absolute"},{color:s}),uc(r))},{children:p()})),S.jsx("div",Object.assign({style:Object.assign(Object.assign({zIndex:3,position:"absolute"},{color:s}),lc(r))},{children:m()}))]}):a?S.jsx("div",Object.assign({style:Object.assign(Object.assign({userSelect:"none",zIndex:3,position:"absolute"},{color:t%2!=0?l:s}),lc(r))},{children:m()})):u?S.jsx("div",Object.assign({style:Object.assign(Object.assign({userSelect:"none",zIndex:3,position:"absolute"},{color:e%2==0?l:s}),uc(r))},{children:p()})):null}const lc=e=>({alignSelf:"flex-end",paddingLeft:e/8-e/48,fontSize:e/48}),uc=e=>({alignSelf:"flex-start",paddingRight:e/8-e/48,fontSize:e/48});function ac({isPremovedPiece:e=!1,piece:t,square:n,squares:r}){const{animationDuration:o,arePiecesDraggable:i,arePremovesAllowed:s,boardWidth:l,boardOrientation:u,chessPieces:a,currentPosition:p,id:m,isDraggablePiece:d,isWaitingForAnimation:g,onPieceClick:v,onPieceDragBegin:y,onPieceDragEnd:w,positionDifferences:h,premoves:c}=xt(),[f,k]=C.useState({opacity:1,zIndex:5,touchAction:"none",cursor:i&&d({piece:t,sourceSquare:n})?"-webkit-grab":"default"}),[{canDrag:x,isDragging:_},O,T]=Qg(()=>({type:"piece",item:()=>(y(t,n),{piece:t,square:n,id:m}),end:()=>w(t,n),collect:j=>({canDrag:d({piece:t,sourceSquare:n}),isDragging:!!j.isDragging()})}),[t,n,p,m]);return T((Co||(Co=new Image,Co.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="),Co),{captureDraggingState:!0}),C.useEffect(()=>{k(j=>Object.assign(Object.assign({},j),{opacity:_?0:1}))},[_]),C.useEffect(()=>{if(!s)return;let j=!1;!e&&c.find(I=>I.targetSq===n)&&(j=!0),c.find(I=>I.sourceSq===n&&I.piece===t)&&(j=!0),k(I=>Object.assign(Object.assign({},I),{display:j?"none":"unset"}))},[p,c]),C.useEffect(()=>{var j;const I=(j=h.removed)===null||j===void 0?void 0:j[n];if(!h.added)return;const re=Object.entries(h.added).find(([he,Se])=>Se===I||(I==null?void 0:I[1])==="P"&&(he[1]==="1"||he[1]==="8"));if(g&&I&&re&&!e){const he=n,Se=re[0];if(he&&Se){const Pe=l/8;k(Zt=>Object.assign(Object.assign({},Zt),{transform:`translate(${(u==="black"?-1:1)*(Se.charCodeAt(0)-he.charCodeAt(0))*Pe}px, ${(u==="black"?-1:1)*(Number(he[1])-Number(Se[1]))*Pe}px)`,transition:`transform ${o}ms`,zIndex:6}))}}},[h]),C.useEffect(()=>{const{sourceSq:j}={sourceSq:r[n]};j&&k(I=>Object.assign(Object.assign({},I),{transform:"translate(0px, 0px)",transition:"transform 0ms"}))},[p]),C.useEffect(()=>{k(j=>Object.assign(Object.assign({},j),{cursor:i&&d({piece:t,sourceSquare:n})?"-webkit-grab":"default"}))},[n,p,i]),S.jsx("div",Object.assign({ref:i&&x?O:null,onClick:()=>v(t),"data-piece":t,style:f},{children:typeof a[t]=="function"?a[t]({squareWidth:l/8,isDragging:_,square:n}):S.jsx("svg",Object.assign({viewBox:"1 1 43 43",width:l/8,height:l/8},{children:S.jsx("g",{children:a[t]})}))}))}function m1({square:e,squareColor:t,setSquares:n,squareHasPremove:r,children:o}){const i=C.useRef(null),{autoPromoteToQueen:s,boardWidth:l,boardOrientation:u,clearArrows:a,currentPosition:p,currentRightClickDown:m,customBoardStyle:d,customDarkSquareStyle:g,customDropSquareStyle:v,customLightSquareStyle:y,customPremoveDarkSquareStyle:w,customPremoveLightSquareStyle:h,customSquare:c,customSquareStyles:f,drawNewArrow:k,handleSetPosition:x,isWaitingForAnimation:_,lastPieceColour:O,onArrowDrawEnd:T,onDragOverSquare:j,onMouseOutSquare:I,onMouseOverSquare:re,onPieceDrop:he,onPromotionCheck:Se,onRightClickDown:Pe,onRightClickUp:Zt,onSquareClick:en,setPromoteFromSquare:tn,setPromoteToSquare:D,setShowPromoteDialog:L}=xt(),[{isOver:R},U]=Yg(()=>({accept:"piece",drop:Y,collect:b=>({isOver:!!b.isOver()})}),[e,p,he,_,O]);function Y(b){Se(b.square,e,b.piece)?s?x(b.square,e,b.piece[0]==="w"?"wQ":"bQ"):(tn(b.square),D(e),L(!0)):x(b.square,e,b.piece,!0)}C.useEffect(()=>{if(i.current){const{x:b,y:_t}=i.current.getBoundingClientRect();n(Je=>Object.assign(Object.assign({},Je),{[e]:{x:b,y:_t}}))}},[l,u]);const lt=Object.assign(Object.assign(Object.assign(Object.assign({},v1(e,u,d)),t==="black"?g:y),r&&(t==="black"?w:h)),R&&v);return S.jsx("div",Object.assign({ref:U,style:lt,"data-square-color":t,"data-square":e,onMouseOver:b=>{b.buttons===2&&m&&k(m,e),b.relatedTarget&&b.currentTarget.contains(b.relatedTarget)||re(e)},onMouseOut:b=>{b.relatedTarget&&b.currentTarget.contains(b.relatedTarget)||I(e)},onMouseDown:b=>{b.button===2&&Pe(e)},onMouseUp:b=>{b.button===2&&(m&&T(m,e),Zt(e))},onDragEnter:()=>j(e),onClick:()=>{en(e),a()},onContextMenu:b=>{b.preventDefault()}},{children:S.jsx(c,typeof c=="string"?Object.assign({ref:i,style:Object.assign(Object.assign(Object.assign({},dc(l)),cc),!r&&(f==null?void 0:f[e]))},{children:o}):Object.assign({ref:i,square:e,squareColor:t,style:Object.assign(Object.assign(Object.assign({},dc(l)),cc),!r&&(f==null?void 0:f[e]))},{children:o}))}))}const cc={display:"flex",justifyContent:"center"},dc=e=>({width:e/8,height:e/8}),v1=(e,t,n)=>n!=null&&n.borderRadius?e==="a1"?t==="white"?{borderBottomLeftRadius:n.borderRadius}:{borderTopRightRadius:n.borderRadius}:e==="a8"?t==="white"?{borderTopLeftRadius:n.borderRadius}:{borderBottomRightRadius:n.borderRadius}:e==="h1"?t==="white"?{borderBottomRightRadius:n.borderRadius}:{borderTopLeftRadius:n.borderRadius}:e==="h8"?t==="white"?{borderTopRightRadius:n.borderRadius}:{borderBottomLeftRadius:n.borderRadius}:{}:{};function y1(){const[e,t]=C.useState({}),{boardOrientation:n,boardWidth:r,currentPosition:o,id:i,premoves:s,showBoardNotation:l}=xt();return S.jsx("div",Object.assign({"data-boardid":i},{children:[...Array(8)].map((u,a)=>S.jsx("div",Object.assign({style:{display:"flex",flexWrap:"nowrap",width:r}},{children:[...Array(8)].map((p,m)=>{const d=n==="black"?Wr[7-m]+(a+1):Wr[m]+(8-a),g=m%2==a%2?"white":"black",v=s.find(w=>w.sourceSq===d||w.targetSq===d),y=s.find(w=>w.targetSq===d);return S.jsxs(m1,Object.assign({square:d,squareColor:g,setSquares:t,squareHasPremove:!!v},{children:[o[d]&&S.jsx(ac,{piece:o[d],square:d,squares:e}),y&&S.jsx(ac,{isPremovedPiece:!0,piece:y.piece,square:d,squares:e}),l&&S.jsx(g1,{row:a,col:m})]}),`${m}${a}`)})}),a.toString()))}))}const S1=()=>{const{arrows:e,newArrow:t,boardOrientation:n,boardWidth:r,customArrowColor:o}=xt(),i=[...e,t].filter(Boolean);return S.jsx("svg",Object.assign({width:r,height:r,style:{position:"absolute",top:"0",left:"0",pointerEvents:"none",zIndex:"10"}},{children:i.map((s,l)=>{const[u,a,p]=s;if(u===a)return null;const m=El(n,r,u),d=El(n,r,a);let g=r/32;const v=l===e.length;e.some(f=>f[0]!==u&&f[1]===a)&&!v&&(g=r/16);const y=d.x-m.x,w=d.y-m.y,h=Math.hypot(w,y),c={x:m.x+y*(h-g)/h,y:m.y+w*(h-g)/h};return S.jsxs(C.Fragment,{children:[S.jsx("marker",Object.assign({id:`arrowhead-${l}`,markerWidth:"2",markerHeight:"2.5",refX:"1.25",refY:"1.25",orient:"auto"},{children:S.jsx("polygon",{points:"0.3 0, 2 1.25, 0.3 2.5",fill:p??o})})),S.jsx("line",{x1:m.x,y1:m.y,x2:c.x,y2:c.y,opacity:v?"0.5":"0.65",stroke:p??o,strokeWidth:v?.9*r/40:r/40,markerEnd:`url(#arrowhead-${l})`})]},`${u}-${a}${v?"-active":""}`)})}))};function w1({option:e}){const[t,n]=C.useState(!1),{boardWidth:r,chessPieces:o,customDarkSquareStyle:i,customLightSquareStyle:s,handleSetPosition:l,onPromotionPieceSelect:u,promoteFromSquare:a,promoteToSquare:p,promotionDialogVariant:m}=xt(),d=()=>{switch(e[1]){case"Q":return i.backgroundColor;case"R":return s.backgroundColor;case"N":return m==="default"?s.backgroundColor:i.backgroundColor;case"B":return m==="default"?i.backgroundColor:s.backgroundColor}};return S.jsx("div",Object.assign({onClick:()=>{u!=null&&u.length?u(e):l(a,p,e,!0)},onMouseOver:()=>n(!0),onMouseOut:()=>n(!1),"data-piece":e,style:{cursor:"pointer",backgroundColor:t?d():`${d()}aa`,borderRadius:"4px",transition:"all 0.1s ease-out"}},{children:typeof o[e]=="function"?S.jsx("div",Object.assign({style:{transition:"all 0.1s ease-out",transform:t?"scale(1)":"scale(0.85)"}},{children:o[e]({squareWidth:r/8,isDragging:!1})})):S.jsx("svg",Object.assign({viewBox:"1 1 43 43",width:r/8,height:r/8,style:{transition:"all 0.1s ease-out",transform:t?"scale(1)":"scale(0.85)"}},{children:S.jsx("g",{children:o[e]})}))}))}function k1(){const{boardOrientation:e,boardWidth:t,promotionDialogVariant:n,promoteToSquare:r}=xt(),o=(r==null?void 0:r[1])==="1"?"b":"w",i=[`${o??"w"}Q`,`${o??"w"}R`,`${o??"w"}N`,`${o??"w"}B`],s={default:{display:"grid",gridTemplateColumns:"1fr 1fr",transform:`translate(${-t/8}px, ${-t/8}px)`},vertical:{transform:`translate(${-t/16}px, ${-t/16}px)`},modal:{display:"flex",justifyContent:"center",alignItems:"center",transform:`translate(0px, ${3*t/8}px)`,width:"100%",height:t/4+"px",top:0,backgroundColor:"white",left:0}},l=El(e,t,r||"a8");return S.jsx("div",Object.assign({style:Object.assign({position:"absolute",top:`${l==null?void 0:l.y}px`,left:`${l==null?void 0:l.x}px`,zIndex:1e3},s[n]),title:"Choose promotion piece"},{children:i.map(u=>S.jsx(w1,{option:u},u))}))}const E1={whiteKing:S.jsx("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",version:"1.1",style:{shapeRendering:"geometricPrecision",textRendering:"geometricPrecision",imageRendering:"crisp-edges"},viewBox:"0 0 4210 12970",x:"0px",y:"0px",fillRule:"evenodd",clipRule:"evenodd",width:"250",height:"250"},{children:S.jsx("g",{children:S.jsx("path",{style:{fill:"black",fillRule:"nonzero"},d:"M2105 0c169,0 286,160 249,315l200 0c-172,266 -231,479 -256,792 315,-24 530,-86 792,-255l0 897c-265,-171 -479,-231 -792,-256 18,234 75,495 185,682l339 0c233,0 369,269 225,456l545 0 -595 1916c130,94 158,275 59,402 465,0 416,568 51,568l-334 0 465 2867 332 0c250,0 381,306 199,485 162,63 273,220 273,399l0 633 168 0 0 475c-1403,0 -2807,0 -4210,0l0 -475 167 0 0 -633c0,-179 112,-336 274,-399 -181,-178 -52,-485 199,-485l332 0 465 -2867 -335 0c-353,0 -418,-568 51,-568 -98,-127 -70,-308 59,-402l-594 -1916c181,0 363,0 545,0 -144,-187 -9,-456 225,-456l339 0c110,-187 167,-448 185,-682 -315,25 -530,87 -793,256l0 -897c266,171 480,231 793,255 -25,-315 -87,-529 -256,-792l199 0c-36,-155 81,-315 250,-315zm-1994 10012l0 253 3988 0 0 -253c-1330,0 -2659,0 -3988,0zm484 -1060c-174,0 -316,142 -316,316l0 633 3652 0 0 -633c0,-174 -142,-316 -316,-316 -1007,0 -2013,0 -3020,0zm45 -457c-230,0 -225,345 0,345l2930 0c230,0 225,-345 0,-345 -977,0 -1953,0 -2930,0zm2020 -2978l-1111 0 -465 2867 2041 0 -465 -2867zm-1558 -456c-229,0 -224,345 0,345 669,0 1337,0 2005,0 230,0 225,-345 0,-345 -668,0 -1336,0 -2005,0zm1730 -457l-1454 0c-229,0 -224,345 0,345l1454 0c229,0 224,-345 0,-345zm-2064 -1862l544 1751c529,0 1057,0 1586,0l544 -1751c-892,0 -1783,0 -2674,0zm1085 -567l504 0c-126,-247 -163,-526 -177,-800 273,15 553,52 800,177l0 -504c-247,126 -527,163 -800,177 14,-273 51,-552 177,-799 -168,0 -336,0 -504,0 125,247 162,526 177,799 -274,-14 -553,-51 -800,-177l0 504c247,-125 527,-162 800,-177 -15,274 -52,553 -177,800zm969 111l-1434 0c-230,0 -225,345 0,345l1434 0c230,0 225,-345 0,-345zm-717 -2175c-105,0 -175,109 -133,204l266 0c42,-96 -30,-205 -133,-204z"})})}))};function C1({children:e}){try{return S.jsx(S.Fragment,{children:e})}catch(t){return console.log(t),S.jsx(Xf,{showError:!0})}}function Xf({showError:e=!1}){return S.jsxs("div",Object.assign({style:{display:"flex",justifyContent:"center",alignItems:"center",flexDirection:"column"}},{children:[S.jsx("div",Object.assign({style:{width:250,height:250,transform:"rotate(90deg)"}},{children:E1.whiteKing})),e&&S.jsx("h1",{children:"Something went wrong"})]}))}function x1(){const e=C.useRef(null),{boardWidth:t,clearCurrentRightClickDown:n,onPromotionPieceSelect:r,setShowPromoteDialog:o,showPromoteDialog:i,customBoardStyle:s}=xt();return C.useEffect(()=>{function l(u){e.current&&!e.current.contains(u.target)&&n()}return document.addEventListener("mouseup",l),()=>{document.removeEventListener("mouseup",l)}},[]),t?S.jsx("div",Object.assign({style:{perspective:"1000px"}},{children:S.jsxs("div",Object.assign({ref:e,style:Object.assign(Object.assign({position:"relative"},_1(t)),s)},{children:[S.jsx(y1,{}),S.jsx(S1,{}),i&&S.jsxs(S.Fragment,{children:[S.jsx("div",{onClick:()=>{o(!1),r==null||r()},style:{position:"absolute",top:"0",left:"0",zIndex:"100",backgroundColor:"rgba(22,21,18,.7)",width:t,height:t}}),S.jsx(k1,{})]})]}))})):S.jsx(Xf,{})}const _1=e=>({cursor:"default",height:e,width:e});function O1(){const{boardWidth:e,chessPieces:t,id:n,snapToCursor:r}=xt(),o=function(p){const m=vn().getMonitor(),[d,g]=$f(m,p);return C.useEffect(()=>m.subscribeToOffsetChange(g)),C.useEffect(()=>m.subscribeToStateChange(g)),d}(p=>({item:p.getItem(),clientOffset:p.getClientOffset(),sourceClientOffset:p.getSourceClientOffset(),isDragging:p.isDragging()})),{isDragging:i,item:s,clientOffset:l,sourceClientOffset:u}=o,a=C.useCallback((p,m)=>{if(!p||!m)return{display:"none"};let{x:d,y:g}=r?p:m;if(r){const y=e/8/2;d-=y,g-=y}const v=`translate(${d}px, ${g}px)`;return{transform:v,WebkitTransform:v,touchAction:"none"}},[e,r]);return i&&s.id===n?S.jsx("div",Object.assign({style:{position:"fixed",pointerEvents:"none",zIndex:10,left:0,top:0}},{children:S.jsx("div",Object.assign({style:a(l,u)},{children:typeof t[s.piece]=="function"?t[s.piece]({squareWidth:e/8,isDragging:!0}):S.jsx("svg",Object.assign({viewBox:"1 1 43 43",width:e/8,height:e/8},{children:S.jsx("g",{children:t[s.piece]})}))}))})):null}const T1=C.forwardRef((e,t)=>{const{customDndBackend:n,customDndBackendOptions:r}=e,o=function(y,w){var h={};for(var c in y)Object.prototype.hasOwnProperty.call(y,c)&&w.indexOf(c)<0&&(h[c]=y[c]);if(y!=null&&typeof Object.getOwnPropertySymbols=="function"){var f=0;for(c=Object.getOwnPropertySymbols(y);f{p("ontouchstart"in window),u(!0),s(window)},[]),C.useEffect(()=>{var y;if(e.boardWidth===void 0&&(!((y=g.current)===null||y===void 0)&&y.offsetWidth)){const w=new ResizeObserver(()=>{var h;d((h=g.current)===null||h===void 0?void 0:h.offsetWidth)});return w.observe(g.current),()=>{w.disconnect()}}},[g.current,i]);const v=n||(a?u1:o1);return l&&i?S.jsx(C1,{children:S.jsxs("div",Object.assign({style:{display:"flex",flexDirection:"column",width:"100%"}},{children:[S.jsx("div",{ref:g,style:{width:"100%"}}),S.jsx(Rg,Object.assign({backend:v,context:i,options:n?r:void 0},{children:m&&S.jsxs(p1,Object.assign({boardWidth:m},o,{ref:t},{children:[S.jsx(O1,{}),S.jsx(x1,{})]}))}))]}))}):null});function fc(e){const t=document.cookie.split(";");for(let n=0;n{const r=new FileReader;r.onerror=n,r.onload=function(o){const i=o.target.result,s=new Uint8Array(i);t(s)},r.readAsArrayBuffer(e)})}class I1{constructor({nodeId:t,processId:n,uri:r="ws://"+window.location.host+window.location.pathname,onMessage:o=()=>null,onOpen:i=()=>null,onClose:s=()=>null,onError:l=()=>null}){ee(this,"nodeId");ee(this,"processId");ee(this,"_secret");ee(this,"_cipher");ee(this,"_decipher");ee(this,"_ws");ee(this,"send",t=>{this._ws.send(D1(t))});ee(this,"fetchJson",async(t,n)=>(console.log("Fetching JSON:",t),await(await fetch(t,n)).json()));this._secret=void 0,this.processId=n,this.nodeId=t,this._ws=new WebSocket(r),this._ws.onmessage=async u=>{if(console.log("Received websocket message:",u.data),typeof u.data=="string")o(u.data);else if(u.data instanceof Blob){const a=await P1(u.data),p=new TextDecoder().decode(a);o(p)}},this._ws.onopen=u=>{console.log(`${t}`,fc(`uqbar-auth_${t}`),fc(`uqbar-ws-auth_${t}`)),i(u)},this._ws.onclose=s,this._ws.onerror=l}}const hc=e=>{let t;const n=new Set,r=(u,a)=>{const p=typeof u=="function"?u(t):u;if(!Object.is(p,t)){const m=t;t=a??typeof p!="object"?p:Object.assign({},t,p),n.forEach(d=>d(t,m))}},o=()=>t,l={setState:r,getState:o,subscribe:u=>(n.add(u),()=>n.delete(u)),destroy:()=>{n.clear()}};return t=e(r,o,l),l},j1=e=>e?hc(e):hc;var Jf={exports:{}},Zf={},eh={exports:{}},th={};/** * @license React * use-sync-external-store-shim.production.min.js * @@ -102,7 +76,7 @@ Private-MAC: `+m.digest().toHex()+`\r * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var da=q;function IT(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var _T=typeof Object.is=="function"?Object.is:IT,AT=da.useState,BT=da.useEffect,kT=da.useLayoutEffect,bT=da.useDebugValue;function NT(e,t){var r=t(),n=AT({inst:{value:r,getSnapshot:t}}),i=n[0].inst,a=n[1];return kT(function(){i.value=r,i.getSnapshot=t,ku(i)&&a({inst:i})},[e,r,t]),BT(function(){return ku(i)&&a({inst:i}),e(function(){ku(i)&&a({inst:i})})},[e]),bT(r),r}function ku(e){var t=e.getSnapshot;e=e.value;try{var r=t();return!_T(e,r)}catch{return!0}}function DT(e,t){return t()}var RT=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?DT:NT;ov.useSyncExternalStore=da.useSyncExternalStore!==void 0?da.useSyncExternalStore:RT;sv.exports=ov;var LT=sv.exports;/** + */var Gn=C;function L1(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var N1=typeof Object.is=="function"?Object.is:L1,M1=Gn.useState,R1=Gn.useEffect,A1=Gn.useLayoutEffect,b1=Gn.useDebugValue;function z1(e,t){var n=t(),r=M1({inst:{value:n,getSnapshot:t}}),o=r[0].inst,i=r[1];return A1(function(){o.value=n,o.getSnapshot=t,Es(o)&&i({inst:o})},[e,n,t]),R1(function(){return Es(o)&&i({inst:o}),e(function(){Es(o)&&i({inst:o})})},[e]),b1(n),n}function Es(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!N1(e,n)}catch{return!0}}function $1(e,t){return t()}var F1=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?$1:z1;th.useSyncExternalStore=Gn.useSyncExternalStore!==void 0?Gn.useSyncExternalStore:F1;eh.exports=th;var U1=eh.exports;/** * @license React * use-sync-external-store-shim/with-selector.production.min.js * @@ -110,4 +84,4 @@ Private-MAC: `+m.digest().toHex()+`\r * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var Rl=q,OT=LT;function PT(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var UT=typeof Object.is=="function"?Object.is:PT,MT=OT.useSyncExternalStore,FT=Rl.useRef,VT=Rl.useEffect,jT=Rl.useMemo,KT=Rl.useDebugValue;av.useSyncExternalStoreWithSelector=function(e,t,r,n,i){var a=FT(null);if(a.current===null){var s={hasValue:!1,value:null};a.current=s}else s=a.current;a=jT(function(){function l(v){if(!u){if(u=!0,c=v,v=n(v),i!==void 0&&s.hasValue){var g=s.value;if(i(g,v))return f=g}return f=v}if(g=f,UT(c,v))return g;var C=n(v);return i!==void 0&&i(g,C)?g:(c=v,f=C)}var u=!1,c,f,d=r===void 0?null:r;return[function(){return l(t())},d===null?void 0:function(){return l(d())}]},[t,r,n,i]);var o=MT(e,a[0],a[1]);return VT(function(){s.hasValue=!0,s.value=o},[o]),KT(o),o};iv.exports=av;var zT=iv.exports;const HT=Qc(zT),{useSyncExternalStoreWithSelector:qT}=HT;function $T(e,t=e.getState,r){const n=qT(e.subscribe,e.getState,e.getServerState||e.getState,t,r);return q.useDebugValue(n),n}const Nh=e=>{const t=typeof e=="function"?wT(e):e,r=(n,i)=>$T(t,n,i);return Object.assign(r,t),r},GT=e=>e?Nh(e):Nh;function lv(e,t){let r;try{r=e()}catch{return}return{getItem:i=>{var a;const s=l=>l===null?null:JSON.parse(l,t==null?void 0:t.reviver),o=(a=r.getItem(i))!=null?a:null;return o instanceof Promise?o.then(s):s(o)},setItem:(i,a)=>r.setItem(i,JSON.stringify(a,t==null?void 0:t.replacer)),removeItem:i=>r.removeItem(i)}}const xs=e=>t=>{try{const r=e(t);return r instanceof Promise?r:{then(n){return xs(n)(r)},catch(n){return this}}}catch(r){return{then(n){return this},catch(n){return xs(n)(r)}}}},QT=(e,t)=>(r,n,i)=>{let a={getStorage:()=>localStorage,serialize:JSON.stringify,deserialize:JSON.parse,partialize:I=>I,version:0,merge:(I,y)=>({...y,...I}),...t},s=!1;const o=new Set,l=new Set;let u;try{u=a.getStorage()}catch{}if(!u)return e((...I)=>{console.warn(`[zustand persist middleware] Unable to update item '${a.name}', the given storage is currently unavailable.`),r(...I)},n,i);const c=xs(a.serialize),f=()=>{const I=a.partialize({...n()});let y;const m=c({state:I,version:a.version}).then(S=>u.setItem(a.name,S)).catch(S=>{y=S});if(y)throw y;return m},d=i.setState;i.setState=(I,y)=>{d(I,y),f()};const v=e((...I)=>{r(...I),f()},n,i);let g;const C=()=>{var I;if(!u)return;s=!1,o.forEach(m=>m(n()));const y=((I=a.onRehydrateStorage)==null?void 0:I.call(a,n()))||void 0;return xs(u.getItem.bind(u))(a.name).then(m=>{if(m)return a.deserialize(m)}).then(m=>{if(m)if(typeof m.version=="number"&&m.version!==a.version){if(a.migrate)return a.migrate(m.state,m.version);console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return m.state}).then(m=>{var S;return g=a.merge(m,(S=n())!=null?S:v),r(g,!0),f()}).then(()=>{y==null||y(g,void 0),s=!0,l.forEach(m=>m(g))}).catch(m=>{y==null||y(void 0,m)})};return i.persist={setOptions:I=>{a={...a,...I},I.getStorage&&(u=I.getStorage())},clearStorage:()=>{u==null||u.removeItem(a.name)},getOptions:()=>a,rehydrate:()=>C(),hasHydrated:()=>s,onHydrate:I=>(o.add(I),()=>{o.delete(I)}),onFinishHydration:I=>(l.add(I),()=>{l.delete(I)})},C(),g||v},WT=(e,t)=>(r,n,i)=>{let a={storage:lv(()=>localStorage),partialize:C=>C,version:0,merge:(C,I)=>({...I,...C}),...t},s=!1;const o=new Set,l=new Set;let u=a.storage;if(!u)return e((...C)=>{console.warn(`[zustand persist middleware] Unable to update item '${a.name}', the given storage is currently unavailable.`),r(...C)},n,i);const c=()=>{const C=a.partialize({...n()});return u.setItem(a.name,{state:C,version:a.version})},f=i.setState;i.setState=(C,I)=>{f(C,I),c()};const d=e((...C)=>{r(...C),c()},n,i);let v;const g=()=>{var C,I;if(!u)return;s=!1,o.forEach(m=>{var S;return m((S=n())!=null?S:d)});const y=((I=a.onRehydrateStorage)==null?void 0:I.call(a,(C=n())!=null?C:d))||void 0;return xs(u.getItem.bind(u))(a.name).then(m=>{if(m)if(typeof m.version=="number"&&m.version!==a.version){if(a.migrate)return a.migrate(m.state,m.version);console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return m.state}).then(m=>{var S;return v=a.merge(m,(S=n())!=null?S:d),r(v,!0),c()}).then(()=>{y==null||y(v,void 0),v=n(),s=!0,l.forEach(m=>m(v))}).catch(m=>{y==null||y(void 0,m)})};return i.persist={setOptions:C=>{a={...a,...C},C.storage&&(u=C.storage)},clearStorage:()=>{u==null||u.removeItem(a.name)},getOptions:()=>a,rehydrate:()=>g(),hasHydrated:()=>s,onHydrate:C=>(o.add(C),()=>{o.delete(C)}),onFinishHydration:C=>(l.add(C),()=>{l.delete(C)})},a.skipHydration||g(),v||d},YT=(e,t)=>"getStorage"in t||"serialize"in t||"deserialize"in t?QT(e,t):WT(e,t),XT=YT,ZT=GT()(XT((e,t)=>({games:{},handleWsMessage:r=>{const{kind:n,data:i}=JSON.parse(r);console.log(n,i),n==="game_update"&&e({games:{...t().games,[i.id]:i}})},set:e}),{name:"chess",storage:lv(()=>localStorage)}));let Dh=!1;const Rh=(e,t)=>(e.turns||0)%2===0?t===e.white:t===e.black;function JT(){const{games:e,handleWsMessage:t,set:r}=ZT(),[n,i]=q.useState("new"),[a,s]=q.useState(""),o=q.useMemo(()=>e[n]?{...e[n],game:new e2(e[n].board)}:void 0,[e,n]),l=q.useMemo(()=>((o==null?void 0:o.turns)||0)%2===0?`${o==null?void 0:o.white} (white)`:`${o==null?void 0:o.black} (black)`,[o]);q.useEffect(()=>{Dh||(Dh=!0,new TT({nodeId:window.our.node,channelId:window.our.process,onMessage:t})),fetch("/chess:chess:uqbar/games").then(v=>v.json()).then(v=>{r({games:v})}).catch(console.error)},[]);const u=q.useCallback(async v=>{v.preventDefault();try{const g=await fetch("/chess:chess:uqbar/games",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:a})}).then(I=>{if(I.status===409)throw e[a]?i(a):alert("Game already exists, please refresh the page and select it."),new Error("Game already exists");if(I.status===503)throw alert(`${a} may be offline, please confirm it is online and try again.`),new Error("Player offline");if(I.status===400)throw alert("Please enter a valid player ID"),new Error("Invalid player ID");if(I.status>399)throw alert("There was an error creating the game. Please try again."),new Error("Error creating game");return I.json()}),C={...e};C[g.id]=g,r({games:C}),i(a),s("")}catch(g){console.error(g)}},[e,a,s,r]),c=q.useCallback((v,g)=>{if(!o||!Rh(o,window.our.node))return!1;const C={from:v,to:g,promotion:"q"},I={...o};if(I.game.move(C)===null)return!1;I.board=I.game.fen();const m={...e};return m[o.id]=I,r({games:m}),fetch("/chess:chess:uqbar/games",{method:"PUT",body:JSON.stringify({id:o.id,move:v+g})}).then(S=>S.json()).then(S=>{const B={...e};B[o.id]=S,r({games:B})}).catch(S=>{console.error(S),alert("There was an error making your move. Please try again");const B={...e},R={...o};R.game.undo(),B[o.id]=R,r({games:B})}),!0},[o,e,r]),f=q.useCallback(v=>{v.preventDefault(),v.stopPropagation(),o&&window.confirm("Are you sure you want to resign this game?")&&fetch(`/chess:chess:uqbar/games?id=${o.id}`,{method:"DELETE"}).then(g=>g.json()).then(g=>{const C={...e};C[o.id]=g,r({games:C})}).catch(g=>{console.error(g),alert("There was an error resigning the game. Please try again")})},[o]),d=q.useCallback(async v=>{if(v.preventDefault(),v.stopPropagation(),!!o)try{const g=await fetch("/chess:chess:uqbar/games",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:o.id})}).then(I=>I.json()),C={...e};C[g.id]=g,r({games:C})}catch(g){console.error(g),alert("You could not create the game. Please make sure your current game with this player (if any) has ended and try again.")}},[o]);return D.jsx("div",{className:"flex flex-col justify-center items-center",children:D.jsxs("div",{className:"flex flex-col justify-center",style:{maxHeight:"100vh",maxWidth:"800px",width:"100%",position:"relative"},children:[D.jsx("a",{href:"/",className:"absolute top-6 left-0 m-4",style:{fontSize:24,color:"white"},onClick:v=>{v.preventDefault(),window.history.back()},children:"◀ Back"}),D.jsx("h1",{className:"m-4",children:"Chess by Uqbar"}),D.jsxs("div",{className:"flex flex-row justify-center items-center h-screen border rounded",children:[Object.keys(e).length>0&&D.jsxs("div",{className:"flex flex-col border-r",style:{width:"25%",height:"100%"},children:[D.jsx("h3",{className:"m-2",children:"Games"}),D.jsx("button",{className:"bg-green-600 hover:bg-green-800 text-white font-bold py-2 px-4 m-2 rounded",onClick:()=>i("new"),children:"New"}),D.jsx("div",{className:"flex flex-col overflow-scroll",children:Object.values(e).map(v=>D.jsx("div",{onClick:()=>i(v==null?void 0:v.id),className:`game-entry m-2 ${n!==(v==null?void 0:v.id)&&Rh(v,window.our.node)?"is-turn":""} ${n===(v==null?void 0:v.id)?"selected":""} ${v!=null&&v.ended?"ended":""}`,children:v==null?void 0:v.id},v==null?void 0:v.id))})]}),D.jsx("div",{className:"flex flex-col justify-center items-center",style:{width:"75%"},children:n==="new"||!o?D.jsxs(D.Fragment,{children:[D.jsx("h2",{className:"mb-2",children:"Start New Game"}),D.jsx("h4",{className:"mb-2",children:"(game creator will be white)"}),D.jsxs("form",{onSubmit:u,className:"flex flex-col justify-center mb-40",style:{maxWidth:400},children:[D.jsx("label",{className:"mb-2",style:{alignSelf:"flex-start",fontWeight:"600"},children:"Player ID"}),D.jsx("input",{className:"border rounded p-2 mb-2",style:{color:"black"},type:"text",placeholder:"Player ID",value:a,onChange:v=>s(v.target.value)}),D.jsx("button",{className:"bg-green-600 hover:bg-green-800 text-white font-bold py-2 px-4 rounded",type:"submit",children:"Start Game"})]})]}):D.jsxs(D.Fragment,{children:[D.jsxs("div",{className:"flex flex-row justify-between items-center w-full px-4 pb-2",children:[D.jsx("h3",{children:n}),D.jsx("h4",{children:o!=null&&o.ended?"Game Ended":`Turn: ${l}`}),o!=null&&o.ended?D.jsx("button",{className:"bg-green-600 hover:bg-green-800 text-white font-bold py-1 px-4 rounded",onClick:d,children:"Rematch"}):D.jsx("button",{className:"bg-green-600 hover:bg-green-800 text-white font-bold py-1 px-4 rounded",onClick:f,children:"Resign"})]}),D.jsx(TC,{position:o==null?void 0:o.game.fen(),onPieceDrop:c,boardOrientation:(o==null?void 0:o.white)===window.our.node?"white":"black"})]})})]})]})})}bu.createRoot(document.getElementById("root")).render(D.jsx(bv.StrictMode,{children:D.jsx(JT,{})})); + */var Ti=C,H1=U1;function B1(e,t){return e===t&&(e!==0||1/e===1/t)||e!==e&&t!==t}var W1=typeof Object.is=="function"?Object.is:B1,q1=H1.useSyncExternalStore,Q1=Ti.useRef,K1=Ti.useEffect,V1=Ti.useMemo,G1=Ti.useDebugValue;Zf.useSyncExternalStoreWithSelector=function(e,t,n,r,o){var i=Q1(null);if(i.current===null){var s={hasValue:!1,value:null};i.current=s}else s=i.current;i=V1(function(){function u(g){if(!a){if(a=!0,p=g,g=r(g),o!==void 0&&s.hasValue){var v=s.value;if(o(v,g))return m=v}return m=g}if(v=m,W1(p,g))return v;var y=r(g);return o!==void 0&&o(v,y)?v:(p=g,m=y)}var a=!1,p,m,d=n===void 0?null:n;return[function(){return u(t())},d===null?void 0:function(){return u(d())}]},[t,n,r,o]);var l=q1(e,i[0],i[1]);return K1(function(){s.hasValue=!0,s.value=l},[l]),G1(l),l};Jf.exports=Zf;var Y1=Jf.exports;const X1=vc(Y1),{useSyncExternalStoreWithSelector:J1}=X1;function Z1(e,t=e.getState,n){const r=J1(e.subscribe,e.getState,e.getServerState||e.getState,t,n);return C.useDebugValue(r),r}const pc=e=>{const t=typeof e=="function"?j1(e):e,n=(r,o)=>Z1(t,r,o);return Object.assign(n,t),n},em=e=>e?pc(e):pc;function nh(e,t){let n;try{n=e()}catch{return}return{getItem:o=>{var i;const s=u=>u===null?null:JSON.parse(u,t==null?void 0:t.reviver),l=(i=n.getItem(o))!=null?i:null;return l instanceof Promise?l.then(s):s(l)},setItem:(o,i)=>n.setItem(o,JSON.stringify(i,t==null?void 0:t.replacer)),removeItem:o=>n.removeItem(o)}}const qr=e=>t=>{try{const n=e(t);return n instanceof Promise?n:{then(r){return qr(r)(n)},catch(r){return this}}}catch(n){return{then(r){return this},catch(r){return qr(r)(n)}}}},tm=(e,t)=>(n,r,o)=>{let i={getStorage:()=>localStorage,serialize:JSON.stringify,deserialize:JSON.parse,partialize:w=>w,version:0,merge:(w,h)=>({...h,...w}),...t},s=!1;const l=new Set,u=new Set;let a;try{a=i.getStorage()}catch{}if(!a)return e((...w)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),n(...w)},r,o);const p=qr(i.serialize),m=()=>{const w=i.partialize({...r()});let h;const c=p({state:w,version:i.version}).then(f=>a.setItem(i.name,f)).catch(f=>{h=f});if(h)throw h;return c},d=o.setState;o.setState=(w,h)=>{d(w,h),m()};const g=e((...w)=>{n(...w),m()},r,o);let v;const y=()=>{var w;if(!a)return;s=!1,l.forEach(c=>c(r()));const h=((w=i.onRehydrateStorage)==null?void 0:w.call(i,r()))||void 0;return qr(a.getItem.bind(a))(i.name).then(c=>{if(c)return i.deserialize(c)}).then(c=>{if(c)if(typeof c.version=="number"&&c.version!==i.version){if(i.migrate)return i.migrate(c.state,c.version);console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return c.state}).then(c=>{var f;return v=i.merge(c,(f=r())!=null?f:g),n(v,!0),m()}).then(()=>{h==null||h(v,void 0),s=!0,u.forEach(c=>c(v))}).catch(c=>{h==null||h(void 0,c)})};return o.persist={setOptions:w=>{i={...i,...w},w.getStorage&&(a=w.getStorage())},clearStorage:()=>{a==null||a.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>y(),hasHydrated:()=>s,onHydrate:w=>(l.add(w),()=>{l.delete(w)}),onFinishHydration:w=>(u.add(w),()=>{u.delete(w)})},y(),v||g},nm=(e,t)=>(n,r,o)=>{let i={storage:nh(()=>localStorage),partialize:y=>y,version:0,merge:(y,w)=>({...w,...y}),...t},s=!1;const l=new Set,u=new Set;let a=i.storage;if(!a)return e((...y)=>{console.warn(`[zustand persist middleware] Unable to update item '${i.name}', the given storage is currently unavailable.`),n(...y)},r,o);const p=()=>{const y=i.partialize({...r()});return a.setItem(i.name,{state:y,version:i.version})},m=o.setState;o.setState=(y,w)=>{m(y,w),p()};const d=e((...y)=>{n(...y),p()},r,o);let g;const v=()=>{var y,w;if(!a)return;s=!1,l.forEach(c=>{var f;return c((f=r())!=null?f:d)});const h=((w=i.onRehydrateStorage)==null?void 0:w.call(i,(y=r())!=null?y:d))||void 0;return qr(a.getItem.bind(a))(i.name).then(c=>{if(c)if(typeof c.version=="number"&&c.version!==i.version){if(i.migrate)return i.migrate(c.state,c.version);console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}else return c.state}).then(c=>{var f;return g=i.merge(c,(f=r())!=null?f:d),n(g,!0),p()}).then(()=>{h==null||h(g,void 0),g=r(),s=!0,u.forEach(c=>c(g))}).catch(c=>{h==null||h(void 0,c)})};return o.persist={setOptions:y=>{i={...i,...y},y.storage&&(a=y.storage)},clearStorage:()=>{a==null||a.removeItem(i.name)},getOptions:()=>i,rehydrate:()=>v(),hasHydrated:()=>s,onHydrate:y=>(l.add(y),()=>{l.delete(y)}),onFinishHydration:y=>(u.add(y),()=>{u.delete(y)})},i.skipHydration||v(),g||d},rm=(e,t)=>"getStorage"in t||"serialize"in t||"deserialize"in t?tm(e,t):nm(e,t),om=rm,im=em()(om((e,t)=>({games:{},handleWsMessage:n=>{const{kind:r,data:o}=JSON.parse(n);console.log(r,o),r==="game_update"&&e({games:{...t().games,[o.id]:o}})},set:e}),{name:"chess",storage:nh(()=>localStorage)}));let gc=!1;const mc=(e,t)=>(e.turns||0)%2===0?t===e.white:t===e.black;function sm(){const{games:e,handleWsMessage:t,set:n}=im(),[r,o]=C.useState("new"),[i,s]=C.useState(""),l=C.useMemo(()=>e[r]?{...e[r],game:new og(e[r].board)}:void 0,[e,r]),u=C.useMemo(()=>((l==null?void 0:l.turns)||0)%2===0?`${l==null?void 0:l.white} (white)`:`${l==null?void 0:l.black} (black)`,[l]);C.useEffect(()=>{gc||(gc=!0,new I1({nodeId:window.our.node,processId:window.our.process,onMessage:t})),fetch(`/${window.our.process}/games`).then(g=>g.json()).then(g=>{n({games:g})}).catch(console.error)},[]);const a=C.useCallback(async g=>{g.preventDefault();try{const v=await fetch(`/${window.our.process}/games`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:i})}).then(w=>{if(w.status===409)throw e[i]?o(i):alert("Game already exists, please refresh the page and select it."),new Error("Game already exists");if(w.status===503)throw alert(`${i} may be offline, please confirm it is online and try again.`),new Error("Player offline");if(w.status===400)throw alert("Please enter a valid player ID"),new Error("Invalid player ID");if(w.status>399)throw alert("There was an error creating the game. Please try again."),new Error("Error creating game");return w.json()}),y={...e};y[v.id]=v,n({games:y}),o(i),s("")}catch(v){console.error(v)}},[e,i,s,n]),p=C.useCallback((g,v)=>{if(!l||!mc(l,window.our.node))return!1;const y={from:g,to:v,promotion:"q"},w={...l};if(w.game.move(y)===null)return!1;w.board=w.game.fen();const c={...e};return c[l.id]=w,n({games:c}),fetch(`/${window.our.process}/games`,{method:"PUT",body:JSON.stringify({id:l.id,move:g+v})}).then(f=>f.json()).then(f=>{const k={...e};k[l.id]=f,n({games:k})}).catch(f=>{console.error(f),alert("There was an error making your move. Please try again");const k={...e},x={...l};x.game.undo(),k[l.id]=x,n({games:k})}),!0},[l,e,n]),m=C.useCallback(g=>{g.preventDefault(),g.stopPropagation(),l&&window.confirm("Are you sure you want to resign this game?")&&fetch(`/${window.our.process}/games?id=${l.id}`,{method:"DELETE"}).then(v=>v.json()).then(v=>{const y={...e};y[l.id]=v,n({games:y})}).catch(v=>{console.error(v),alert("There was an error resigning the game. Please try again")})},[l]),d=C.useCallback(async g=>{if(g.preventDefault(),g.stopPropagation(),!!l)try{const v=await fetch(`/${window.our.process}/games`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:l.id})}).then(w=>w.json()),y={...e};y[v.id]=v,n({games:y})}catch(v){console.error(v),alert("You could not create the game. Please make sure your current game with this player (if any) has ended and try again.")}},[l]);return S.jsx("div",{className:"flex flex-col justify-center items-center",children:S.jsxs("div",{className:"flex flex-col justify-center",style:{maxHeight:"100vh",maxWidth:"800px",width:"100%",position:"relative"},children:[S.jsx("a",{href:"/",className:"absolute top-6 left-0 m-4",style:{fontSize:24,color:"white"},onClick:g=>{g.preventDefault()},children:"◀ Back"}),S.jsx("h1",{className:"m-4",children:"Chess by Uqbar"}),S.jsxs("div",{className:"flex flex-row justify-center items-center h-screen border rounded",children:[Object.keys(e).length>0&&S.jsxs("div",{className:"flex flex-col border-r",style:{width:"25%",height:"100%"},children:[S.jsx("h3",{className:"m-2",children:"Games"}),S.jsx("button",{className:"bg-green-600 hover:bg-green-800 text-white font-bold py-2 px-4 m-2 rounded",onClick:()=>o("new"),children:"New"}),S.jsx("div",{className:"flex flex-col overflow-scroll",children:Object.values(e).map(g=>S.jsx("div",{onClick:()=>o(g==null?void 0:g.id),className:`game-entry m-2 ${r!==(g==null?void 0:g.id)&&mc(g,window.our.node)?"is-turn":""} ${r===(g==null?void 0:g.id)?"selected":""} ${g!=null&&g.ended?"ended":""}`,children:g==null?void 0:g.id},g==null?void 0:g.id))})]}),S.jsx("div",{className:"flex flex-col justify-center items-center",style:{width:"75%"},children:r==="new"||!l?S.jsxs(S.Fragment,{children:[S.jsx("h2",{className:"mb-2",children:"Start New Game"}),S.jsx("h4",{className:"mb-2",children:"(game creator will be white)"}),S.jsxs("form",{onSubmit:a,className:"flex flex-col justify-center mb-40",style:{maxWidth:400},children:[S.jsx("label",{className:"mb-2",style:{alignSelf:"flex-start",fontWeight:"600"},children:"Player ID"}),S.jsx("input",{className:"border rounded p-2 mb-2",style:{color:"black"},type:"text",placeholder:"Player ID",value:i,onChange:g=>s(g.target.value)}),S.jsx("button",{className:"bg-green-600 hover:bg-green-800 text-white font-bold py-2 px-4 rounded",type:"submit",children:"Start Game"})]})]}):S.jsxs(S.Fragment,{children:[S.jsxs("div",{className:"flex flex-row justify-between items-center w-full px-4 pb-2",children:[S.jsx("h3",{children:r}),S.jsx("h4",{children:l!=null&&l.ended?"Game Ended":`Turn: ${u}`}),l!=null&&l.ended?S.jsx("button",{className:"bg-green-600 hover:bg-green-800 text-white font-bold py-1 px-4 rounded",onClick:d,children:"Rematch"}):S.jsx("button",{className:"bg-green-600 hover:bg-green-800 text-white font-bold py-1 px-4 rounded",onClick:m,children:"Resign"})]}),S.jsx(T1,{position:l==null?void 0:l.game.fen(),onPieceDrop:p,boardOrientation:(l==null?void 0:l.white)===window.our.node?"white":"black"})]})})]})]})})}Cs.createRoot(document.getElementById("root")).render(S.jsx(Mh.StrictMode,{children:S.jsx(sm,{})})); diff --git a/modules/chess/pkg/manifest.json b/modules/chess/pkg/manifest.json index e8c1751c..c06cffe2 100644 --- a/modules/chess/pkg/manifest.json +++ b/modules/chess/pkg/manifest.json @@ -2,11 +2,14 @@ { "process_name": "chess", "process_wasm_path": "/chess.wasm", - "on_panic": "Restart", + "on_exit": "Restart", "request_networking": true, "request_messaging": [ + "net:sys:uqbar" + ], + "grant_messaging": [ "http_server:sys:uqbar" ], - "public": false + "public": true } ] diff --git a/modules/chess/src/lib.rs b/modules/chess/src/lib.rs index 1456d0be..c02ba2dd 100644 --- a/modules/chess/src/lib.rs +++ b/modules/chess/src/lib.rs @@ -1,39 +1,45 @@ #![feature(let_chains)] -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -extern crate base64; -extern crate pleco; use pleco::Board; -use uqbar_process_lib::uqbar::process::standard as wit; +use serde::{Deserialize, Serialize}; +use std::collections::{HashMap, HashSet}; use uqbar_process_lib::{ - get_payload, get_typed_state, grant_messaging, http, println, receive, set_state, Address, - Message, Payload, ProcessId, Request, Response, + await_message, call_init, get_payload, get_typed_state, http, println, set_state, Address, + Message, NodeId, Payload, Request, Response, }; +extern crate base64; -mod utils; +// Lazy way to include our static files in the binary. We'll use these to serve +// our chess app's frontend. +const CHESS_HTML: &str = include_str!("../pkg/chess.html"); +const CHESS_JS: &str = include_str!("../pkg/index.js"); +const CHESS_CSS: &str = include_str!("../pkg/index.css"); -wit_bindgen::generate!({ - path: "../../wit", - world: "process", - exports: { - world: Component, - }, -}); +// +// Our "chess protocol" request/response format. We'll always serialize these +// to a byte vector and send them over IPC. +// -struct Component; - -#[derive(Clone, Debug)] -pub struct Game { - pub id: String, // the node with whom we are playing - pub turns: u64, - pub board: Board, - pub white: String, - pub black: String, - pub ended: bool, +#[derive(Debug, Serialize, Deserialize)] +enum ChessRequest { + NewGame { white: String, black: String }, + Move { game_id: String, move_str: String }, + Resign(String), } +#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] +enum ChessResponse { + NewGameAccepted, + NewGameRejected, + MoveAccepted, + MoveRejected, +} + +// +// Our serializable state format. +// + #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct StoredGame { +struct Game { pub id: String, // the node with whom we are playing pub turns: u64, pub board: String, @@ -42,280 +48,408 @@ pub struct StoredGame { pub ended: bool, } -#[derive(Clone, Debug)] -pub struct ChessState { +#[derive(Debug, Serialize, Deserialize)] +struct ChessState { pub games: HashMap, // game is by opposing player id - pub records: HashMap, // wins, losses, draws + pub clients: HashSet, // doesn't get persisted } -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct StoredChessState { - pub games: HashMap, // game is by opposing player id - pub records: HashMap, // wins, losses, draws +#[derive(Debug, Serialize, Deserialize)] +struct StoredChessState { + pub games: HashMap, // game is by opposing player id } -const CHESS_PAGE: &str = include_str!("../pkg/chess.html"); -const CHESS_JS: &str = include_str!("../pkg/index.js"); -const CHESS_CSS: &str = include_str!("../pkg/index.css"); +fn save_chess_state(state: &ChessState) { + set_state(&bincode::serialize(&state.games).unwrap()); +} -impl Guest for Component { - fn init(our: String) { - let our = Address::from_str(&our).unwrap(); - println!("{our}: start"); +fn load_chess_state() -> ChessState { + match get_typed_state(|bytes| Ok(bincode::deserialize::>(bytes)?)) { + Some(games) => ChessState { + games, + clients: HashSet::new(), + }, + None => ChessState { + games: HashMap::new(), + clients: HashSet::new(), + }, + } +} - grant_messaging( - &our, - vec![ProcessId::new(Some("http_server"), "sys", "uqbar")], - ); +fn send_ws_update(our: &Address, game: &Game, open_channels: &HashSet) -> anyhow::Result<()> { + for channel in open_channels { + Request::new() + .target((&our.node, "http_server", "sys", "uqbar")) + .ipc(serde_json::to_vec( + &http::HttpServerAction::WebSocketPush { + channel_id: *channel, + message_type: http::WsMessageType::Binary, + }, + )?) + .payload(Payload { + mime: Some("application/json".to_string()), + bytes: serde_json::json!({ + "kind": "game_update", + "data": game, + }) + .to_string() + .into_bytes(), + }) + .send()?; + } + Ok(()) +} - // serve static page at / - // dynamically handle requests to /games - http::bind_http_static_path( - "/", - true, - false, - Some("text/html".to_string()), - CHESS_PAGE - .replace("${node}", &our.node) - .replace("${process}", &our.process.to_string()) - // TODO serve these independently on paths.. - // also build utils for just serving a vfs dir - .replace("${js}", CHESS_JS) - .replace("${css}", CHESS_CSS) - .as_bytes() - .to_vec(), - ) - .unwrap(); - http::bind_http_path("/games", true, false).unwrap(); +// Boilerplate: generate the wasm bindings for an Uqbar app +wit_bindgen::generate!({ + path: "../../wit", + world: "process", + exports: { + world: Component, + }, +}); +// After generating bindings, use this macro to define the Component struct +// and its init() function, which the kernel will look for on startup. +call_init!(initialize); - let mut state: ChessState = match get_typed_state(|bytes| { - Ok(bincode::deserialize::(bytes)?) - }) { - Some(mut state) => ChessState { - games: state - .games - .iter_mut() - .map(|(id, game)| { - ( - id.clone(), - Game { - id: id.to_owned(), - turns: game.turns, - board: Board::from_fen(&game.board).unwrap_or(Board::start_pos()), - white: game.white.to_owned(), - black: game.black.to_owned(), - ended: game.ended, - }, - ) - }) - .collect(), - records: state.records, - }, - None => ChessState { - games: HashMap::new(), - records: HashMap::new(), - }, - }; +fn initialize(our: Address) { + // A little printout to show in terminal that the process has started. + println!("{} by {}: start", our.process(), our.publisher()); - loop { - let Ok((source, message)) = receive() else { - println!("chess: got network error"); + // serve static page at /index.html, /index.js, /index.css + // dynamically handle requests to /games + http::bind_http_static_path( + "/", + true, // only serve for ourselves + false, // can access remotely + Some("text/html".to_string()), + CHESS_HTML + .replace("${node}", &our.node) + .replace("${process}", &our.process.to_string()) + .as_bytes() + .to_vec(), + ) + .unwrap(); + http::bind_http_static_path( + "/index.js", + true, + false, + Some("text/javascript".to_string()), + CHESS_JS.as_bytes().to_vec(), + ) + .unwrap(); + http::bind_http_static_path( + "/index.css", + true, + false, + Some("text/css".to_string()), + CHESS_CSS.as_bytes().to_vec(), + ) + .unwrap(); + http::bind_http_path("/games", true, false).unwrap(); + // Allow websockets to be opened at / (our process ID will be prepended). + http::bind_ws_path("/", true, false).unwrap(); + + // Grab our state, then enter the main event loop. + let mut state: ChessState = load_chess_state(); + main_loop(&our, &mut state); +} + +fn main_loop(our: &Address, state: &mut ChessState) { + loop { + // Call await_message() to wait for any incoming messages. + // If we get a network error, make a print and throw it away. + // In a high-quality consumer-grade app, we'd want to explicitly handle + // this and surface it to the user. + match await_message() { + Err(send_error) => { + println!("{our}: got network error: {send_error:?}"); continue; - }; - let Message::Request(request) = message else { - println!("chess: got unexpected Response"); - continue; - }; - match handle_request(&our, &source, &request, &mut state) { - Ok(()) => continue, - Err(e) => println!("chess: error handling request: {:?}", e), } + Ok(message) => match handle_request(&our, &message, state) { + Ok(()) => continue, + Err(e) => println!("{our}: error handling request: {:?}", e), + }, } } } -fn handle_request( - our: &Address, - source: &Address, - request: &wit::Request, - state: &mut ChessState, -) -> anyhow::Result<()> { - if source.process == "chess:chess:uqbar" { - let message_json = serde_json::from_slice::(&request.ipc)?; - handle_chess_request(our, source, message_json, state) - } else if source.process.to_string() == "http_server:sys:uqbar" { - let http_request = serde_json::from_slice::(&request.ipc)?; - handle_http_request(our, http_request, state) +/// Handle chess protocol messages from ourself *or* other nodes. +fn handle_request(our: &Address, message: &Message, state: &mut ChessState) -> anyhow::Result<()> { + // Throw away responses. We never expect any responses *here*, because for every + // chess protocol request, we *await* its response in-place. This is appropriate + // for direct node<>node comms, less appropriate for other circumstances... + if !message.is_request() { + return Ok(()); + } + // If the request is from another node, handle it as an incoming request. + // Note that we can enforce the ProcessId as well, but it shouldn't be a trusted + // piece of information, since another node can easily spoof any ProcessId on a request. + // It can still be useful simply as a protocol-level switch to handle different kinds of + // requests from the same node, with the knowledge that the remote node can finagle with + // which ProcessId a given message can be from. It's their code, after all. + if message.source().node != our.node { + // Deserialize the request IPC to our format, and throw it away if it + // doesn't fit. + let Ok(chess_request) = serde_json::from_slice::(message.ipc()) else { + return Err(anyhow::anyhow!("invalid chess request")); + }; + handle_chess_request(our, &message.source().node, state, &chess_request) + // ...and if the request is from ourselves, handle it as our own! + // Note that since this is a local request, we *can* trust the ProcessId. + // Here, we'll accept messages from the local terminal so as to make this a "CLI" app. + } else if message.source().node == our.node + && message.source().process == "terminal:terminal:uqbar" + { + let Ok(chess_request) = serde_json::from_slice::(message.ipc()) else { + return Err(anyhow::anyhow!("invalid chess request")); + }; + handle_local_request(our, state, &chess_request) + } else if message.source().node == our.node + && message.source().process == "http_server:sys:uqbar" + { + // receive HTTP requests and websocket connection messages from our server + match serde_json::from_slice::(message.ipc())? { + http::HttpServerRequest::Http(ref incoming) => { + match handle_http_request(our, state, incoming) { + Ok(()) => Ok(()), + Err(e) => { + println!("chess: error handling http request: {:?}", e); + http::send_response( + http::StatusCode::SERVICE_UNAVAILABLE, + None, + "Service Unavailable".to_string().as_bytes().to_vec(), + ) + } + } + } + http::HttpServerRequest::WebSocketOpen { path, channel_id } => { + // We know this is authenticated and unencrypted because we only + // bound one path, the root path. So we know that client + // frontend opened a websocket and can send updates + state.clients.insert(channel_id); + Ok(()) + } + http::HttpServerRequest::WebSocketClose(channel_id) => { + // client frontend closed a websocket + state.clients.remove(&channel_id); + Ok(()) + } + http::HttpServerRequest::WebSocketPush { .. } => { + // client frontend sent a websocket message + // we don't expect this! we only use websockets to push updates + Ok(()) + } + } } else { - return Err(anyhow::anyhow!("chess: got request from unexpected source")); + // If we get a request from ourselves that isn't from the terminal, we'll just + // throw it away. This is a good place to put a printout to show that we've + // received a request from ourselves that we don't know how to handle. + return Err(anyhow::anyhow!( + "got request from not-the-terminal, ignoring" + )); } } +/// Handle chess protocol messages from other nodes. fn handle_chess_request( our: &Address, - source: &Address, - message_json: serde_json::Value, + source_node: &NodeId, state: &mut ChessState, + action: &ChessRequest, ) -> anyhow::Result<()> { - let action = message_json["action"].as_str().unwrap_or(""); - let game_id = &source.node; + println!("chess: handling action from {source_node}: {action:?}"); + + // For simplicity's sake, we'll just use the node we're playing with as the game id. + // This limits us to one active game per partner. + let game_id = source_node; + match action { - "new_game" => { - // make a new game with source.node if the current game has ended - if let Some(game) = state.games.get(game_id) { - if !game.ended { - return Response::new() - .ipc(vec![]) - .payload(Payload { - mime: Some("application/octet-stream".to_string()), - bytes: "conflict".as_bytes().to_vec(), - }) - .send(); - } + ChessRequest::NewGame { white, black } => { + // Make a new game with source.node + // This will replace any existing game with source.node! + if state.games.contains_key(game_id) { + println!("chess: resetting game with {game_id} on their request!"); } let game = Game { id: game_id.to_string(), turns: 0, - board: Board::start_pos(), - white: message_json["white"] - .as_str() - .unwrap_or(game_id) - .to_string(), - black: message_json["black"] - .as_str() - .unwrap_or(&our.node) - .to_string(), + board: Board::start_pos().fen(), + white: white.to_string(), + black: black.to_string(), ended: false, }; - state.games.insert(game_id.to_string(), game.clone()); - - utils::send_ws_update(&our, &game)?; - utils::save_chess_state(&state); - + // Use our helper function to persist state after every action. + // The simplest and most trivial way to keep state. You'll want to + // use a database or something in a real app, and consider performance + // when doing intensive data-based operations. + send_ws_update(&our, &game, &state.clients)?; + state.games.insert(game_id.to_string(), game); + save_chess_state(&state); + // Send a response to tell them we've accepted the game. + // Remember, the other player is waiting for this. Response::new() - .ipc(vec![]) - .payload(Payload { - mime: Some("application/octet-stream".to_string()), - bytes: "success".as_bytes().to_vec(), - }) + .ipc(serde_json::to_vec(&ChessResponse::NewGameAccepted)?) .send() } - "make_move" => { - // check the move and then update if correct and send WS update + ChessRequest::Move { ref move_str, .. } => { + // Get the associated game, and respond with an error if + // we don't have it in our state. let Some(game) = state.games.get_mut(game_id) else { + // If we don't have a game with them, reject the move. return Response::new() - .ipc(vec![]) - .payload(Payload { - mime: Some("application/octet-stream".to_string()), - bytes: "not found".as_bytes().to_vec(), - }) + .ipc(serde_json::to_vec(&ChessResponse::MoveRejected)?) .send(); }; - let valid_move = game - .board - .apply_uci_move(message_json["move"].as_str().unwrap_or("")); - if valid_move { - game.turns += 1; - let checkmate = game.board.checkmate(); - let draw = game.board.stalemate(); - - if checkmate || draw { + // Convert the saved board to one we can manipulate. + let mut board = Board::from_fen(&game.board).unwrap(); + if !board.apply_uci_move(move_str) { + // Reject invalid moves! + return Response::new() + .ipc(serde_json::to_vec(&ChessResponse::MoveRejected)?) + .send(); + } + game.turns += 1; + if board.checkmate() || board.stalemate() { + game.ended = true; + } + // Persist state. + game.board = board.fen(); + send_ws_update(&our, &game, &state.clients)?; + save_chess_state(&state); + // Send a response to tell them we've accepted the move. + Response::new() + .ipc(serde_json::to_vec(&ChessResponse::MoveAccepted)?) + .send() + } + ChessRequest::Resign(_) => { + // They've resigned. The sender isn't waiting for a response to this, + // so we don't need to send one. + match state.games.get_mut(game_id) { + Some(game) => { game.ended = true; - let winner = if checkmate { - if game.turns % 2 == 1 { - game.white.clone() - } else { - game.black.clone() - } - } else { - "".to_string() - }; - - // update the records - if draw { - if let Some(record) = state.records.get_mut(&game.id) { - record.2 += 1; - } else { - state.records.insert(game.id.clone(), (0, 0, 1)); - } - } else { - if let Some(record) = state.records.get_mut(&game.id) { - if winner == our.node { - record.0 += 1; - } else { - record.1 += 1; - } - } else { - if winner == our.node { - state.records.insert(game.id.clone(), (1, 0, 0)); - } else { - state.records.insert(game.id.clone(), (0, 1, 0)); - } - } - } + send_ws_update(&our, &game, &state.clients)?; + save_chess_state(&state); } - - utils::send_ws_update(&our, &game)?; - utils::save_chess_state(&state); - - Response::new() - .ipc(vec![]) - .payload(Payload { - mime: Some("application/octet-stream".to_string()), - bytes: "success".as_bytes().to_vec(), - }) - .send() - } else { - Response::new() - .ipc(vec![]) - .payload(Payload { - mime: Some("application/octet-stream".to_string()), - bytes: "invalid move".as_bytes().to_vec(), - }) - .send() + None => {} } + Ok(()) } - "end_game" => { - // end the game and send WS update, update the standings - let Some(game) = state.games.get_mut(game_id) else { - return Response::new() - .ipc(vec![]) - .payload(Payload { - mime: Some("application/octet-stream".to_string()), - bytes: "not found".as_bytes().to_vec(), - }) - .send(); - }; - - game.ended = true; - - if let Some(record) = state.records.get_mut(&game.id) { - record.0 += 1; - } else { - state.records.insert(game.id.clone(), (1, 0, 0)); - } - - utils::send_ws_update(&our, &game)?; - utils::save_chess_state(&state); - - Response::new() - .ipc(vec![]) - .payload(Payload { - mime: Some("application/octet-stream".to_string()), - bytes: "success".as_bytes().to_vec(), - }) - .send() - } - _ => return Err(anyhow::anyhow!("chess: got unexpected action")), } } +/// Handle actions we are performing. Here's where we'll send_and_await various requests. +fn handle_local_request( + our: &Address, + state: &mut ChessState, + action: &ChessRequest, +) -> anyhow::Result<()> { + match action { + ChessRequest::NewGame { white, black } => { + // Create a new game. We'll enforce that one of the two players is us. + if white != &our.node && black != &our.node { + return Err(anyhow::anyhow!("cannot start a game without us!")); + } + let game_id = if white == &our.node { black } else { white }; + // If we already have a game with this player, throw an error. + if let Some(game) = state.games.get(game_id) + && !game.ended + { + return Err(anyhow::anyhow!("already have a game with {game_id}")); + }; + // Send the other player a NewGame request + // The request is exactly the same as what we got from terminal. + // We'll give them 5 seconds to respond... + let Ok(Message::Response { ref ipc, .. }) = Request::new() + .target((game_id.as_ref(), our.process.clone())) + .ipc(serde_json::to_vec(&action)?) + .send_and_await_response(5)? + else { + return Err(anyhow::anyhow!( + "other player did not respond properly to new game request" + )); + }; + // If they accept, create a new game -- otherwise, error out. + if serde_json::from_slice::(ipc)? != ChessResponse::NewGameAccepted { + return Err(anyhow::anyhow!("other player rejected new game request!")); + } + // New game with default board. + let game = Game { + id: game_id.to_string(), + turns: 0, + board: Board::start_pos().fen(), + white: white.to_string(), + black: black.to_string(), + ended: false, + }; + state.games.insert(game_id.to_string(), game); + save_chess_state(&state); + Ok(()) + } + ChessRequest::Move { game_id, move_str } => { + // Make a move. We'll enforce that it's our turn. The game_id is the + // person we're playing with. + let Some(game) = state.games.get_mut(game_id) else { + return Err(anyhow::anyhow!("no game with {game_id}")); + }; + if (game.turns % 2 == 0 && game.white != our.node) + || (game.turns % 2 == 1 && game.black != our.node) + { + return Err(anyhow::anyhow!("not our turn!")); + } else if game.ended { + return Err(anyhow::anyhow!("that game is over!")); + } + let mut board = Board::from_fen(&game.board).unwrap(); + if !board.apply_uci_move(move_str) { + return Err(anyhow::anyhow!("illegal move!")); + } + // Send the move to the other player, then check if the game is over. + // The request is exactly the same as what we got from terminal. + // We'll give them 5 seconds to respond... + let Ok(Message::Response { ref ipc, .. }) = Request::new() + .target((game_id.as_ref(), our.process.clone())) + .ipc(serde_json::to_vec(&action)?) + .send_and_await_response(5)? + else { + return Err(anyhow::anyhow!( + "other player did not respond properly to our move" + )); + }; + if serde_json::from_slice::(ipc)? != ChessResponse::MoveAccepted { + return Err(anyhow::anyhow!("other player rejected our move")); + } + game.turns += 1; + if board.checkmate() || board.stalemate() { + game.ended = true; + } + game.board = board.fen(); + save_chess_state(&state); + Ok(()) + } + ChessRequest::Resign(ref with_who) => { + // Resign from a game with a given player. + let Some(game) = state.games.get_mut(with_who) else { + return Err(anyhow::anyhow!("no game with {with_who}")); + }; + // send the other player an end game request -- no response expected + Request::new() + .target((with_who.as_ref(), our.process.clone())) + .ipc(serde_json::to_vec(&action)?) + .send()?; + game.ended = true; + save_chess_state(&state); + Ok(()) + } + } +} + +/// Handle HTTP requests from our own frontend. fn handle_http_request( our: &Address, - http_request: http::IncomingHttpRequest, state: &mut ChessState, + http_request: &http::IncomingHttpRequest, ) -> anyhow::Result<()> { - if http_request.path()? != "/games" { + if http_request.path()? != "games" { return http::send_response( http::StatusCode::NOT_FOUND, None, @@ -323,20 +457,17 @@ fn handle_http_request( ); } match http_request.method.as_str() { + // on GET: give the frontend all of our active games "GET" => http::send_response( http::StatusCode::OK, Some(HashMap::from([( String::from("Content-Type"), String::from("application/json"), )])), - serde_json::to_vec(&serde_json::json!(state - .games - .iter() - .map(|(id, game)| (id.to_string(), utils::json_game(game))) - .collect::>()))?, + serde_json::to_vec(&state.games)?, ), + // on POST: create a new game "POST" => { - // create a new game let Some(payload) = get_payload() else { return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); }; @@ -360,38 +491,36 @@ fn handle_http_request( .to_string(); // send the other player a new game request - let response = Request::new() - .target((game_id, "chess", "chess", "uqbar")) - .ipc(serde_json::to_vec(&serde_json::json!({ - "action": "new_game", - "white": player_white.clone(), - "black": player_black.clone(), - }))?) - .send_and_await_response(30)?; + let Ok(msg) = Request::new() + .target((game_id, our.process.clone())) + .ipc(serde_json::to_vec(&ChessRequest::NewGame { + white: player_white.clone(), + black: player_black.clone(), + })?) + .send_and_await_response(5)? + else { + return Err(anyhow::anyhow!( + "other player did not respond properly to new game request" + )); + }; // if they accept, create a new game // otherwise, should surface error to FE... - let Ok((_source, Message::Response((resp, _context)))) = response else { - return http::send_response( - http::StatusCode::SERVICE_UNAVAILABLE, - None, - "Service Unavailable".to_string().as_bytes().to_vec(), - ); - }; - if resp.ipc != "success".as_bytes() { - return http::send_response(http::StatusCode::SERVICE_UNAVAILABLE, None, vec![]); + if serde_json::from_slice::(msg.ipc())? != ChessResponse::NewGameAccepted + { + return Err(anyhow::anyhow!("other player rejected new game request")); } // create a new game let game = Game { id: game_id.to_string(), turns: 0, - board: Board::start_pos(), + board: Board::start_pos().fen(), white: player_white, black: player_black, ended: false, }; - let body = serde_json::to_vec(&utils::json_game(&game))?; + let body = serde_json::to_vec(&game)?; state.games.insert(game_id.to_string(), game); - utils::save_chess_state(&state); + save_chess_state(&state); http::send_response( http::StatusCode::OK, Some(HashMap::from([( @@ -401,8 +530,8 @@ fn handle_http_request( body, ) } + // on PUT: make a move "PUT" => { - // make a move let Some(payload) = get_payload() else { return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); }; @@ -420,71 +549,41 @@ fn handle_http_request( } else if game.ended { return http::send_response(http::StatusCode::CONFLICT, None, vec![]); } - let move_str = payload_json["move"].as_str().unwrap_or(""); - if !game.board.apply_uci_move(move_str) { + let Some(move_str) = payload_json["move"].as_str() else { + return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); + }; + let mut board = Board::from_fen(&game.board).unwrap(); + if !board.apply_uci_move(move_str) { // TODO surface illegal move to player or something here return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); } // send the move to the other player // check if the game is over // if so, update the records - let response = Request::new() - .target((game_id, "chess", "chess", "uqbar")) - .ipc(serde_json::to_vec(&serde_json::json!({ - "action": "make_move", - "move": move_str, - }))?) - .send_and_await_response(30)?; - let Ok((_source, Message::Response((resp, _context)))) = response else { - // TODO surface error to player, let them know other player is - // offline or whatever they respond here was invalid - return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); + let Ok(msg) = Request::new() + .target((game_id, our.process.clone())) + .ipc(serde_json::to_vec(&ChessRequest::Move { + game_id: game_id.to_string(), + move_str: move_str.to_string(), + })?) + .send_and_await_response(5)? + else { + return Err(anyhow::anyhow!( + "other player did not respond properly to our move" + )); }; - if resp.ipc != "success".as_bytes() { - return http::send_response(http::StatusCode::SERVICE_UNAVAILABLE, None, vec![]); + if serde_json::from_slice::(msg.ipc())? != ChessResponse::MoveAccepted { + return Err(anyhow::anyhow!("other player rejected our move")); } // update the game game.turns += 1; - let checkmate = game.board.checkmate(); - let draw = game.board.stalemate(); - - if checkmate || draw { + if board.checkmate() || board.stalemate() { game.ended = true; - let winner = if checkmate { - if game.turns % 2 == 1 { - &game.white - } else { - &game.black - } - } else { - "" - }; - // update the records - if draw { - if let Some(record) = state.records.get_mut(&game.id) { - record.2 += 1; - } else { - state.records.insert(game.id.clone(), (0, 0, 1)); - } - } else { - if let Some(record) = state.records.get_mut(&game.id) { - if winner == our.node { - record.0 += 1; - } else { - record.1 += 1; - } - } else { - if winner == our.node { - state.records.insert(game.id.clone(), (1, 0, 0)); - } else { - state.records.insert(game.id.clone(), (0, 1, 0)); - } - } - } } - // game is not over, update state and return to FE - let body = serde_json::to_vec(&utils::json_game(&game))?; - utils::save_chess_state(&state); + game.board = board.fen(); + // update state and return to FE + let body = serde_json::to_vec(&game)?; + save_chess_state(&state); // return the game http::send_response( http::StatusCode::OK, @@ -495,41 +594,22 @@ fn handle_http_request( body, ) } + // on DELETE: end the game "DELETE" => { - // "end the game"? - let query_params = http_request.query_params()?; - let Some(game_id) = query_params.get("id") else { + let Some(game_id) = http_request.query_params.get("id") else { return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); }; let Some(game) = state.games.get_mut(game_id) else { return http::send_response(http::StatusCode::BAD_REQUEST, None, vec![]); }; // send the other player an end game request - let response = Request::new() - .target((game_id, "chess", "chess", "uqbar")) - .ipc(serde_json::to_vec(&serde_json::json!({ - "action": "end_game", - }))?) - .send_and_await_response(30)?; - let Ok((_source, Message::Response((resp, _context)))) = response else { - // TODO surface error to player, let them know other player is - // offline or whatever they respond here was invalid - return http::send_response(http::StatusCode::SERVICE_UNAVAILABLE, None, vec![]); - }; - if resp.ipc != "success".as_bytes() { - return http::send_response(http::StatusCode::SERVICE_UNAVAILABLE, None, vec![]); - } - + Request::new() + .target((game_id.as_str(), our.process.clone())) + .ipc(serde_json::to_vec(&ChessRequest::Resign(our.node.clone()))?) + .send()?; game.ended = true; - if let Some(record) = state.records.get_mut(&game.id) { - record.1 += 1; - } else { - state.records.insert(game.id.clone(), (0, 1, 0)); - } - // return the game - let body = serde_json::to_vec(&utils::json_game(&game))?; - utils::save_chess_state(&state); - + let body = serde_json::to_vec(&game)?; + save_chess_state(&state); http::send_response( http::StatusCode::OK, Some(HashMap::from([( @@ -539,11 +619,7 @@ fn handle_http_request( body, ) } - _ => Response::new() - .ipc(serde_json::to_vec(&http::HttpResponse { - status: 405, - headers: HashMap::new(), - })?) - .send(), + // Any other method will be rejected. + _ => http::send_response(http::StatusCode::METHOD_NOT_ALLOWED, None, vec![]), } } diff --git a/modules/chess/src/utils.rs b/modules/chess/src/utils.rs deleted file mode 100644 index 4416af91..00000000 --- a/modules/chess/src/utils.rs +++ /dev/null @@ -1,82 +0,0 @@ -use crate::*; - -pub fn save_chess_state(state: &ChessState) { - let stored_state = convert_state(&state); - set_state(&bincode::serialize(&stored_state).unwrap()); -} - -fn convert_game(game: Game) -> StoredGame { - StoredGame { - id: game.id, - turns: game.turns, - board: game.board.fen(), - white: game.white, - black: game.black, - ended: game.ended, - } -} - -fn convert_state(state: &ChessState) -> StoredChessState { - StoredChessState { - games: state - .games - .iter() - .map(|(id, game)| (id.to_string(), convert_game(game.clone()))) - .collect(), - records: state.records.clone(), - } -} - -pub fn json_game(game: &Game) -> serde_json::Value { - serde_json::json!({ - "id": game.id, - "turns": game.turns, - "board": game.board.fen(), - "white": game.white, - "black": game.black, - "ended": game.ended, - }) -} - -pub fn send_ws_update(our: &Address, game: &Game) -> anyhow::Result<()> { - Request::new() - .target((&our.node, "http_server", "sys", "uqbar")) - .ipc( - serde_json::json!({ - "EncryptAndForward": { - "channel_id": our.process.to_string(), - "forward_to": { - "node": our.node.clone(), - "process": { - "process_name": "http_server", - "package_name": "sys", - "publisher_node": "uqbar" - } - }, // node, process - "json": Some(serde_json::json!({ // this is the JSON to forward - "WebSocketPush": { - "target": { - "node": our.node.clone(), - "id": "chess", // If the message passed in an ID then we could send to just that ID - } - } - })), - } - - }) - .to_string() - .as_bytes() - .to_vec(), - ) - .payload(Payload { - mime: Some("application/json".to_string()), - bytes: serde_json::json!({ - "kind": "game_update", - "data": json_game(game), - }) - .to_string() - .as_bytes() - .to_vec(), - }) - .send() -} diff --git a/modules/homepage/Cargo.lock b/modules/homepage/Cargo.lock index c5b78138..17ecc82d 100644 --- a/modules/homepage/Cargo.lock +++ b/modules/homepage/Cargo.lock @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "leb128" @@ -146,9 +146,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "log" @@ -170,9 +170,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -218,9 +218,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "semver" @@ -230,18 +230,18 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.191" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.191" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -261,9 +261,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "spdx" @@ -276,9 +276,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" dependencies = [ "proc-macro2", "quote", @@ -322,9 +322,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -355,8 +355,8 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "uqbar_process_lib" -version = "0.3.0" -source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=5e1b94a#5e1b94ae2f85c66da33ec52117a72b90d53c4d22" +version = "0.4.0" +source = "git+ssh://git@github.com/uqbar-dao/process_lib.git?rev=1ce0d41#1ce0d412169e795c2a99464563b42ae2a2628d77" dependencies = [ "anyhow", "bincode", @@ -388,18 +388,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-encoder" -version = "0.36.2" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822b645bf4f2446b949776ffca47e2af60b167209ffb70814ef8779d299cd421" +checksum = "0ad2b51884de9c7f4fe2fd1043fccb8dcad4b1e29558146ee57a144d15779f3f" dependencies = [ "leb128", ] [[package]] name = "wasm-metadata" -version = "0.10.11" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2167ce53b2faa16a92c6cafd4942cff16c9a4fa0c5a5a0a41131ee4e49fc055f" +checksum = "d835d67708f6374937c550ad8dd1d17c616ae009e3f00d7a0ac9f7825e78c36a" dependencies = [ "anyhow", "indexmap", @@ -413,9 +413,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.116.1" +version = "0.118.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" +checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" dependencies = [ "indexmap", "semver", @@ -423,8 +423,8 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "bitflags", "wit-bindgen-rust-macro", @@ -432,8 +432,8 @@ dependencies = [ [[package]] name = "wit-bindgen-core" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "wit-component", @@ -442,8 +442,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust" -version = "0.13.2" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "heck", @@ -454,8 +454,8 @@ dependencies = [ [[package]] name = "wit-bindgen-rust-macro" -version = "0.13.1" -source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=5390bab780733f1660d14c254ec985df2816bf1d#5390bab780733f1660d14c254ec985df2816bf1d" +version = "0.16.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=efcc759#efcc7592cf3277bcb9be1034e48569c6d822b322" dependencies = [ "anyhow", "proc-macro2", @@ -468,9 +468,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.17.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480cc1a078b305c1b8510f7c455c76cbd008ee49935f3a6c5fd5e937d8d95b1e" +checksum = "5b8a35a2a9992898c9d27f1664001860595a4bc99d32dd3599d547412e17d7e2" dependencies = [ "anyhow", "bitflags", @@ -487,9 +487,9 @@ dependencies = [ [[package]] name = "wit-parser" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43771ee863a16ec4ecf9da0fc65c3bbd4a1235c8e3da5f094b562894843dfa76" +checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" dependencies = [ "anyhow", "id-arena", diff --git a/modules/homepage/Cargo.toml b/modules/homepage/Cargo.toml index dbf88537..e43572de 100644 --- a/modules/homepage/Cargo.toml +++ b/modules/homepage/Cargo.toml @@ -13,10 +13,10 @@ lto = true [dependencies] anyhow = "1.0" bincode = "1.3.3" -serde = {version = "1.0", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "5e1b94a" } -wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "5390bab780733f1660d14c254ec985df2816bf1d" } +uqbar_process_lib = { git = "ssh://git@github.com/uqbar-dao/process_lib.git", rev = "1ce0d41" } +wit-bindgen = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "efcc759" } [lib] crate-type = ["cdylib"] diff --git a/modules/homepage/pkg/manifest.json b/modules/homepage/pkg/manifest.json index 0a9fac58..22317c4d 100644 --- a/modules/homepage/pkg/manifest.json +++ b/modules/homepage/pkg/manifest.json @@ -2,7 +2,7 @@ { "process_name": "homepage", "process_wasm_path": "/homepage.wasm", - "on_panic": "Restart", + "on_exit": "Restart", "request_networking": false, "request_messaging": [ "http_bindings:http_bindings:uqbar", diff --git a/modules/homepage/src/home.html b/modules/homepage/src/home.html index 20a16cd5..fa7be274 100644 --- a/modules/homepage/src/home.html +++ b/modules/homepage/src/home.html @@ -196,7 +196,7 @@

Apps:

- Chess [NOT WORKING] + Chess
+ + + + + \ No newline at end of file diff --git a/src/http/server.rs b/src/http/server.rs index 3608ea1a..95d21d45 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -1,11 +1,13 @@ use crate::http::types::*; use crate::http::utils::*; -use crate::register; use crate::types::*; +use crate::{keygen, register}; use anyhow::Result; use dashmap::DashMap; use futures::{SinkExt, StreamExt}; +use http::uri::Authority; use route_recognizer::Router; +use sha2::{Digest, Sha256}; use std::collections::HashMap; use std::net::SocketAddr; use std::sync::Arc; @@ -14,7 +16,12 @@ use warp::http::{header::HeaderValue, StatusCode}; use warp::ws::{WebSocket, Ws}; use warp::{Filter, Reply}; +#[cfg(not(feature = "simulation-mode"))] const HTTP_SELF_IMPOSED_TIMEOUT: u64 = 15; +#[cfg(feature = "simulation-mode")] +const HTTP_SELF_IMPOSED_TIMEOUT: u64 = 600; + +const LOGIN_HTML: &str = include_str!("login.html"); /// mapping from a given HTTP request (assigned an ID) to the oneshot /// channel that will get a response from the app that handles the request, @@ -29,14 +36,23 @@ type WebSocketSenders = Arc>; type WebSocketSender = tokio::sync::mpsc::Sender; type PathBindings = Arc>>; +type WsPathBindings = Arc>>; struct BoundPath { pub app: ProcessId, + pub secure_subdomain: Option, pub authenticated: bool, pub local_only: bool, pub static_content: Option, // TODO store in filesystem and cache } +struct BoundWsPath { + pub app: ProcessId, + pub secure_subdomain: Option, + pub authenticated: bool, + pub encrypted: bool, // TODO use +} + /// HTTP server: a runtime module that handles HTTP requests at a given port. /// The server accepts bindings-requests from apps. These can be used in two ways: /// @@ -55,34 +71,41 @@ struct BoundPath { pub async fn http_server( our_name: String, our_port: u16, + encoded_keyfile: Vec, jwt_secret_bytes: Vec, mut recv_in_server: MessageReceiver, send_to_loop: MessageSender, print_tx: PrintSender, ) -> Result<()> { let our_name = Arc::new(our_name); + let encoded_keyfile = Arc::new(encoded_keyfile); let jwt_secret_bytes = Arc::new(jwt_secret_bytes); let http_response_senders: HttpResponseSenders = Arc::new(DashMap::new()); let ws_senders: WebSocketSenders = Arc::new(DashMap::new()); - // Add RPC path + // add RPC path let mut bindings_map: Router = Router::new(); let rpc_bound_path = BoundPath { app: ProcessId::from_str("rpc:sys:uqbar").unwrap(), + secure_subdomain: None, // TODO maybe RPC should have subdomain? authenticated: false, local_only: true, static_content: None, }; bindings_map.add("/rpc:sys:uqbar/message", rpc_bound_path); - let path_bindings: PathBindings = Arc::new(RwLock::new(bindings_map)); + // ws path bindings + let ws_path_bindings: WsPathBindings = Arc::new(RwLock::new(Router::new())); + tokio::spawn(serve( our_name.clone(), our_port, http_response_senders.clone(), path_bindings.clone(), + ws_path_bindings.clone(), ws_senders.clone(), + encoded_keyfile.clone(), jwt_secret_bytes.clone(), send_to_loop.clone(), print_tx.clone(), @@ -94,10 +117,9 @@ pub async fn http_server( km, http_response_senders.clone(), path_bindings.clone(), + ws_path_bindings.clone(), ws_senders.clone(), - jwt_secret_bytes.clone(), send_to_loop.clone(), - print_tx.clone(), ) .await; } @@ -111,7 +133,9 @@ async fn serve( our_port: u16, http_response_senders: HttpResponseSenders, path_bindings: PathBindings, + ws_path_bindings: WsPathBindings, ws_senders: WebSocketSenders, + encoded_keyfile: Arc>, jwt_secret_bytes: Arc>, send_to_loop: MessageSender, print_tx: PrintSender, @@ -123,42 +147,42 @@ async fn serve( }) .await; - // Filter to receive websockets + // filter to receive websockets let cloned_msg_tx = send_to_loop.clone(); let cloned_our = our.clone(); let cloned_jwt_secret_bytes = jwt_secret_bytes.clone(); let cloned_print_tx = print_tx.clone(); - let ws_route = warp::path::end() - .and(warp::ws()) + let ws_route = warp::ws() + .and(warp::path::full()) + .and(warp::filters::host::optional()) + .and(warp::filters::header::headers_cloned()) .and(warp::any().map(move || cloned_our.clone())) .and(warp::any().map(move || cloned_jwt_secret_bytes.clone())) .and(warp::any().map(move || ws_senders.clone())) + .and(warp::any().map(move || ws_path_bindings.clone())) .and(warp::any().map(move || cloned_msg_tx.clone())) .and(warp::any().map(move || cloned_print_tx.clone())) - .map( - |ws_connection: Ws, - our: Arc, - jwt_secret_bytes: Arc>, - ws_senders: WebSocketSenders, - send_to_loop: MessageSender, - print_tx: PrintSender| { - ws_connection.on_upgrade(move |ws: WebSocket| async move { - maintain_websocket( - ws, - our, - jwt_secret_bytes, - ws_senders, - send_to_loop, - print_tx, - ) - .await - }) - }, - ); - // Filter to receive HTTP requests + .and_then(ws_handler); + + // filter to receive and handle login requests + let cloned_our = our.clone(); + let login = warp::path("login").and(warp::path::end()).and( + warp::get() + .map(|| warp::reply::with_status(warp::reply::html(LOGIN_HTML), StatusCode::OK)) + .or(warp::post() + .and(warp::body::content_length_limit(1024 * 16)) + .and(warp::body::json()) + .and(warp::any().map(move || cloned_our.clone())) + .and(warp::any().map(move || encoded_keyfile.clone())) + .and_then(login_handler)), + ); + + // filter to receive all other HTTP requests let filter = warp::filters::method::method() .and(warp::addr::remote()) + .and(warp::filters::host::optional()) .and(warp::path::full()) + .and(warp::query::>()) .and(warp::filters::header::headers_cloned()) .and(warp::filters::body::bytes()) .and(warp::any().map(move || our.clone())) @@ -166,18 +190,148 @@ async fn serve( .and(warp::any().map(move || path_bindings.clone())) .and(warp::any().map(move || jwt_secret_bytes.clone())) .and(warp::any().map(move || send_to_loop.clone())) + .and(warp::any().map(move || print_tx.clone())) .and_then(http_handler); - let filter_with_ws = ws_route.or(filter); + let filter_with_ws = ws_route.or(login).or(filter); warp::serve(filter_with_ws) .run(([0, 0, 0, 0], our_port)) .await; } +/// handle non-GET requests on /login. if POST, validate password +/// and return auth token, which will be stored in a cookie. +/// then redirect to wherever they were trying to go. +async fn login_handler( + info: LoginInfo, + our: Arc, + encoded_keyfile: Arc>, +) -> Result { + match keygen::decode_keyfile(&encoded_keyfile, &info.password) { + Ok(keyfile) => { + let token = match register::generate_jwt(&keyfile.jwt_secret_bytes, our.as_ref()) { + Some(token) => token, + None => { + return Ok(warp::reply::with_status( + warp::reply::json(&"Failed to generate JWT"), + StatusCode::SERVICE_UNAVAILABLE, + ) + .into_response()) + } + }; + + let mut response = warp::reply::with_status( + warp::reply::json(&base64::encode(encoded_keyfile.to_vec())), + StatusCode::FOUND, + ) + .into_response(); + + match HeaderValue::from_str(&format!("uqbar-auth_{}={};", our.as_ref(), &token)) { + Ok(v) => { + response.headers_mut().append(http::header::SET_COOKIE, v); + Ok(response) + } + Err(_) => { + return Ok(warp::reply::with_status( + warp::reply::json(&"Failed to generate Auth JWT"), + StatusCode::INTERNAL_SERVER_ERROR, + ) + .into_response()) + } + } + } + Err(_) => Ok(warp::reply::with_status( + warp::reply::json(&"Failed to decode keyfile"), + StatusCode::INTERNAL_SERVER_ERROR, + ) + .into_response()), + } +} + +async fn ws_handler( + ws_connection: Ws, + path: warp::path::FullPath, + host: Option, + headers: warp::http::HeaderMap, + our: Arc, + jwt_secret_bytes: Arc>, + ws_senders: WebSocketSenders, + ws_path_bindings: WsPathBindings, + send_to_loop: MessageSender, + print_tx: PrintSender, +) -> Result { + let original_path = normalize_path(path.as_str()); + let _ = print_tx.send(Printout { + verbosity: 1, + content: format!("got ws request for {original_path}"), + }); + + let serialized_headers = serialize_headers(&headers); + let ws_path_bindings = ws_path_bindings.read().await; + + let Ok(route) = ws_path_bindings.recognize(&original_path) else { + return Err(warp::reject::not_found()); + }; + + let bound_path = route.handler(); + if let Some(ref subdomain) = bound_path.secure_subdomain { + let _ = print_tx + .send(Printout { + verbosity: 1, + content: format!( + "got request for path {original_path} bound by subdomain {subdomain}" + ), + }) + .await; + // assert that host matches what this app wants it to be + if host.is_none() { + return Err(warp::reject::not_found()); + } + let host = host.as_ref().unwrap(); + // parse out subdomain from host (there can only be one) + let request_subdomain = host.host().split('.').next().unwrap_or(""); + if request_subdomain != subdomain { + return Err(warp::reject::not_found()); + } + } + + if bound_path.authenticated { + let Some(auth_token) = serialized_headers.get("cookie") else { + return Err(warp::reject::not_found()); + }; + if !auth_cookie_valid(&our, &auth_token, &jwt_secret_bytes) { + return Err(warp::reject::not_found()); + } + } + + let app = bound_path.app.clone(); + Ok(ws_connection.on_upgrade(move |ws: WebSocket| async move { + maintain_websocket( + ws, + our.clone(), + app, + // remove process id from beginning of path by splitting into segments + // separated by "/" and taking all but the first + original_path + .split('/') + .skip(1) + .collect::>() + .join("/"), + jwt_secret_bytes.clone(), + ws_senders.clone(), + send_to_loop.clone(), + print_tx.clone(), + ) + .await; + })) +} + async fn http_handler( method: warp::http::Method, socket_addr: Option, + host: Option, path: warp::path::FullPath, + query_params: HashMap, headers: warp::http::HeaderMap, body: warp::hyper::body::Bytes, our: Arc, @@ -185,11 +339,18 @@ async fn http_handler( path_bindings: PathBindings, jwt_secret_bytes: Arc>, send_to_loop: MessageSender, + print_tx: PrintSender, ) -> Result { // TODO this is all so dirty. Figure out what actually matters. // trim trailing "/" let original_path = normalize_path(path.as_str()); + let _ = print_tx + .send(Printout { + verbosity: 1, + content: format!("got request for path {original_path}"), + }) + .await; let id: u64 = rand::random(); let serialized_headers = serialize_headers(&headers); let path_bindings = path_bindings.read().await; @@ -200,11 +361,55 @@ async fn http_handler( let bound_path = route.handler(); if bound_path.authenticated { - let auth_token = serialized_headers - .get("cookie") - .cloned() - .unwrap_or_default(); - if !auth_cookie_valid(&our, &auth_token, &jwt_secret_bytes) { + match serialized_headers.get("cookie") { + Some(auth_token) => { + // they have an auth token, validate + if !auth_cookie_valid(&our, &auth_token, &jwt_secret_bytes) { + return Ok( + warp::reply::with_status(vec![], StatusCode::UNAUTHORIZED).into_response() + ); + } + } + None => { + // redirect to login page so they can get an auth token + let _ = print_tx + .send(Printout { + verbosity: 1, + content: format!("redirecting request from {socket_addr:?} to login page"), + }) + .await; + return Ok(warp::http::Response::builder() + .status(StatusCode::TEMPORARY_REDIRECT) + .header( + "Location", + format!( + "http://{}/login", + host.unwrap_or(Authority::from_static("localhost")) + ), + ) + .body(vec![]) + .into_response()); + } + } + } + + if let Some(ref subdomain) = bound_path.secure_subdomain { + let _ = print_tx + .send(Printout { + verbosity: 1, + content: format!( + "got request for path {original_path} bound by subdomain {subdomain}" + ), + }) + .await; + // assert that host matches what this app wants it to be + if host.is_none() { + return Ok(warp::reply::with_status(vec![], StatusCode::UNAUTHORIZED).into_response()); + } + let host = host.as_ref().unwrap(); + // parse out subdomain from host (there can only be one) + let request_subdomain = host.host().split('.').next().unwrap_or(""); + if request_subdomain != subdomain { return Ok(warp::reply::with_status(vec![], StatusCode::UNAUTHORIZED).into_response()); } } @@ -258,14 +463,20 @@ async fn http_handler( message: Message::Request(Request { inherit: false, expects_response: Some(HTTP_SELF_IMPOSED_TIMEOUT), - ipc: serde_json::to_vec(&IncomingHttpRequest { + ipc: serde_json::to_vec(&HttpServerRequest::Http(IncomingHttpRequest { source_socket_addr: socket_addr.map(|addr| addr.to_string()), method: method.to_string(), - raw_path: format!("http://localhost{}", original_path), + raw_path: format!( + "http://{}{}", + host.unwrap_or(Authority::from_static("localhost")) + .to_string(), + original_path + ), headers: serialized_headers, - }) + query_params, + })) .unwrap(), - metadata: None, + metadata: Some("http".into()), }), payload: Some(Payload { mime: None, @@ -387,57 +598,25 @@ async fn handle_rpc_message( async fn maintain_websocket( ws: WebSocket, our: Arc, - jwt_secret_bytes: Arc>, + app: ProcessId, + path: String, + _jwt_secret_bytes: Arc>, // TODO use for encrypted channels ws_senders: WebSocketSenders, send_to_loop: MessageSender, - _print_tx: PrintSender, + print_tx: PrintSender, ) { let (mut write_stream, mut read_stream) = ws.split(); + let _ = print_tx + .send(Printout { + verbosity: 1, + content: format!("got new client websocket connection"), + }) + .await; - // first, receive a message from client that contains the target process - // and the auth token - - let Some(Ok(register_msg)) = read_stream.next().await else { - // stream closed, exit - let stream = write_stream.reunite(read_stream).unwrap(); - let _ = stream.close().await; - return; - }; - - let Ok(ws_register) = serde_json::from_slice::(register_msg.as_bytes()) else { - // stream error, exit - let stream = write_stream.reunite(read_stream).unwrap(); - let _ = stream.close().await; - return; - }; - - let Ok(owner_process) = ProcessId::from_str(&ws_register.target_process) else { - // invalid process id, exit - let stream = write_stream.reunite(read_stream).unwrap(); - let _ = stream.close().await; - return; - }; - - let Ok(our_name) = verify_auth_token(&ws_register.auth_token, &jwt_secret_bytes) else { - // invalid auth token, exit - let stream = write_stream.reunite(read_stream).unwrap(); - let _ = stream.close().await; - return; - }; - - if our_name != *our { - // invalid auth token, exit - let stream = write_stream.reunite(read_stream).unwrap(); - let _ = stream.close().await; - return; - } - - let ws_channel_id: u32 = rand::random(); + let channel_id: u32 = rand::random(); let (ws_sender, mut ws_receiver) = tokio::sync::mpsc::channel(100); - ws_senders.insert(ws_channel_id, (owner_process.clone(), ws_sender)); + ws_senders.insert(channel_id, (app.clone(), ws_sender)); - // send a message to the process associated with this channel - // notifying them that the channel is now open let _ = send_to_loop .send(KernelMessage { id: rand::random(), @@ -446,91 +625,69 @@ async fn maintain_websocket( process: HTTP_SERVER_PROCESS_ID.clone(), }, target: Address { - node: our.to_string(), - process: owner_process.clone(), + node: our.clone().to_string(), + process: app.clone(), }, rsvp: None, message: Message::Request(Request { inherit: false, expects_response: None, - ipc: serde_json::to_vec(&HttpServerAction::WebSocketOpen(ws_channel_id)).unwrap(), - metadata: None, + ipc: serde_json::to_vec(&HttpServerRequest::WebSocketOpen { path, channel_id }) + .unwrap(), + metadata: Some("ws".into()), }), payload: None, signed_capabilities: None, }) .await; - // respond to the client notifying them that the channel is now open - let Ok(()) = write_stream - .send(warp::ws::Message::text( - serde_json::to_string(&WsRegisterResponse { - channel_id: ws_channel_id, - }) - .unwrap(), - )) - .await - else { - // stream error, exit - let stream = write_stream.reunite(read_stream).unwrap(); - let _ = stream.close().await; - return; - }; - + let _ = print_tx.send(Printout { + verbosity: 1, + content: format!("websocket channel {channel_id} opened"), + }); loop { tokio::select! { read = read_stream.next() => { match read { - None => { - // stream closed, remove and exit - websocket_close(ws_channel_id, owner_process, &ws_senders, &send_to_loop).await; - break; - } - Some(Err(_e)) => { - // stream error, remove and exit - websocket_close(ws_channel_id, owner_process, &ws_senders, &send_to_loop).await; - break; - } Some(Ok(msg)) => { - // forward message to process associated with this channel - let _ = send_to_loop - .send(KernelMessage { - id: rand::random(), - source: Address { - node: our.to_string(), - process: HTTP_SERVER_PROCESS_ID.clone(), - }, - target: Address { - node: our.to_string(), - process: owner_process.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: false, - expects_response: None, - ipc: serde_json::to_vec(&HttpServerAction::WebSocketPush { - channel_id: ws_channel_id, - message_type: WsMessageType::Binary, - }).unwrap(), - metadata: None, - }), - payload: Some(Payload { - mime: None, - bytes: msg.into_bytes(), - }), - signed_capabilities: None, - }) - .await; + let _ = send_to_loop.send(KernelMessage { + id: rand::random(), + source: Address { + node: our.to_string(), + process: HTTP_SERVER_PROCESS_ID.clone(), + }, + target: Address { + node: our.to_string(), + process: app.clone(), + }, + rsvp: None, + message: Message::Request(Request { + inherit: false, + expects_response: None, + ipc: serde_json::to_vec(&HttpServerRequest::WebSocketPush { + channel_id, + message_type: WsMessageType::Binary, + }).unwrap(), + metadata: Some("ws".into()), + }), + payload: Some(Payload { + mime: None, + bytes: msg.into_bytes(), + }), + signed_capabilities: None, + }); + } + _ => { + websocket_close(channel_id, app.clone(), &ws_senders, &send_to_loop).await; + break; } } } Some(outgoing) = ws_receiver.recv() => { - // forward message to websocket match write_stream.send(outgoing).await { Ok(()) => continue, - Err(_e) => { - // stream error, remove and exit - websocket_close(ws_channel_id, owner_process, &ws_senders, &send_to_loop).await; + Err(_) => { + websocket_close(channel_id, app.clone(), &ws_senders, &send_to_loop).await; break; } } @@ -563,8 +720,8 @@ async fn websocket_close( message: Message::Request(Request { inherit: false, expects_response: None, - ipc: serde_json::to_vec(&HttpServerAction::WebSocketClose(channel_id)).unwrap(), - metadata: None, + ipc: serde_json::to_vec(&HttpServerRequest::WebSocketClose(channel_id)).unwrap(), + metadata: Some("ws".into()), }), payload: Some(Payload { mime: None, @@ -583,10 +740,9 @@ async fn handle_app_message( km: KernelMessage, http_response_senders: HttpResponseSenders, path_bindings: PathBindings, + ws_path_bindings: WsPathBindings, ws_senders: WebSocketSenders, - jwt_secret_bytes: Arc>, send_to_loop: MessageSender, - print_tx: PrintSender, ) { // when we get a Response, try to match it to an outstanding HTTP // request and send it there. @@ -618,60 +774,10 @@ async fn handle_app_message( .unwrap(), )); } else { - let Ok(mut response) = serde_json::from_slice::(&response.ipc) else { + let Ok(response) = serde_json::from_slice::(&response.ipc) else { // the receiver will automatically trigger a 503 when sender is dropped. return; }; - // XX REFACTOR THIS: - // for the login case, todo refactor out? - let segments: Vec<&str> = path - .split('/') - .filter(|&segment| !segment.is_empty()) - .collect(); - // If we're getting back a /login from a proxy (or our own node), - // then we should generate a jwt from the secret + the name of the ship, - // and then attach it to a header. - if response.status < 400 - && (segments.len() == 1 || segments.len() == 4) - && matches!(segments.last(), Some(&"login")) - { - if let Some(auth_cookie) = response.headers.get("set-cookie") { - let mut ws_auth_username = km.source.node.clone(); - - if segments.len() == 4 - && matches!(segments.first(), Some(&"http-proxy")) - && matches!(segments.get(1), Some(&"serve")) - { - if let Some(segment) = segments.get(2) { - ws_auth_username = segment.to_string(); - } - } - if let Some(token) = register::generate_jwt( - jwt_secret_bytes.to_vec().as_slice(), - ws_auth_username.clone(), - ) { - let auth_cookie_with_ws = format!( - "{}; uqbar-ws-auth_{}={};", - auth_cookie, - ws_auth_username.clone(), - token - ); - response - .headers - .insert("set-cookie".to_string(), auth_cookie_with_ws); - - let _ = print_tx - .send(Printout { - verbosity: 2, - content: format!( - "SET WS AUTH COOKIE WITH USERNAME: {}", - ws_auth_username - ), - }) - .await; - } - } - } let _ = sender.send(( HttpResponse { status: response.status, @@ -722,6 +828,7 @@ async fn handle_app_message( &normalize_path(&path), BoundPath { app: km.source.process.clone(), + secure_subdomain: None, authenticated, local_only, static_content: None, @@ -743,6 +850,7 @@ async fn handle_app_message( &normalize_path(&path), BoundPath { app: km.source.process.clone(), + secure_subdomain: None, authenticated, local_only, static_content: Some(payload), @@ -751,7 +859,99 @@ async fn handle_app_message( } send_action_response(km.id, km.source, &send_to_loop, Ok(())).await; } - HttpServerAction::WebSocketOpen(_) => { + HttpServerAction::SecureBind { path, cache } => { + // the process ID is hashed to generate a unique subdomain + // only the first 32 chars, or 128 bits are used. + // we hash because the process ID can contain many more than + // simply alphanumeric characters that will cause issues as a subdomain. + let process_id_hash = + format!("{:x}", Sha256::digest(km.source.process.to_string())); + let subdomain = process_id_hash.split_at(32).0.to_owned(); + let mut path_bindings = path_bindings.write().await; + if !cache { + // trim trailing "/" + path_bindings.add( + &normalize_path(&path), + BoundPath { + app: km.source.process.clone(), + secure_subdomain: Some(subdomain), + authenticated: true, + local_only: false, + static_content: None, + }, + ); + } else { + let Some(payload) = km.payload else { + send_action_response( + km.id, + km.source, + &send_to_loop, + Err(HttpServerError::NoPayload), + ) + .await; + return; + }; + // trim trailing "/" + path_bindings.add( + &normalize_path(&path), + BoundPath { + app: km.source.process.clone(), + secure_subdomain: Some(subdomain), + authenticated: true, + local_only: false, + static_content: Some(payload), + }, + ); + } + send_action_response(km.id, km.source, &send_to_loop, Ok(())).await; + } + HttpServerAction::WebSocketBind { + mut path, + authenticated, + encrypted, + } => { + path = if path.starts_with('/') { + format!("/{}{}", km.source.process, path) + } else { + format!("/{}/{}", km.source.process, path) + }; + let mut ws_path_bindings = ws_path_bindings.write().await; + ws_path_bindings.add( + &normalize_path(&path), + BoundWsPath { + app: km.source.process.clone(), + secure_subdomain: None, + authenticated, + encrypted, + }, + ); + send_action_response(km.id, km.source, &send_to_loop, Ok(())).await; + } + HttpServerAction::WebSocketSecureBind { + mut path, + encrypted, + } => { + path = if path.starts_with('/') { + format!("/{}{}", km.source.process, path) + } else { + format!("/{}/{}", km.source.process, path) + }; + let process_id_hash = + format!("{:x}", Sha256::digest(km.source.process.to_string())); + let subdomain = process_id_hash.split_at(32).0.to_owned(); + let mut ws_path_bindings = ws_path_bindings.write().await; + ws_path_bindings.add( + &normalize_path(&path), + BoundWsPath { + app: km.source.process.clone(), + secure_subdomain: Some(subdomain), + authenticated: true, + encrypted, + }, + ); + send_action_response(km.id, km.source, &send_to_loop, Ok(())).await; + } + HttpServerAction::WebSocketOpen { .. } => { // we cannot receive these, only send them to processes send_action_response( km.id, diff --git a/src/http/types.rs b/src/http/types.rs index ecba6711..0dbff938 100644 --- a/src/http/types.rs +++ b/src/http/types.rs @@ -5,12 +5,35 @@ use thiserror::Error; /// HTTP Request type that can be shared over WASM boundary to apps. /// This is the one you receive from the `http_server:sys:uqbar` service. +#[derive(Debug, Serialize, Deserialize)] +pub enum HttpServerRequest { + Http(IncomingHttpRequest), + /// Processes will receive this kind of request when a client connects to them. + /// If a process does not want this websocket open, they should issue a *request* + /// containing a [`type@HttpServerAction::WebSocketClose`] message and this channel ID. + WebSocketOpen { + path: String, + channel_id: u32, + }, + /// Processes can both SEND and RECEIVE this kind of request + /// (send as [`type@HttpServerAction::WebSocketPush`]). + /// When received, will contain the message bytes as payload. + WebSocketPush { + channel_id: u32, + message_type: WsMessageType, + }, + /// Receiving will indicate that the client closed the socket. Can be sent to close + /// from the server-side, as [`type@HttpServerAction::WebSocketClose`]. + WebSocketClose(u32), +} + #[derive(Debug, Serialize, Deserialize)] pub struct IncomingHttpRequest { pub source_socket_addr: Option, // will parse to SocketAddr pub method: String, // will parse to http::Method pub raw_path: String, pub headers: HashMap, + pub query_params: HashMap, // BODY is stored in the payload, as bytes } @@ -56,8 +79,8 @@ pub enum HttpClientError { } /// Request type sent to `http_server:sys:uqbar` in order to configure it. -/// You can also send [`WebSocketPush`], which allows you to push messages -/// across an existing open WebSocket connection. +/// You can also send [`type@HttpServerAction::WebSocketPush`], which +/// allows you to push messages across an existing open WebSocket connection. /// /// If a response is expected, all HttpServerActions will return a Response /// with the shape Result<(), HttpServerActionError> serialized to JSON. @@ -67,23 +90,53 @@ pub enum HttpServerAction { /// be the static file to serve at this path. Bind { path: String, + /// Set whether the HTTP request needs a valid login cookie, AKA, whether + /// the user needs to be logged in to access this path. authenticated: bool, + /// Set whether requests can be fielded from anywhere, or only the loopback address. local_only: bool, + /// Set whether to bind the payload statically to this path. That is, take the + /// payload bytes and serve them as the response to any request to this path. cache: bool, }, + /// SecureBind expects a payload if and only if `cache` is TRUE. The payload should + /// be the static file to serve at this path. + /// + /// SecureBind is the same as Bind, except that it forces requests to be made from + /// the unique subdomain of the process that bound the path. These requests are + /// *always* authenticated, and *never* local_only. The purpose of SecureBind is to + /// serve elements of an app frontend or API in an exclusive manner, such that other + /// apps installed on this node cannot access them. Since the subdomain is unique, it + /// will require the user to be logged in separately to the general domain authentication. + SecureBind { + path: String, + /// Set whether to bind the payload statically to this path. That is, take the + /// payload bytes and serve them as the response to any request to this path. + cache: bool, + }, + /// Bind a path to receive incoming WebSocket connections. + /// Doesn't need a cache since does not serve assets. + WebSocketBind { + path: String, + authenticated: bool, + encrypted: bool, + }, + /// SecureBind is the same as Bind, except that it forces new connections to be made + /// from the unique subdomain of the process that bound the path. These are *always* + /// authenticated. Since the subdomain is unique, it will require the user to be + /// logged in separately to the general domain authentication. + WebSocketSecureBind { path: String, encrypted: bool }, /// Processes will RECEIVE this kind of request when a client connects to them. + /// If a process does not want this websocket open, they should issue a *request* - /// containing a [`enum@HttpServerAction::WebSocketClose`] message and this channel ID. - WebSocketOpen(u32), - /// Processes can both SEND and RECEIVE this kind of request. + /// containing a [`type@HttpServerAction::WebSocketClose`] message and this channel ID. + WebSocketOpen { path: String, channel_id: u32 }, /// When sent, expects a payload containing the WebSocket message bytes to send. WebSocketPush { channel_id: u32, message_type: WsMessageType, }, - /// Processes can both SEND and RECEIVE this kind of request. Sending will - /// close a socket the process controls. Receiving will indicate that the - /// client closed the socket. + /// Sending will close a socket the process controls. WebSocketClose(u32), } diff --git a/src/http/utils.rs b/src/http/utils.rs index f33202b8..81393bf1 100644 --- a/src/http/utils.rs +++ b/src/http/utils.rs @@ -21,11 +21,13 @@ pub struct RpcMessage { } /// Ingest an auth token given from client and return the node name or an error. -pub fn verify_auth_token(auth_token: &str, jwt_secret: &[u8]) -> Result { +pub fn _verify_auth_token(auth_token: &str, jwt_secret: &[u8]) -> Result { let Ok(secret) = Hmac::::new_from_slice(jwt_secret) else { return Err(jwt::Error::Format); }; + println!("hello\r"); + let claims: Result = auth_token.verify_with_key(&secret); match claims { diff --git a/src/kernel/mod.rs b/src/kernel/mod.rs index 67690734..4b995a64 100644 --- a/src/kernel/mod.rs +++ b/src/kernel/mod.rs @@ -1,5 +1,5 @@ -use crate::types as t; -use crate::FILESYSTEM_PROCESS_ID; +use crate::types::STATE_PROCESS_ID; +use crate::types::{self as t, VFS_PROCESS_ID}; use crate::KERNEL_PROCESS_ID; use anyhow::Result; use ring::signature::{self, KeyPair}; @@ -57,13 +57,14 @@ async fn persist_state( }, target: t::Address { node: our_name.to_string(), - process: FILESYSTEM_PROCESS_ID.clone(), + process: STATE_PROCESS_ID.clone(), }, rsvp: None, message: t::Message::Request(t::Request { inherit: true, expects_response: None, - ipc: serde_json::to_vec(&t::FsAction::SetState(KERNEL_PROCESS_ID.clone())).unwrap(), + ipc: serde_json::to_vec(&t::StateAction::SetState(KERNEL_PROCESS_ID.clone())) + .unwrap(), metadata: None, }), payload: Some(t::Payload { mime: None, bytes }), @@ -142,7 +143,7 @@ async fn handle_kernel_request( t::KernelCommand::InitializeProcess { id, wasm_bytes_handle, - on_panic, + on_exit, initial_capabilities, public, } => { @@ -248,7 +249,7 @@ async fn handle_kernel_request( process_id: id, persisted: t::PersistedProcess { wasm_bytes_handle, - on_panic, + on_exit, capabilities: valid_capabilities, public, }, @@ -453,8 +454,8 @@ async fn handle_kernel_response( .await; return; }; - // ignore responses that aren't filesystem responses - if km.source.process != *FILESYSTEM_PROCESS_ID { + // ignore responses that aren't filesystem or state responses + if km.source.process != *STATE_PROCESS_ID && km.source.process != *VFS_PROCESS_ID { return; } let Some(ref metadata) = response.metadata else { @@ -571,8 +572,8 @@ async fn start_process( node: our_name.clone(), process: id.clone(), }, - wasm_bytes_handle: process_metadata.persisted.wasm_bytes_handle, - on_panic: process_metadata.persisted.on_panic.clone(), + wasm_bytes_handle: process_metadata.persisted.wasm_bytes_handle.clone(), + on_exit: process_metadata.persisted.on_exit.clone(), public: process_metadata.persisted.public, }; process_handles.insert( @@ -659,7 +660,7 @@ pub async fn kernel( for (process_id, persisted) in &process_map { // runtime extensions will have a bytes_handle of 0, because they have no // WASM code saved in filesystem. - if persisted.on_panic.is_restart() && persisted.wasm_bytes_handle != 0 { + if persisted.on_exit.is_restart() && persisted.wasm_bytes_handle != "" { send_to_loop .send(t::KernelMessage { id: rand::random(), @@ -669,14 +670,17 @@ pub async fn kernel( }, target: t::Address { node: our.name.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), + process: VFS_PROCESS_ID.clone(), }, rsvp: None, message: t::Message::Request(t::Request { inherit: true, expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&t::FsAction::Read(persisted.wasm_bytes_handle)) - .unwrap(), + ipc: serde_json::to_vec(&t::VfsRequest { + path: persisted.wasm_bytes_handle.clone(), + action: t::VfsAction::Read, + }) + .unwrap(), metadata: Some( serde_json::to_string(&StartProcessMetadata { source: t::Address { @@ -696,7 +700,7 @@ pub async fn kernel( .await .expect("event loop: fatal: sender died"); } - if let t::OnPanic::Requests(requests) = &persisted.on_panic { + if let t::OnExit::Requests(requests) = &persisted.on_exit { // if a persisted process had on-death-requests, we should perform them now // even in death, a process can only message processes it has capabilities for for (address, request, payload) in requests { @@ -851,7 +855,7 @@ pub async fn kernel( verbosity: 0, content: format!( "event loop: don't have {} amongst registered processes (got message for it from network)", - kernel_message.source.process, + kernel_message.target.process, ) }) .await; @@ -881,7 +885,7 @@ pub async fn kernel( // enforce that local process has capability to message a target process of this name // kernel and filesystem can ALWAYS message any local process if kernel_message.source.process != *KERNEL_PROCESS_ID - && kernel_message.source.process != *FILESYSTEM_PROCESS_ID + && kernel_message.source.process != *STATE_PROCESS_ID { let Some(persisted_source) = process_map.get(&kernel_message.source.process) else { continue diff --git a/src/kernel/process.rs b/src/kernel/process.rs index 1bbe1520..2f47fe32 100644 --- a/src/kernel/process.rs +++ b/src/kernel/process.rs @@ -534,11 +534,11 @@ pub async fn make_process_loop( .await .expect("event loop: fatal: sender died"); - // fulfill the designated OnPanic behavior - match metadata.on_panic { - t::OnPanic::None => {} + // fulfill the designated OnExit behavior + match metadata.on_exit { + t::OnExit::None => {} // if restart, tell ourselves to init the app again, with same capabilities - t::OnPanic::Restart => { + t::OnExit::Restart => { send_to_loop .send(t::KernelMessage { id: rand::random(), @@ -551,7 +551,7 @@ pub async fn make_process_loop( ipc: serde_json::to_vec(&t::KernelCommand::InitializeProcess { id: metadata.our.process.clone(), wasm_bytes_handle: metadata.wasm_bytes_handle, - on_panic: metadata.on_panic, + on_exit: metadata.on_exit, initial_capabilities, public: metadata.public, }) @@ -569,7 +569,7 @@ pub async fn make_process_loop( } // if requests, fire them // even in death, a process can only message processes it has capabilities for - t::OnPanic::Requests(requests) => { + t::OnExit::Requests(requests) => { for (address, mut request, payload) in requests { request.expects_response = None; let (tx, rx) = tokio::sync::oneshot::channel(); diff --git a/src/kernel/standard_host.rs b/src/kernel/standard_host.rs index c08884e0..8b1d5a43 100644 --- a/src/kernel/standard_host.rs +++ b/src/kernel/standard_host.rs @@ -1,7 +1,7 @@ use crate::kernel::process; use crate::kernel::process::uqbar::process::standard as wit; use crate::types as t; -use crate::FILESYSTEM_PROCESS_ID; +use crate::types::STATE_PROCESS_ID; use crate::KERNEL_PROCESS_ID; use crate::VFS_PROCESS_ID; use anyhow::Result; @@ -40,11 +40,15 @@ impl StandardHost for process::ProcessWasi { // /// TODO critical: move to kernel logic to enable persistence of choice made here - async fn set_on_panic(&mut self, on_panic: wit::OnPanic) -> Result<()> { - self.process.metadata.on_panic = t::de_wit_on_panic(on_panic); + async fn set_on_exit(&mut self, on_exit: wit::OnExit) -> Result<()> { + self.process.metadata.on_exit = t::OnExit::de_wit(on_exit); Ok(()) } + async fn get_on_exit(&mut self) -> Result { + Ok(self.process.metadata.on_exit.en_wit()) + } + /// create a message from the *kernel* to the filesystem, /// asking it to fetch the current state saved under this process async fn get_state(&mut self) -> Result>> { @@ -57,12 +61,12 @@ impl StandardHost for process::ProcessWasi { }), wit::Address { node: self.process.metadata.our.node.clone(), - process: FILESYSTEM_PROCESS_ID.en_wit(), + process: STATE_PROCESS_ID.en_wit(), }, wit::Request { inherit: false, expects_response: Some(5), - ipc: serde_json::to_vec(&t::FsAction::GetState( + ipc: serde_json::to_vec(&t::StateAction::GetState( self.process.metadata.our.process.clone(), )) .unwrap(), @@ -98,12 +102,12 @@ impl StandardHost for process::ProcessWasi { }), wit::Address { node: self.process.metadata.our.node.clone(), - process: FILESYSTEM_PROCESS_ID.en_wit(), + process: STATE_PROCESS_ID.en_wit(), }, wit::Request { inherit: false, expects_response: Some(5), - ipc: serde_json::to_vec(&t::FsAction::SetState( + ipc: serde_json::to_vec(&t::StateAction::SetState( self.process.metadata.our.process.clone(), )) .unwrap(), @@ -137,12 +141,12 @@ impl StandardHost for process::ProcessWasi { }), wit::Address { node: self.process.metadata.our.node.clone(), - process: FILESYSTEM_PROCESS_ID.en_wit(), + process: STATE_PROCESS_ID.en_wit(), }, wit::Request { inherit: false, expects_response: Some(5), - ipc: serde_json::to_vec(&t::FsAction::DeleteState( + ipc: serde_json::to_vec(&t::StateAction::DeleteState( self.process.metadata.our.process.clone(), )) .unwrap(), @@ -171,7 +175,7 @@ impl StandardHost for process::ProcessWasi { &mut self, name: Option, wasm_path: String, // must be located within package's drive - on_panic: wit::OnPanic, + on_exit: wit::OnExit, capabilities: wit::Capabilities, public: bool, ) -> Result> { @@ -181,11 +185,18 @@ impl StandardHost for process::ProcessWasi { node: self.process.metadata.our.node.clone(), process: VFS_PROCESS_ID.en_wit(), }; - let our_drive_name = [ + // TODO: note, drive could just be your basic process maybe. + let path = format!( + "/{}/{}/{}", + self.process.metadata.our.process.to_string(), self.process.metadata.our.process.package(), - self.process.metadata.our.process.publisher(), - ] - .join(":"); + wasm_path + ); + // let our_drive_name = [ + // self.process.metadata.our.process.package(), + // self.process.metadata.our.process.publisher(), + // ] + // .join(":"); let Ok(Ok((_, hash_response))) = process::send_and_await_response( self, None, @@ -194,8 +205,8 @@ impl StandardHost for process::ProcessWasi { inherit: false, expects_response: Some(5), ipc: serde_json::to_vec(&t::VfsRequest { - drive: our_drive_name.clone(), - action: t::VfsAction::GetHash(wasm_path.clone()), + path: path.clone(), + action: t::VfsAction::Read, }) .unwrap(), metadata: None, @@ -214,29 +225,7 @@ impl StandardHost for process::ProcessWasi { self.process.last_payload = old_last_payload; return Ok(Err(wit::SpawnError::NoFileAtPath)); }; - let t::VfsResponse::GetHash(Some(hash)) = serde_json::from_slice(&ipc).unwrap() else { - // reset payload to what it was - self.process.last_payload = old_last_payload; - return Ok(Err(wit::SpawnError::NoFileAtPath)); - }; - let Ok(Ok(_)) = process::send_and_await_response( - self, - None, - vfs_address, - wit::Request { - inherit: false, - expects_response: Some(5), - ipc: serde_json::to_vec(&t::VfsRequest { - drive: our_drive_name, - action: t::VfsAction::GetEntry(wasm_path.clone()), - }) - .unwrap(), - metadata: None, - }, - None, - ) - .await - else { + let t::VfsResponse::Read = serde_json::from_slice(&ipc).unwrap() else { // reset payload to what it was self.process.last_payload = old_last_payload; return Ok(Err(wit::SpawnError::NoFileAtPath)); @@ -271,8 +260,8 @@ impl StandardHost for process::ProcessWasi { expects_response: Some(5), // TODO evaluate ipc: serde_json::to_vec(&t::KernelCommand::InitializeProcess { id: new_process_id.clone(), - wasm_bytes_handle: hash, - on_panic: t::de_wit_on_panic(on_panic), + wasm_bytes_handle: path, + on_exit: t::OnExit::de_wit(on_exit), initial_capabilities: match capabilities { wit::Capabilities::None => HashSet::new(), wit::Capabilities::All => { diff --git a/src/keygen.rs b/src/keygen.rs index a130a664..74762069 100644 --- a/src/keygen.rs +++ b/src/keygen.rs @@ -23,7 +23,7 @@ pub fn encode_keyfile( password: String, username: String, routers: Vec, - networking_key: Document, + networking_key: &[u8], jwt: Vec, file_key: Vec, ) -> Vec { @@ -49,9 +49,7 @@ pub fn encode_keyfile( let jwt_nonce = Aes256Gcm::generate_nonce(&mut OsRng); let file_nonce = Aes256Gcm::generate_nonce(&mut OsRng); - let keyciphertext: Vec = cipher - .encrypt(&network_nonce, networking_key.as_ref()) - .unwrap(); + let keyciphertext: Vec = cipher.encrypt(&network_nonce, networking_key).unwrap(); let jwtciphertext: Vec = cipher.encrypt(&jwt_nonce, jwt.as_ref()).unwrap(); let fileciphertext: Vec = cipher.encrypt(&file_nonce, file_key.as_ref()).unwrap(); @@ -66,9 +64,9 @@ pub fn encode_keyfile( .unwrap() } -pub fn decode_keyfile(keyfile: Vec, password: &str) -> Result { +pub fn decode_keyfile(keyfile: &[u8], password: &str) -> Result { let (username, routers, salt, key_enc, jwt_enc, file_enc) = - bincode::deserialize::<(String, Vec, Vec, Vec, Vec, Vec)>(&keyfile) + bincode::deserialize::<(String, Vec, Vec, Vec, Vec, Vec)>(keyfile) .map_err(|_| "failed to deserialize keyfile")?; // rederive disk key @@ -112,9 +110,9 @@ pub fn decode_keyfile(keyfile: Vec, password: &str) -> Result) -> Result<(String, Vec), &'static str> { +pub fn get_username_and_routers(keyfile: &[u8]) -> Result<(String, Vec), &'static str> { let (username, routers, _salt, _key_enc, _jwt_enc, _file_enc) = - bincode::deserialize::<(String, Vec, Vec, Vec, Vec, Vec)>(&keyfile) + bincode::deserialize::<(String, Vec, Vec, Vec, Vec, Vec)>(keyfile) .map_err(|_| "failed to deserialize keyfile")?; Ok((username, routers)) diff --git a/src/kv.rs b/src/kv.rs new file mode 100644 index 00000000..bdcb3144 --- /dev/null +++ b/src/kv.rs @@ -0,0 +1,520 @@ +use anyhow::Result; +use dashmap::DashMap; +// use rocksdb::checkpoint::Checkpoint; +use rocksdb::OptimisticTransactionDB; +use std::collections::{HashMap, VecDeque}; +use std::sync::Arc; +use tokio::fs; +use tokio::sync::Mutex; + +use crate::types::*; + +pub async fn kv( + our_node: String, + send_to_loop: MessageSender, + send_to_terminal: PrintSender, + mut recv_from_loop: MessageReceiver, + send_to_caps_oracle: CapMessageSender, + home_directory_path: String, +) -> anyhow::Result<()> { + let kv_path = format!("{}/kv", &home_directory_path); + + if let Err(e) = fs::create_dir_all(&kv_path).await { + panic!("failed creating kv dir! {:?}", e); + } + + let open_kvs: Arc> = + Arc::new(DashMap::new()); + let txs: Arc>)>>> = Arc::new(DashMap::new()); + + let mut process_queues: HashMap>>> = + HashMap::new(); + + loop { + tokio::select! { + Some(km) = recv_from_loop.recv() => { + if our_node.clone() != km.source.node { + println!( + "kv: request must come from our_node={}, got: {}", + our_node, + km.source.node, + ); + continue; + } + + let queue = process_queues + .entry(km.source.process.clone()) + .or_insert_with(|| Arc::new(Mutex::new(VecDeque::new()))) + .clone(); + + { + let mut queue_lock = queue.lock().await; + queue_lock.push_back(km.clone()); + } + + // clone Arcs + let our_node = our_node.clone(); + let send_to_caps_oracle = send_to_caps_oracle.clone(); + let send_to_terminal = send_to_terminal.clone(); + let send_to_loop = send_to_loop.clone(); + let open_kvs = open_kvs.clone(); + let txs = txs.clone(); + let kv_path = kv_path.clone(); + + tokio::spawn(async move { + let mut queue_lock = queue.lock().await; + if let Some(km) = queue_lock.pop_front() { + if let Err(e) = handle_request( + our_node.clone(), + km.clone(), + open_kvs.clone(), + txs.clone(), + send_to_loop.clone(), + send_to_terminal.clone(), + send_to_caps_oracle.clone(), + kv_path.clone(), + ) + .await + { + let _ = send_to_loop + .send(make_error_message(our_node.clone(), &km, e)) + .await; + } + } + }); + } + } + } +} + +async fn handle_request( + our_node: String, + km: KernelMessage, + open_kvs: Arc>, + txs: Arc>)>>>, + send_to_loop: MessageSender, + send_to_terminal: PrintSender, + send_to_caps_oracle: CapMessageSender, + kv_path: String, +) -> Result<(), KvError> { + let KernelMessage { + id, + source, + message, + payload, + .. + } = km.clone(); + let Message::Request(Request { + ipc, + expects_response, + metadata, + .. + }) = message.clone() + else { + return Err(KvError::InputError { + error: "not a request".into(), + }); + }; + + let request: KvRequest = match serde_json::from_slice(&ipc) { + Ok(r) => r, + Err(e) => { + println!("kv: got invalid Request: {}", e); + return Err(KvError::InputError { + error: "didn't serialize to KvAction.".into(), + }); + } + }; + + check_caps( + our_node.clone(), + source.clone(), + open_kvs.clone(), + send_to_caps_oracle.clone(), + &request, + kv_path.clone(), + ) + .await?; + + let (ipc, bytes) = match &request.action { + KvAction::New => { + // handled in check_caps. + (serde_json::to_vec(&KvResponse::Ok).unwrap(), None) + } + KvAction::Get { key } => { + let db = match open_kvs.get(&(request.package_id, request.db)) { + None => { + return Err(KvError::NoDb); + } + Some(db) => db, + }; + + match db.get(&key) { + Ok(Some(value)) => ( + serde_json::to_vec(&KvResponse::Get { key: key.to_vec() }).unwrap(), + Some(value), + ), + Ok(None) => { + return Err(KvError::KeyNotFound); + } + Err(e) => { + return Err(KvError::RocksDBError { + action: request.action.to_string(), + error: e.to_string(), + }) + } + } + } + KvAction::BeginTx => { + let tx_id = rand::random::(); + txs.insert(tx_id, Vec::new()); + ( + serde_json::to_vec(&KvResponse::BeginTx { tx_id }).unwrap(), + None, + ) + } + KvAction::Set { key, tx_id } => { + let db = match open_kvs.get(&(request.package_id, request.db)) { + None => { + return Err(KvError::NoDb); + } + Some(db) => db, + }; + let Some(payload) = payload else { + return Err(KvError::InputError { + error: "no payload".into(), + }); + }; + + match tx_id { + None => { + db.put(key, payload.bytes)?; + } + Some(tx_id) => { + let mut tx = match txs.get_mut(&tx_id) { + None => { + return Err(KvError::NoTx); + } + Some(tx) => tx, + }; + tx.push((request.action.clone(), Some(payload.bytes))); + } + } + + (serde_json::to_vec(&KvResponse::Ok).unwrap(), None) + } + KvAction::Delete { key, tx_id } => { + let db = match open_kvs.get(&(request.package_id, request.db)) { + None => { + return Err(KvError::NoDb); + } + Some(db) => db, + }; + match tx_id { + None => { + db.delete(key)?; + } + Some(tx_id) => { + let mut tx = match txs.get_mut(&tx_id) { + None => { + return Err(KvError::NoTx); + } + Some(tx) => tx, + }; + tx.push((request.action.clone(), None)); + } + } + (serde_json::to_vec(&KvResponse::Ok).unwrap(), None) + } + KvAction::Commit { tx_id } => { + let db = match open_kvs.get(&(request.package_id, request.db)) { + None => { + return Err(KvError::NoDb); + } + Some(db) => db, + }; + + let txs = match txs.remove(&tx_id).map(|(_, tx)| tx) { + None => { + return Err(KvError::NoTx); + } + Some(tx) => tx, + }; + let tx = db.transaction(); + + for (action, payload) in txs { + match action { + KvAction::Set { key, .. } => { + if let Some(payload) = payload { + tx.put(&key, &payload)?; + } + } + KvAction::Delete { key, .. } => { + tx.delete(&key)?; + } + _ => {} + } + } + + match tx.commit() { + Ok(_) => (serde_json::to_vec(&KvResponse::Ok).unwrap(), None), + Err(e) => { + return Err(KvError::RocksDBError { + action: request.action.to_string(), + error: e.to_string(), + }) + } + } + } + KvAction::Backup => { + // loop through all db directories and backup. + // + (serde_json::to_vec(&KvResponse::Ok).unwrap(), None) + } + }; + + if let Some(target) = km.rsvp.or_else(|| { + expects_response.map(|_| Address { + node: our_node.clone(), + process: source.process.clone(), + }) + }) { + let response = KernelMessage { + id, + source: Address { + node: our_node.clone(), + process: KV_PROCESS_ID.clone(), + }, + target, + rsvp: None, + message: Message::Response(( + Response { + inherit: false, + ipc, + metadata, + }, + None, + )), + payload: bytes.map(|bytes| Payload { + mime: Some("application/octet-stream".into()), + bytes, + }), + signed_capabilities: None, + }; + + let _ = send_to_loop.send(response).await; + } else { + send_to_terminal + .send(Printout { + verbosity: 2, + content: format!( + "kv: not sending response: {:?}", + serde_json::from_slice::(&ipc) + ), + }) + .await + .unwrap(); + } + + Ok(()) +} + +async fn check_caps( + our_node: String, + source: Address, + open_kvs: Arc>, + mut send_to_caps_oracle: CapMessageSender, + request: &KvRequest, + kv_path: String, +) -> Result<(), KvError> { + let (send_cap_bool, recv_cap_bool) = tokio::sync::oneshot::channel(); + let src_package_id = PackageId::new(source.process.package(), source.process.publisher()); + + match &request.action { + KvAction::Delete { .. } + | KvAction::Set { .. } + | KvAction::BeginTx + | KvAction::Commit { .. } => { + send_to_caps_oracle + .send(CapMessage::Has { + on: source.process.clone(), + cap: Capability { + issuer: Address { + node: our_node.clone(), + process: KV_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ + "kind": "write", + "db": request.db.to_string(), + })) + .unwrap(), + }, + responder: send_cap_bool, + }) + .await?; + let has_cap = recv_cap_bool.await?; + if !has_cap { + return Err(KvError::NoCap { + error: request.action.to_string(), + }); + } + Ok(()) + } + KvAction::Get { .. } => { + send_to_caps_oracle + .send(CapMessage::Has { + on: source.process.clone(), + cap: Capability { + issuer: Address { + node: our_node.clone(), + process: KV_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ + "kind": "read", + "db": request.db.to_string(), + })) + .unwrap(), + }, + responder: send_cap_bool, + }) + .await?; + let has_cap = recv_cap_bool.await?; + if !has_cap { + return Err(KvError::NoCap { + error: request.action.to_string(), + }); + } + Ok(()) + } + KvAction::New { .. } => { + if src_package_id != request.package_id { + return Err(KvError::NoCap { + error: request.action.to_string(), + }); + } + + add_capability( + "read", + &request.db.to_string(), + &our_node, + &source, + &mut send_to_caps_oracle, + ) + .await?; + add_capability( + "write", + &request.db.to_string(), + &our_node, + &source, + &mut send_to_caps_oracle, + ) + .await?; + + let db_path = format!("{}{}", kv_path, request.db.to_string()); + + fs::create_dir_all(&db_path).await?; + + let db = OptimisticTransactionDB::open_default(&db_path)?; + + open_kvs.insert((request.package_id.clone(), request.db.clone()), db); + Ok(()) + } + KvAction::Backup { .. } => { + if source.process != *STATE_PROCESS_ID { + return Err(KvError::NoCap { + error: request.action.to_string(), + }); + } + Ok(()) + } + } +} + +async fn add_capability( + kind: &str, + db: &str, + our_node: &str, + source: &Address, + send_to_caps_oracle: &mut CapMessageSender, +) -> Result<(), KvError> { + let cap = Capability { + issuer: Address { + node: our_node.to_string(), + process: KV_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ "kind": kind, "db": db })).unwrap(), + }; + let (send_cap_bool, recv_cap_bool) = tokio::sync::oneshot::channel(); + send_to_caps_oracle + .send(CapMessage::Add { + on: source.process.clone(), + cap, + responder: send_cap_bool, + }) + .await?; + let _ = recv_cap_bool.await?; + Ok(()) +} + +fn make_error_message(our_name: String, km: &KernelMessage, error: KvError) -> KernelMessage { + KernelMessage { + id: km.id, + source: Address { + node: our_name.clone(), + process: KV_PROCESS_ID.clone(), + }, + target: match &km.rsvp { + None => km.source.clone(), + Some(rsvp) => rsvp.clone(), + }, + rsvp: None, + message: Message::Response(( + Response { + inherit: false, + ipc: serde_json::to_vec(&KvResponse::Err { error: error }).unwrap(), + metadata: None, + }, + None, + )), + payload: None, + signed_capabilities: None, + } +} + +impl std::fmt::Display for KvAction { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl From for KvError { + fn from(err: tokio::sync::oneshot::error::RecvError) -> Self { + KvError::NoCap { + error: err.to_string(), + } + } +} + +impl From> for KvError { + fn from(err: tokio::sync::mpsc::error::SendError) -> Self { + KvError::NoCap { + error: err.to_string(), + } + } +} + +impl From for KvError { + fn from(err: std::io::Error) -> Self { + KvError::IOError { + error: err.to_string(), + } + } +} +impl From for KvError { + fn from(error: rocksdb::Error) -> Self { + KvError::RocksDBError { + action: "".into(), + error: error.to_string(), + } + } +} diff --git a/src/llm/README.md b/src/llm/README.md deleted file mode 100644 index 8d75d02e..00000000 --- a/src/llm/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Local LLM Integration -1. Clone and build [llama.cpp](https://github.com/ggerganov/llama.cpp) on the same machine where you will run your uqbar node - - follow their README for details on how to do this. In most cases simply running `make` works - - make sure to get your model as a .gguf file -2. Within the llama.cpp directory, run this command in llama.cpp on the same machine you will run your uqbar node: `./server --port ` - - Note: you can pass in whatever other command line arguments to the llama cpp server you want depending on your preferences/hardware/model/etc. -3. Run your Uqbar node with `--features llm` and `--llm http://localhost:`. For example `cargo +nightly run --features llm --release home --rpc wss://eth-sepolia.g.alchemy.com/v2/ --llm http://localhost:` diff --git a/src/llm/mod.rs b/src/llm/mod.rs deleted file mode 100644 index 31b7f490..00000000 --- a/src/llm/mod.rs +++ /dev/null @@ -1,180 +0,0 @@ -use crate::llm::types::*; -use crate::types::*; -use anyhow::Result; -use reqwest::Response as ReqwestResponse; - -mod types; - -pub async fn llm( - our_name: String, - send_to_loop: MessageSender, - mut recv_in_client: MessageReceiver, - llm_url: String, - print_tx: PrintSender, -) -> Result<()> { - while let Some(message) = recv_in_client.recv().await { - let KernelMessage { - id, - source, - rsvp, - message: - Message::Request(Request { - expects_response, - ipc, - .. - }), - .. - } = message.clone() - else { - return Err(anyhow::anyhow!("llm: bad message")); - }; - - let our_name = our_name.clone(); - let llm_url = llm_url.clone(); - let send_to_loop = send_to_loop.clone(); - let print_tx = print_tx.clone(); - - tokio::spawn(async move { - if let Err(e) = handle_message( - our_name.clone(), - send_to_loop.clone(), - llm_url.clone(), - id, - rsvp, - expects_response, - source.clone(), - ipc, - print_tx.clone(), - ) - .await - { - send_to_loop - .send(make_error_message(our_name.clone(), id, source, e)) - .await - .unwrap(); - } - }); - } - Err(anyhow::anyhow!("llm: exited")) -} - -async fn handle_message( - our: String, - send_to_loop: MessageSender, - llm_url: String, - id: u64, - rsvp: Option
, - expects_response: Option, - source: Address, - json: Vec, - _print_tx: PrintSender, -) -> Result<(), LlmError> { - let target = if expects_response.is_some() { - source.clone() - } else if source.process == ProcessId::from_str("terminal:terminal:uqbar").unwrap() { - source.clone() - } else { - let Some(rsvp) = rsvp else { - return Err(LlmError::BadRsvp); - }; - rsvp.clone() - }; - - let req: LlmPrompt = match serde_json::from_slice(&json) { - Ok(req) => req, - Err(e) => { - return Err(LlmError::BadJson { - json: String::from_utf8(json).unwrap_or_default(), - error: format!("{}", e), - }) - } - }; - - let client = reqwest::Client::new(); - - let res: ReqwestResponse = match client - .post(&format!("{}/completion", llm_url)) - .json(&req) - .send() - .await - { - Ok(res) => res, - Err(e) => { - return Err(LlmError::RequestFailed { - error: format!("{}", e), - }); - } - }; - - let llm_response = match res.json::().await { - Ok(response) => response, - Err(e) => { - return Err(LlmError::DeserializationToLlmResponseFailed { - error: format!("{}", e), - }); - } - }; - - let _ = _print_tx - .send(Printout { - verbosity: 0, - content: format!("llm: {:?}", llm_response.clone().content), - }) - .await; - - let message = KernelMessage { - id, - source: Address { - node: our, - process: ProcessId::new(Some("llm"), "sys", "uqbar"), - }, - target, - rsvp: None, - message: Message::Response(( - Response { - inherit: false, - ipc: serde_json::to_vec::>(&Ok(llm_response)) - .unwrap(), - metadata: None, - }, - None, - )), - payload: None, - signed_capabilities: None, - }; - - send_to_loop.send(message).await.unwrap(); - - Ok(()) -} - -// -// helpers -// -fn make_error_message( - our_name: String, - id: u64, - source: Address, - error: LlmError, -) -> KernelMessage { - KernelMessage { - id, - source: source.clone(), - target: Address { - node: our_name.clone(), - process: source.process.clone(), - }, - rsvp: None, - message: Message::Response(( - Response { - inherit: false, - ipc: serde_json::to_vec::>(&Err(error)) - .unwrap(), - metadata: None, - }, - None, - )), - payload: None, - signed_capabilities: None, - } -} diff --git a/src/llm/types.rs b/src/llm/types.rs deleted file mode 100644 index dc78e946..00000000 --- a/src/llm/types.rs +++ /dev/null @@ -1,114 +0,0 @@ -use serde::{Deserialize, Serialize}; -use thiserror::Error; - -#[derive(Debug, Serialize, Deserialize)] -pub struct LlmPrompt { - prompt: String, // TODO can be a string or an array of strings - temperature: Option, - top_k: Option, - top_p: Option, - n_predict: Option, // isize to accommodate -1 - n_keep: Option, // isize to accommodate -1 - stream: Option, - stop: Option>, - tfs_z: Option, - typical_p: Option, - repeat_penalty: Option, - repeat_last_n: Option, // isize to accommodate -1 - penalize_nl: Option, - presence_penalty: Option, - frequency_penalty: Option, - mirostat: Option, // u8 as it's 0, 1, or 2 - mirostat_tau: Option, - mirostat_eta: Option, - grammar: Option, - seed: Option, // isize to accommodate -1 - ignore_eos: Option, - logit_bias: Option>, - n_probs: Option, - image_data: Option>, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct ImageData { - data: String, // Base64 string - id: usize, -} - -#[derive(Clone, Serialize, Deserialize, Debug)] -pub struct LlmResponse { - pub content: String, - pub generation_settings: GenerationSettings, - pub model: String, - pub prompt: String, - pub slot_id: u64, - pub stop: bool, - pub stopped_eos: bool, - pub stopped_limit: bool, - pub stopped_word: bool, - pub stopping_word: String, - pub timings: Timings, - pub tokens_cached: u64, - pub tokens_evaluated: u64, - pub tokens_predicted: u64, - pub truncated: bool, -} - -#[derive(Clone, Serialize, Deserialize, Debug)] -pub struct GenerationSettings { - pub frequency_penalty: f64, - pub grammar: String, - pub ignore_eos: bool, - pub logit_bias: Vec, // This should be changed to the appropriate type - pub mirostat: u64, - pub mirostat_eta: f64, - pub mirostat_tau: f64, - pub model: String, - pub n_ctx: u64, - pub n_keep: u64, - pub n_predict: u64, - pub n_probs: u64, - pub penalize_nl: bool, - pub presence_penalty: f64, - pub repeat_last_n: u64, - pub repeat_penalty: f64, - pub seed: u64, - pub stop: Vec, // This should be changed to the appropriate type - pub stream: bool, - pub temp: f64, - pub tfs_z: f64, - pub top_k: u64, - pub top_p: f64, - pub typical_p: f64, -} - -#[derive(Clone, Serialize, Deserialize, Debug)] -pub struct Timings { - pub predicted_ms: f64, - pub predicted_n: u64, - pub predicted_per_second: f64, - pub predicted_per_token_ms: f64, - pub prompt_ms: f64, - pub prompt_n: u64, - pub prompt_per_second: f64, - pub prompt_per_token_ms: f64, -} - -#[derive(Error, Debug, Serialize, Deserialize)] -pub enum LlmError { - #[error("llm: rsvp is None but message is expecting response")] - BadRsvp, - #[error("llm: no json in request")] - NoJson, - #[error( - "llm: JSON payload could not be parsed to LlmPrompt: {error}. Got {:?}.", - json - )] - BadJson { json: String, error: String }, - #[error("llm: http method not supported: {:?}", method)] - BadMethod { method: String }, - #[error("llm: failed to execute request {:?}", error)] - RequestFailed { error: String }, - #[error("llm: failed to deserialize response {:?}", error)] - DeserializationToLlmResponseFailed { error: String }, -} diff --git a/src/main.rs b/src/main.rs index 8a9c90f6..a7775f47 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,37 +12,34 @@ use tokio::{fs, time::timeout}; use ring::{rand::SystemRandom, signature, signature::KeyPair}; mod eth_rpc; -mod filesystem; mod http; mod kernel; mod keygen; +mod kv; mod net; mod register; +mod sqlite; +mod state; mod terminal; mod timer; mod types; mod vfs; -// extensions -#[cfg(feature = "llm")] -mod llm; - const EVENT_LOOP_CHANNEL_CAPACITY: usize = 10_000; const EVENT_LOOP_DEBUG_CHANNEL_CAPACITY: usize = 50; const TERMINAL_CHANNEL_CAPACITY: usize = 32; const WEBSOCKET_SENDER_CHANNEL_CAPACITY: usize = 32; -const FILESYSTEM_CHANNEL_CAPACITY: usize = 32; const HTTP_CHANNEL_CAPACITY: usize = 32; const HTTP_CLIENT_CHANNEL_CAPACITY: usize = 32; const ETH_RPC_CHANNEL_CAPACITY: usize = 32; const VFS_CHANNEL_CAPACITY: usize = 1_000; const CAP_CHANNEL_CAPACITY: usize = 1_000; -#[cfg(feature = "llm")] -const LLM_CHANNEL_CAPACITY: usize = 32; +const KV_CHANNEL_CAPACITY: usize = 1_000; +const SQLITE_CHANNEL_CAPACITY: usize = 1_000; const VERSION: &str = env!("CARGO_PKG_VERSION"); -/// This can and should be an environment variable / setting. It configures networking +/// Tshis can and should be an environment variable / setting. It configures networking /// such that indirect nodes always use routers, even when target is a direct node, /// such that only their routers can ever see their physical networking details. const REVEAL_IP: bool = true; @@ -52,7 +49,7 @@ async fn serve_register_fe( our_ip: String, http_server_port: u16, rpc_url: String, -) -> (Identity, Keyfile) { +) -> (Identity, Vec, Keyfile) { // check if we have keys saved on disk, encrypted // if so, prompt user for "password" to decrypt with @@ -66,10 +63,9 @@ async fn serve_register_fe( // that updates their PKI info on-chain. let (kill_tx, kill_rx) = oneshot::channel::(); - let disk_keyfile = match fs::read(format!("{}/.keys", home_directory_path)).await { - Ok(keyfile) => keyfile, - Err(_) => Vec::new(), - }; + let disk_keyfile: Option> = fs::read(format!("{}/.keys", home_directory_path)) + .await + .ok(); let (tx, mut rx) = mpsc::channel::<(Identity, Keyfile, Vec)>(1); let (our, decoded_keyfile, encoded_keyfile) = tokio::select! { @@ -81,20 +77,16 @@ async fn serve_register_fe( } }; - println!( - "saving encrypted networking keys to {}/.keys", - home_directory_path - ); - - fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile) - .await - .unwrap(); - - println!("registration complete!"); + fs::write( + format!("{}/.keys", home_directory_path), + encoded_keyfile.clone(), + ) + .await + .unwrap(); let _ = kill_tx.send(true); - (our, decoded_keyfile) + (our, encoded_keyfile, decoded_keyfile) } #[tokio::main] @@ -124,9 +116,6 @@ async fn main() { .value_parser(value_parser!(u16)), ); - #[cfg(feature = "llm")] - let app = app.arg(arg!(--llm "LLM endpoint")); - let matches = app.get_matches(); let home_directory_path = matches.get_one::("home").unwrap(); @@ -146,9 +135,6 @@ async fn main() { matches.get_one::("fake-node-name"), ); - #[cfg(feature = "llm")] - let llm_url = matches.get_one::("llm").unwrap(); - if let Err(e) = fs::create_dir_all(home_directory_path).await { panic!("failed to create home directory: {:?}", e); } @@ -169,9 +155,15 @@ async fn main() { // websocket sender receives send messages via this channel, kernel send messages let (net_message_sender, net_message_receiver): (MessageSender, MessageReceiver) = mpsc::channel(WEBSOCKET_SENDER_CHANNEL_CAPACITY); - // filesystem receives request messages via this channel, kernel sends messages - let (fs_message_sender, fs_message_receiver): (MessageSender, MessageReceiver) = - mpsc::channel(FILESYSTEM_CHANNEL_CAPACITY); + // kernel_state sender and receiver + let (state_sender, state_receiver): (MessageSender, MessageReceiver) = + mpsc::channel(VFS_CHANNEL_CAPACITY); + // kv sender and receiver + let (kv_sender, kv_receiver): (MessageSender, MessageReceiver) = + mpsc::channel(KV_CHANNEL_CAPACITY); + // sqlite sender and receiver + let (sqlite_sender, sqlite_receiver): (MessageSender, MessageReceiver) = + mpsc::channel(SQLITE_CHANNEL_CAPACITY); // http server channel w/ websockets (eyre) let (http_server_sender, http_server_receiver): (MessageSender, MessageReceiver) = mpsc::channel(HTTP_CHANNEL_CAPACITY); @@ -188,75 +180,6 @@ async fn main() { // terminal receives prints via this channel, all other modules send prints let (print_sender, print_receiver): (PrintSender, PrintReceiver) = mpsc::channel(TERMINAL_CHANNEL_CAPACITY); - // optional llm extension - #[cfg(feature = "llm")] - let (llm_sender, llm_receiver): (MessageSender, MessageReceiver) = - mpsc::channel(LLM_CHANNEL_CAPACITY); - - // fs config in .env file (todo add -- arguments cleanly (with clap?)) - dotenv::dotenv().ok(); - - let mem_buffer_limit = env::var("MEM_BUFFER_LIMIT") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(1024 * 1024 * 5); // 5mb default - - let read_cache_limit = env::var("READ_CACHE_LIMIT") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(1024 * 1024 * 5); // 5mb default - - let chunk_size = env::var("CHUNK_SIZE") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(1024 * 256); // 256kb default - - let flush_to_cold_interval = env::var("FLUSH_TO_COLD_INTERVAL") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(60); // 60s default - - let encryption = env::var("ENCRYPTION") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(true); // default true - - let cloud_enabled = env::var("CLOUD_ENABLED") - .ok() - .and_then(|s| s.parse().ok()) - .unwrap_or(false); // default false - - let s3_config = if let (Ok(access_key), Ok(secret_key), Ok(region), Ok(bucket), Ok(endpoint)) = ( - env::var("S3_ACCESS_KEY"), - env::var("S3_SECRET_KEY"), - env::var("S3_REGION"), - env::var("S3_BUCKET"), - env::var("S3_ENDPOINT"), - ) { - Some(S3Config { - access_key, - secret_key, - region, - bucket, - endpoint, - }) - } else { - None - }; - - let fs_config = FsConfig { - s3_config, - mem_buffer_limit, - read_cache_limit, - chunk_size, - flush_to_cold_interval, - encryption, - cloud_enabled, - }; - - // shutdown signal send and await to fs - let (fs_kill_send, fs_kill_recv) = oneshot::channel::<()>(); - let (fs_kill_confirm_send, fs_kill_confirm_recv) = oneshot::channel::<()>(); println!("finding public IP address..."); let our_ip: std::net::Ipv4Addr = { @@ -272,13 +195,21 @@ async fn main() { }; let http_server_port = http::utils::find_open_port(port).await.unwrap(); - println!("runtime bound port {}\r", http_server_port); + if http_server_port != port { + let error_message = format!( + "uqbar: couldn't bind {}; first available port found {}. Set an available port with `--port` and try again.", + port, + http_server_port, + ); + println!("{error_message}"); + panic!("{error_message}"); + } println!( "login or register at http://localhost:{}\r", http_server_port ); #[cfg(not(feature = "simulation-mode"))] - let (our, decoded_keyfile) = serve_register_fe( + let (our, encoded_keyfile, decoded_keyfile) = serve_register_fe( &home_directory_path, our_ip.to_string(), http_server_port.clone(), @@ -286,7 +217,7 @@ async fn main() { ) .await; #[cfg(feature = "simulation-mode")] - let (our, decoded_keyfile) = match fake_node_name { + let (our, encoded_keyfile, decoded_keyfile) = match fake_node_name { None => { match password { None => match rpc_url { @@ -305,7 +236,7 @@ async fn main() { match fs::read(format!("{}/.keys", home_directory_path)).await { Err(e) => panic!("could not read keyfile: {}", e), Ok(keyfile) => { - match keygen::decode_keyfile(keyfile, &password) { + match keygen::decode_keyfile(&keyfile, &password) { Err(e) => panic!("could not decode keyfile: {}", e), Ok(decoded_keyfile) => { let our = Identity { @@ -322,7 +253,7 @@ async fn main() { ws_routing: None, // TODO allowed_routers: decoded_keyfile.routers.clone(), }; - (our, decoded_keyfile) + (our, keyfile, decoded_keyfile) } } } @@ -363,16 +294,19 @@ async fn main() { password, name.clone(), decoded_keyfile.routers.clone(), - networking_keypair, + networking_keypair.as_ref(), decoded_keyfile.jwt_secret_bytes.clone(), decoded_keyfile.file_key.clone(), ); - fs::write(format!("{}/.keys", home_directory_path), encoded_keyfile) - .await - .unwrap(); + fs::write( + format!("{}/.keys", home_directory_path), + encoded_keyfile.clone(), + ) + .await + .unwrap(); - (our, decoded_keyfile) + (our, encoded_keyfile, decoded_keyfile) } }; @@ -380,11 +314,6 @@ async fn main() { // where public means that any process can always message it. #[allow(unused_mut)] let mut runtime_extensions = vec![ - ( - ProcessId::new(Some("filesystem"), "sys", "uqbar"), - fs_message_sender, - false, - ), ( ProcessId::new(Some("http_server"), "sys", "uqbar"), http_server_sender, @@ -410,6 +339,17 @@ async fn main() { vfs_message_sender, true, ), + ( + ProcessId::new(Some("state"), "sys", "uqbar"), + state_sender, + true, + ), + (ProcessId::new(Some("kv"), "sys", "uqbar"), kv_sender, true), + ( + ProcessId::new(Some("sqlite"), "sys", "uqbar"), + sqlite_sender, + true, + ), ]; #[cfg(feature = "llm")] @@ -419,15 +359,13 @@ async fn main() { true, )); - let (kernel_process_map, manifest, vfs_messages) = filesystem::load_fs( + let (kernel_process_map, db) = state::load_state( our.name.clone(), home_directory_path.clone(), - decoded_keyfile.file_key, - fs_config, runtime_extensions.clone(), ) .await - .expect("fs load failed!"); + .expect("state load failed!"); /* * the kernel module will handle our userspace processes and receives @@ -471,18 +409,34 @@ async fn main() { kernel_message_sender.clone(), net_message_receiver, )); - tasks.spawn(filesystem::fs_sender( + tasks.spawn(state::state_sender( our.name.clone(), - manifest, kernel_message_sender.clone(), print_sender.clone(), - fs_message_receiver, - fs_kill_recv, - fs_kill_confirm_send, + state_receiver, + db, + home_directory_path.clone(), + )); + tasks.spawn(kv::kv( + our.name.clone(), + kernel_message_sender.clone(), + print_sender.clone(), + kv_receiver, + caps_oracle_sender.clone(), + home_directory_path.clone(), + )); + tasks.spawn(sqlite::sqlite( + our.name.clone(), + kernel_message_sender.clone(), + print_sender.clone(), + sqlite_receiver, + caps_oracle_sender.clone(), + home_directory_path.clone(), )); tasks.spawn(http::server::http_server( our.name.clone(), http_server_port, + encoded_keyfile, decoded_keyfile.jwt_secret_bytes.clone(), http_server_receiver, kernel_message_sender.clone(), @@ -514,18 +468,8 @@ async fn main() { print_sender.clone(), vfs_message_receiver, caps_oracle_sender.clone(), - vfs_messages, + home_directory_path.clone(), )); - #[cfg(feature = "llm")] - { - tasks.spawn(llm::llm( - our.name.clone(), - kernel_message_sender.clone(), - llm_receiver, - llm_url.to_string(), - print_sender.clone(), - )); - } // if a runtime task exits, try to recover it, // unless it was terminal signaling a quit let quit_msg: String = tokio::select! { @@ -551,10 +495,6 @@ async fn main() { } }; - // shutdown signal to fs for flush - let _ = fs_kill_send.send(()); - let _ = fs_kill_confirm_recv.await; - // gracefully abort all running processes in kernel let _ = kernel_message_sender .send(KernelMessage { diff --git a/src/net/utils.rs b/src/net/utils.rs index 4e2464d5..cb28510e 100644 --- a/src/net/utils.rs +++ b/src/net/utils.rs @@ -65,7 +65,7 @@ pub async fn maintain_connection( if km.source.node != peer_name { let _ = print_tx.send(Printout { verbosity: 0, - content: format!("net: got message with spoofed source from {peer_name}") + content: format!("net: got message with spoofed source from {peer_name}!") }).await; break } else { @@ -136,7 +136,9 @@ pub async fn maintain_passthrough(mut conn: PassthroughConnection) { maybe_recv = conn.read_stream_1.next() => { match maybe_recv { Some(Ok(msg)) => { - conn.write_stream_2.send(msg).await.expect("net error: fatal: kernel died"); + let Ok(()) = conn.write_stream_2.send(msg).await else { + break + }; last_message = std::time::Instant::now(); } _ => break, @@ -145,7 +147,9 @@ pub async fn maintain_passthrough(mut conn: PassthroughConnection) { maybe_recv = conn.read_stream_2.next() => { match maybe_recv { Some(Ok(msg)) => { - conn.write_stream_1.send(msg).await.expect("net error: fatal: kernel died"); + let Ok(()) = conn.write_stream_1.send(msg).await else { + break + }; last_message = std::time::Instant::now(); } _ => break, diff --git a/src/register.rs b/src/register.rs index 9f75c959..933fbe9f 100644 --- a/src/register.rs +++ b/src/register.rs @@ -1,15 +1,13 @@ use aes_gcm::aead::KeyInit; - use ethers::prelude::{abigen, namehash, Address as EthAddress, Provider, U256}; use ethers_providers::Ws; use hmac::Hmac; use jwt::SignWithKey; -use ring::pkcs8::Document; use ring::rand::SystemRandom; use ring::signature; use ring::signature::KeyPair; use sha2::Sha256; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use tokio::sync::{mpsc, oneshot}; use warp::{ http::{ @@ -77,14 +75,14 @@ fn _hex_string_to_u8_array(hex_str: &str) -> Result<[u8; 32], &'static str> { Ok(bytes) } -pub fn generate_jwt(jwt_secret_bytes: &[u8], username: String) -> Option { +pub fn generate_jwt(jwt_secret_bytes: &[u8], username: &str) -> Option { let jwt_secret: Hmac = match Hmac::new_from_slice(jwt_secret_bytes) { Ok(secret) => secret, Err(_) => return None, }; let claims = crate::http::types::JwtClaims { - username: username.clone(), + username: username.to_string(), expiration: 0, }; @@ -101,16 +99,34 @@ pub async fn register( ip: String, port: u16, rpc_url: String, - keyfile: Vec, + keyfile: Option>, ) { - let our_temp_arc = Arc::new(Mutex::new(None)); // Networking info is generated and passed to the UI, but not used until confirmed - let our_ws_info = our_temp_arc.clone(); + // Networking info is generated and passed to the UI, but not used until confirmed + let (public_key, serialized_networking_keypair) = keygen::generate_networking_key(); + let net_keypair = Arc::new(serialized_networking_keypair.as_ref().to_vec()); + let tx = Arc::new(tx); - let net_keypair_arc = Arc::new(Mutex::new(None)); - let net_keypair_ws_info = net_keypair_arc.clone(); + // TODO: if IP is localhost, don't allow registration as direct + let ws_port = crate::http::utils::find_open_port(9000).await.unwrap(); - let keyfile_arc = Arc::new(Mutex::new(Some(keyfile))); - let keyfile_vet = keyfile_arc.clone(); + // This is a temporary identity, passed to the UI. If it is confirmed through a /boot or /confirm-change-network-keys, then it will be used to replace the current identity + let our_temp_id = Arc::new(Identity { + networking_key: format!("0x{}", public_key), + name: "".to_string(), + ws_routing: Some((ip.clone(), ws_port)), + allowed_routers: vec![ + "uqbar-router-1.uq".into(), // "0x8d9e54427c50660c6d4802f63edca86a9ca5fd6a78070c4635950e9d149ed441".into(), + "uqbar-router-2.uq".into(), // "0x06d331ed65843ecf0860c73292005d8103af20820546b2f8f9007d01f60595b1".into(), + "uqbar-router-3.uq".into(), // "0xe6ab611eb62e8aee0460295667f8179cda4315982717db4b0b3da6022deecac1".into(), + ], + }); + + let keyfile = warp::any().map(move || keyfile.clone()); + let our_temp_id = warp::any().map(move || our_temp_id.clone()); + let net_keypair = warp::any().map(move || net_keypair.clone()); + let tx = warp::any().map(move || tx.clone()); + let ip = warp::any().map(move || ip.clone()); + let rpc_url = warp::any().map(move || rpc_url.clone()); let static_files = warp::path("static").and(warp::fs::dir("./src/register-ui/build/static/")); @@ -118,73 +134,60 @@ pub async fn register( .and(warp::get()) .and(warp::fs::file("./src/register-ui/build/index.html")); - let keyfile_info_copy = keyfile_arc.clone(); - let boot_tx = tx.clone(); - let boot_our_arc = our_temp_arc.clone(); - let boot_net_keypair_arc = net_keypair_arc.clone(); - let import_tx = tx.clone(); - let import_ip = ip.clone(); - let import_rpc_url = rpc_url.clone(); - let login_tx = tx.clone(); - let login_keyfile_arc = keyfile_arc.clone(); - let generate_keys_ip = ip.clone(); - let api = warp::path("info") .and( warp::get() - .and(warp::any().map(move || keyfile_info_copy.clone())) + .and(keyfile.clone()) .and_then(get_unencrypted_info), ) .or(warp::path("generate-networking-info").and( warp::post() - .and(warp::any().map(move || generate_keys_ip.clone())) - .and(warp::any().map(move || our_ws_info.clone())) - .and(warp::any().map(move || net_keypair_ws_info.clone())) + .and(our_temp_id.clone()) .and_then(generate_networking_info), )) .or(warp::path("vet-keyfile").and( warp::post() .and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::json()) - .and(warp::any().map(move || keyfile_vet.clone())) + .and(keyfile.clone()) .and_then(handle_keyfile_vet), )) .or(warp::path("boot").and( warp::post() .and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::json()) - .and(warp::any().map(move || boot_tx.clone())) - .and(warp::any().map(move || boot_our_arc.lock().unwrap().take().unwrap())) - .and(warp::any().map(move || boot_net_keypair_arc.lock().unwrap().take().unwrap())) + .and(tx.clone()) + .and(our_temp_id.clone()) + .and(net_keypair.clone()) .and_then(handle_boot), )) .or(warp::path("import-keyfile").and( warp::post() .and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::json()) - .and(warp::any().map(move || import_ip.clone())) - .and(warp::any().map(move || import_rpc_url.clone())) - .and(warp::any().map(move || import_tx.clone())) + .and(ip.clone()) + .and(rpc_url.clone()) + .and(tx.clone()) .and_then(handle_import_keyfile), )) .or(warp::path("login").and( warp::post() .and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::json()) - .and(warp::any().map(move || ip.clone())) - .and(warp::any().map(move || rpc_url.clone())) - .and(warp::any().map(move || login_tx.clone())) - .and(warp::any().map(move || login_keyfile_arc.lock().unwrap().take().unwrap())) + .and(ip) + .and(rpc_url) + .and(tx.clone()) + .and(keyfile.clone()) .and_then(handle_login), )) .or(warp::path("confirm-change-network-keys").and( warp::post() .and(warp::body::content_length_limit(1024 * 16)) .and(warp::body::json()) - .and(warp::any().map(move || tx.clone())) - .and(warp::any().map(move || our_temp_arc.lock().unwrap().take().unwrap())) - .and(warp::any().map(move || net_keypair_arc.lock().unwrap().take().unwrap())) - .and(warp::any().map(move || keyfile_arc.lock().unwrap().take().unwrap())) + .and(tx) + .and(our_temp_id) + .and(net_keypair) + .and(keyfile) .and_then(confirm_change_network_keys), )); @@ -208,101 +211,72 @@ pub async fn register( .await; } -async fn get_unencrypted_info( - keyfile_arc: Arc>>>, -) -> Result { +async fn get_unencrypted_info(keyfile: Option>) -> Result { let (name, allowed_routers) = { - match keyfile_arc.lock().unwrap().clone() { - Some(encoded_keyfile) => match keygen::get_username_and_routers(encoded_keyfile) { + match keyfile { + Some(encoded_keyfile) => match keygen::get_username_and_routers(&encoded_keyfile) { Ok(k) => k, Err(_) => { return Ok(warp::reply::with_status( - warp::reply::json(&"Failed to decode keyfile".to_string()), - StatusCode::INTERNAL_SERVER_ERROR, + warp::reply::json(&"Incorrect password"), + StatusCode::UNAUTHORIZED, ) .into_response()) } }, None => { return Ok(warp::reply::with_status( - warp::reply::json(&"Keyfile not present".to_string()), + warp::reply::json(&"Keyfile not present"), StatusCode::NOT_FOUND, ) .into_response()) } } }; - - let our = UnencryptedIdentity { - name, - allowed_routers, - }; - - Ok(warp::reply::with_status(Ok(warp::reply::json(&our)), StatusCode::OK).into_response()) + Ok(warp::reply::with_status( + Ok(warp::reply::json(&UnencryptedIdentity { + name, + allowed_routers, + })), + StatusCode::OK, + ) + .into_response()) } -async fn generate_networking_info( - ip: String, - our_temp_arc: Arc>>, - networking_keypair_arc: Arc>>, -) -> Result { - let (public_key, serialized_networking_keypair) = keygen::generate_networking_key(); - *networking_keypair_arc.lock().unwrap() = Some(serialized_networking_keypair); - - // TODO: if IP is localhost, don't allow registration as direct - let ws_port = crate::http::utils::find_open_port(9000).await.unwrap(); - - // This is a temporary identity, passed to the UI. If it is confirmed through a /boot or /confirm-change-network-keys, then it will be used to replace the current identity - let our_temp = Identity { - networking_key: format!("0x{}", public_key), - name: "".to_string(), - ws_routing: Some((ip, ws_port)), - allowed_routers: vec![ - "uqbar-router-1.uq".into(), // "0x8d9e54427c50660c6d4802f63edca86a9ca5fd6a78070c4635950e9d149ed441".into(), - "uqbar-router-2.uq".into(), // "0x06d331ed65843ecf0860c73292005d8103af20820546b2f8f9007d01f60595b1".into(), - "uqbar-router-3.uq".into(), // "0xe6ab611eb62e8aee0460295667f8179cda4315982717db4b0b3da6022deecac1".into(), - ], - }; - - *our_temp_arc.lock().unwrap() = Some(our_temp.clone()); - - Ok(warp::reply::json(&our_temp)) +async fn generate_networking_info(our_temp_id: Arc) -> Result { + Ok(warp::reply::json(our_temp_id.as_ref())) } async fn handle_keyfile_vet( payload: KeyfileVet, - keyfile_arc: Arc>>>, + keyfile: Option>, ) -> Result { let encoded_keyfile = match payload.keyfile.is_empty() { - true => keyfile_arc.lock().unwrap().clone().unwrap(), - false => base64::decode(payload.keyfile).unwrap(), + true => keyfile.ok_or(warp::reject())?, + false => base64::decode(payload.keyfile).map_err(|_| warp::reject())?, }; - let decoded_keyfile = match keygen::decode_keyfile(encoded_keyfile, &payload.password) { - Ok(k) => k, - Err(_) => return Err(warp::reject()), - }; + let decoded_keyfile = + keygen::decode_keyfile(&encoded_keyfile, &payload.password).map_err(|_| warp::reject())?; - let keyfile_vetted = KeyfileVetted { + Ok(warp::reply::json(&KeyfileVetted { username: decoded_keyfile.username, networking_key: format!( "0x{}", hex::encode(decoded_keyfile.networking_keypair.public_key().as_ref()) ), routers: decoded_keyfile.routers, - }; - - Ok(warp::reply::json(&keyfile_vetted)) + })) } async fn handle_boot( info: BootInfo, - sender: RegistrationSender, - mut our: Identity, - networking_keypair: Document, + sender: Arc, + our: Arc, + networking_keypair: Arc>, ) -> Result { + let mut our = our.as_ref().clone(); our.name = info.username; - if info.direct { our.allowed_routers = vec![]; } else { @@ -326,35 +300,26 @@ async fn handle_boot( info.password, decoded_keyfile.username.clone(), decoded_keyfile.routers.clone(), - networking_keypair, + networking_keypair.as_ref(), decoded_keyfile.jwt_secret_bytes.clone(), decoded_keyfile.file_key.clone(), ); - let encoded_keyfile_str = base64::encode(encoded_keyfile.clone()); - - success_response( - sender, - our, - decoded_keyfile, - encoded_keyfile, - encoded_keyfile_str, - ) - .await + success_response(sender, our, decoded_keyfile, encoded_keyfile).await } async fn handle_import_keyfile( info: ImportKeyfileInfo, ip: String, _rpc_url: String, - sender: RegistrationSender, + sender: Arc, ) -> Result { // if keyfile was not present in node and is present from user upload let encoded_keyfile = match base64::decode(info.keyfile.clone()) { Ok(k) => k, Err(_) => { return Ok(warp::reply::with_status( - warp::reply::json(&"Keyfile not valid base64".to_string()), + warp::reply::json(&"Keyfile not valid base64"), StatusCode::BAD_REQUEST, ) .into_response()) @@ -363,39 +328,38 @@ async fn handle_import_keyfile( let Some(ws_port) = crate::http::utils::find_open_port(9000).await else { return Ok(warp::reply::with_status( - warp::reply::json(&"Unable to find free port".to_string()), + warp::reply::json(&"Unable to find free port"), StatusCode::INTERNAL_SERVER_ERROR, ) .into_response()); }; - let (decoded_keyfile, our) = - match keygen::decode_keyfile(encoded_keyfile.clone(), &info.password) { - Ok(k) => { - let our = Identity { - name: k.username.clone(), - networking_key: format!( - "0x{}", - hex::encode(k.networking_keypair.public_key().as_ref()) - ), - ws_routing: if k.routers.is_empty() { - Some((ip, ws_port)) - } else { - None - }, - allowed_routers: k.routers.clone(), - }; + let (decoded_keyfile, our) = match keygen::decode_keyfile(&encoded_keyfile, &info.password) { + Ok(k) => { + let our = Identity { + name: k.username.clone(), + networking_key: format!( + "0x{}", + hex::encode(k.networking_keypair.public_key().as_ref()) + ), + ws_routing: if k.routers.is_empty() { + Some((ip, ws_port)) + } else { + None + }, + allowed_routers: k.routers.clone(), + }; - (k, our) - } - Err(_) => { - return Ok(warp::reply::with_status( - warp::reply::json(&"Failed to decode keyfile".to_string()), - StatusCode::INTERNAL_SERVER_ERROR, - ) - .into_response()) - } - }; + (k, our) + } + Err(_) => { + return Ok(warp::reply::with_status( + warp::reply::json(&"Incorrect Password".to_string()), + StatusCode::UNAUTHORIZED, + ) + .into_response()) + } + }; // if !networking_info_valid(rpc_url, ip, ws_port, &our).await { // return Ok(warp::reply::with_status( @@ -405,114 +369,89 @@ async fn handle_import_keyfile( // .into_response()); // } - let encoded_keyfile_str = info.keyfile.clone(); - - success_response( - sender, - our, - decoded_keyfile, - encoded_keyfile, - encoded_keyfile_str, - ) - .await + success_response(sender, our, decoded_keyfile, encoded_keyfile).await } async fn handle_login( info: LoginInfo, ip: String, _rpc_url: String, - sender: RegistrationSender, - encoded_keyfile: Vec, + sender: Arc, + encoded_keyfile: Option>, ) -> Result { - if encoded_keyfile.is_empty() { + if encoded_keyfile.is_none() { return Ok(warp::reply::with_status( - warp::reply::json(&"Keyfile not present".to_string()), + warp::reply::json(&"Keyfile not present"), StatusCode::NOT_FOUND, ) .into_response()); } + let encoded_keyfile = encoded_keyfile.unwrap(); let Some(ws_port) = crate::http::utils::find_open_port(9000).await else { return Ok(warp::reply::with_status( - warp::reply::json(&"Unable to find free port".to_string()), + warp::reply::json(&"Unable to find free port"), StatusCode::INTERNAL_SERVER_ERROR, ) .into_response()); }; - let (decoded_keyfile, our) = - match keygen::decode_keyfile(encoded_keyfile.clone(), &info.password) { - Ok(k) => { - let our = Identity { - name: k.username.clone(), - networking_key: format!( - "0x{}", - hex::encode(k.networking_keypair.public_key().as_ref()) - ), - ws_routing: if k.routers.is_empty() { - Some((ip, ws_port)) - } else { - None - }, - allowed_routers: k.routers.clone(), - }; + let (decoded_keyfile, our) = match keygen::decode_keyfile(&encoded_keyfile, &info.password) { + Ok(k) => { + let our = Identity { + name: k.username.clone(), + networking_key: format!( + "0x{}", + hex::encode(k.networking_keypair.public_key().as_ref()) + ), + ws_routing: if k.routers.is_empty() { + Some((ip, ws_port)) + } else { + None + }, + allowed_routers: k.routers.clone(), + }; - (k, our) - } - Err(_) => { - return Ok(warp::reply::with_status( - warp::reply::json(&"Failed to decode keyfile".to_string()), - StatusCode::INTERNAL_SERVER_ERROR, - ) - .into_response()) - } - }; + (k, our) + } + Err(_) => { + return Ok(warp::reply::with_status( + warp::reply::json(&"Incorrect Password"), + StatusCode::UNAUTHORIZED, + ) + .into_response()) + } + }; - // if !networking_info_valid(rpc_url, ip, ws_port, &our).await { - // return Ok(warp::reply::with_status( - // warp::reply::json(&"Networking info invalid".to_string()), - // StatusCode::UNAUTHORIZED, - // ) - // .into_response()); - // } - - let encoded_keyfile_str = base64::encode(encoded_keyfile.clone()); - - success_response( - sender, - our, - decoded_keyfile, - encoded_keyfile, - encoded_keyfile_str, - ) - .await + success_response(sender, our, decoded_keyfile, encoded_keyfile).await } async fn confirm_change_network_keys( info: LoginAndResetInfo, - sender: RegistrationSender, - mut our: Identity, // the arc of our temporary identity - networking_keypair: Document, - encoded_keyfile: Vec, + sender: Arc, + our: Arc, + networking_keypair: Arc>, + encoded_keyfile: Option>, ) -> Result { - if encoded_keyfile.is_empty() { + if encoded_keyfile.is_none() { return Ok(warp::reply::with_status( - warp::reply::json(&"Keyfile not present".to_string()), + warp::reply::json(&"Keyfile not present"), StatusCode::NOT_FOUND, ) .into_response()); } + let encoded_keyfile = encoded_keyfile.unwrap(); + let mut our = our.as_ref().clone(); // Get our name from our current keyfile - let old_decoded_keyfile = match keygen::decode_keyfile(encoded_keyfile.clone(), &info.password) - { + let old_decoded_keyfile = match keygen::decode_keyfile(&encoded_keyfile, &info.password) { Ok(k) => { our.name = k.username.clone(); k } Err(_) => { return Ok(warp::reply::with_status( - warp::reply::json(&"Invalid password".to_string()), + warp::reply::json(&"Invalid password"), StatusCode::UNAUTHORIZED, ) .into_response()); @@ -539,35 +478,26 @@ async fn confirm_change_network_keys( info.password, decoded_keyfile.username.clone(), decoded_keyfile.routers.clone(), - networking_keypair, + networking_keypair.as_ref(), decoded_keyfile.jwt_secret_bytes.clone(), decoded_keyfile.file_key.clone(), ); - let encoded_keyfile_str = base64::encode(encoded_keyfile.clone()); - - success_response( - sender, - our, - decoded_keyfile, - encoded_keyfile, - encoded_keyfile_str, - ) - .await + success_response(sender, our.clone(), decoded_keyfile, encoded_keyfile).await } async fn success_response( - sender: RegistrationSender, + sender: Arc, our: Identity, decoded_keyfile: Keyfile, encoded_keyfile: Vec, - encoded_keyfile_str: String, ) -> Result { - let token = match generate_jwt(&decoded_keyfile.jwt_secret_bytes, our.name.clone()) { + let encoded_keyfile_str = base64::encode(&encoded_keyfile); + let token = match generate_jwt(&decoded_keyfile.jwt_secret_bytes, &our.name) { Some(token) => token, None => { return Ok(warp::reply::with_status( - warp::reply::json(&"Failed to generate JWT".to_string()), + warp::reply::json(&"Failed to generate JWT"), StatusCode::SERVICE_UNAVAILABLE, ) .into_response()) @@ -591,26 +521,13 @@ async fn success_response( } Err(_) => { return Ok(warp::reply::with_status( - warp::reply::json(&"Failed to generate Auth JWT".to_string()), + warp::reply::json(&"Failed to generate Auth JWT"), StatusCode::INTERNAL_SERVER_ERROR, ) .into_response()) } } - // match HeaderValue::from_str(&format!("uqbar-ws-auth_{}={};", &our.name, &token)) { - // Ok(v) => { - // headers.append(SET_COOKIE, v); - // }, - // Err(_) => { - // return Ok(warp::reply::with_status( - // warp::reply::json(&"Failed to generate WS JWT".to_string()), - // StatusCode::INTERNAL_SERVER_ERROR, - // ) - // .into_response()) - // } - // } - Ok(response) } diff --git a/src/sqlite.rs b/src/sqlite.rs new file mode 100644 index 00000000..68f5b5e6 --- /dev/null +++ b/src/sqlite.rs @@ -0,0 +1,570 @@ +use anyhow::Result; +use dashmap::DashMap; +use rusqlite::types::{FromSql, FromSqlError, ToSql, ValueRef}; +use rusqlite::Connection; +use std::collections::{HashMap, VecDeque}; +use std::sync::Arc; +use tokio::fs; +use tokio::sync::Mutex; + +use crate::types::*; + +pub async fn sqlite( + our_node: String, + send_to_loop: MessageSender, + send_to_terminal: PrintSender, + mut recv_from_loop: MessageReceiver, + send_to_caps_oracle: CapMessageSender, + home_directory_path: String, +) -> anyhow::Result<()> { + let sqlite_path = format!("{}/sqlite", &home_directory_path); + + if let Err(e) = fs::create_dir_all(&sqlite_path).await { + panic!("failed creating sqlite dir! {:?}", e); + } + + let open_dbs: Arc>> = Arc::new(DashMap::new()); + let txs: Arc)>>> = Arc::new(DashMap::new()); + + let mut process_queues: HashMap>>> = + HashMap::new(); + + loop { + tokio::select! { + Some(km) = recv_from_loop.recv() => { + if our_node.clone() != km.source.node { + println!( + "sqlite: request must come from our_node={}, got: {}", + our_node, + km.source.node, + ); + continue; + } + + let queue = process_queues + .entry(km.source.process.clone()) + .or_insert_with(|| Arc::new(Mutex::new(VecDeque::new()))) + .clone(); + + { + let mut queue_lock = queue.lock().await; + queue_lock.push_back(km.clone()); + } + + // clone Arcs + let our_node = our_node.clone(); + let send_to_caps_oracle = send_to_caps_oracle.clone(); + let send_to_terminal = send_to_terminal.clone(); + let send_to_loop = send_to_loop.clone(); + let open_dbs = open_dbs.clone(); + let txs = txs.clone(); + let sqlite_path = sqlite_path.clone(); + + tokio::spawn(async move { + let mut queue_lock = queue.lock().await; + if let Some(km) = queue_lock.pop_front() { + if let Err(e) = handle_request( + our_node.clone(), + km.clone(), + open_dbs.clone(), + txs.clone(), + send_to_loop.clone(), + send_to_terminal.clone(), + send_to_caps_oracle.clone(), + sqlite_path.clone(), + ) + .await + { + let _ = send_to_loop + .send(make_error_message(our_node.clone(), &km, e)) + .await; + } + } + }); + } + } + } +} + +async fn handle_request( + our_node: String, + km: KernelMessage, + open_dbs: Arc>>, + txs: Arc)>>>, + send_to_loop: MessageSender, + send_to_terminal: PrintSender, + send_to_caps_oracle: CapMessageSender, + sqlite_path: String, +) -> Result<(), SqliteError> { + let KernelMessage { + id, + source, + message, + payload, + .. + } = km.clone(); + let Message::Request(Request { + ipc, + expects_response, + metadata, + .. + }) = message.clone() + else { + return Err(SqliteError::InputError { + error: "not a request".into(), + }); + }; + + let request: SqliteRequest = match serde_json::from_slice(&ipc) { + Ok(r) => r, + Err(e) => { + println!("sqlite: got invalid Request: {}", e); + return Err(SqliteError::InputError { + error: "didn't serialize to SqliteRequest.".into(), + }); + } + }; + + check_caps( + our_node.clone(), + source.clone(), + open_dbs.clone(), + send_to_caps_oracle.clone(), + &request, + sqlite_path.clone(), + ) + .await?; + + let (ipc, bytes) = match request.action { + SqliteAction::New => { + // handled in check_caps + // + (serde_json::to_vec(&SqliteResponse::Ok).unwrap(), None) + } + SqliteAction::Read { query } => { + let db = match open_dbs.get(&(request.package_id, request.db)) { + Some(db) => db, + None => { + return Err(SqliteError::NoDb); + } + }; + let db = db.lock().await; + + let parameters = get_json_params(payload)?; + + let mut statement = db.prepare(&query)?; + let column_names: Vec = statement + .column_names() + .iter() + .map(|c| c.to_string()) + .collect(); + + let results: Vec> = statement + .query_map(rusqlite::params_from_iter(parameters.iter()), |row| { + let mut map = HashMap::new(); + for (i, column_name) in column_names.iter().enumerate() { + let value: SqlValue = row.get(i)?; + let value_json = match value { + SqlValue::Integer(int) => serde_json::Value::Number(int.into()), + SqlValue::Real(real) => serde_json::Value::Number( + serde_json::Number::from_f64(real).unwrap(), + ), + SqlValue::Text(text) => serde_json::Value::String(text), + SqlValue::Blob(blob) => serde_json::Value::String(base64::encode(blob)), // or another representation if you prefer + _ => serde_json::Value::Null, + }; + map.insert(column_name.clone(), value_json); + } + Ok(map) + })? + .collect::, _>>()?; + + let results = serde_json::json!(results).to_string(); + let results_bytes = results.as_bytes().to_vec(); + + ( + serde_json::to_vec(&SqliteResponse::Read).unwrap(), + Some(results_bytes), + ) + } + SqliteAction::Write { statement, tx_id } => { + let db = match open_dbs.get(&(request.package_id, request.db)) { + Some(db) => db, + None => { + return Err(SqliteError::NoDb); + } + }; + let db = db.lock().await; + + let parameters = get_json_params(payload)?; + + match tx_id { + Some(tx_id) => { + txs.entry(tx_id) + .or_insert_with(Vec::new) + .push((statement.clone(), parameters)); + } + None => { + let mut stmt = db.prepare(&statement)?; + stmt.execute(rusqlite::params_from_iter(parameters.iter()))?; + } + }; + (serde_json::to_vec(&SqliteResponse::Ok).unwrap(), None) + } + SqliteAction::BeginTx => { + let tx_id = rand::random::(); + txs.insert(tx_id, Vec::new()); + + ( + serde_json::to_vec(&SqliteResponse::BeginTx { tx_id }).unwrap(), + None, + ) + } + SqliteAction::Commit { tx_id } => { + let db = match open_dbs.get(&(request.package_id, request.db)) { + Some(db) => db, + None => { + return Err(SqliteError::NoDb); + } + }; + let mut db = db.lock().await; + + let txs = match txs.remove(&tx_id).map(|(_, tx)| tx) { + None => { + return Err(SqliteError::NoTx); + } + Some(tx) => tx, + }; + + let tx = db.transaction()?; + for (query, params) in txs { + tx.execute(&query, rusqlite::params_from_iter(params.iter()))?; + } + + tx.commit()?; + (serde_json::to_vec(&SqliteResponse::Ok).unwrap(), None) + } + SqliteAction::Backup => { + // execute WAL flush. + // + (serde_json::to_vec(&SqliteResponse::Ok).unwrap(), None) + } + }; + + if let Some(target) = km.rsvp.or_else(|| { + expects_response.map(|_| Address { + node: our_node.clone(), + process: source.process.clone(), + }) + }) { + let response = KernelMessage { + id, + source: Address { + node: our_node.clone(), + process: SQLITE_PROCESS_ID.clone(), + }, + target, + rsvp: None, + message: Message::Response(( + Response { + inherit: false, + ipc, + metadata, + }, + None, + )), + payload: bytes.map(|bytes| Payload { + mime: Some("application/octet-stream".into()), + bytes, + }), + signed_capabilities: None, + }; + + let _ = send_to_loop.send(response).await; + } else { + send_to_terminal + .send(Printout { + verbosity: 2, + content: format!( + "sqlite: not sending response: {:?}", + serde_json::from_slice::(&ipc) + ), + }) + .await + .unwrap(); + } + + Ok(()) +} + +async fn check_caps( + our_node: String, + source: Address, + open_dbs: Arc>>, + mut send_to_caps_oracle: CapMessageSender, + request: &SqliteRequest, + sqlite_path: String, +) -> Result<(), SqliteError> { + let (send_cap_bool, recv_cap_bool) = tokio::sync::oneshot::channel(); + let src_package_id = PackageId::new(source.process.package(), source.process.publisher()); + + match &request.action { + SqliteAction::Write { .. } | SqliteAction::BeginTx | SqliteAction::Commit { .. } => { + send_to_caps_oracle + .send(CapMessage::Has { + on: source.process.clone(), + cap: Capability { + issuer: Address { + node: our_node.clone(), + process: SQLITE_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ + "kind": "write", + "db": request.db.to_string(), + })) + .unwrap(), + }, + responder: send_cap_bool, + }) + .await?; + let has_cap = recv_cap_bool.await?; + if !has_cap { + return Err(SqliteError::NoCap { + error: request.action.to_string(), + }); + } + Ok(()) + } + SqliteAction::Read { .. } => { + send_to_caps_oracle + .send(CapMessage::Has { + on: source.process.clone(), + cap: Capability { + issuer: Address { + node: our_node.clone(), + process: SQLITE_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ + "kind": "read", + "db": request.db.to_string(), + })) + .unwrap(), + }, + responder: send_cap_bool, + }) + .await?; + let has_cap = recv_cap_bool.await?; + if !has_cap { + return Err(SqliteError::NoCap { + error: request.action.to_string(), + }); + } + Ok(()) + } + SqliteAction::New => { + if src_package_id != request.package_id { + return Err(SqliteError::NoCap { + error: request.action.to_string(), + }); + } + + add_capability( + "read", + &request.db.to_string(), + &our_node, + &source, + &mut send_to_caps_oracle, + ) + .await?; + add_capability( + "write", + &request.db.to_string(), + &our_node, + &source, + &mut send_to_caps_oracle, + ) + .await?; + + let db_path = format!("{}{}", sqlite_path, request.db.to_string()); + + fs::create_dir_all(&db_path).await?; + + let db = Connection::open(&db_path)?; + db.execute("PRAGMA journal_mode=WAL;", [])?; + + open_dbs.insert( + (request.package_id.clone(), request.db.clone()), + Mutex::new(db), + ); + Ok(()) + } + SqliteAction::Backup => { + if source.process != *STATE_PROCESS_ID { + return Err(SqliteError::NoCap { + error: request.action.to_string(), + }); + } + Ok(()) + } + } +} + +async fn add_capability( + kind: &str, + db: &str, + our_node: &str, + source: &Address, + send_to_caps_oracle: &mut CapMessageSender, +) -> Result<(), SqliteError> { + let cap = Capability { + issuer: Address { + node: our_node.to_string(), + process: SQLITE_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ "kind": kind, "db": db })).unwrap(), + }; + let (send_cap_bool, recv_cap_bool) = tokio::sync::oneshot::channel(); + send_to_caps_oracle + .send(CapMessage::Add { + on: source.process.clone(), + cap, + responder: send_cap_bool, + }) + .await?; + let _ = recv_cap_bool.await?; + Ok(()) +} + +fn json_to_sqlite(value: &serde_json::Value) -> Result { + match value { + serde_json::Value::Number(n) => { + if let Some(int_val) = n.as_i64() { + Ok(SqlValue::Integer(int_val)) + } else if let Some(float_val) = n.as_f64() { + Ok(SqlValue::Real(float_val)) + } else { + Err(SqliteError::InvalidParameters) + } + } + serde_json::Value::String(s) => { + match base64::decode(&s) { + Ok(decoded_bytes) => { + // convert to SQLite Blob if it's a valid base64 string + Ok(SqlValue::Blob(decoded_bytes)) + } + Err(_) => { + // if it's not base64, just use the string itself + Ok(SqlValue::Text(s.clone())) + } + } + } + serde_json::Value::Bool(b) => Ok(SqlValue::Boolean(*b)), + serde_json::Value::Null => Ok(SqlValue::Null), + _ => Err(SqliteError::InvalidParameters), + } +} + +fn get_json_params(payload: Option) -> Result, SqliteError> { + match payload { + None => Ok(vec![]), + Some(payload) => match serde_json::from_slice::(&payload.bytes) { + Ok(serde_json::Value::Array(vec)) => vec + .iter() + .map(|value| json_to_sqlite(value)) + .collect::, _>>(), + _ => Err(SqliteError::InvalidParameters), + }, + } +} + +fn make_error_message(our_name: String, km: &KernelMessage, error: SqliteError) -> KernelMessage { + KernelMessage { + id: km.id, + source: Address { + node: our_name.clone(), + process: KV_PROCESS_ID.clone(), + }, + target: match &km.rsvp { + None => km.source.clone(), + Some(rsvp) => rsvp.clone(), + }, + rsvp: None, + message: Message::Response(( + Response { + inherit: false, + ipc: serde_json::to_vec(&SqliteResponse::Err { error: error }).unwrap(), + metadata: None, + }, + None, + )), + payload: None, + signed_capabilities: None, + } +} +impl ToSql for SqlValue { + fn to_sql(&self) -> rusqlite::Result { + match self { + SqlValue::Integer(i) => i.to_sql(), + SqlValue::Real(f) => f.to_sql(), + SqlValue::Text(ref s) => s.to_sql(), + SqlValue::Blob(ref b) => b.to_sql(), + SqlValue::Boolean(b) => b.to_sql(), + SqlValue::Null => Ok(rusqlite::types::ToSqlOutput::Owned( + rusqlite::types::Value::Null, + )), + } + } +} + +impl FromSql for SqlValue { + fn column_result(value: ValueRef<'_>) -> Result { + match value { + ValueRef::Integer(i) => Ok(SqlValue::Integer(i)), + ValueRef::Real(f) => Ok(SqlValue::Real(f)), + ValueRef::Text(t) => { + let text_str = std::str::from_utf8(t).map_err(|_| FromSqlError::InvalidType)?; + Ok(SqlValue::Text(text_str.to_string())) + } + ValueRef::Blob(b) => Ok(SqlValue::Blob(b.to_vec())), + _ => Err(FromSqlError::InvalidType), + } + } +} + +impl std::fmt::Display for SqliteAction { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl From for SqliteError { + fn from(err: std::io::Error) -> Self { + SqliteError::IOError { + error: err.to_string(), + } + } +} + +impl From for SqliteError { + fn from(err: rusqlite::Error) -> Self { + SqliteError::RusqliteError { + error: err.to_string(), + } + } +} + +impl From for SqliteError { + fn from(err: tokio::sync::oneshot::error::RecvError) -> Self { + SqliteError::NoCap { + error: err.to_string(), + } + } +} + +impl From> for SqliteError { + fn from(err: tokio::sync::mpsc::error::SendError) -> Self { + SqliteError::NoCap { + error: err.to_string(), + } + } +} diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 00000000..01c5e5de --- /dev/null +++ b/src/state.rs @@ -0,0 +1,650 @@ +use anyhow::Result; +use rocksdb::checkpoint::Checkpoint; +use rocksdb::{Options, DB}; +use std::collections::{HashMap, HashSet, VecDeque}; +use std::io::Read; +use std::path::Path; +use std::sync::Arc; +use tokio::fs; +use tokio::sync::Mutex; + +use crate::types::*; + +pub async fn load_state( + our_name: String, + home_directory_path: String, + runtime_extensions: Vec<(ProcessId, MessageSender, bool)>, +) -> Result<(ProcessMap, DB), StateError> { + let state_path = format!("{}/kernel", &home_directory_path); + + if let Err(e) = fs::create_dir_all(&state_path).await { + panic!("failed creating kernel state dir! {:?}", e); + } + + // more granular kernel_state in column families + + // let mut options = Option::default().unwrap(); + // options.create_if_missing(true); + //let db = DB::open_default(&state_directory_path_str).unwrap(); + let mut opts = Options::default(); + opts.create_if_missing(true); + // let cf_name = "kernel_state"; + // let cf_descriptor = ColumnFamilyDescriptor::new(cf_name, Options::default()); + let db = DB::open_default(state_path).unwrap(); + let mut process_map: ProcessMap = HashMap::new(); + + let kernel_id = process_to_vec(KERNEL_PROCESS_ID.clone()); + match db.get(&kernel_id) { + Ok(Some(value)) => { + process_map = bincode::deserialize::(&value).unwrap(); + } + Ok(None) => { + bootstrap( + &our_name, + home_directory_path.clone(), + runtime_extensions.clone(), + &mut process_map, + ) + .await + .unwrap(); + + db.put(&kernel_id, bincode::serialize(&process_map).unwrap()) + .unwrap(); + } + Err(e) => { + panic!("failed to load kernel state from db: {:?}", e); + } + } + + Ok((process_map, db)) +} + +pub async fn state_sender( + our_name: String, + send_to_loop: MessageSender, + send_to_terminal: PrintSender, + mut recv_state: MessageReceiver, + db: DB, + home_directory_path: String, +) -> Result<(), anyhow::Error> { + let db = Arc::new(db); + + let mut process_queues: HashMap>>> = + HashMap::new(); + + loop { + tokio::select! { + Some(km) = recv_state.recv() => { + if our_name != km.source.node { + println!( + "state: request must come from our_name={}, got: {}", + our_name, &km, + ); + continue; + } + + let queue = process_queues + .entry(km.source.process.clone()) + .or_insert_with(|| Arc::new(Mutex::new(VecDeque::new()))) + .clone(); + + { + let mut queue_lock = queue.lock().await; + queue_lock.push_back(km.clone()); + } + + let db_clone = db.clone(); + let send_to_loop = send_to_loop.clone(); + let send_to_terminal = send_to_terminal.clone(); + let our_name = our_name.clone(); + let home_directory_path = home_directory_path.clone(); + + tokio::spawn(async move { + let mut queue_lock = queue.lock().await; + if let Some(km) = queue_lock.pop_front() { + if let Err(e) = handle_request( + our_name.clone(), + km.clone(), + db_clone, + send_to_loop.clone(), + send_to_terminal, + home_directory_path, + ) + .await + { + let _ = send_to_loop + .send(make_error_message(our_name.clone(), &km, e)) + .await; + } + } + }); + } + } + } +} + +async fn handle_request( + our_name: String, + kernel_message: KernelMessage, + db: Arc, + send_to_loop: MessageSender, + _send_to_terminal: PrintSender, + home_directory_path: String, +) -> Result<(), StateError> { + let KernelMessage { + id, + source, + rsvp, + message, + payload, + .. + } = kernel_message; + let Message::Request(Request { + expects_response, + ipc, + metadata, // for kernel + .. + }) = message + else { + return Err(StateError::BadRequest { + error: "not a request".into(), + }); + }; + + let action: StateAction = match serde_json::from_slice(&ipc) { + Ok(r) => r, + Err(e) => { + return Err(StateError::BadJson { + error: format!("parse into StateAction failed: {:?}", e), + }) + } + }; + + let (ipc, bytes) = match action { + StateAction::SetState(process_id) => { + let key = process_to_vec(process_id); + + let Some(ref payload) = payload else { + return Err(StateError::BadBytes { + action: "SetState".into(), + }); + }; + + db.put(key, &payload.bytes) + .map_err(|e| StateError::RocksDBError { + action: "SetState".into(), + error: e.to_string(), + })?; + + (serde_json::to_vec(&StateResponse::SetState).unwrap(), None) + } + StateAction::GetState(process_id) => { + let key = process_to_vec(process_id.clone()); + match db.get(key) { + Ok(Some(value)) => ( + serde_json::to_vec(&StateResponse::GetState).unwrap(), + Some(value), + ), + Ok(None) => { + return Err(StateError::NotFound { + process_id: process_id.clone(), + }); + } + Err(e) => { + println!("get state error: {:?}", e); + return Err(StateError::RocksDBError { + action: "GetState".into(), + error: e.to_string(), + }); + } + } + } + StateAction::DeleteState(process_id) => { + let key = process_to_vec(process_id); + match db.delete(key) { + Ok(_) => ( + serde_json::to_vec(&StateResponse::DeleteState).unwrap(), + None, + ), + Err(e) => { + println!("delete state error: {:?}", e); + return Err(StateError::RocksDBError { + action: "DeleteState".into(), + error: e.to_string(), + }); + } + } + } + StateAction::Backup => { + // handle Backup action + println!("got backup"); + let checkpoint_dir = format!("{}/kernel/checkpoint", &home_directory_path); + + if Path::new(&checkpoint_dir).exists() { + let _ = fs::remove_dir_all(&checkpoint_dir).await; + } + let checkpoint = Checkpoint::new(&db).unwrap(); + checkpoint.create_checkpoint(&checkpoint_dir).unwrap(); + (serde_json::to_vec(&StateResponse::Backup).unwrap(), None) + } + }; + + if let Some(target) = rsvp.or_else(|| { + expects_response.map(|_| Address { + node: our_name.clone(), + process: source.process.clone(), + }) + }) { + let response = KernelMessage { + id, + source: Address { + node: our_name.clone(), + process: STATE_PROCESS_ID.clone(), + }, + target, + rsvp: None, + message: Message::Response(( + Response { + inherit: false, + ipc, + metadata, + }, + None, + )), + payload: bytes.map(|bytes| Payload { + mime: Some("application/octet-stream".into()), + bytes, + }), + signed_capabilities: None, + }; + + let _ = send_to_loop.send(response).await; + }; + + Ok(()) +} + +/// function run only upon fresh boot. +/// +/// for each folder in /modules, looks for a package.zip file, extracts the contents, +/// sends the contents to VFS, and reads the manifest.json. +/// +/// the manifest.json contains instructions for which processes to boot and what +/// capabilities to give them. since we are inside runtime, can spawn those out of +/// thin air. +async fn bootstrap( + our_name: &str, + home_directory_path: String, + runtime_extensions: Vec<(ProcessId, MessageSender, bool)>, + process_map: &mut ProcessMap, +) -> Result<()> { + println!("bootstrapping node...\r"); + + let mut runtime_caps: HashSet = HashSet::new(); + // kernel is a special case + runtime_caps.insert(Capability { + issuer: Address { + node: our_name.to_string(), + process: ProcessId::from_str("kernel:sys:uqbar").unwrap(), + }, + params: "\"messaging\"".into(), + }); + // net is a special case + runtime_caps.insert(Capability { + issuer: Address { + node: our_name.to_string(), + process: ProcessId::from_str("net:sys:uqbar").unwrap(), + }, + params: "\"messaging\"".into(), + }); + for runtime_module in runtime_extensions.clone() { + runtime_caps.insert(Capability { + issuer: Address { + node: our_name.to_string(), + process: runtime_module.0, + }, + params: "\"messaging\"".into(), + }); + } + // give all runtime processes the ability to send messages across the network + runtime_caps.insert(Capability { + issuer: Address { + node: our_name.to_string(), + process: KERNEL_PROCESS_ID.clone(), + }, + params: "\"network\"".into(), + }); + + // finally, save runtime modules in state map as well, somewhat fakely + // special cases for kernel and net + process_map + .entry(ProcessId::from_str("kernel:sys:uqbar").unwrap()) + .or_insert(PersistedProcess { + wasm_bytes_handle: "".into(), + on_exit: OnExit::Restart, + capabilities: runtime_caps.clone(), + public: false, + }); + process_map + .entry(ProcessId::from_str("net:sys:uqbar").unwrap()) + .or_insert(PersistedProcess { + wasm_bytes_handle: "".into(), + on_exit: OnExit::Restart, + capabilities: runtime_caps.clone(), + public: false, + }); + for runtime_module in runtime_extensions { + process_map + .entry(runtime_module.0) + .or_insert(PersistedProcess { + wasm_bytes_handle: "".into(), + on_exit: OnExit::Restart, + capabilities: runtime_caps.clone(), + public: runtime_module.2, + }); + } + + let packages: Vec<(String, zip::ZipArchive>>)> = + get_zipped_packages().await; + + for (package_name, mut package) in packages { + // special case tester: only load it in if in simulation mode + if package_name == "tester" { + #[cfg(not(feature = "simulation-mode"))] + continue; + #[cfg(feature = "simulation-mode")] + {} + } + + println!("fs: handling package {package_name}...\r"); + // get and read metadata.json + let Ok(mut package_metadata_zip) = package.by_name("metadata.json") else { + println!( + "fs: missing metadata for package {}, skipping", + package_name + ); + continue; + }; + let mut metadata_content = Vec::new(); + package_metadata_zip + .read_to_end(&mut metadata_content) + .unwrap(); + drop(package_metadata_zip); + let package_metadata: serde_json::Value = + serde_json::from_slice(&metadata_content).expect("fs: metadata parse error"); + + println!("fs: found package metadata: {:?}\r", package_metadata); + + let package_name = package_metadata["package"] + .as_str() + .expect("fs: metadata parse error: bad package name"); + + let package_publisher = package_metadata["publisher"] + .as_str() + .expect("fs: metadata parse error: bad publisher name"); + + // create a new package in VFS + let our_drive_name = [package_name, package_publisher].join(":"); + let pkg_path = format!("{}/vfs/{}/pkg", &home_directory_path, &our_drive_name); + fs::create_dir_all(&pkg_path) + .await + .expect("bootstrap vfs dir pkg creation failed!"); + + let drive_path = format!("/{}/pkg", &our_drive_name); + + // for each file in package.zip, recursively through all dirs, send a newfile KM to VFS + for i in 0..package.len() { + let mut file = package.by_index(i).unwrap(); + if file.is_file() { + let file_path = file + .enclosed_name() + .expect("fs: name error reading package.zip") + .to_owned(); + let mut file_path = file_path.to_string_lossy().to_string(); + if !file_path.starts_with('/') { + file_path = format!("/{}", file_path); + } + println!("fs: found file {}...\r", file_path); + let mut file_content = Vec::new(); + file.read_to_end(&mut file_content).unwrap(); + let path = format!("{}/{}", &pkg_path, file_path); + fs::write(&path, file_content).await.unwrap(); + } + } + + // get and read manifest.json + let Ok(mut package_manifest_zip) = package.by_name("manifest.json") else { + println!( + "fs: missing manifest for package {}, skipping", + package_name + ); + continue; + }; + let mut manifest_content = Vec::new(); + package_manifest_zip + .read_to_end(&mut manifest_content) + .unwrap(); + drop(package_manifest_zip); + let package_manifest = String::from_utf8(manifest_content)?; + let package_manifest = serde_json::from_str::>(&package_manifest) + .expect("fs: manifest parse error"); + + // for each process-entry in manifest.json: + for mut entry in package_manifest { + let wasm_bytes = &mut Vec::new(); + let mut file_path = entry.process_wasm_path.to_string(); + if file_path.starts_with('/') { + file_path = file_path[1..].to_string(); + } + package + .by_name(&file_path) + .expect("fs: no wasm found in package!") + .read_to_end(wasm_bytes) + .unwrap(); + + // spawn the requested capabilities + // remember: out of thin air, because this is the root distro + let mut requested_caps = HashSet::new(); + let our_process_id = format!( + "{}:{}:{}", + entry.process_name, package_name, package_publisher + ); + entry.request_messaging = Some(entry.request_messaging.unwrap_or_default()); + if let Some(ref mut request_messaging) = entry.request_messaging { + request_messaging.push(serde_json::Value::String(our_process_id.clone())); + for value in request_messaging { + match value { + serde_json::Value::String(process_name) => { + requested_caps.insert(Capability { + issuer: Address { + node: our_name.to_string(), + process: ProcessId::from_str(process_name).unwrap(), + }, + params: "\"messaging\"".into(), + }); + } + serde_json::Value::Object(map) => { + if let Some(process_name) = map.get("process") { + if let Some(params) = map.get("params") { + requested_caps.insert(Capability { + issuer: Address { + node: our_name.to_string(), + process: ProcessId::from_str( + process_name.as_str().unwrap(), + ) + .unwrap(), + }, + params: params.to_string(), + }); + } + } + } + _ => { + // other json types + continue; + } + } + } + } + + // grant capabilities to other initially spawned processes, distro + if let Some(to_grant) = &entry.grant_messaging { + for value in to_grant { + let mut capability = None; + let mut to_process = None; + match value { + serde_json::Value::String(process_name) => { + if let Ok(parsed_process_id) = ProcessId::from_str(process_name) { + capability = Some(Capability { + issuer: Address { + node: our_name.to_string(), + process: ProcessId::from_str(process_name).unwrap(), + }, + params: "\"messaging\"".into(), + }); + to_process = Some(parsed_process_id); + } + } + serde_json::Value::Object(map) => { + if let Some(process_name) = map.get("process") { + if let Ok(parsed_process_id) = + ProcessId::from_str(&process_name.as_str().unwrap()) + { + if let Some(params) = map.get("params") { + capability = Some(Capability { + issuer: Address { + node: our_name.to_string(), + process: ProcessId::from_str( + process_name.as_str().unwrap(), + ) + .unwrap(), + }, + params: params.to_string(), + }); + to_process = Some(parsed_process_id); + } + } + } + } + _ => { + continue; + } + } + + if let Some(cap) = capability { + if let Some(process) = process_map.get_mut(&to_process.unwrap()) { + process.capabilities.insert(cap); + } + } + } + } + + if entry.request_networking { + requested_caps.insert(Capability { + issuer: Address { + node: our_name.to_string(), + process: KERNEL_PROCESS_ID.clone(), + }, + params: "\"network\"".into(), + }); + } + + // give access to package_name vfs + requested_caps.insert(Capability { + issuer: Address { + node: our_name.into(), + process: VFS_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ + "kind": "read", + "drive": drive_path, + })) + .unwrap(), + }); + requested_caps.insert(Capability { + issuer: Address { + node: our_name.into(), + process: VFS_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ + "kind": "write", + "drive": drive_path, + })) + .unwrap(), + }); + + let public_process = entry.public; + + let wasm_bytes_handle = format!("{}/{}", &drive_path, &file_path); + + process_map.insert( + ProcessId::new(Some(&entry.process_name), package_name, package_publisher), + PersistedProcess { + wasm_bytes_handle, + on_exit: entry.on_exit, + capabilities: requested_caps, + public: public_process, + }, + ); + } + } + Ok(()) +} + +/// go into /target folder and get all .zip package files +async fn get_zipped_packages() -> Vec<(String, zip::ZipArchive>>)> { + println!("fs: reading distro packages...\r"); + let target_path = std::path::Path::new("target"); + + let mut packages = Vec::new(); + + if let Ok(mut entries) = fs::read_dir(target_path).await { + while let Ok(Some(entry)) = entries.next_entry().await { + if entry.file_name().to_string_lossy().ends_with(".zip") { + let package_name = entry + .file_name() + .to_string_lossy() + .trim_end_matches(".zip") + .to_string(); + if let Ok(bytes) = fs::read(entry.path()).await { + if let Ok(zip) = zip::ZipArchive::new(std::io::Cursor::new(bytes)) { + // add to list of packages + println!("fs: found package: {}\r", package_name); + packages.push((package_name, zip)); + } + } + } + } + } + + packages +} + +fn make_error_message(our_name: String, km: &KernelMessage, error: StateError) -> KernelMessage { + KernelMessage { + id: km.id, + source: Address { + node: our_name.clone(), + process: STATE_PROCESS_ID.clone(), + }, + target: match &km.rsvp { + None => km.source.clone(), + Some(rsvp) => rsvp.clone(), + }, + rsvp: None, + message: Message::Response(( + Response { + inherit: false, + ipc: serde_json::to_vec(&StateResponse::Err(error)).unwrap(), + metadata: None, + }, + None, + )), + payload: None, + signed_capabilities: None, + } +} + +fn process_to_vec(process: ProcessId) -> Vec { + process.to_string().as_bytes().to_vec() +} diff --git a/src/terminal/mod.rs b/src/terminal/mod.rs index 74bd7ef7..2ddfa3f4 100644 --- a/src/terminal/mod.rs +++ b/src/terminal/mod.rs @@ -146,7 +146,13 @@ pub async fn terminal( stdout, cursor::MoveTo(0, win_rows - 1), terminal::Clear(ClearType::CurrentLine), - Print(format!("{} {}/{} {:02}:{:02} ", + Print(format!("{}{} {}/{} {:02}:{:02} ", + match printout.verbosity { + 0 => "", + 1 => "1️⃣ ", + 2 => "2️⃣ ", + _ => "3️⃣ ", + }, now.weekday(), now.month(), now.day(), diff --git a/src/types.rs b/src/types.rs index aed13560..e5c09f2e 100644 --- a/src/types.rs +++ b/src/types.rs @@ -7,13 +7,15 @@ use thiserror::Error; lazy_static::lazy_static! { pub static ref ENCRYPTOR_PROCESS_ID: ProcessId = ProcessId::new(Some("encryptor"), "sys", "uqbar"); pub static ref ETH_RPC_PROCESS_ID: ProcessId = ProcessId::new(Some("eth_rpc"), "sys", "uqbar"); - pub static ref FILESYSTEM_PROCESS_ID: ProcessId = ProcessId::new(Some("filesystem"), "sys", "uqbar"); pub static ref HTTP_CLIENT_PROCESS_ID: ProcessId = ProcessId::new(Some("http_client"), "sys", "uqbar"); pub static ref HTTP_SERVER_PROCESS_ID: ProcessId = ProcessId::new(Some("http_server"), "sys", "uqbar"); pub static ref KERNEL_PROCESS_ID: ProcessId = ProcessId::new(Some("kernel"), "sys", "uqbar"); pub static ref TERMINAL_PROCESS_ID: ProcessId = ProcessId::new(Some("terminal"), "terminal", "uqbar"); pub static ref TIMER_PROCESS_ID: ProcessId = ProcessId::new(Some("timer"), "sys", "uqbar"); pub static ref VFS_PROCESS_ID: ProcessId = ProcessId::new(Some("vfs"), "sys", "uqbar"); + pub static ref STATE_PROCESS_ID: ProcessId = ProcessId::new(Some("state"), "sys", "uqbar"); + pub static ref KV_PROCESS_ID: ProcessId = ProcessId::new(Some("kv"), "sys", "uqbar"); + pub static ref SQLITE_PROCESS_ID: ProcessId = ProcessId::new(Some("sqlite"), "sys", "uqbar"); } // @@ -66,13 +68,13 @@ pub struct PackageId { } impl PackageId { - pub fn _new(package_name: &str, publisher_node: &str) -> Self { + pub fn new(package_name: &str, publisher_node: &str) -> Self { PackageId { package_name: package_name.into(), publisher_node: publisher_node.into(), } } - pub fn _from_str(input: &str) -> Result { + pub fn from_str(input: &str) -> Result { // split string on colons into 2 segments let mut segments = input.split(':'); let package_name = segments @@ -428,18 +430,54 @@ pub enum SendErrorKind { } #[derive(Clone, Debug, Serialize, Deserialize)] -pub enum OnPanic { +pub enum OnExit { None, Restart, Requests(Vec<(Address, Request, Option)>), } -impl OnPanic { +impl OnExit { pub fn is_restart(&self) -> bool { match self { - OnPanic::None => false, - OnPanic::Restart => true, - OnPanic::Requests(_) => false, + OnExit::None => false, + OnExit::Restart => true, + OnExit::Requests(_) => false, + } + } + + pub fn en_wit(&self) -> wit::OnExit { + match self { + OnExit::None => wit::OnExit::None, + OnExit::Restart => wit::OnExit::Restart, + OnExit::Requests(reqs) => wit::OnExit::Requests( + reqs.iter() + .map(|(address, request, payload)| { + ( + address.en_wit(), + en_wit_request(request.clone()), + en_wit_payload(payload.clone()), + ) + }) + .collect(), + ), + } + } + + pub fn de_wit(wit: wit::OnExit) -> Self { + match wit { + wit::OnExit::None => OnExit::None, + wit::OnExit::Restart => OnExit::Restart, + wit::OnExit::Requests(reqs) => OnExit::Requests( + reqs.into_iter() + .map(|(address, request, payload)| { + ( + Address::de_wit(address), + de_wit_request(request), + de_wit_payload(payload), + ) + }) + .collect(), + ), } } } @@ -585,23 +623,6 @@ pub fn en_wit_send_error_kind(kind: SendErrorKind) -> wit::SendErrorKind { } } -pub fn de_wit_on_panic(wit: wit::OnPanic) -> OnPanic { - match wit { - wit::OnPanic::None => OnPanic::None, - wit::OnPanic::Restart => OnPanic::Restart, - wit::OnPanic::Requests(reqs) => OnPanic::Requests( - reqs.into_iter() - .map(|(address, request, payload)| { - ( - Address::de_wit(address), - de_wit_request(request), - de_wit_payload(payload), - ) - }) - .collect(), - ), - } -} // // END SYNC WITH process_lib // @@ -715,8 +736,8 @@ pub struct IdentityTransaction { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ProcessMetadata { pub our: Address, - pub wasm_bytes_handle: u128, - pub on_panic: OnPanic, + pub wasm_bytes_handle: String, + pub on_exit: OnExit, pub public: bool, } @@ -791,8 +812,8 @@ pub enum KernelCommand { /// for the new process if `public` is false. InitializeProcess { id: ProcessId, - wasm_bytes_handle: u128, - on_panic: OnPanic, + wasm_bytes_handle: String, + on_exit: OnExit, initial_capabilities: HashSet, public: bool, }, @@ -846,10 +867,8 @@ pub type ProcessMap = HashMap; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct PersistedProcess { - pub wasm_bytes_handle: u128, - // pub drive: String, - // pub full_path: String, - pub on_panic: OnPanic, + pub wasm_bytes_handle: String, + pub on_exit: OnExit, pub capabilities: HashSet, pub public: bool, // marks if a process allows messages from any process } @@ -870,6 +889,7 @@ pub struct PackageMetadata { pub package: String, pub publisher: String, pub version: PackageVersion, + pub wit_version: Option<(u32, u32, u32)>, pub description: Option, pub website: Option, } @@ -879,214 +899,266 @@ pub struct PackageMetadata { pub struct PackageManifestEntry { pub process_name: String, pub process_wasm_path: String, - pub on_panic: OnPanic, + pub on_exit: OnExit, pub request_networking: bool, - pub request_messaging: Option>, - pub grant_messaging: Option>, + pub request_messaging: Option>, + pub grant_messaging: Option>, pub public: bool, } #[derive(Serialize, Deserialize, Debug)] -pub enum FsAction { - Write(Option), - WriteOffset((u128, u64)), - Append(Option), - Read(u128), - ReadChunk(ReadChunkRequest), - Delete(u128), - Length(u128), - SetLength((u128, u64)), +pub enum StateAction { GetState(ProcessId), SetState(ProcessId), DeleteState(ProcessId), + Backup, } #[derive(Serialize, Deserialize, Debug)] -pub struct ReadChunkRequest { - pub file: u128, - pub start: u64, - pub length: u64, -} - -#[derive(Clone, Serialize, Deserialize, Debug)] -pub enum FsResponse { - Write(u128), - Read(u128), - ReadChunk(u128), // TODO: remove? - Append(u128), - Delete(u128), - Length(u64), +pub enum StateResponse { GetState, SetState, -} - -#[derive(Debug)] -pub struct S3Config { - pub access_key: String, - pub secret_key: String, - pub region: String, - pub bucket: String, - pub endpoint: String, -} - -#[derive(Debug)] -pub struct FsConfig { - pub s3_config: Option, - pub mem_buffer_limit: usize, - pub read_cache_limit: usize, - pub chunk_size: usize, - pub flush_to_cold_interval: usize, - pub encryption: bool, - pub cloud_enabled: bool, - // pub flush_to_wal_interval: usize, + DeleteState, + Backup, + Err(StateError), } #[derive(Error, Debug, Serialize, Deserialize)] -pub enum FsError { - #[error("fs: Bytes payload required for {action}.")] +pub enum StateError { + #[error("kernel_state: rocksdb internal error: {error}")] + RocksDBError { action: String, error: String }, + #[error("kernel_state: startup error")] + StartupError { action: String }, + #[error("kernel_state: bytes payload required for {action}")] BadBytes { action: String }, - #[error( - "fs: JSON payload could not be parsed to FsAction: {:?}, error: {:?}.", - json, - error - )] - BadJson { json: String, error: String }, - #[error("fs: No JSON payload.")] - NoJson, - #[error("fs: Read failed to file {file}: {error}.")] - ReadFailed { file: u128, error: String }, - #[error("fs: Write failed to file {file}: {error}.")] - WriteFailed { file: u128, error: String }, - #[error("fs: file not found: {file}")] - NotFound { file: u128 }, - #[error("fs: S3 error: {error}")] - S3Error { error: String }, - #[error("fs: IO error: {error}")] + #[error("kernel_state: bad request error: {error}")] + BadRequest { error: String }, + #[error("kernel_state: Bad JSON payload: {error}")] + BadJson { error: String }, + #[error("kernel_state: state not found for ProcessId {process_id}")] + NotFound { process_id: ProcessId }, + #[error("kernel_state: IO error: {error}")] IOError { error: String }, - #[error("fs: Encryption error: {error}")] - EncryptionError { error: String }, - #[error("fs: Limit error: {error}")] - LimitError { error: String }, - #[error("fs: memory buffer error: {error}")] - MemoryBufferError { error: String }, - #[error("fs: length operation error: {error}")] - LengthError { error: String }, - #[error("fs: creating fs dir failed at path: {path}: {error}")] - CreateInitialDirError { path: String, error: String }, } #[allow(dead_code)] -impl FsError { +impl StateError { pub fn kind(&self) -> &str { match *self { - FsError::BadBytes { .. } => "BadBytes", - FsError::BadJson { .. } => "BadJson", - FsError::NoJson { .. } => "NoJson", - FsError::ReadFailed { .. } => "ReadFailed", - FsError::WriteFailed { .. } => "WriteFailed", - FsError::S3Error { .. } => "S3Error", - FsError::IOError { .. } => "IOError", - FsError::EncryptionError { .. } => "EncryptionError", - FsError::LimitError { .. } => "LimitError", - FsError::MemoryBufferError { .. } => "MemoryBufferError", - FsError::NotFound { .. } => "NotFound", - FsError::LengthError { .. } => "LengthError", - FsError::CreateInitialDirError { .. } => "CreateInitialDirError", + StateError::RocksDBError { .. } => "RocksDBError", + StateError::StartupError { .. } => "StartupError", + StateError::BadBytes { .. } => "BadBytes", + StateError::BadRequest { .. } => "BadRequest", + StateError::BadJson { .. } => "NoJson", + StateError::NotFound { .. } => "NotFound", + StateError::IOError { .. } => "IOError", } } } #[derive(Debug, Serialize, Deserialize)] pub struct VfsRequest { - pub drive: String, + pub path: String, pub action: VfsAction, } #[derive(Debug, Serialize, Deserialize)] pub enum VfsAction { - New, - Add { - full_path: String, - entry_type: AddEntryType, - }, - Rename { - full_path: String, - new_full_path: String, - }, - Delete(String), - WriteOffset { - full_path: String, - offset: u64, - }, - Append(String), - SetSize { - full_path: String, - size: u64, - }, - GetPath(u128), - GetHash(String), - GetEntry(String), - GetFileChunk { - full_path: String, - offset: u64, - length: u64, - }, - GetEntryLength(String), + CreateDrive, + CreateDir, + CreateDirAll, + CreateFile, + OpenFile, + CloseFile, + WriteAll, + Write, + ReWrite, + WriteAt(u64), + Append, + SyncAll, + Read, + ReadDir, + ReadToEnd, + ReadExact(u64), + ReadToString, + Seek(SeekFrom), + RemoveFile, + RemoveDir, + RemoveDirAll, + Rename(String), + AddZip, + Len, + SetLen(u64), + Hash, } #[derive(Debug, Serialize, Deserialize)] -pub enum AddEntryType { - Dir, - NewFile, // add a new file to fs and add name in vfs - ExistingFile { hash: u128 }, // link an existing file in fs to a new name in vfs - ZipArchive, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum GetEntryType { - Dir, - File, +pub enum SeekFrom { + Start(u64), + End(i64), + Current(i64), } #[derive(Debug, Serialize, Deserialize)] pub enum VfsResponse { Ok, Err(VfsError), - GetPath(Option), - GetHash(Option), - GetEntry { - // file bytes in payload, if entry was a file - is_file: bool, - children: Vec, - }, - GetFileChunk, // chunk in payload, if file exists - GetEntryLength(Option), + Read, + ReadDir(Vec), + ReadToString(String), + Len(u64), + Hash([u8; 32]), } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Error, Debug, Serialize, Deserialize)] pub enum VfsError { - BadJson, - BadPayload, - BadDriveName, - BadDescriptor, - NoCap, - EntryNotFound, - PersistError, - InternalError, // String + #[error("vfs: No capability for action {action} at path {path}")] + NoCap { action: String, path: String }, + #[error("vfs: Bytes payload required for {action} at path {path}")] + BadBytes { action: String, path: String }, + #[error("vfs: bad request error: {error}")] + BadRequest { error: String }, + #[error("vfs: error parsing path: {path}, error: {error}")] + ParseError { error: String, path: String }, + #[error("vfs: IO error: {error}, at path {path}")] + IOError { error: String, path: String }, + #[error("vfs: kernel capability channel error: {error}")] + CapChannelFail { error: String }, + #[error("vfs: Bad JSON payload: {error}")] + BadJson { error: String }, + #[error("vfs: File not found at path {path}")] + NotFound { path: String }, + #[error("vfs: Creating directory failed at path: {path}: {error}")] + CreateDirError { path: String, error: String }, } #[allow(dead_code)] impl VfsError { pub fn kind(&self) -> &str { match *self { - VfsError::BadJson => "BadJson", - VfsError::BadPayload => "BadPayload", - VfsError::BadDriveName => "BadDriveName", - VfsError::BadDescriptor => "BadDescriptor", - VfsError::NoCap => "NoCap", - VfsError::EntryNotFound => "EntryNotFound", - VfsError::PersistError => "PersistError", - VfsError::InternalError => "InternalError", + VfsError::NoCap { .. } => "NoCap", + VfsError::BadBytes { .. } => "BadBytes", + VfsError::BadRequest { .. } => "BadRequest", + VfsError::ParseError { .. } => "ParseError", + VfsError::IOError { .. } => "IOError", + VfsError::CapChannelFail { .. } => "CapChannelFail", + VfsError::BadJson { .. } => "NoJson", + VfsError::NotFound { .. } => "NotFound", + VfsError::CreateDirError { .. } => "CreateDirError", } } } + +#[derive(Debug, Serialize, Deserialize)] +pub struct KvRequest { + pub package_id: PackageId, + pub db: String, + pub action: KvAction, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub enum KvAction { + New, + Set { key: Vec, tx_id: Option }, + Delete { key: Vec, tx_id: Option }, + Get { key: Vec }, + BeginTx, + Commit { tx_id: u64 }, + Backup, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum KvResponse { + Ok, + BeginTx { tx_id: u64 }, + Get { key: Vec }, + Err { error: KvError }, +} + +#[derive(Debug, Serialize, Deserialize, Error)] +pub enum KvError { + #[error("kv: DbDoesNotExist")] + NoDb, + #[error("kv: DbAlreadyExists")] + DbAlreadyExists, + #[error("kv: KeyNotFound")] + KeyNotFound, + #[error("kv: no Tx found")] + NoTx, + #[error("kv: No capability: {error}")] + NoCap { error: String }, + #[error("kv: rocksdb internal error: {error}")] + RocksDBError { action: String, error: String }, + #[error("kv: input bytes/json/key error: {error}")] + InputError { error: String }, + #[error("kv: IO error: {error}")] + IOError { error: String }, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct SqliteRequest { + pub package_id: PackageId, + pub db: String, + pub action: SqliteAction, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum SqliteAction { + New, + Write { + statement: String, + tx_id: Option, + }, + Read { + query: String, + }, + BeginTx, + Commit { + tx_id: u64, + }, + Backup, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum SqliteResponse { + Ok, + Read, + BeginTx { tx_id: u64 }, + Err { error: SqliteError }, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum SqlValue { + Integer(i64), + Real(f64), + Text(String), + Blob(Vec), + Boolean(bool), + Null, +} + +#[derive(Debug, Serialize, Deserialize, Error)] +pub enum SqliteError { + #[error("sqlite: DbDoesNotExist")] + NoDb, + #[error("sqlite: DbAlreadyExists")] + DbAlreadyExists, + #[error("sqlite: NoTx")] + NoTx, + #[error("sqlite: No capability: {error}")] + NoCap { error: String }, + #[error("sqlite: UnexpectedResponse")] + UnexpectedResponse, + #[error("sqlite: NotAWriteKeyword")] + NotAWriteKeyword, + #[error("sqlite: NotAReadKeyword")] + NotAReadKeyword, + #[error("sqlite: Invalid Parameters")] + InvalidParameters, + #[error("sqlite: IO error: {error}")] + IOError { error: String }, + #[error("sqlite: rusqlite error: {error}")] + RusqliteError { error: String }, + #[error("sqlite: input bytes/json/key error: {error}")] + InputError { error: String }, +} diff --git a/src/vfs.rs b/src/vfs.rs index 95fbeeb8..15143130 100644 --- a/src/vfs.rs +++ b/src/vfs.rs @@ -1,690 +1,426 @@ -use serde::{Deserialize, Serialize}; -use std::collections::{HashMap, HashSet, VecDeque}; +use dashmap::DashMap; +use std::collections::{HashMap, VecDeque}; use std::io::prelude::*; +use std::path::{Path, PathBuf}; use std::sync::Arc; -use tokio::sync::{Mutex, MutexGuard}; +use tokio::fs; +use tokio::fs::OpenOptions; +use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt, SeekFrom}; +use tokio::sync::Mutex; use crate::types::*; -const VFS_PERSIST_STATE_CHANNEL_CAPACITY: usize = 5; -const VFS_TASK_DONE_CHANNEL_CAPACITY: usize = 5; -const VFS_RESPONSE_CHANNEL_CAPACITY: usize = 2; - -type ResponseRouter = HashMap; -#[derive(Clone, Debug, Eq, PartialEq, Hash, Deserialize, Serialize)] -enum Key { - Dir { id: u64 }, - File { id: u128 }, - // ... -} -type KeyToEntry = HashMap; -type PathToKey = HashMap; - -#[derive(Clone, Debug, Deserialize, Serialize)] -struct Vfs { - key_to_entry: KeyToEntry, - path_to_key: PathToKey, -} -type DriveToVfs = HashMap>>; -type DriveToVfsSerializable = HashMap; - -type RequestQueue = VecDeque<(KernelMessage, MessageReceiver)>; -type DriveToQueue = Arc>>; - -#[derive(Clone, Debug, Deserialize, Serialize)] -struct Entry { - name: String, - full_path: String, - entry_type: EntryType, - // ... // general metadata? -} - -#[derive(Clone, Debug, Deserialize, Serialize)] -enum EntryType { - Dir { parent: Key, children: HashSet }, - File { parent: Key }, // hash could be generalized to `location` if we want to be able to point at, e.g., remote files -} - -impl Vfs { - fn new() -> Self { - let mut key_to_entry: KeyToEntry = HashMap::new(); - let mut path_to_key: PathToKey = HashMap::new(); - let root_path: String = "/".into(); - let root_key = Key::Dir { id: 0 }; - key_to_entry.insert( - root_key.clone(), - Entry { - name: root_path.clone(), - full_path: root_path.clone(), - entry_type: EntryType::Dir { - parent: root_key.clone(), - children: HashSet::new(), - }, - }, - ); - path_to_key.insert(root_path.clone(), root_key.clone()); - Vfs { - key_to_entry, - path_to_key, - } - } -} - -fn clean_path(path: &str) -> String { - let cleaned = path.trim_start_matches('/').trim_end_matches('/'); - format!("/{}", cleaned) -} - -fn get_parent_path(path: &str) -> String { - let mut split_path: Vec<&str> = path.split('/').collect(); - split_path.pop(); - let parent_path = split_path.join("/"); - if parent_path.is_empty() { - "/".to_string() - } else { - parent_path - } -} - -#[async_recursion::async_recursion] -async fn create_entry(vfs: &mut MutexGuard, path: &str, key: Key) -> Result { - if let Some(existing_key) = vfs.path_to_key.get(path) { - return Ok(existing_key.clone()); - } - - let parent_path = get_parent_path(path); - let parent_key = create_entry(vfs, &parent_path, Key::Dir { id: rand::random() }).await?; - - let entry_type = match key { - Key::Dir { id: _ } => EntryType::Dir { - parent: parent_key.clone(), - children: HashSet::new(), - }, - Key::File { id: _ } => EntryType::File { - parent: parent_key.clone(), - }, - }; - let entry = Entry { - name: path.split('/').last().unwrap().to_string(), - full_path: path.to_string(), - entry_type, - }; - vfs.key_to_entry.insert(key.clone(), entry); - vfs.path_to_key.insert(path.to_string(), key.clone()); - - if let Some(parent_entry) = vfs.key_to_entry.get_mut(&parent_key) { - if let EntryType::Dir { children, .. } = &mut parent_entry.entry_type { - children.insert(key.clone()); - } - } - - Ok(key) -} - -#[async_recursion::async_recursion] -async fn rename_entry( - vfs: Arc>, - old_path: &str, - new_path: &str, -) -> Result<(), VfsError> { - let children = { - let mut vfs = vfs.lock().await; - let key = match vfs.path_to_key.remove(old_path) { - Some(key) => key, - None => return Err(VfsError::EntryNotFound), - }; - let entry = match vfs.key_to_entry.get_mut(&key) { - Some(entry) => entry, - None => return Err(VfsError::EntryNotFound), - }; - entry.name = new_path.split('/').last().unwrap().to_string(); - entry.full_path = new_path.to_string(); - - let children = if let EntryType::Dir { children, .. } = &entry.entry_type { - children.clone() - } else { - HashSet::new() - }; - - vfs.path_to_key.insert(new_path.to_string(), key); - children - }; - - // recursively update the paths of the children - for child_key in children { - let child_entry = { - let vfs = vfs.lock().await; - vfs.key_to_entry.get(&child_key).unwrap().clone() - }; - let old_child_path = child_entry.full_path.clone(); - let new_child_path = old_child_path.replace(old_path, new_path); - rename_entry(vfs.clone(), &old_child_path, &new_child_path).await?; - } - - Ok(()) -} - -fn make_error_message( - our_node: String, - id: u64, - source: Address, - error: VfsError, -) -> KernelMessage { - KernelMessage { - id, - source: Address { - node: our_node, - process: VFS_PROCESS_ID.clone(), - }, - target: source, - rsvp: None, - message: Message::Response(( - Response { - inherit: false, - ipc: serde_json::to_vec(&VfsResponse::Err(error)).unwrap(), - metadata: None, - }, - None, - )), - payload: None, - signed_capabilities: None, - } -} - -async fn state_to_bytes(state: &DriveToVfs) -> Vec { - let mut serializable: DriveToVfsSerializable = HashMap::new(); - for (id, vfs) in state.iter() { - let vfs = vfs.lock().await; - serializable.insert(id.clone(), (*vfs).clone()); - } - bincode::serialize(&serializable).unwrap() -} - -fn bytes_to_state(bytes: &[u8], state: &mut DriveToVfs) { - let serializable: DriveToVfsSerializable = bincode::deserialize(bytes).unwrap(); - for (id, vfs) in serializable.into_iter() { - state.insert(id, Arc::new(Mutex::new(vfs))); - } -} - -async fn send_persist_state_message( - our_node: String, - send_to_loop: MessageSender, - id: u64, - state: Vec, -) { - let _ = send_to_loop - .send(KernelMessage { - id, - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node, - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&FsAction::SetState(VFS_PROCESS_ID.clone())).unwrap(), - metadata: None, - }), - payload: Some(Payload { - mime: None, - bytes: state, - }), - signed_capabilities: None, - }) - .await; -} - -async fn persist_state( - send_to_persist: &tokio::sync::mpsc::Sender, - recv_response: &mut MessageReceiver, - id: u64, -) -> Result<(), VfsError> { - send_to_persist - .send(id) - .await - .map_err(|_| VfsError::PersistError)?; - let persist_response = recv_response.recv().await.ok_or(VfsError::PersistError)?; - let KernelMessage { message, .. } = persist_response; - let Message::Response((Response { ipc, .. }, None)) = message else { - return Err(VfsError::PersistError); - }; - - let response = serde_json::from_slice::>(&ipc) - .map_err(|_| VfsError::PersistError)?; - match response { - Ok(FsResponse::SetState) => Ok(()), - _ => Err(VfsError::PersistError), - } -} - -async fn load_state_from_reboot( - our_node: String, - send_to_loop: &MessageSender, - recv_from_loop: &mut MessageReceiver, - drive_to_vfs: &mut DriveToVfs, -) { - let _ = send_to_loop - .send(KernelMessage { - id: rand::random(), - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&FsAction::GetState(VFS_PROCESS_ID.clone())).unwrap(), - metadata: None, - }), - payload: None, - signed_capabilities: None, - }) - .await; - let km = recv_from_loop.recv().await; - let Some(km) = km else { - return; - }; - - let KernelMessage { - message, payload, .. - } = km; - let Message::Response((Response { ipc, .. }, None)) = message else { - return; - }; - let Ok(Ok(FsResponse::GetState)) = serde_json::from_slice::>(&ipc) - else { - return; - }; - let Some(payload) = payload else { - return; - }; - bytes_to_state(&payload.bytes, drive_to_vfs); -} - pub async fn vfs( our_node: String, send_to_loop: MessageSender, send_to_terminal: PrintSender, mut recv_from_loop: MessageReceiver, send_to_caps_oracle: CapMessageSender, - vfs_messages: Vec, + home_directory_path: String, ) -> anyhow::Result<()> { - let mut drive_to_vfs: DriveToVfs = HashMap::new(); - let drive_to_queue: DriveToQueue = Arc::new(Mutex::new(HashMap::new())); - let mut response_router: ResponseRouter = HashMap::new(); - let (send_vfs_task_done, mut recv_vfs_task_done): ( - tokio::sync::mpsc::Sender, - tokio::sync::mpsc::Receiver, - ) = tokio::sync::mpsc::channel(VFS_TASK_DONE_CHANNEL_CAPACITY); - let (send_persist_state, mut recv_persist_state): ( - tokio::sync::mpsc::Sender, - tokio::sync::mpsc::Receiver, - ) = tokio::sync::mpsc::channel(VFS_PERSIST_STATE_CHANNEL_CAPACITY); + let vfs_path = format!("{}/vfs", &home_directory_path); - load_state_from_reboot( - our_node.clone(), - &send_to_loop, - &mut recv_from_loop, - &mut drive_to_vfs, - ) - .await; - - for vfs_message in vfs_messages { - send_to_loop.send(vfs_message).await.unwrap(); + if let Err(e) = fs::create_dir_all(&vfs_path).await { + panic!("failed creating vfs dir! {:?}", e); } + let open_files: Arc>>> = Arc::new(DashMap::new()); + + let mut process_queues: HashMap>>> = + HashMap::new(); + loop { tokio::select! { - id_done = recv_vfs_task_done.recv() => { - let Some(id_done) = id_done else { continue }; - response_router.remove(&id_done); - }, - respond_to_id = recv_persist_state.recv() => { - let Some(respond_to_id) = respond_to_id else { continue }; - let our_node = our_node.clone(); - let send_to_loop = send_to_loop.clone(); - let serialized_state = state_to_bytes(&drive_to_vfs).await; - send_persist_state_message( - our_node.clone(), - send_to_loop, - respond_to_id, - serialized_state, - ).await; - }, - km = recv_from_loop.recv() => { - let Some(km) = km else { - continue; - }; - if let Some(response_sender) = response_router.get(&km.id) { - let _ = response_sender.send(km).await; - continue; - } - - let KernelMessage { - id, - source, - message, - .. - } = km.clone(); - let Message::Request(Request { - ipc, - .. - }) = message.clone() - else { - // consider moving this handling into it's own function - continue; - }; - - let request: VfsRequest = match serde_json::from_slice(&ipc) { - Ok(r) => r, - Err(e) => { - println!("vfs: got invalid Request: {}", e); - continue; - } - }; - - if our_node != source.node { + Some(km) = recv_from_loop.recv() => { + if our_node.clone() != km.source.node { println!( "vfs: request must come from our_node={}, got: {}", our_node, - source.node, + km.source.node, ); continue; } - let (response_sender, response_receiver): ( - MessageSender, - MessageReceiver, - ) = tokio::sync::mpsc::channel(VFS_RESPONSE_CHANNEL_CAPACITY); - response_router.insert(km.id, response_sender); + let queue = process_queues + .entry(km.source.process.clone()) + .or_insert_with(|| Arc::new(Mutex::new(VecDeque::new()))) + .clone(); - let mut drive_to_queue_lock = drive_to_queue.lock().await; - match drive_to_queue_lock.remove(&request.drive) { - Some(mut queue) => { - queue.push_back((km, response_receiver)); - drive_to_queue_lock.insert(request.drive, queue); - }, - None => { - let mut queue: RequestQueue = VecDeque::new(); - queue.push_back((km, response_receiver)); - drive_to_queue_lock.insert(request.drive.clone(), queue); - - let (vfs, new_caps) = match drive_to_vfs.get(&request.drive) { - Some(vfs) => (Arc::clone(vfs), vec![]), - None => { - let VfsAction::New = request.action else { - // clean up queue - match drive_to_queue_lock.remove(&request.drive) { - None => {}, - Some(mut queue) => { - let _ = queue.pop_back(); - if !queue.is_empty() { - drive_to_queue_lock.insert(request.drive, queue); - } - }, - } - send_to_loop - .send(make_error_message( - our_node.clone(), - id, - source.clone(), - VfsError::BadDriveName, - )) - .await - .unwrap(); - continue; - }; - drive_to_vfs.insert( - request.drive.clone(), - Arc::new(Mutex::new(Vfs::new())), - ); - let read_cap = Capability { - issuer: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - params: serde_json::to_string( - &serde_json::json!({"kind": "read", "drive": request.drive}) - ).unwrap(), - }; - let write_cap = Capability { - issuer: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - params: serde_json::to_string( - &serde_json::json!({"kind": "write", "drive": request.drive}) - ).unwrap(), - }; - - ( - Arc::clone(drive_to_vfs.get(&request.drive).unwrap()), - vec![read_cap, write_cap], - ) - } - }; - - let our_node = our_node.clone(); - let drive = request.drive.clone(); - let send_to_loop = send_to_loop.clone(); - let send_persist_state = send_persist_state.clone(); - let send_to_terminal = send_to_terminal.clone(); - let send_to_caps_oracle = send_to_caps_oracle.clone(); - let send_vfs_task_done = send_vfs_task_done.clone(); - let drive_to_queue = Arc::clone(&drive_to_queue); - match &message { - Message::Response(_) => {}, - Message::Request(_) => { - tokio::spawn(async move { - loop { - let our_node = our_node.clone(); - let drive = drive.clone(); - let next_message = { - let mut drive_to_queue_lock = drive_to_queue.lock().await; - match drive_to_queue_lock.remove(&drive) { - None => None, - Some(mut queue) => { - let next_message = queue.pop_front(); - drive_to_queue_lock.insert(drive.clone(), queue); - next_message - }, - } - }; - match next_message { - None => { - // queue is empty - let mut drive_to_queue_lock = drive_to_queue.lock().await; - match drive_to_queue_lock.remove(&drive) { - None => {}, - Some(queue) => { - if queue.is_empty() {} - else { - // between setting next_message - // and lock() in this block, new - // entry was added to queue: - // process it - drive_to_queue_lock.insert(drive, queue); - continue; - } - }, - } - let _ = send_vfs_task_done.send(id).await; - return ; - }, - Some((km, response_receiver)) => { - // handle next item - let KernelMessage { - id, - source, - rsvp, - message, - payload, - .. - } = km; - let Message::Request(Request { - expects_response, - ipc, - metadata, // we return this to Requester for kernel reasons - .. - }) = message.clone() - else { - continue; - }; - - let request: VfsRequest = match serde_json::from_slice(&ipc) { - Ok(r) => r, - Err(e) => { - println!("vfs: got invalid Request: {}", e); - continue; - } - }; - if let Err(e) = handle_request( - our_node.clone(), - id, - source.clone(), - expects_response, - rsvp, - request, - metadata, - payload, - new_caps.clone(), - Arc::clone(&vfs), - send_to_loop.clone(), - send_persist_state.clone(), - send_to_terminal.clone(), - send_to_caps_oracle.clone(), - response_receiver, - ).await { - send_to_loop - .send(make_error_message( - our_node, - id, - source, - e, - )) - .await - .unwrap(); - } - }, - } - } - }); - }, - } - }, + { + let mut queue_lock = queue.lock().await; + queue_lock.push_back(km.clone()); } - }, + + // clone Arcs + let our_node = our_node.clone(); + let send_to_caps_oracle = send_to_caps_oracle.clone(); + let send_to_terminal = send_to_terminal.clone(); + let send_to_loop = send_to_loop.clone(); + let open_files = open_files.clone(); + let vfs_path = vfs_path.clone(); + + tokio::spawn(async move { + let mut queue_lock = queue.lock().await; + if let Some(km) = queue_lock.pop_front() { + if let Err(e) = handle_request( + our_node.clone(), + km.clone(), + open_files.clone(), + send_to_loop.clone(), + send_to_terminal.clone(), + send_to_caps_oracle.clone(), + vfs_path.clone(), + ) + .await + { + let _ = send_to_loop + .send(make_error_message(our_node.clone(), km.id, km.source, e)) + .await; + } + } + }); + } } } } async fn handle_request( our_node: String, - id: u64, - source: Address, - expects_response: Option, - rsvp: Rsvp, - request: VfsRequest, - metadata: Option, - payload: Option, - new_caps: Vec, - vfs: Arc>, + km: KernelMessage, + open_files: Arc>>>, send_to_loop: MessageSender, - send_to_persist: tokio::sync::mpsc::Sender, send_to_terminal: PrintSender, send_to_caps_oracle: CapMessageSender, - recv_response: MessageReceiver, + vfs_path: String, ) -> Result<(), VfsError> { - let (send_cap_bool, recv_cap_bool) = tokio::sync::oneshot::channel(); - match &request.action { - VfsAction::Add { .. } - | VfsAction::Rename { .. } - | VfsAction::Delete { .. } - | VfsAction::WriteOffset { .. } - | VfsAction::Append { .. } - | VfsAction::SetSize { .. } => { - send_to_caps_oracle - .send(CapMessage::Has { - on: source.process.clone(), - cap: Capability { - issuer: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - params: serde_json::to_string(&serde_json::json!({ - "kind": "write", - "drive": request.drive, - })) - .unwrap(), - }, - responder: send_cap_bool, - }) - .await - .unwrap(); - let has_cap = recv_cap_bool.await.unwrap(); - if !has_cap { - return Err(VfsError::NoCap); - } - } - VfsAction::GetPath { .. } - | VfsAction::GetHash { .. } - | VfsAction::GetEntry { .. } - | VfsAction::GetFileChunk { .. } - | VfsAction::GetEntryLength { .. } => { - send_to_caps_oracle - .send(CapMessage::Has { - on: source.process.clone(), - cap: Capability { - issuer: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - params: serde_json::to_string(&serde_json::json!({ - "kind": "read", - "drive": request.drive, - })) - .unwrap(), - }, - responder: send_cap_bool, - }) - .await - .unwrap(); - let has_cap = recv_cap_bool.await.unwrap(); - if !has_cap { - return Err(VfsError::NoCap); - } - } - VfsAction::New { .. } => {} - } - - let (ipc, bytes) = match_request( - our_node.clone(), + let KernelMessage { id, - source.clone(), - request, + source, + message, payload, - new_caps, - vfs, - &send_to_loop, - &send_to_persist, - &send_to_terminal, - &send_to_caps_oracle, - recv_response, - ) - .await?; + .. + } = km.clone(); + let Message::Request(Request { + ipc, + expects_response, + metadata, + .. + }) = message.clone() + else { + return Err(VfsError::BadRequest { + error: "not a request".into(), + }); + }; - if let Some(target) = rsvp.or_else(|| { + let request: VfsRequest = match serde_json::from_slice(&ipc) { + Ok(r) => r, + Err(e) => { + println!("vfs: got invalid Request: {}", e); + return Err(VfsError::BadJson { + error: e.to_string(), + }); + } + }; + + // current prepend to filepaths needs to be: /package_id/drive/path + let (package_id, drive, rest) = parse_package_and_drive(&request.path).await?; + let drive = format!("/{}/{}", package_id, drive); + let path = PathBuf::from(request.path.clone()); + + if km.source.process != *KERNEL_PROCESS_ID { + check_caps( + our_node.clone(), + source.clone(), + send_to_caps_oracle.clone(), + &request, + path.clone(), + drive.clone(), + package_id, + vfs_path.clone(), + ) + .await?; + } + // real safe path that the vfs will use + let path = PathBuf::from(format!("{}{}/{}", vfs_path, drive, rest)); + let (ipc, bytes) = match request.action { + VfsAction::CreateDrive => { + // handled in check_caps. + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::CreateDir => { + // check error mapping + // fs::create_dir_all(path).await.map_err(|e| VfsError::IOError { source: e, path: path.clone() })?; + fs::create_dir(path).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::CreateDirAll => { + fs::create_dir_all(path).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::CreateFile => { + let _file = open_file(open_files.clone(), path, true).await?; + + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::OpenFile => { + let _file = open_file(open_files.clone(), path, false).await?; + + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::CloseFile => { + open_files.remove(&path); + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::WriteAll => { + // should expect open file. + let Some(payload) = payload else { + return Err(VfsError::BadRequest { + error: "payload needs to exist for WriteAll".into(), + }); + }; + let file = open_file(open_files.clone(), path, false).await?; + let mut file = file.lock().await; + file.write_all(&payload.bytes).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::Write => { + let Some(payload) = payload else { + return Err(VfsError::BadRequest { + error: "payload needs to exist for Write".into(), + }); + }; + let file = open_file(open_files.clone(), path, true).await?; + let mut file = file.lock().await; + file.write_all(&payload.bytes).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::ReWrite => { + let Some(payload) = payload else { + return Err(VfsError::BadRequest { + error: "payload needs to exist for Write".into(), + }); + }; + let file = open_file(open_files.clone(), path, true).await?; + let mut file = file.lock().await; + + file.seek(SeekFrom::Start(0)).await?; + file.write_all(&payload.bytes).await?; + file.set_len(payload.bytes.len() as u64).await?; + + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::WriteAt(offset) => { + let Some(payload) = payload else { + return Err(VfsError::BadRequest { + error: "payload needs to exist for WriteAt".into(), + }); + }; + let file = open_file(open_files.clone(), path, false).await?; + let mut file = file.lock().await; + file.seek(SeekFrom::Start(offset)).await?; + file.write_all(&payload.bytes).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::Append => { + let Some(payload) = payload else { + return Err(VfsError::BadRequest { + error: "payload needs to exist for Append".into(), + }); + }; + let file = open_file(open_files.clone(), path, false).await?; + let mut file = file.lock().await; + file.seek(SeekFrom::End(0)).await?; + file.write_all(&payload.bytes).await?; + + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::SyncAll => { + let file = open_file(open_files.clone(), path, false).await?; + let file = file.lock().await; + file.sync_all().await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::Read => { + let file = open_file(open_files.clone(), path.clone(), false).await?; + let mut file = file.lock().await; + let mut contents = Vec::new(); + file.seek(SeekFrom::Start(0)).await?; + file.read_to_end(&mut contents).await?; + + ( + serde_json::to_vec(&VfsResponse::Read).unwrap(), + Some(contents), + ) + } + VfsAction::ReadToEnd => { + let file = open_file(open_files.clone(), path.clone(), false).await?; + let mut file = file.lock().await; + let mut contents = Vec::new(); + + file.read_to_end(&mut contents).await?; + + ( + serde_json::to_vec(&VfsResponse::Read).unwrap(), + Some(contents), + ) + } + VfsAction::ReadDir => { + let mut dir = fs::read_dir(path).await?; + let mut entries = Vec::new(); + while let Some(entry) = dir.next_entry().await? { + let entry_path = entry.path(); + let relative_path = entry_path.strip_prefix(&vfs_path).unwrap_or(&entry_path); + + entries.push(relative_path.display().to_string()); + } + ( + serde_json::to_vec(&VfsResponse::ReadDir(entries)).unwrap(), + None, + ) + } + VfsAction::ReadExact(length) => { + let file = open_file(open_files.clone(), path, false).await?; + let mut file = file.lock().await; + let mut contents = vec![0; length as usize]; + file.read_exact(&mut contents).await?; + ( + serde_json::to_vec(&VfsResponse::Read).unwrap(), + Some(contents), + ) + } + VfsAction::ReadToString => { + let file = open_file(open_files.clone(), path, false).await?; + let mut file = file.lock().await; + let mut contents = String::new(); + file.read_to_string(&mut contents).await?; + ( + serde_json::to_vec(&VfsResponse::ReadToString(contents)).unwrap(), + None, + ) + } + VfsAction::Seek(seek_from) => { + let file = open_file(open_files.clone(), path, false).await?; + let mut file = file.lock().await; + // same type, rust tingz + let seek_from = match seek_from { + crate::types::SeekFrom::Start(offset) => std::io::SeekFrom::Start(offset), + crate::types::SeekFrom::End(offset) => std::io::SeekFrom::End(offset), + crate::types::SeekFrom::Current(offset) => std::io::SeekFrom::Current(offset), + }; + file.seek(seek_from).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::RemoveFile => { + fs::remove_file(path).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::RemoveDir => { + fs::remove_dir(path).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::RemoveDirAll => { + fs::remove_dir_all(path).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::Rename(new_path) => { + // doublecheck permission weirdness, sanitize new path + fs::rename(path, new_path).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::Len => { + let file = open_file(open_files.clone(), path, false).await?; + let file = file.lock().await; + let len = file.metadata().await?.len(); + (serde_json::to_vec(&VfsResponse::Len(len)).unwrap(), None) + } + VfsAction::SetLen(len) => { + let file = open_file(open_files.clone(), path, false).await?; + let file = file.lock().await; + file.set_len(len).await?; + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + VfsAction::Hash => { + let file = open_file(open_files.clone(), path, false).await?; + let mut file = file.lock().await; + file.seek(SeekFrom::Start(0)).await?; + let mut hasher = blake3::Hasher::new(); + let mut buffer = [0; 1024]; + loop { + let bytes_read = file.read(&mut buffer).await?; + if bytes_read == 0 { + break; + } + hasher.update(&buffer[..bytes_read]); + } + let hash: [u8; 32] = hasher.finalize().into(); + (serde_json::to_vec(&VfsResponse::Hash(hash)).unwrap(), None) + } + VfsAction::AddZip => { + let Some(payload) = payload else { + return Err(VfsError::BadRequest { + error: "payload needs to exist for AddZip".into(), + }); + }; + let Some(mime) = payload.mime else { + return Err(VfsError::BadRequest { + error: "payload mime type needs to exist for AddZip".into(), + }); + }; + if "application/zip" != mime { + return Err(VfsError::BadRequest { + error: "payload mime type needs to be application/zip for AddZip".into(), + }); + } + let file = std::io::Cursor::new(&payload.bytes); + let mut zip = match zip::ZipArchive::new(file) { + Ok(f) => f, + Err(e) => { + return Err(VfsError::ParseError { + error: e.to_string(), + path: path.display().to_string(), + }) + } + }; + + // loop through items in archive; recursively add to root + for i in 0..zip.len() { + // must destruct the zip file created in zip.by_index() + // Before any `.await`s are called since ZipFile is not + // Send and so does not play nicely with await + let (is_file, is_dir, local_path, file_contents) = { + let mut file = zip.by_index(i).unwrap(); + let is_file = file.is_file(); + let is_dir = file.is_dir(); + let mut file_contents = Vec::new(); + if is_file { + file.read_to_end(&mut file_contents).unwrap(); + }; + let local_path = path.join(file.name()); + (is_file, is_dir, local_path, file_contents) + }; + if is_file { + let file = open_file(open_files.clone(), local_path, true).await?; + let mut file = file.lock().await; + + file.seek(SeekFrom::Start(0)).await?; + file.write_all(&file_contents).await?; + file.set_len(file_contents.len() as u64).await?; + } else if is_dir { + // If it's a directory, create it + fs::create_dir_all(local_path).await?; + } else { + println!("vfs: zip with non-file non-dir"); + return Err(VfsError::CreateDirError { + path: path.display().to_string(), + error: "vfs: zip with non-file non-dir".into(), + }); + }; + } + (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) + } + }; + + if let Some(target) = km.rsvp.or_else(|| { expects_response.map(|_| Address { node: our_node.clone(), process: source.process.clone(), @@ -715,6 +451,7 @@ async fn handle_request( let _ = send_to_loop.send(response).await; } else { + println!("vfs: not sending response: "); send_to_terminal .send(Printout { verbosity: 2, @@ -730,788 +467,285 @@ async fn handle_request( Ok(()) } -// #[async_recursion::async_recursion] -async fn match_request( - our_node: String, - id: u64, - source: Address, - request: VfsRequest, - payload: Option, - new_caps: Vec, - vfs: Arc>, - send_to_loop: &MessageSender, - send_to_persist: &tokio::sync::mpsc::Sender, - send_to_terminal: &PrintSender, - send_to_caps_oracle: &CapMessageSender, - mut recv_response: MessageReceiver, -) -> Result<(Vec, Option>), VfsError> { - Ok(match request.action { - VfsAction::New => { - for new_cap in new_caps { - let (send_cap_bool, recv_cap_bool) = tokio::sync::oneshot::channel(); - send_to_caps_oracle - .send(CapMessage::Add { - on: source.process.clone(), - cap: new_cap, - responder: send_cap_bool, - }) +async fn parse_package_and_drive(path: &str) -> Result<(PackageId, String, String), VfsError> { + let mut parts: Vec<&str> = path.split('/').collect(); + + if parts[0].is_empty() { + parts.remove(0); + } + if parts.len() < 2 { + return Err(VfsError::ParseError { + error: "malformed path".into(), + path: path.to_string(), + }); + } + + let package_id = match PackageId::from_str(parts[0]) { + Ok(id) => id, + Err(e) => { + return Err(VfsError::ParseError { + error: e.to_string(), + path: path.to_string(), + }) + } + }; + + let drive = parts[1].to_string(); + let remaining_path = parts[2..].join("/"); + + Ok((package_id, drive, remaining_path)) +} + +async fn open_file>( + open_files: Arc>>>, + path: P, + create: bool, +) -> Result>, VfsError> { + let path = path.as_ref().to_path_buf(); + Ok(match open_files.get(&path) { + Some(file) => Arc::clone(file.value()), + None => { + let file = Arc::new(Mutex::new( + OpenOptions::new() + .read(true) + .write(true) + .create(create) + .open(&path) .await - .unwrap(); - let _ = recv_cap_bool.await.unwrap(); - } - persist_state(send_to_persist, &mut recv_response, id).await?; - (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) - } - VfsAction::Add { - mut full_path, - entry_type, - } => { - match entry_type { - AddEntryType::Dir => { - full_path = clean_path(&full_path); - - let mut vfs = vfs.lock().await; - if vfs.path_to_key.contains_key(&full_path) { - send_to_terminal - .send(Printout { - verbosity: 0, - content: format!("vfs: not overwriting dir {}", full_path), - }) - .await - .unwrap(); - return Ok((serde_json::to_vec(&VfsResponse::Ok).unwrap(), None)); - }; - match create_entry(&mut vfs, &full_path, Key::Dir { id: rand::random() }).await - { - Ok(_) => {} - Err(e) => { - return Err(e); - } - } - } - AddEntryType::NewFile => { - full_path = clean_path(&full_path); - let hash = { - let mut vfs = vfs.lock().await; - if !vfs.path_to_key.contains_key(&full_path) { - None - } else { - send_to_terminal - .send(Printout { - verbosity: 2, - content: format!("vfs: overwriting file {}", full_path), - }) - .await - .unwrap(); - match vfs.path_to_key.remove(&full_path) { - None => None, - Some(key) => { - let Key::File { id: hash } = key else { - return Err(VfsError::InternalError); - }; - Some(hash) - } - } - // vfs.key_to_entry.remove(&old_key); - } - }; - - let _ = send_to_loop - .send(KernelMessage { - id, - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&FsAction::Write(hash)).unwrap(), - metadata: None, - }), - payload, - signed_capabilities: None, - }) - .await; - let write_response = recv_response.recv().await.unwrap(); - let KernelMessage { message, .. } = write_response; - let Message::Response((Response { ipc, .. }, None)) = message else { - return Err(VfsError::InternalError); - }; - - let Ok(FsResponse::Write(hash)) = - serde_json::from_slice::>(&ipc).unwrap() - else { - return Err(VfsError::InternalError); - }; - - match create_entry(&mut vfs.lock().await, &full_path, Key::File { id: hash }) - .await - { - Ok(_) => {} - Err(e) => { - return Err(e); - } - } - } - AddEntryType::ExistingFile { hash } => { - full_path = clean_path(&full_path); - - let mut vfs = vfs.lock().await; - if vfs.path_to_key.contains_key(&full_path) { - send_to_terminal - .send(Printout { - verbosity: 2, - content: format!("vfs: overwriting file {}", full_path), - }) - .await - .unwrap(); - let Some(old_key) = vfs.path_to_key.remove(&full_path) else { - println!("no old key"); - return Err(VfsError::InternalError); - }; - vfs.key_to_entry.remove(&old_key); - }; - match create_entry(&mut vfs, &full_path, Key::File { id: hash }).await { - Ok(_) => {} - Err(e) => { - return Err(e); - } - } - } - AddEntryType::ZipArchive => { - let Some(payload) = payload else { - return Err(VfsError::BadPayload); - }; - let Some(mime) = payload.mime else { - return Err(VfsError::BadPayload); - }; - if "application/zip" != mime { - return Err(VfsError::BadPayload); - } - let file = std::io::Cursor::new(&payload.bytes); - let mut zip = match zip::ZipArchive::new(file) { - Ok(f) => f, - Err(_) => return Err(VfsError::InternalError), - }; - - // loop through items in archive; recursively add to root - for i in 0..zip.len() { - // must destruct the zip file created in zip.by_index() - // Before any `.await`s are called since ZipFile is not - // Send and so does not play nicely with await - let (is_file, is_dir, full_path, file_contents) = { - let mut file = zip.by_index(i).unwrap(); - let is_file = file.is_file(); - let is_dir = file.is_dir(); - let full_path = format!("/{}", file.name()); - let mut file_contents = Vec::new(); - if is_file { - file.read_to_end(&mut file_contents).unwrap(); - }; - (is_file, is_dir, full_path, file_contents) - }; - if is_file { - let hash = { - let vfs = vfs.lock().await; - if !vfs.path_to_key.contains_key(&full_path) { - None - } else { - send_to_terminal - .send(Printout { - verbosity: 2, - content: format!("vfs: overwriting file {}", full_path), - }) - .await - .unwrap(); - match vfs.path_to_key.get(&full_path) { - None => None, - Some(key) => { - let Key::File { id: hash } = key else { - return Err(VfsError::InternalError); - }; - Some(*hash) - } - } - // vfs.key_to_entry.remove(&old_key); - } - }; - let _ = send_to_loop - .send(KernelMessage { - id, - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&FsAction::Write(hash)).unwrap(), - metadata: None, - }), - payload: Some(Payload { - mime: None, - bytes: file_contents, - }), - signed_capabilities: None, - }) - .await; - let write_response = match recv_response.recv().await { - Some(response) => response, - None => { - println!("No response received..."); - continue; - } - }; - let KernelMessage { message, .. } = write_response; - let Message::Response((Response { ipc, .. }, None)) = message else { - return Err(VfsError::InternalError); - }; - - let Ok(FsResponse::Write(hash)) = - serde_json::from_slice::>(&ipc) - .unwrap() - else { - return Err(VfsError::InternalError); - }; - - match create_entry( - &mut vfs.lock().await, - &full_path, - Key::File { id: hash }, - ) - .await - { - Ok(_) => {} - Err(e) => { - return Err(e); - } - } - } else if is_dir { - // If it's a directory, create it - match create_entry( - &mut vfs.lock().await, - &full_path, - Key::Dir { id: rand::random() }, - ) - .await - { - Ok(_) => {} - Err(e) => { - return Err(e); - } - } - } else { - println!("vfs: zip with non-file non-dir"); - return Err(VfsError::InternalError); - }; - } - } - } - persist_state(send_to_persist, &mut recv_response, id).await?; - (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) - } - VfsAction::Rename { - mut full_path, - mut new_full_path, - } => { - full_path = clean_path(&full_path); - new_full_path = clean_path(&new_full_path); - match rename_entry(vfs, &full_path, &new_full_path).await { - Ok(_) => {} - Err(e) => { - return Err(e); - } - } - - persist_state(send_to_persist, &mut recv_response, id).await?; - (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) - } - VfsAction::Delete(mut full_path) => { - full_path = clean_path(&full_path); - - { - let mut vfs = vfs.lock().await; - let Some(key) = vfs.path_to_key.remove(&full_path) else { - send_to_terminal - .send(Printout { - verbosity: 0, - content: format!("vfs: can't delete: nonexistent entry {}", full_path), - }) - .await - .unwrap(); - return Err(VfsError::EntryNotFound); - }; - let Some(entry) = vfs.key_to_entry.remove(&key) else { - send_to_terminal - .send(Printout { - verbosity: 0, - content: format!("vfs: can't delete: nonexistent entry {}", full_path), - }) - .await - .unwrap(); - return Err(VfsError::EntryNotFound); - }; - match entry.entry_type { - EntryType::Dir { - parent: _, - ref children, - } => { - if !children.is_empty() { - send_to_terminal - .send(Printout { - verbosity: 0, - content: format!( - "vfs: can't delete: non-empty directory {}", - full_path - ), - }) - .await - .unwrap(); - vfs.path_to_key.insert(full_path.clone(), key.clone()); - vfs.key_to_entry.insert(key.clone(), entry); - } - } - EntryType::File { parent } => match vfs.key_to_entry.get_mut(&parent) { - None => { - send_to_terminal - .send(Printout { - verbosity: 0, - content: format!( - "vfs: delete: unexpected file with no parent dir: {}", - full_path - ), - }) - .await - .unwrap(); - return Err(VfsError::InternalError); - } - Some(parent) => { - let EntryType::Dir { - parent: _, - ref mut children, - } = parent.entry_type - else { - return Err(VfsError::InternalError); - }; - children.remove(&key); - } - }, - } - } - - persist_state(send_to_persist, &mut recv_response, id).await?; - (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) - } - VfsAction::WriteOffset { - mut full_path, - offset, - } => { - full_path = clean_path(&full_path); - - let file_hash = { - let vfs = vfs.lock().await; - let Some(key) = vfs.path_to_key.get(&full_path) else { - return Err(VfsError::EntryNotFound); - }; - let Key::File { id: file_hash } = key else { - return Err(VfsError::InternalError); - }; - *file_hash - }; - let _ = send_to_loop - .send(KernelMessage { - id, - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&FsAction::WriteOffset((file_hash, offset))) - .unwrap(), - metadata: None, - }), - payload, - signed_capabilities: None, - }) - .await; - let write_response = recv_response.recv().await.unwrap(); - let KernelMessage { message, .. } = write_response; - let Message::Response((Response { ipc, .. }, None)) = message else { - return Err(VfsError::InternalError); - }; - - let Ok(FsResponse::Write(_)) = - serde_json::from_slice::>(&ipc).unwrap() - else { - return Err(VfsError::InternalError); - }; - (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) - } - VfsAction::Append(mut full_path) => { - full_path = clean_path(&full_path); - - let file_hash = { - let vfs = vfs.lock().await; - let Some(key) = vfs.path_to_key.get(&full_path) else { - return Err(VfsError::EntryNotFound); - }; - let Key::File { id: file_hash } = key else { - return Err(VfsError::InternalError); - }; - *file_hash - }; - let _ = send_to_loop - .send(KernelMessage { - id, - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&FsAction::Append(Some(file_hash))).unwrap(), - metadata: None, - }), - payload, - signed_capabilities: None, - }) - .await; - let write_response = recv_response.recv().await.unwrap(); - let KernelMessage { message, .. } = write_response; - let Message::Response((Response { ipc, .. }, None)) = message else { - return Err(VfsError::InternalError); - }; - - let Ok(FsResponse::Append(_)) = - serde_json::from_slice::>(&ipc).unwrap() - else { - return Err(VfsError::InternalError); - }; - persist_state(send_to_persist, &mut recv_response, id).await?; - (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) - } - VfsAction::SetSize { - mut full_path, - size, - } => { - full_path = clean_path(&full_path); - - let file_hash = { - let vfs = vfs.lock().await; - let Some(key) = vfs.path_to_key.get(&full_path) else { - return Err(VfsError::EntryNotFound); - }; - let Key::File { id: file_hash } = key else { - return Err(VfsError::InternalError); - }; - *file_hash - }; - - let _ = send_to_loop - .send(KernelMessage { - id, - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(15), - ipc: serde_json::to_vec(&FsAction::SetLength((file_hash, size))).unwrap(), - metadata: None, - }), - payload: None, - signed_capabilities: None, - }) - .await; - let write_response = recv_response.recv().await.unwrap(); - let KernelMessage { message, .. } = write_response; - let Message::Response((Response { ipc, .. }, None)) = message else { - return Err(VfsError::InternalError); - }; - - let Ok(FsResponse::Length(length)) = - serde_json::from_slice::>(&ipc).unwrap() - else { - return Err(VfsError::InternalError); - }; - if length != size { - return Err(VfsError::InternalError); - }; - (serde_json::to_vec(&VfsResponse::Ok).unwrap(), None) - } - VfsAction::GetPath(hash) => { - let mut vfs = vfs.lock().await; - let key = Key::File { id: hash }; - let ipc = - serde_json::to_vec(&VfsResponse::GetPath(match vfs.key_to_entry.remove(&key) { - None => None, - Some(entry) => { - let full_path = entry.full_path.clone(); - vfs.key_to_entry.insert(key, entry); - Some(full_path) - } - })) - .unwrap(); - (ipc, None) - } - VfsAction::GetHash(full_path) => { - let vfs = vfs.lock().await; - let Some(key) = vfs.path_to_key.get(&full_path) else { - return Err(VfsError::EntryNotFound); - }; - let ipc = serde_json::to_vec(&VfsResponse::GetHash(match key { - Key::File { id } => Some(*id), - Key::Dir { .. } => None, - })) - .unwrap(); - (ipc, None) - } - VfsAction::GetEntry(mut full_path) => { - full_path = clean_path(&full_path); - - let vfs = vfs.lock().await; - let key = vfs.path_to_key.get(&full_path); - match key { - None => return Err(VfsError::EntryNotFound), - Some(key) => { - let entry = vfs.key_to_entry.get(key); - match entry { - None => return Err(VfsError::EntryNotFound), - Some(entry) => match &entry.entry_type { - EntryType::Dir { children, .. } => { - let paths: Vec = children - .iter() - .filter_map(|child_key| { - vfs.key_to_entry - .get(child_key) - .map(|child| child.full_path.clone()) - }) - .collect(); - ( - serde_json::to_vec(&VfsResponse::GetEntry { - is_file: false, - children: paths, - }) - .unwrap(), - None, - ) - } - EntryType::File { parent: _ } => { - let Key::File { id: file_hash } = key else { - return Err(VfsError::InternalError); - }; - let _ = send_to_loop - .send(KernelMessage { - id, - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&FsAction::Read(*file_hash)) - .unwrap(), - metadata: None, - }), - payload: None, - signed_capabilities: None, - }) - .await; - let read_response = recv_response.recv().await.unwrap(); - let KernelMessage { - message, payload, .. - } = read_response; - let Message::Response((Response { ipc, .. }, None)) = message - else { - return Err(VfsError::InternalError); - }; - - let Ok(FsResponse::Read(_read_hash)) = - serde_json::from_slice::>(&ipc) - .unwrap() - else { - return Err(VfsError::InternalError); - }; - let Some(payload) = payload else { - return Err(VfsError::InternalError); - }; - ( - serde_json::to_vec(&VfsResponse::GetEntry { - is_file: true, - children: vec![], - }) - .unwrap(), - Some(payload.bytes), - ) - } - }, - } - } - } - } - VfsAction::GetFileChunk { - mut full_path, - offset, - length, - } => { - full_path = clean_path(&full_path); - let file_hash = { - let vfs = vfs.lock().await; - let Some(key) = vfs.path_to_key.get(&full_path) else { - return Err(VfsError::EntryNotFound); - }; - let Key::File { id: file_hash } = key else { - return Err(VfsError::InternalError); - }; - *file_hash - }; - - let _ = send_to_loop - .send(KernelMessage { - id, - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&FsAction::ReadChunk(ReadChunkRequest { - file: file_hash, - start: offset, - length, - })) - .unwrap(), - metadata: None, - }), - payload: None, - signed_capabilities: None, - }) - .await; - let read_response = recv_response.recv().await.unwrap(); - let KernelMessage { - message, payload, .. - } = read_response; - let Message::Response((Response { ipc, .. }, None)) = message else { - return Err(VfsError::InternalError); - }; - - let Ok(FsResponse::Read(read_hash)) = - serde_json::from_slice::>(&ipc).unwrap() - else { - return Err(VfsError::InternalError); - }; - if read_hash != file_hash { - return Err(VfsError::InternalError); - }; - let Some(payload) = payload else { - return Err(VfsError::InternalError); - }; - - ( - serde_json::to_vec(&VfsResponse::GetFileChunk).unwrap(), - Some(payload.bytes), - ) - } - VfsAction::GetEntryLength(mut full_path) => { - full_path = clean_path(&full_path); - if full_path.ends_with('/') { - ( - serde_json::to_vec(&VfsResponse::GetEntryLength(None)).unwrap(), - None, - ) - } else { - let file_hash = { - let vfs = vfs.lock().await; - let Some(key) = vfs.path_to_key.get(&full_path) else { - return Err(VfsError::EntryNotFound); - }; - let Key::File { id: file_hash } = key else { - return Err(VfsError::InternalError); - }; - *file_hash - }; - - let _ = send_to_loop - .send(KernelMessage { - id, - source: Address { - node: our_node.clone(), - process: VFS_PROCESS_ID.clone(), - }, - target: Address { - node: our_node.clone(), - process: FILESYSTEM_PROCESS_ID.clone(), - }, - rsvp: None, - message: Message::Request(Request { - inherit: true, - expects_response: Some(5), // TODO evaluate - ipc: serde_json::to_vec(&FsAction::Length(file_hash)).unwrap(), - metadata: None, - }), - payload: None, - signed_capabilities: None, - }) - .await; - let length_response = recv_response.recv().await.unwrap(); - let KernelMessage { message, .. } = length_response; - let Message::Response((Response { ipc, .. }, None)) = message else { - return Err(VfsError::InternalError); - }; - - let Ok(FsResponse::Length(length)) = - serde_json::from_slice::>(&ipc).unwrap() - else { - return Err(VfsError::InternalError); - }; - - ( - serde_json::to_vec(&VfsResponse::GetEntryLength(Some(length))).unwrap(), - None, - ) - } + .map_err(|e| VfsError::IOError { + error: e.to_string(), + path: path.display().to_string(), + })?, + )); + open_files.insert(path.clone(), Arc::clone(&file)); + file } }) } + +async fn check_caps( + our_node: String, + source: Address, + mut send_to_caps_oracle: CapMessageSender, + request: &VfsRequest, + path: PathBuf, + drive: String, + package_id: PackageId, + vfs_dir_path: String, +) -> Result<(), VfsError> { + let src_package_id = PackageId::new(source.process.package(), source.process.publisher()); + + let (send_cap_bool, recv_cap_bool) = tokio::sync::oneshot::channel(); + match &request.action { + VfsAction::CreateDir + | VfsAction::CreateDirAll + | VfsAction::CreateFile + | VfsAction::OpenFile + | VfsAction::CloseFile + | VfsAction::WriteAll + | VfsAction::Write + | VfsAction::ReWrite + | VfsAction::WriteAt(_) + | VfsAction::Append + | VfsAction::SyncAll + | VfsAction::RemoveFile + | VfsAction::RemoveDir + | VfsAction::RemoveDirAll + | VfsAction::Rename(_) + | VfsAction::AddZip + | VfsAction::SetLen(_) => { + if src_package_id == package_id { + return Ok(()); + } + send_to_caps_oracle + .send(CapMessage::Has { + on: source.process.clone(), + cap: Capability { + issuer: Address { + node: our_node.clone(), + process: VFS_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ + "kind": "write", + "drive": drive, + })) + .unwrap(), + }, + responder: send_cap_bool, + }) + .await?; + let has_cap = recv_cap_bool.await?; + if !has_cap { + return Err(VfsError::NoCap { + action: request.action.to_string(), + path: path.display().to_string(), + }); + } + Ok(()) + } + VfsAction::Read + | VfsAction::ReadDir + | VfsAction::ReadExact(_) + | VfsAction::ReadToEnd + | VfsAction::ReadToString + | VfsAction::Seek(_) + | VfsAction::Hash + | VfsAction::Len => { + if src_package_id == package_id { + return Ok(()); + } + send_to_caps_oracle + .send(CapMessage::Has { + on: source.process.clone(), + cap: Capability { + issuer: Address { + node: our_node.clone(), + process: VFS_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ + "kind": "read", + "drive": drive, + })) + .unwrap(), + }, + responder: send_cap_bool, + }) + .await?; + let has_cap = recv_cap_bool.await?; + if !has_cap { + return Err(VfsError::NoCap { + action: request.action.to_string(), + path: path.display().to_string(), + }); + } + Ok(()) + } + VfsAction::CreateDrive => { + if src_package_id != package_id { + // might have root caps + send_to_caps_oracle + .send(CapMessage::Has { + on: source.process.clone(), + cap: Capability { + issuer: Address { + node: our_node.clone(), + process: VFS_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ + "root": true, + })) + .unwrap(), + }, + responder: send_cap_bool, + }) + .await?; + let has_cap = recv_cap_bool.await?; + if !has_cap { + return Err(VfsError::NoCap { + action: request.action.to_string(), + path: path.display().to_string(), + }); + } + } + + add_capability("read", &drive, &our_node, &source, &mut send_to_caps_oracle).await?; + add_capability( + "write", + &drive, + &our_node, + &source, + &mut send_to_caps_oracle, + ) + .await?; + + let drive_path = format!("{}{}", vfs_dir_path, drive); + fs::create_dir_all(drive_path).await?; + Ok(()) + } + } +} + +async fn add_capability( + kind: &str, + drive: &str, + our_node: &str, + source: &Address, + send_to_caps_oracle: &mut CapMessageSender, +) -> Result<(), VfsError> { + let cap = Capability { + issuer: Address { + node: our_node.to_string(), + process: VFS_PROCESS_ID.clone(), + }, + params: serde_json::to_string(&serde_json::json!({ "kind": kind, "drive": drive })) + .unwrap(), + }; + let (send_cap_bool, recv_cap_bool) = tokio::sync::oneshot::channel(); + send_to_caps_oracle + .send(CapMessage::Add { + on: source.process.clone(), + cap, + responder: send_cap_bool, + }) + .await?; + let _ = recv_cap_bool.await?; + Ok(()) +} + +fn make_error_message( + our_node: String, + id: u64, + source: Address, + error: VfsError, +) -> KernelMessage { + KernelMessage { + id, + source: Address { + node: our_node, + process: VFS_PROCESS_ID.clone(), + }, + target: source, + rsvp: None, + message: Message::Response(( + Response { + inherit: false, + ipc: serde_json::to_vec(&VfsResponse::Err(error)).unwrap(), + metadata: None, + }, + None, + )), + payload: None, + signed_capabilities: None, + } +} + +impl From for VfsError { + fn from(err: tokio::sync::oneshot::error::RecvError) -> Self { + VfsError::CapChannelFail { + error: err.to_string(), + } + } +} + +impl From> for VfsError { + fn from(err: tokio::sync::mpsc::error::SendError) -> Self { + VfsError::CapChannelFail { + error: err.to_string(), + } + } +} + +impl From for VfsError { + fn from(err: std::io::Error) -> Self { + VfsError::IOError { + path: "".into(), + error: err.to_string(), + } + } +} + +impl std::fmt::Display for VfsAction { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} diff --git a/wasi_snapshot_preview1.wasm b/wasi_snapshot_preview1.wasm index 9b621b98..c8320e0b 100644 Binary files a/wasi_snapshot_preview1.wasm and b/wasi_snapshot_preview1.wasm differ diff --git a/wit/uqbar.wit b/wit/uqbar.wit deleted file mode 100644 index 1ed0a1f1..00000000 --- a/wit/uqbar.wit +++ /dev/null @@ -1,188 +0,0 @@ -package uqbar:process@0.4.0; - -interface standard { - // JSON is passed over WASM boundary as a string. - type json = string; - - type node-id = string; - - // context, like ipc, is a protocol-defined serialized byte array. - // it is used when building a Request to save information - // that will not be part of a Response, in order to more - // easily handle ("contextualize") that Response. - type context = list; - - record process-id { - process-name: string, - package-name: string, - publisher-node: node-id, - } - - // TODO better name for this - record address { - node: node-id, - process: process-id, - } - - record payload { - mime: option, - bytes: list, - } - - record request { - // if true, this request inherits context AND payload of incipient - // request, and cannot have its own context. - inherit: bool, - // if Some, this request expects a response in the number of seconds given - expects-response: option, - ipc: list, - metadata: option, - // to grab payload, use get_payload() - } - - record response { - inherit: bool, - ipc: list, - metadata: option, - // to grab payload, use get_payload() - } - - // a message can be a request or a response. - // within a response, there is a result which surfaces any error - // that happened because of a request. - // a successful response will contain the context of the request - // it matches, if any was set. - variant message { - request(request), - response(tuple>), - } - - variant capabilities { - none, - all, - some(list), - } - - record signed-capability { - issuer: address, - params: json, - signature: list, - } - - // on-panic is a setting that determines what happens when a process panics. - // NOTE: requests should have expects-response set to false, will always be set to that by kernel - variant on-panic { - none, - restart, - requests(list>>), - } - - // network errors come from trying to send a message to another node. - // a message can fail by timing out, or by the node being entirely unreachable (offline). - // in either case, the message is not delivered, and the process that sent it - // receives that message along with any assigned context and/or payload, - // and is free to handle it as it sees fit. - // note that if the message is a response, the process can issue a response again, - // and it will be directed to the same (remote) request as the original. - record send-error { - kind: send-error-kind, - message: message, - payload: option, - } - - enum send-error-kind { - offline, - timeout, - } - - enum spawn-error { - name-taken, - no-file-at-path, - // TODO more here? - } - - // system utils: - print-to-terminal: func(verbosity: u8, message: string); - - // **more will be added here with regard to blockchains** - get-eth-block: func() -> u64; - - // process management: - - set-on-panic: func(on-panic: on-panic); - - get-state: func() -> option>; - - set-state: func(bytes: list); - - clear-state: func(); - - spawn: func( - name: option, - wasm-path: string, // must be located within package's drive - on-panic: on-panic, - capabilities: capabilities, - public: bool - ) -> result; - - // capabilities management - - // gives us all our signed capabilities so we can send them to others - get-capabilities: func() -> list; - - // gets a single specific capability - get-capability: func(issuer: address, params: json) -> option; - - // attaches a specific signed capability to our next message - attach-capability: func(capability: signed-capability); - - // saves capabilities to our store, so we can use them - save-capabilities: func(capabilities: list); - - // check to see if the sender of a prompting message has a given capability, issued by us - // if the prompting message has a remote source, they must have attached it. - has-capability: func(params: json) -> bool; - - // generates a new capability with our process as the issuer and gives it to the target, - // which must be a locally-running process. - create-capability: func(to: process-id, params: json); - - // take a signed capability and save it to a given locally-running process - share-capability: func(to: process-id, capability: signed-capability); - - - // message I/O: - - // ingest next message when it arrives along with its source. - // almost all long-running processes will call this in a loop - receive: func() -> result, tuple>>; - - // gets payload, if any, of the message we just received - get-payload: func() -> option; - - // send message(s) to target(s) - send-request: - func(target: address, request: request, context: option, payload: option); - - send-requests: - func(requests: list, option>>); - - send-response: - func(response: response, payload: option); - - // send a single request, then block (internally) until its response - // the type is Message but will always contain Response - send-and-await-response: - func(target: address, request: request, payload: option) -> - result, send-error>; -} - -world lib { - import standard; -} - -world process { - include lib; - - export init: func(our: string); -}