diff --git a/.gitignore b/.gitignore index 0acd9db..4d6c313 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ werewolves/img/icons.svg license_headers.fish util/ werewolves/Trunk-local.toml + +werewolves-old-client/ +werewolves-old-server/ diff --git a/Cargo.lock b/Cargo.lock index 606bb5c..9ec27ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aho-corasick" version = "1.1.4" @@ -11,6 +17,27 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -20,18 +47,145 @@ dependencies = [ "libc", ] +[[package]] +name = "any_spawner" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1384d3fe1eecb464229fcf6eebb72306591c56bf27b373561489458a7c73027d" +dependencies = [ + "futures", + "thiserror 2.0.17", + "tokio", + "wasm-bindgen-futures", +] + [[package]] name = "anyhow" version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "api" +version = "0.1.0" +dependencies = [ + "anyhow", + "argon2", + "async-trait", + "axum", + "axum-extra", + "bytes", + "chrono", + "ciborium", + "futures", + "leptos", + "log", + "rand 0.9.2", + "serde", + "serde_json", + "sqlx", + "thiserror 2.0.17", + "uuid", + "werewolves-proto", +] + +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", +] + +[[package]] +name = "async-compression" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68650b7df54f0293fd061972a0fb05aaf4fc0879d3b3d21a638a182c5c543b9f" +dependencies = [ + "compression-codecs", + "compression-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-once-cell" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288f83726785267c6f2ef073a3d83dc3f9b81464e9f99898240cced85fce35a" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "atomic-waker" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "attribute-derive" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05832cdddc8f2650cc2cc187cc2e952b8c133a48eb055f35211f61ee81502d77" +dependencies = [ + "attribute-derive-macro", + "derive-where", + "manyhow", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "attribute-derive-macro" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a7cdbbd4bd005c5d3e2e9c885e6fa575db4f4a3572335b974d8db853b6beb61" +dependencies = [ + "collection_literals", + "interpolator", + "manyhow", + "proc-macro-utils", + "proc-macro2", + "quote", + "quote-use", + "syn", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -45,7 +199,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b098575ebe77cb6d14fc7f32749631a6e44edbef6b796f89b020e99ba20d425" dependencies = [ "axum-core", - "base64 0.22.1", + "axum-macros", + "base64", "bytes", "form_urlencoded", "futures-util", @@ -58,6 +213,7 @@ dependencies = [ "matchit", "memchr", "mime", + "multer", "percent-encoding", "pin-project-lite", "serde_core", @@ -116,10 +272,21 @@ dependencies = [ ] [[package]] -name = "base64" -version = "0.21.7" +name = "axum-macros" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "base16" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" [[package]] name = "base64" @@ -127,6 +294,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + [[package]] name = "bincode" version = "1.3.3" @@ -145,6 +318,15 @@ dependencies = [ "serde_core", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -154,17 +336,53 @@ dependencies = [ "generic-array", ] +[[package]] +name = "brotli" +version = "8.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +dependencies = [ + "serde", +] + +[[package]] +name = "camino" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" [[package]] name = "cc" @@ -173,6 +391,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -196,15 +416,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "chrono-humanize" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799627e6b4d27827a814e837b9d8a504832086081806d45b1afa34dc982b023b" -dependencies = [ - "chrono", -] - [[package]] name = "ciborium" version = "0.2.2" @@ -232,6 +443,24 @@ dependencies = [ "half", ] +[[package]] +name = "codee" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9dbbdc4b4d349732bc6690de10a9de952bd39ba6a065c586e26600b6b0b91f5" +dependencies = [ + "rmp-serde", + "serde", + "serde_json", + "thiserror 2.0.17", +] + +[[package]] +name = "collection_literals" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2550f75b8cfac212855f6b1885455df8eaee8fe8e246b647d69146142e016084" + [[package]] name = "colored" version = "3.0.0" @@ -241,6 +470,48 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "compression-codecs" +version = "0.4.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00828ba6fd27b45a448e57dbfe84f1029d4c9f26b368157e9a448a5f49a2ec2a" +dependencies = [ + "brotli", + "compression-core", + "flate2", + "memchr", + "zstd", + "zstd-safe", +] + +[[package]] +name = "compression-core" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "config" +version = "0.15.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30fa8254caad766fc03cb0ccae691e14bf3bd72bfff27f72802ce729551b3d6" +dependencies = [ + "convert_case 0.6.0", + "pathdiff", + "serde_core", + "toml", + "winnow 0.7.14", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -251,6 +522,62 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-str" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451d0640545a0553814b4c646eb549343561618838e9b42495f466131fe3ad49" + +[[package]] +name = "const_format" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "const_str_slice_concat" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f67855af358fcb20fac58f9d714c94e2b228fe5694c1c9b4ead4a366343eda1b" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "convert_case" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "convert_case" version = "0.9.0" @@ -269,6 +596,26 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "convert_case" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -284,6 +631,45 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crunchy" version = "0.2.4" @@ -301,10 +687,102 @@ dependencies = [ ] [[package]] -name = "data-encoding" -version = "2.9.0" +name = "darling" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" + +[[package]] +name = "default-struct-builder" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0df63c21a4383f94bd5388564829423f35c316aed85dc4f8427aded372c7c0d" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive-where" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "diff" @@ -319,7 +797,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", + "subtle", ] [[package]] @@ -330,7 +810,47 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "drain_filter_polyfill" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + +[[package]] +name = "either_of" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216d23e0ec69759a17f05e1c553f3a6870e5ec73420fbb07807a6f34d5d1d5a4" +dependencies = [ + "paste", + "pin-project-lite", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", ] [[package]] @@ -352,6 +872,44 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "erased" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1731451909bde27714eacba19c2566362a7f35224f52b153d3f42cf60f72472" + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + [[package]] name = "fast_qr" version = "0.13.1" @@ -364,12 +922,39 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -419,6 +1004,18 @@ dependencies = [ "futures-core", "futures-task", "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", ] [[package]] @@ -435,7 +1032,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -516,7 +1113,7 @@ dependencies = [ "gloo-events", "gloo-file", "gloo-history", - "gloo-net", + "gloo-net 0.5.0", "gloo-render", "gloo-storage", "gloo-timers", @@ -563,7 +1160,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97563d71863fb2824b2e974e754a81d19c4a7ec47b09ced8a0e6656b6d54bd1f" dependencies = [ - "futures-channel", "gloo-events", "js-sys", "wasm-bindgen", @@ -608,6 +1204,27 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gloo-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06f627b1a58ca3d42b45d6104bf1e1a03799df472df00988b6ba21accc10580" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http 1.4.0", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror 1.0.69", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "gloo-render" version = "0.2.0" @@ -686,9 +1303,15 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] +[[package]] +name = "guardian" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17e2ac29387b1aa07a1e448f7bb4f35b500787971e965b02842b900afa5c8f6f" + [[package]] name = "half" version = "2.7.1" @@ -700,19 +1323,45 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + [[package]] name = "headers" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "headers-core", "http 1.4.0", @@ -730,12 +1379,60 @@ dependencies = [ "http 1.4.0", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + [[package]] name = "http" version = "0.2.12" @@ -780,6 +1477,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-range-header" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" + [[package]] name = "httparse" version = "1.10.1" @@ -798,6 +1501,22 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" +[[package]] +name = "hydration_context" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8714ae4adeaa846d838f380fbd72f049197de629948f91bf045329e0cf0a283" +dependencies = [ + "futures", + "js-sys", + "once_cell", + "or_poisoned", + "pin-project-lite", + "serde", + "throw_error", + "wasm-bindgen", +] + [[package]] name = "hyper" version = "1.8.1" @@ -940,6 +1659,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.1.0" @@ -961,26 +1686,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "implicit-clone" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1689b939ee35e3a075b0834b5672efd43aec8a6e81a1c6002b76a5ca2f211ae0" -dependencies = [ - "implicit-clone-derive", - "indexmap", -] - -[[package]] -name = "implicit-clone-derive" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "699c1b6d335e63d0ba5c1e1c7f647371ce989c3bcbe1f7ed2b85fa56e3bd1a21" -dependencies = [ - "quote", - "syn 2.0.111", -] - [[package]] name = "indexmap" version = "2.12.1" @@ -988,19 +1693,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", ] [[package]] -name = "instant" -version = "0.1.13" +name = "interpolator" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8" + +[[package]] +name = "inventory" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", + "rustversion", +] + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", ] [[package]] @@ -1014,6 +1732,15 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" @@ -1021,21 +1748,322 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] -name = "js-sys" -version = "0.3.77" +name = "jobserver" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "leptos" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87c98f6d751e524ff425ad9d63d53e120ed68311ffbc22bbd9c0b3c4005a421e" +dependencies = [ + "any_spawner", + "base64", + "cfg-if", + "either_of", + "futures", + "getrandom 0.3.4", + "hydration_context", + "leptos_config", + "leptos_dom", + "leptos_hot_reload", + "leptos_macro", + "leptos_server", + "oco_ref", + "or_poisoned", + "paste", + "rand 0.9.2", + "reactive_graph", + "rustc-hash", + "rustc_version", + "send_wrapper", + "serde", + "serde_json", + "serde_qs", + "server_fn", + "slotmap", + "tachys", + "thiserror 2.0.17", + "throw_error", + "typed-builder 0.22.0", + "typed-builder-macro 0.22.0", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm_split_helpers", + "web-sys", +] + +[[package]] +name = "leptos-use" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e652389aa67f810bab687dd32566346a1d0dc4d25b44370d952ffc2ca4c627c0" +dependencies = [ + "cfg-if", + "chrono", + "codee", + "cookie", + "default-struct-builder", + "futures-util", + "gloo-timers", + "http 1.4.0", + "js-sys", + "lazy_static", + "leptos", + "leptos_axum", + "paste", + "send_wrapper", + "thiserror 2.0.17", + "unic-langid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "leptos_axum" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0caa95760f87f3067e05025140becefdbdfd36cbc2adac4519f06e1f1edf4af" +dependencies = [ + "any_spawner", + "axum", + "dashmap", + "futures", + "hydration_context", + "leptos", + "leptos_integration_utils", + "leptos_macro", + "leptos_meta", + "leptos_router", + "parking_lot", + "server_fn", + "tachys", + "tokio", + "tower", + "tower-http", +] + +[[package]] +name = "leptos_config" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a2ac32008dda0d657f2147cc33336f4e743e091597db10f7a99d668e92a46d" +dependencies = [ + "config", + "regex", + "serde", + "thiserror 2.0.17", + "typed-builder 0.23.2", +] + +[[package]] +name = "leptos_dom" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78f4330c88694c5575e0bfe4eecf81b045d14e76a4f8b00d5fd2a63f8779f895" +dependencies = [ + "js-sys", + "or_poisoned", + "reactive_graph", + "send_wrapper", + "tachys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "leptos_hot_reload" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d61ec3e1ff8aaee8c5151688550c0363f85bc37845450764c31ff7584a33f38" +dependencies = [ + "anyhow", + "camino", + "indexmap", + "parking_lot", + "proc-macro2", + "quote", + "rstml", + "serde", + "syn", + "walkdir", +] + +[[package]] +name = "leptos_integration_utils" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13cccc9305df53757bae61bf15641bfa6a667b5f78456ace4879dfe0591ae0e8" +dependencies = [ + "futures", + "hydration_context", + "leptos", + "leptos_config", + "leptos_meta", + "leptos_router", + "reactive_graph", +] + +[[package]] +name = "leptos_macro" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86ffd2e9cf3e264e9b3e16bdb086cefa26bd0fa7bc6a26b0cc5f6c1fd3178ed" +dependencies = [ + "attribute-derive", + "cfg-if", + "convert_case 0.10.0", + "html-escape", + "itertools", + "leptos_hot_reload", + "prettyplease", + "proc-macro-error2", + "proc-macro2", + "quote", + "rstml", + "rustc_version", + "server_fn_macro", + "syn", + "uuid", +] + +[[package]] +name = "leptos_meta" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d489e38d3f541e9e43ecc2e3a815527840345a2afca629b3e23fcc1dd254578" +dependencies = [ + "futures", + "indexmap", + "leptos", + "or_poisoned", + "send_wrapper", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "leptos_router" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b824cae28db1551b71f8c2a45eab7bb98d61407f5adcc368cfe7b671e4a71d" +dependencies = [ + "any_spawner", + "either_of", + "futures", + "gloo-net 0.6.0", + "js-sys", + "leptos", + "leptos_router_macro", + "or_poisoned", + "percent-encoding", + "reactive_graph", + "rustc_version", + "send_wrapper", + "tachys", + "thiserror 2.0.17", + "url", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "leptos_router_macro" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "409c0bd99f986c3cfa1a4db2443c835bc602ded1a12784e22ecb28c3ed5a2ae2" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "leptos_server" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf1045af93050bf3388d1c138426393fc131f6d9e46a65519da884c033ed730" +dependencies = [ + "any_spawner", + "base64", + "codee", + "futures", + "hydration_context", + "or_poisoned", + "reactive_graph", + "send_wrapper", + "serde", + "serde_json", + "server_fn", + "tachys", +] + [[package]] name = "libc" version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags", + "libc", + "redox_syscall 0.7.1", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linear-map" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfae20f6b19ad527b550c223fddc3077a547fc70cda94b9b566575423fd303ee" + [[package]] name = "litemap" version = "0.8.1" @@ -1057,12 +2085,45 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "manyhow" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587" +dependencies = [ + "manyhow-macros", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "manyhow-macros" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495" +dependencies = [ + "proc-macro-utils", + "proc-macro2", + "quote", +] + [[package]] name = "matchit" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + [[package]] name = "memchr" version = "2.7.6" @@ -1085,6 +2146,26 @@ dependencies = [ "url", ] +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "mio" version = "1.1.1" @@ -1096,6 +2177,71 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "multer" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 1.4.0", + "httparse", + "memchr", + "mime", + "spin", + "version_check", +] + +[[package]] +name = "next_tuple" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60993920e071b0c9b66f14e2b32740a4e27ffc82854dcd72035887f336a09a28" + +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1103,6 +2249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1115,12 +2262,34 @@ dependencies = [ "libc", ] +[[package]] +name = "oco_ref" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0423ff9973dea4d6bd075934fdda86ebb8c05bdf9d6b0507067d4a1226371d" +dependencies = [ + "serde", + "thiserror 2.0.17", +] + [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "or_poisoned" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c04f5d74368e4d0dfe06c45c8627c81bd7c317d52762d118fb9b3076f6420fd" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.5" @@ -1139,11 +2308,43 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", "windows-link", ] +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[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.2" @@ -1167,7 +2368,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -1193,6 +2394,33 @@ dependencies = [ "thiserror 1.0.69", ] +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "potential_utf" version = "0.1.4" @@ -1202,6 +2430,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1238,7 +2472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.111", + "syn", ] [[package]] @@ -1252,27 +2486,36 @@ dependencies = [ ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ - "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.109", - "version_check", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro-utils" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071" dependencies = [ "proc-macro2", "quote", - "version_check", + "smallvec", ] [[package]] @@ -1284,6 +2527,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", +] + [[package]] name = "quote" version = "1.0.42" @@ -1293,20 +2549,63 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "quote-use" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9619db1197b497a36178cfc736dc96b271fe918875fbf1344c436a7e93d0321e" +dependencies = [ + "quote", + "quote-use-macros", +] + +[[package]] +name = "quote-use-macros" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82ebfb7faafadc06a7ab141a6f67bcfb24cb8beb158c6fe933f2f035afa99f35" +dependencies = [ + "proc-macro-utils", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "r-efi" version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha", - "rand_core", + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] @@ -1316,7 +2615,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", ] [[package]] @@ -1328,6 +2636,60 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "reactive_graph" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4043190442021086719fb9183daacb050f44d4ed8d3a1c8534e366d45dd95c29" +dependencies = [ + "any_spawner", + "async-lock", + "futures", + "guardian", + "hydration_context", + "indexmap", + "or_poisoned", + "paste", + "pin-project-lite", + "rustc-hash", + "rustc_version", + "send_wrapper", + "serde", + "slotmap", + "thiserror 2.0.17", + "web-sys", +] + +[[package]] +name = "reactive_stores" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b73d94139821e0a2f31fb4e0eaf6ebbcf4d15c5e2fb353dc3babd4f6d35674" +dependencies = [ + "dashmap", + "guardian", + "itertools", + "or_poisoned", + "paste", + "reactive_graph", + "reactive_stores_macro", + "rustc-hash", + "send_wrapper", +] + +[[package]] +name = "reactive_stores_macro" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa40919eb2975100283b2a70e68eafce1e8bcf81f0622ff168e4c2b3f8d46bb" +dependencies = [ + "convert_case 0.8.0", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -1337,6 +2699,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.12.2" @@ -1367,22 +2738,73 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] -name = "ron" -version = "0.8.1" +name = "rmp" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" dependencies = [ - "base64 0.21.7", - "bitflags", - "serde", - "serde_derive", + "num-traits", ] [[package]] -name = "route-recognizer" -version = "0.3.1" +name = "rmp-serde" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" +checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" +dependencies = [ + "rmp", + "serde", +] + +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rstml" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61cf4616de7499fc5164570d40ca4e1b24d231c6833a88bff0fe00725080fd56" +dependencies = [ + "derive-where", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", + "syn_derive", + "thiserror 2.0.17", +] + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] [[package]] name = "rustversion" @@ -1396,12 +2818,36 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" +dependencies = [ + "futures-core", +] + [[package]] name = "serde" version = "1.0.228" @@ -1440,7 +2886,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -1467,6 +2913,26 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_qs" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" +dependencies = [ + "percent-encoding", + "serde", + "thiserror 2.0.17", +] + +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1479,6 +2945,71 @@ dependencies = [ "serde", ] +[[package]] +name = "server_fn" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc30228718f62d80a376964baf990edbcb5e97688fdc71183a8ef3d44cb6c89" +dependencies = [ + "axum", + "base64", + "bytes", + "const-str", + "const_format", + "dashmap", + "futures", + "gloo-net 0.6.0", + "http 1.4.0", + "http-body-util", + "hyper", + "inventory", + "js-sys", + "pin-project-lite", + "rustc_version", + "rustversion", + "send_wrapper", + "serde", + "serde_json", + "serde_qs", + "server_fn_macro_default", + "thiserror 2.0.17", + "throw_error", + "tokio", + "tower", + "tower-layer", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14faf423aab09f8c3eb2d9785bb37f11a255cdf01857d3c6083eacc82269c191" +dependencies = [ + "const_format", + "convert_case 0.11.0", + "proc-macro2", + "quote", + "rustc_version", + "syn", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro_default" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63eb08f80db903d3c42f64e60ebb3875e0305be502bdc064ec0a0eab42207f00" +dependencies = [ + "server_fn_macro", + "syn", +] + [[package]] name = "sha1" version = "0.10.6" @@ -1490,6 +3021,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1497,25 +3039,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] -name = "signal-hook-registry" -version = "1.4.7" +name = "signature" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "libc", + "digest", + "rand_core 0.6.4", ] +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + [[package]] name = "slab" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +[[package]] +name = "slotmap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" +dependencies = [ + "version_check", +] + [[package]] name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -1527,6 +3088,221 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlx" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +dependencies = [ + "base64", + "bytes", + "chrono", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.5", + "hashlink", + "indexmap", + "log", + "memchr", + "once_cell", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "thiserror 2.0.17", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +dependencies = [ + "atoi", + "base64", + "bitflags", + "byteorder", + "bytes", + "chrono", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.17", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +dependencies = [ + "atoi", + "base64", + "bitflags", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.17", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "thiserror 2.0.17", + "tracing", + "url", + "uuid", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -1534,15 +3310,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] -name = "syn" -version = "1.0.109" +name = "stringprep" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "proc-macro2", - "unicode-ident", + "unicode-bidi", + "unicode-normalization", + "unicode-properties", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.111" @@ -1554,6 +3343,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb066a04799e45f5d582e8fc6ec8e6d6896040d00898eb4e6a835196815b219" +dependencies = [ + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "sync_wrapper" version = "1.0.2" @@ -1568,7 +3369,41 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", +] + +[[package]] +name = "tachys" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b2db11e455f7e84e2cc3e76f8a3f3843f7956096265d5ecff781eabe235077" +dependencies = [ + "any_spawner", + "async-trait", + "const_str_slice_concat", + "drain_filter_polyfill", + "either_of", + "erased", + "futures", + "html-escape", + "indexmap", + "itertools", + "js-sys", + "linear-map", + "next_tuple", + "oco_ref", + "or_poisoned", + "parking_lot", + "paste", + "reactive_graph", + "reactive_stores", + "rustc-hash", + "rustc_version", + "send_wrapper", + "slotmap", + "throw_error", + "wasm-bindgen", + "web-sys", ] [[package]] @@ -1606,7 +3441,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -1617,7 +3452,47 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", +] + +[[package]] +name = "throw_error" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc0ed6038fcbc0795aca7c92963ddda636573b956679204e044492d2b13c8f64" +dependencies = [ + "pin-project-lite", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +dependencies = [ + "num-conv", + "time-core", ] [[package]] @@ -1627,9 +3502,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", + "serde_core", "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.48.0" @@ -1639,9 +3530,7 @@ dependencies = [ "bytes", "libc", "mio", - "parking_lot", "pin-project-lite", - "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.61.2", @@ -1655,7 +3544,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -1682,20 +3571,29 @@ dependencies = [ ] [[package]] -name = "tokise" -version = "0.2.0" +name = "tokio-util" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "decf97738ce15b9e9cc1671ea29b0f6c56538719e1a092d19cc2134bf144e40e" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ - "futures", - "gloo", - "num_cpus", - "once_cell", - "pin-project", - "pinned", + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", "tokio", - "tokio-stream", - "wasm-bindgen-futures", +] + +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "serde_core", + "serde_spanned", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow 0.7.14", ] [[package]] @@ -1704,6 +3602,15 @@ version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.19.15" @@ -1711,8 +3618,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap", - "toml_datetime", - "winnow", + "toml_datetime 0.6.11", + "winnow 0.5.40", +] + +[[package]] +name = "toml_parser" +version = "1.0.9+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +dependencies = [ + "winnow 0.7.14", ] [[package]] @@ -1731,6 +3647,37 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "async-compression", + "base64", + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http 1.4.0", + "http-body", + "http-body-util", + "http-range-header", + "httpdate", + "iri-string", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "uuid", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -1763,7 +3710,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -1786,30 +3733,121 @@ dependencies = [ "http 1.4.0", "httparse", "log", - "rand", + "rand 0.9.2", "sha1", "thiserror 2.0.17", "utf-8", ] +[[package]] +name = "typed-builder" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "398a3a3c918c96de527dc11e6e846cd549d4508030b8a33e1da12789c856b81a" +dependencies = [ + "typed-builder-macro 0.22.0", +] + +[[package]] +name = "typed-builder" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31aa81521b70f94402501d848ccc0ecaa8f93c8eb6999eb9747e72287757ffda" +dependencies = [ + "typed-builder-macro 0.23.2", +] + +[[package]] +name = "typed-builder-macro" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e48cea23f68d1f78eb7bc092881b6bb88d3d6b5b7e6234f6f9c911da1ffb221" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typed-builder-macro" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076a02dc54dd46795c2e9c8282ed40bcfb1e22747e955de9389a1de28190fb26" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "typenum" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +[[package]] +name = "unic-langid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05" +dependencies = [ + "unic-langid-impl", +] + +[[package]] +name = "unic-langid-impl" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658" +dependencies = [ + "tinystr", +] + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-ident" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" + [[package]] name = "unicode-segmentation" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "url" version = "2.5.7" @@ -1822,18 +3860,18 @@ dependencies = [ "serde", ] -[[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - [[package]] name = "utf-8" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -1852,12 +3890,28 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -1874,38 +3928,32 @@ dependencies = [ ] [[package]] -name = "wasm-bindgen" -version = "0.2.100" +name = "wasite" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.111", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ "cfg-if", + "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -1914,9 +3962,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1924,22 +3972,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.111", - "wasm-bindgen-backend", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] @@ -1956,10 +4004,45 @@ dependencies = [ ] [[package]] -name = "web-sys" -version = "0.3.77" +name = "wasm-streams" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasm_split_helpers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a114b3073258dd5de3d812cdd048cca6842342755e828a14dbf15f843f2d1b84" +dependencies = [ + "async-once-cell", + "wasm_split_macros", +] + +[[package]] +name = "wasm_split_macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56481f8ed1a9f9ae97ea7b08a5e2b12e8adf9a7818a6ba952b918e09c7be8bf0" +dependencies = [ + "base16", + "quote", + "sha2", + "syn", +] + +[[package]] +name = "web-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -1969,29 +4052,39 @@ dependencies = [ name = "werewolves" version = "0.1.0" dependencies = [ + "anyhow", + "api", + "axum", + "axum-extra", + "bytes", "chrono", - "chrono-humanize", - "ciborium", - "convert_case 0.10.0", + "codee", + "colored", + "console_error_panic_hook", + "convert_case 0.11.0", + "fast_qr", "futures", "getrandom 0.3.4", "gloo", - "instant", + "leptos", + "leptos-use", + "leptos_axum", + "leptos_meta", + "leptos_router", "log", - "once_cell", - "rand", + "mime-sniffer", + "pretty_env_logger", + "rand 0.9.2", + "reactive_stores", "serde", - "serde_json", - "thiserror 2.0.17", + "sqlx", + "tokio", + "tower-http", "uuid", "wasm-bindgen", - "wasm-bindgen-futures", "wasm-logger", - "web-sys", "werewolves-macros", "werewolves-proto", - "yew", - "yew-router", ] [[package]] @@ -2002,7 +4095,7 @@ dependencies = [ "convert_case 0.9.0", "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -2014,7 +4107,7 @@ dependencies = [ "log", "pretty_assertions", "pretty_env_logger", - "rand", + "rand 0.9.2", "serde", "serde_json", "thiserror 2.0.17", @@ -2023,29 +4116,13 @@ dependencies = [ ] [[package]] -name = "werewolves-server" -version = "0.1.0" +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" dependencies = [ - "anyhow", - "axum", - "axum-extra", - "bytes", - "chrono", - "ciborium", - "colored", - "fast_qr", - "futures", - "log", - "mime-sniffer", - "pretty_env_logger", - "rand", - "ron", - "serde", - "serde_json", - "thiserror 2.0.17", - "tokio", - "werewolves-macros", - "werewolves-proto", + "libredox", + "wasite", ] [[package]] @@ -2078,7 +4155,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -2089,7 +4166,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -2116,6 +4193,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -2143,6 +4229,21 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -2176,6 +4277,12 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -2188,6 +4295,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +[[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.6" @@ -2200,6 +4313,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +[[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.6" @@ -2224,6 +4343,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +[[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.6" @@ -2236,6 +4361,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +[[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.6" @@ -2248,6 +4379,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +[[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.6" @@ -2260,6 +4397,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +[[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.6" @@ -2281,6 +4424,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.46.0" @@ -2293,82 +4445,18 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +[[package]] +name = "xxhash-rust" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" + [[package]] name = "yansi" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" -[[package]] -name = "yew" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3346273ed61b636f5d84e6c696d40f380045b5565b36c5c47f8fc634b8bf5be6" -dependencies = [ - "console_error_panic_hook", - "futures", - "gloo", - "implicit-clone", - "indexmap", - "js-sys", - "rustversion", - "serde", - "slab", - "thiserror 2.0.17", - "tokio", - "tokise", - "tracing", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "yew-macro", -] - -[[package]] -name = "yew-macro" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479e94d645dde3749e81d488c1d32987509dd3b8c31650fcf6e3af1f370e913b" -dependencies = [ - "once_cell", - "prettyplease", - "proc-macro-error", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.111", -] - -[[package]] -name = "yew-router" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415cb628900ddf1eaf55ebd04163adf1ea80d3f5a9832a876554f9c0fdd4c282" -dependencies = [ - "gloo", - "js-sys", - "route-recognizer", - "serde", - "serde_urlencoded", - "tracing", - "urlencoding", - "wasm-bindgen", - "web-sys", - "yew", - "yew-router-macro", -] - -[[package]] -name = "yew-router-macro" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e87a3ce33434ab66a700edbaf2cc8a417d9b89f00a6fd8216fd6ac83b0e7b1c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "yoke" version = "0.8.1" @@ -2388,7 +4476,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", "synstructure", ] @@ -2409,7 +4497,7 @@ checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", ] [[package]] @@ -2429,10 +4517,16 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + [[package]] name = "zerotrie" version = "0.2.3" @@ -2450,6 +4544,7 @@ version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ + "serde", "yoke", "zerofrom", "zerovec-derive", @@ -2463,5 +4558,33 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index 091b37d..bcc8151 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,133 @@ [workspace] resolver = "3" members = [ - "werewolves", + # "werewolves-old-client", "werewolves-macros", "werewolves-proto", - "werewolves-server", + # "werewolves-server", + "werewolves", + "api", ] + +[[workspace.metadata.leptos]] +watch-additional-files = ["werewolves", "api", "style", "public"] + +# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name +output-name = "werewolves" + +# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup. +site-root = "target/site" + +# The site-root relative folder where all compiled output (JS, WASM and CSS) is written +# Defaults to pkg +site-pkg-dir = "pkg" + +# [Optional] The source CSS file. If it ends with .sass or .scss then it will be compiled by dart-sass into CSS. The CSS is optimized by Lightning CSS before being written to //app.css +style-file = "style/main.scss" +# Assets source dir. All files found here will be copied and synchronized to site-root. +# The assets-dir cannot have a sub directory with the same name/path as site-pkg-dir. +# +# Optional. Env: LEPTOS_ASSETS_DIR. +assets-dir = "public" + +# The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup. +site-addr = "127.0.0.1:3000" +# site-addr = "192.168.1.3:3000" + +# The port to use for automatic reload monitoring +reload-port = 3001 + +# [Optional] Command to use when running end2end tests. It will run in the end2end dir. +# [Windows] for non-WSL use "npx.cmd playwright test" +# This binary name can be checked in Powershell with Get-Command npx +end2end-cmd = "npx playwright test" +end2end-dir = "end2end" + +# The browserlist query used for optimizing the CSS. +browserquery = "defaults" + +# The environment Leptos will run in, usually either "DEV" or "PROD" +env = "DEV" + +# The features to use when compiling the bin target +# +# Optional. Can be over-ridden with the command line parameter --bin-features +bin-features = ["ssr"] + +# If the --no-default-features flag should be used when compiling the bin target +# +# Optional. Defaults to false. +bin-default-features = false + +# The features to use when compiling the lib target +# +# Optional. Can be over-ridden with the command line parameter --lib-features +lib-features = ["hydrate"] + +# If the --no-default-features flag should be used when compiling the lib target +# +# Optional. Defaults to false. +lib-default-features = false + +# The profile to use for the lib target when compiling for release +# +# Optional. Defaults to "release". +lib-profile-release = "wasm-release" +name = "werewolves" +bin-package = "werewolves" +lib-package = "werewolves" + +[workspace.dependencies] +axum = "0.8.1" +axum-extra = { version = "0.12", features = ["typed-header"] } +cfg-if = "1.0.0" +console_error_panic_hook = "0.1.7" +console_log = "1.0.0" +http = "1.3.1" +log = "0.4.27" +simple_logger = "5.0.0" +thiserror = "2.0.12" +wasm-bindgen = "0.2.106" +leptos-use = { version = "0.18" } +# leptos-use = { path = "../repos/leptos-use" } +werewolves-macros = { path = "werewolves-macros" } +werewolves-proto = { path = "werewolves-proto" } +serde_json = { version = "1" } +futures = { version = "*" } +codee = { version = "0.3", features = ["msgpack_serde"] } +bytes = { version = "1.10" } +convert_case = { version = "0.11" } +fast_qr = { version = "0.13", features = ["svg"] } +anyhow = { version = "1" } +uuid = { version = "1.18" } +sqlx = { version = "0.8", features = [ + "runtime-tokio", + "postgres", + "derive", + "macros", + "uuid", + "chrono", +] } +argon2 = { version = "0.5" } +async-trait = { version = "0.1" } +chrono = { version = "0.4" } +leptos = { version = "0.8.2" } +leptos_axum = { version = "0.8.2" } +leptos_meta = { version = "0.8.2" } +leptos_router = { version = "0.8.2" } +rand = { version = "*" } +serde = { version = "1.0.228" } +tokio = { version = "1.45.0", features = ["full"] } +tower = { version = "0.5.2", features = ["full"] } +tower-http = { version = "0.6.4", features = ["full"] } +api = { path = "api" } +ciborium = { version = "0.2" } + +[profile.dev] +opt-level = 0 +debug = "full" + +[profile.release] +opt-level = "z" +lto = true +codegen-units = 1 diff --git a/api/Cargo.toml b/api/Cargo.toml new file mode 100644 index 0000000..adee27e --- /dev/null +++ b/api/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "api" +version = "0.1.0" +edition = "2024" + +[dependencies] +bytes = { version = "1.10.1", features = ["serde"] } +rand = { version = "0.9", optional = true } +serde = { workspace = true, features = ["derive"] } +uuid = { workspace = true, features = ["serde", "v4"] } +thiserror = { workspace = true } +chrono = { workspace = true, features = ["serde"] } +sqlx = { workspace = true, optional = true } +axum = { workspace = true, optional = true, features = ["macros"] } +axum-extra = { workspace = true, optional = true, features = ["typed-header"] } +argon2 = { workspace = true, optional = true } +ciborium = { workspace = true } +async-trait = { workspace = true, optional = true } +werewolves-proto = { workspace = true } +serde_json = { workspace = true, optional = true } +futures = { workspace = true, optional = true } + +log.workspace = true +leptos.workspace = true +anyhow.workspace = true + +[features] +ssr = [ + "dep:sqlx", + "dep:axum", + "dep:axum-extra", + "dep:argon2", + "dep:rand", + "dep:async-trait", + "dep:serde_json", + "dep:futures", +] diff --git a/api/src/cbor.rs b/api/src/cbor.rs new file mode 100644 index 0000000..0586e6f --- /dev/null +++ b/api/src/cbor.rs @@ -0,0 +1,143 @@ +use axum::{ + body::Bytes, + extract::{FromRequest, Request, rejection::BytesRejection}, + http::{HeaderMap, HeaderValue, StatusCode, header}, + response::{IntoResponse, Response}, +}; +use axum_extra::headers::Mime; +use bytes::{BufMut, BytesMut}; +use core::fmt::Display; +use leptos::server_fn::{ + ContentType, Decodes, Encodes, Format, FormatType, + codec::{Post, Put}, +}; +use serde::{Serialize, de::DeserializeOwned}; + +const CBOR_CONTENT_TYPE: HeaderValue = HeaderValue::from_static("application/cbor"); +const PLAIN_CONTENT_TYPE: HeaderValue = HeaderValue::from_static("text/plain"); + +#[must_use] +pub struct Cbor(pub T); + +impl Cbor { + pub const fn new(t: T) -> Self { + Self(t) + } +} + +impl FromRequest for Cbor +where + T: DeserializeOwned, + S: Send + Sync, +{ + type Rejection = CborRejection; + + async fn from_request(req: Request, state: &S) -> Result { + if !cbor_content_type(req.headers()) { + return Err(CborRejection::MissingCborContentType); + } + + let bytes = Bytes::from_request(req, state).await?; + Ok(Self(ciborium::from_reader::(&*bytes)?)) + } +} + +impl IntoResponse for Cbor +where + T: Serialize, +{ + fn into_response(self) -> axum::response::Response { + // Extracted into separate fn so it's only compiled once for all T. + fn make_response(buf: BytesMut, ser_result: Result<(), CborRejection>) -> Response { + match ser_result { + Ok(()) => { + ([(header::CONTENT_TYPE, CBOR_CONTENT_TYPE)], buf.freeze()).into_response() + } + Err(err) => err.into_response(), + } + } + + // Use a small initial capacity of 128 bytes like serde_json::to_vec + // https://docs.rs/serde_json/1.0.82/src/serde_json/ser.rs.html#2189 + let mut buf = BytesMut::with_capacity(128).writer(); + let res = ciborium::into_writer(&self.0, &mut buf) + .map_err(|err| CborRejection::SerdeRejection(err.to_string())); + make_response(buf.into_inner(), res) + } +} + +#[derive(Debug)] +pub enum CborRejection { + MissingCborContentType, + BytesRejection(BytesRejection), + DeserializeRejection(String), + SerdeRejection(String), +} +impl From> for CborRejection { + fn from(value: ciborium::de::Error) -> Self { + Self::SerdeRejection(match value { + ciborium::de::Error::Io(err) => format!("i/o: {err}"), + ciborium::de::Error::Syntax(offset) => format!("syntax error at {offset}"), + ciborium::de::Error::Semantic(offset, err) => format!( + "semantic parse: {err}{}", + offset + .map(|offset| format!(" at {offset}")) + .unwrap_or_default(), + ), + ciborium::de::Error::RecursionLimitExceeded => { + String::from("the input caused serde to recurse too much") + } + }) + } +} + +impl From for CborRejection { + fn from(value: BytesRejection) -> Self { + Self::BytesRejection(value) + } +} + +impl IntoResponse for CborRejection { + fn into_response(self) -> axum::response::Response { + match self { + CborRejection::MissingCborContentType => ( + StatusCode::BAD_REQUEST, + [(header::CONTENT_TYPE, PLAIN_CONTENT_TYPE)], + String::from("missing cbor content type"), + ), + CborRejection::BytesRejection(err) => ( + err.status(), + [(header::CONTENT_TYPE, PLAIN_CONTENT_TYPE)], + format!("bytes rejection: {}", err.body_text()), + ), + CborRejection::SerdeRejection(err) => ( + StatusCode::BAD_REQUEST, + [(header::CONTENT_TYPE, PLAIN_CONTENT_TYPE)], + err, + ), + CborRejection::DeserializeRejection(err) => ( + StatusCode::INTERNAL_SERVER_ERROR, + [(header::CONTENT_TYPE, PLAIN_CONTENT_TYPE)], + err, + ), + } + .into_response() + } +} + +fn cbor_content_type(headers: &HeaderMap) -> bool { + let Some(content_type) = headers.get(header::CONTENT_TYPE) else { + return false; + }; + + let Ok(content_type) = content_type.to_str() else { + return false; + }; + + let Ok(mime) = content_type.parse::() else { + return false; + }; + + mime.type_() == "application" + && (mime.subtype() == "cbor" || mime.suffix().is_some_and(|name| name == "cbor")) +} diff --git a/api/src/cbor_leptos.rs b/api/src/cbor_leptos.rs new file mode 100644 index 0000000..13c53e9 --- /dev/null +++ b/api/src/cbor_leptos.rs @@ -0,0 +1,78 @@ +use core::marker::PhantomData; +use std::io::Read; + +use bytes::Bytes; +use leptos::{ + server::codee::{Decoder, Encoder}, + server_fn::{ + ContentType, Decodes, Encodes, Format, FormatType, + codec::{Post, Put}, + }, +}; +use serde::{Serialize, de::DeserializeOwned}; + +pub type CborPost = Post; +pub type CborPut = Put; + +/// Serializes and deserializes JSON with [`serde_json`]. +pub struct CborEncoding; + +impl Decoder for CborEncoding +where + T: DeserializeOwned, +{ + type Error = ciborium::de::Error; + + type Encoded = [u8]; + + fn decode(val: &Self::Encoded) -> Result { + ciborium::from_reader::(val) + } +} + +impl Encoder for CborEncoding +where + T: Serialize, +{ + type Error = ciborium::ser::Error; + + type Encoded = Vec; + + fn encode(val: &T) -> Result { + let mut encoded = vec![]; + ciborium::into_writer(val, &mut encoded)?; + Ok(encoded) + } +} + +impl ContentType for CborEncoding { + const CONTENT_TYPE: &'static str = "application/cbor"; +} + +impl FormatType for CborEncoding { + const FORMAT_TYPE: Format = Format::Binary; +} + +impl Encodes for CborEncoding +where + T: Serialize, +{ + type Error = ciborium::ser::Error; + + fn encode(output: &T) -> Result { + let mut bytes = Vec::new(); + ciborium::into_writer(output, &mut bytes)?; + Ok(Bytes::from_owner(bytes)) + } +} + +impl Decodes for CborEncoding +where + T: DeserializeOwned, +{ + type Error = ciborium::de::Error; + + fn decode(bytes: Bytes) -> Result { + ciborium::from_reader::(&*bytes) + } +} diff --git a/api/src/db/game.rs b/api/src/db/game.rs new file mode 100644 index 0000000..49dfc4c --- /dev/null +++ b/api/src/db/game.rs @@ -0,0 +1,389 @@ +use core::num::NonZeroU8; + +use chrono::Utc; +use futures::executor; +use sqlx::{Pool, Postgres, query, query_as}; +use werewolves_proto::{ + character::CharacterId, + error::GameError, + game::{Game, GameSettings}, + message::{CharacterIdentity, Identification, PublicIdentity, dead::DeadChatMessage}, + player::PlayerId, +}; + +use crate::{ + ServerResult, + db::{DatabaseResult, IntoDatabaseResult}, + error::{DatabaseError, ServerError}, + game::{GameId, GameRecord, GameRecordState}, + identity::PlayerIdentity, + user::UserId, +}; + +#[derive(Debug, Clone)] +pub struct GameDatabase { + pub(super) pool: Pool, +} + +impl GameDatabase { + pub const fn new(pool: Pool) -> Self { + Self { pool } + } + + pub async fn new_game(&self, host: UserId) -> DatabaseResult { + let record = GameRecord { + host, + id: GameId::new(), + created_at: Utc::now(), + game_state: crate::game::GameRecordState::Lobby(GameSettings::default()), + }; + let game_state_json = serde_json::to_value(&record.game_state) + .map_err(|err| DatabaseError::Serialization(err.to_string()))?; + query!( + r#" + insert into + games (id, host, created_at, game_state) + values + ($1, $2, $3, $4) + "#, + record.id.into_uuid(), + record.host.into_uuid(), + record.created_at, + game_state_json + ) + .execute(&self.pool) + .await?; + Ok(record) + } + + pub async fn start_game(&self, game: GameId) -> ServerResult { + let mut tx = self.pool.begin().await.into_db_result()?; + let mut record = self.get_game_inner(game, &mut *tx).await?; + let game_players = self.get_joined_players_inner(record.id, &mut *tx).await?; + + match &record.game_state { + GameRecordState::Lobby(settings) => { + let idents = game_players + .iter() + .map(|p| Identification { + player_id: p.player_id, + public: p.public.clone(), + }) + .collect::>(); + settings.check_with_player_list(&idents)?; + let with_char_ids = game_players + .iter() + .map(|p| { + ( + Identification { + player_id: p.player_id, + public: p.public.clone(), + }, + p.character_id, + ) + }) + .collect::>(); + let new_game = + Game::new_with_assigned_character_ids(&with_char_ids, settings.clone())?; + + record.game_state = GameRecordState::Started(new_game); + } + GameRecordState::GameOver(_) + | GameRecordState::RoleReveal(_) + | GameRecordState::Started(_) => { + return Err(GameError::GameAlreadyStarted.into()); + } + } + self.store_game_state_inner(&record, &mut *tx).await?; + tx.commit().await.into_db_result()?; + + Ok(record) + } + + pub async fn get_game(&self, game: GameId) -> DatabaseResult { + self.get_game_inner(game, &self.pool).await + } + + async fn get_game_inner<'a, E>(&self, game: GameId, executor: E) -> DatabaseResult + where + E: ::sqlx::Executor<'a, Database = Postgres>, + { + let r = query!( + r#" + select + id, host, created_at, game_state + from + games + where + id = $1 + "#, + game.into_uuid(), + ) + .fetch_one(executor) + .await?; + Ok(GameRecord { + id: GameId::from_uuid(r.id), + host: UserId::from_uuid(r.host), + created_at: r.created_at, + game_state: serde_json::from_value(r.game_state)?, + }) + } + + pub async fn store_game_state(&self, record: &GameRecord) -> DatabaseResult<()> { + self.store_game_state_inner(record, &self.pool).await + } + + async fn store_game_state_inner<'a, E>( + &self, + record: &GameRecord, + executor: E, + ) -> DatabaseResult<()> + where + E: ::sqlx::Executor<'a, Database = Postgres>, + { + let game_state_json = serde_json::to_value(&record.game_state) + .map_err(|err| DatabaseError::Serialization(err.to_string()))?; + let game_status = match &record.game_state { + GameRecordState::Lobby(_) => "Lobby", + GameRecordState::RoleReveal(_) => "RoleReveal", + GameRecordState::Started(_) => "Started", + GameRecordState::GameOver(_) => "GameOver", + }; + query!( + r#" + update + games + set + game_state = $2, + game_status = $3::game_status + where + id = $1 + "#, + record.id.into_uuid(), + game_state_json, + game_status as _, + ) + .execute(executor) + .await?; + Ok(()) + } + + pub async fn get_player_number( + &self, + game: GameId, + player: UserId, + ) -> DatabaseResult> { + Ok(query!( + r#" + select + number + from + game_characters + where + game_id = $1 and player_id = $2 + "#, + game.into_uuid(), + player.into_uuid(), + ) + .fetch_one(&self.pool) + .await? + .number + .and_then(|n| NonZeroU8::new(n as u8))) + } + + pub async fn set_player_number( + &self, + game: GameId, + player: UserId, + number: Option, + ) -> DatabaseResult<()> { + query!( + r#" + update + game_characters + set + number = $3 + where + game_id = $1 and player_id = $2 + "#, + game.into_uuid(), + player.into_uuid(), + number.map(|n| n.get() as i32), + ) + .execute(&self.pool) + .await?; + Ok(()) + } + + pub async fn get_joined_active_game(&self, player: UserId) -> DatabaseResult> { + Ok(query!( + r#" + select + g.id + from + game_characters gc + join + games g on g.id = gc.game_id + where + gc.player_id = $1 and g.game_status in ('Lobby', 'RoleReveal', 'Started')"#, + player.into_uuid(), + ) + .fetch_optional(&self.pool) + .await? + .map(|d| GameId::from_uuid(d.id))) + } + + pub async fn join_game( + &self, + game: GameId, + player: UserId, + number: Option, + ) -> ServerResult<()> { + let game = self.get_game(game).await?; + if game.host == player { + return Err(GameError::CannotJoinOwnGame.into()); + } + if !matches!(game.game_state, GameRecordState::Lobby(_)) { + return Err(GameError::CannotJoinStartedGame.into()); + } + if let Some(active) = self.get_joined_active_game(player).await? { + return Err(ServerError::AlreadyInActiveGame(active)); + }; + query!( + r#" + insert into + game_characters (character_id, game_id, player_id, number) + values + ($1, $2, $3, $4) + "#, + CharacterId::new().into_uuid(), + game.id.into_uuid(), + player.into_uuid(), + number.map(|n| n.get() as i32) + ) + .execute(&self.pool) + .await + .into_db_result()?; + Ok(()) + } + + pub async fn leave_game(&self, game: GameId, player: UserId) -> ServerResult<()> { + query!( + r#" + delete from + game_characters + where + game_id = $1 and player_id = $2 + "#, + game.into_uuid(), + player.into_uuid(), + ) + .execute(&self.pool) + .await + .into_db_result()?; + Ok(()) + } + + pub async fn get_joined_players(&self, game_id: GameId) -> ServerResult> { + self.get_joined_players_inner(game_id, &self.pool).await + } + + async fn get_joined_players_inner<'a, E>( + &self, + game_id: GameId, + executor: E, + ) -> ServerResult> + where + E: ::sqlx::Executor<'a, Database = Postgres>, + { + Ok(query!( + r#" + select + gc.character_id, gc.player_id, u.pronouns, + case when u.display_name is not null then + u.display_name + else + u.username + end as name, + case when gc.number > 0 then + gc.number + else + null + end as "number: i16" + from + game_characters gc + join + users u on u.id = gc.player_id + where + gc.game_id = $1 + "#, + game_id.into_uuid() + ) + .fetch_all(executor) + .await + .into_db_result()? + .into_iter() + .map(|r| PlayerIdentity { + player_id: PlayerId::from_uuid(r.player_id), + character_id: CharacterId::from_uuid(r.character_id), + public: PublicIdentity { + name: r.name.unwrap_or_default(), + pronouns: r.pronouns, + number: r.number.map(|r| r as u8).and_then(NonZeroU8::new), + }, + }) + .collect()) + } + + pub async fn record_dead_chat_message( + &self, + game_id: GameId, + message: DeadChatMessage, + ) -> ServerResult<()> { + let content = serde_json::to_value(&message.message).into_db_result()?; + query!( + r#" + insert into + dead_chat (message_id, game_id, created_at, message) + values + ($1, $2, $3, $4) + "#, + message.id, + game_id.into_uuid(), + message.timestamp, + content, + ) + .execute(&self.pool) + .await + .into_db_result()?; + Ok(()) + } + + pub async fn get_dead_chat(&self, game_id: GameId) -> ServerResult> { + Ok(query!( + r#" + select + message_id, created_at, message + from + dead_chat + where + game_id = $1 + order by + created_at asc + "#, + game_id.into_uuid(), + ) + .fetch_all(&self.pool) + .await + .into_db_result()? + .into_iter() + .map(|r| -> DatabaseResult<_> { + Ok(DeadChatMessage { + id: r.message_id, + timestamp: r.created_at, + message: serde_json::from_value(r.message).into_db_result()?, + }) + }) + .collect::, _>>()?) + } +} diff --git a/api/src/db/mod.rs b/api/src/db/mod.rs new file mode 100644 index 0000000..6f8eef9 --- /dev/null +++ b/api/src/db/mod.rs @@ -0,0 +1,60 @@ +pub mod game; +pub mod user; + +use futures::{future::BoxFuture, stream::BoxStream}; +use sqlx::{Executor, Pool, Postgres, Transaction}; + +use crate::{ + db::{game::GameDatabase, user::UserDatabase}, + error::DatabaseError, +}; + +pub(crate) type DatabaseResult = core::result::Result; + +trait IntoDatabaseResult { + fn into_db_result(self) -> DatabaseResult; +} + +impl IntoDatabaseResult for Result { + fn into_db_result(self) -> DatabaseResult { + self.map_err(Into::::into) + } +} + +impl IntoDatabaseResult for Result { + fn into_db_result(self) -> DatabaseResult { + self.map_err(Into::::into) + } +} + +#[derive(Debug, Clone)] +pub struct Database { + pool: Pool, +} + +impl Database { + pub const fn new(pool: Pool) -> Self { + Self { pool } + } + + pub fn user(&self) -> UserDatabase { + UserDatabase { + pool: self.pool.clone(), + } + } + + pub fn game(&self) -> GameDatabase { + GameDatabase { + pool: self.pool.clone(), + } + } + + pub async fn migrate(&self) { + log::info!("running migrations"); + sqlx::migrate!("../migrations") + .run(&self.pool) + .await + .expect("run migrations"); + log::info!("migrations done"); + } +} diff --git a/api/src/db/user.rs b/api/src/db/user.rs new file mode 100644 index 0000000..72a8685 --- /dev/null +++ b/api/src/db/user.rs @@ -0,0 +1,432 @@ +use argon2::{ + Argon2, PasswordHash, PasswordVerifier, + password_hash::{PasswordHasher, SaltString, rand_core::OsRng}, +}; +use chrono::{DateTime, TimeDelta, Utc}; + +use rand::distr::SampleString; +use serde::{Deserialize, Serialize}; +use sqlx::{Decode, Encode, Pool, Postgres, prelude::FromRow, query, query_as}; +use uuid::Uuid; + +use crate::{ + db::DatabaseResult, + error::{DatabaseError, ServerError}, + limited::FixedLenString, + token::{self, TOKEN_LEN}, + user::{Password, ProfileUpdate, Session, UserId}, +}; + +#[derive(Debug, Clone)] +pub struct UserDatabase { + pub(super) pool: Pool, +} + +#[derive(Debug, Clone, FromRow)] +pub struct LoginToken { + pub token: String, + pub user_id: UserId, + + pub created_at: DateTime, + pub expires_at: DateTime, +} + +impl LoginToken { + pub const TOKEN_LONGEVITY: TimeDelta = TimeDelta::days(30); + + pub fn new(user_id: UserId) -> Self { + let created_at = Utc::now(); + let expires_at = created_at + .checked_add_signed(Self::TOKEN_LONGEVITY) + .unwrap_or_else(|| { + panic!( + "could not add {} time to {created_at}", + Self::TOKEN_LONGEVITY + ) + }); + + let token = rand::distr::Alphanumeric.sample_string(&mut rand::rng(), token::TOKEN_LEN); + + Self { + token, + user_id, + created_at, + expires_at, + } + } +} + +pub enum GetUserBy<'a> { + Username(&'a str), + Id(UserId), +} + +impl UserDatabase { + pub const fn new(pool: Pool) -> Self { + Self { pool } + } + + pub async fn create_dummy_user( + &self, + display_name: &str, + pronouns: Option, + ) -> DatabaseResult { + let username = Uuid::new_v4().to_string(); + let id = Uuid::new_v4(); + let password_hash = String::new(); + let created_at = Utc::now(); + let updated_at = created_at; + query!( + r#" + insert into + users (id, username, display_name, pronouns, password_hash, + dummy, created_at, updated_at) + values + ($1, $2, $3, $4, $5, true, $6, $6) + "#, + id, + username, + display_name, + pronouns, + password_hash, + created_at + ) + .execute(&self.pool) + .await?; + Ok(User { + username, + pronouns, + created_at, + updated_at, + password_hash, + id: UserId::from_uuid(id), + display_name: Some(display_name.to_string()), + }) + } + + pub async fn create( + &self, + username: &str, + password: &str, + pronouns: Option, + ) -> DatabaseResult { + let salt = SaltString::generate(&mut OsRng); + let argon2 = Argon2::default(); + let password_hash = argon2 + .hash_password(password.as_bytes(), &salt)? + .to_string(); + + let now = chrono::offset::Utc::now(); + + let user = User { + pronouns, + id: UserId::new(), + username: username.into(), + password_hash, + display_name: None, + created_at: now, + updated_at: now, + }; + + query!( + r#"insert into users + (id, username, password_hash, pronouns, created_at, updated_at) + values + ($1, $2, $3, $4, $5, $6)"#, + user.id.into_uuid(), + user.username, + user.password_hash, + user.pronouns, + user.created_at, + user.updated_at + ) + .execute(&self.pool) + .await + .map_err(|err| { + if let sqlx::Error::Database(db_err) = &err + && let Some(constraint) = db_err.constraint() + && constraint == "users_username_unique" + { + DatabaseError::UserAlreadyExists + } else { + err.into() + } + })?; + + Ok(user) + } + + pub async fn delete_user(&self, user: User) -> DatabaseResult<()> { + query!( + r#" + delete from + users + where + id = $1 + "#, + user.id.into_uuid(), + ) + .execute(&self.pool) + .await?; + Ok(()) + } + + pub async fn update_profile( + &self, + user_id: UserId, + update: ProfileUpdate, + ) -> DatabaseResult<()> { + query!( + r#" + update + users + set + display_name = $2, + pronouns = $3 + where + id = $1 + "#, + user_id.into_uuid(), + update.display_name, + update.pronouns, + ) + .execute(&self.pool) + .await?; + Ok(()) + } + + pub async fn change_password(&self, user: User, password: Password) -> DatabaseResult { + let salt = SaltString::generate(&mut OsRng); + let argon2 = Argon2::default(); + let password_hash = argon2 + .hash_password(password.as_bytes(), &salt)? + .to_string(); + + let updated_at = chrono::Utc::now(); + query!( + r#" + update + users + set + password_hash = $1, + updated_at = $2 + where + id = $3 + "#, + password_hash, + updated_at, + user.id.into_uuid(), + ) + .execute(&self.pool) + .await?; + + Ok(User { + password_hash, + updated_at, + ..user + }) + } + + pub async fn get_session(&self, token: &str) -> DatabaseResult { + let rec = query!( + r#" + select + u.id, u.username, u.display_name, u.pronouns, + u.created_at, u.updated_at, t.token, + t.created_at as token_created_at, t.expires_at + from + users u + join + login_tokens t on t.user_id = u.id + where + t.token = $1 + limit 1 + "#, + token, + ) + .fetch_one(&self.pool) + .await?; + Ok(Session { + username: rec.username, + display_name: rec.display_name, + pronouns: rec.pronouns, + user_created_at: rec.created_at, + user_updated_at: rec.updated_at, + token_created_at: rec.token_created_at, + token_expires_at: rec.expires_at, + token: unsafe { FixedLenString::new_unchecked(rec.token) }, + }) + } + + pub async fn get_user(&self, get_user_by: GetUserBy<'_>) -> DatabaseResult { + Ok(match get_user_by { + GetUserBy::Username(username) => { + query_as!( + User, + r#" + select + id, username, password_hash, + display_name, pronouns, + created_at, updated_at + from + users + where + username = $1"#, + username + ) + .fetch_one(&self.pool) + .await? + } + GetUserBy::Id(id) => { + query_as!( + User, + r#" + select + id, username, password_hash, + display_name, pronouns, + created_at, updated_at + from + users + where + id = $1"#, + id.into_uuid() + ) + .fetch_one(&self.pool) + .await? + } + }) + } + + pub async fn verify_login(&self, username: &str, password: &str) -> Result { + let user = self.get_user(GetUserBy::Username(username)).await?; + + let parsed_hash = PasswordHash::new(&user.password_hash).map_err(DatabaseError::from)?; + Argon2::default() + .verify_password(password.as_bytes(), &parsed_hash) + .map_err(|err| match err { + argon2::password_hash::Error::Password => ServerError::InvalidCredentials, + err => { + let db_err: DatabaseError = err.into(); + db_err.into() + } + })?; + + Ok(user) + } + + pub async fn replace_token(&self, token: &str) -> Result { + let user = self.check_token(token).await?; + let mut tx = self.pool.begin().await.map_err(|err| { + log::error!("begin transaction: {err}"); + ServerError::InternalServerError + })?; + let new_token = LoginToken::new(user.id); + query!( + r#" insert into login_tokens + (token, user_id, created_at, expires_at) + values + ($1, $2, $3, $4)"#, + new_token.token, + new_token.user_id.into_uuid(), + new_token.created_at, + new_token.expires_at + ) + .execute(&mut *tx) + .await + .map_err(Into::::into)?; + query!( + r#" + delete from + login_tokens + where + token = $1 + "#, + token + ) + .execute(&mut *tx) + .await + .map_err(Into::::into)?; + + tx.commit().await.map_err(|err| { + log::error!("commit transaction: {err}"); + ServerError::InternalServerError + })?; + Ok(new_token) + } + + pub async fn login( + &self, + username: &str, + password: &str, + ) -> core::result::Result { + let user = self.verify_login(username, password).await?; + + let token = LoginToken::new(user.id); + + query!( + r#" insert into login_tokens + (token, user_id, created_at, expires_at) + values + ($1, $2, $3, $4)"#, + token.token, + token.user_id.into_uuid(), + token.created_at, + token.expires_at + ) + .execute(&self.pool) + .await + .map_err(Into::::into)?; + + Ok(Session { + username: user.username, + display_name: user.display_name, + pronouns: user.pronouns, + user_created_at: user.created_at, + user_updated_at: user.updated_at, + token_created_at: token.created_at, + token_expires_at: token.expires_at, + token: unsafe { FixedLenString::new_unchecked(token.token) }, + }) + } + + pub async fn check_token(&self, token: &str) -> core::result::Result { + let token: LoginToken = query_as!( + LoginToken, + r#" select + token, user_id, created_at, expires_at + from + login_tokens + where + token = $1 + and + expires_at > now() + "#, + token + ) + .fetch_one(&self.pool) + .await + .map_err(Into::::into) + .map_err(|err| match err { + DatabaseError::NotFound => ServerError::ExpiredToken, + _ => err.into(), + })?; + + if Utc::now() >= token.expires_at { + return Err(ServerError::ExpiredToken); + } + + Ok(self.get_user(GetUserBy::Id(token.user_id)).await?) + } +} + +#[derive(Debug, Clone, FromRow, Encode, Decode)] +pub struct User { + pub id: UserId, + pub username: String, + pub password_hash: String, + pub display_name: Option, + pub pronouns: Option, + + pub created_at: DateTime, + pub updated_at: DateTime, +} diff --git a/api/src/error.rs b/api/src/error.rs new file mode 100644 index 0000000..3c552cf --- /dev/null +++ b/api/src/error.rs @@ -0,0 +1,193 @@ +use leptos::prelude::{ServerFnError, ServerFnErrorErr}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; +use werewolves_proto::error::GameError; + +use crate::game::GameId; + +#[derive(Debug, Clone, PartialEq, Error, Serialize, Deserialize)] +pub enum ServerError { + #[error("internal server error")] + InternalServerError, + #[error("not found")] + NotFound, + #[error("user already exists")] + UserAlreadyExists, + #[error("invalid credentials")] + InvalidCredentials, + #[error("token expired")] + ExpiredToken, + #[error("connection error")] + ConnectionError, + #[error("invalid request: {0}")] + InvalidRequest(String), + #[error("you're already in an active game: {0}")] + AlreadyInActiveGame(GameId), + #[error("{0}")] + GameError(#[from] GameError), +} + +impl leptos::prelude::FromServerFnError for ServerError { + type Encoder = leptos::server_fn::codec::JsonEncoding; + + fn from_server_fn_error(value: ServerFnErrorErr) -> Self { + match value { + ServerFnErrorErr::ServerError(err) => { + log::error!("server error: {err}; truncating to ServerError::InternalServerError"); + ServerError::InternalServerError + } + ServerFnErrorErr::MiddlewareError(err) => { + log::error!( + "middleware error: {err}; truncating to ServerError::InternalServerError" + ); + ServerError::InternalServerError + } + ServerFnErrorErr::Request(err) => { + const CONN_ERR: &str = "TypeError: NetworkError when attempting to fetch resource."; + if err == CONN_ERR { + Self::ConnectionError + } else { + Self::InvalidRequest(err) + } + } + err => { + let t = match &err { + ServerFnErrorErr::Registration(_) => "Registration", + ServerFnErrorErr::UnsupportedRequestMethod(_) => "UnsupportedRequestMethod", + ServerFnErrorErr::Request(_) => "Request", + ServerFnErrorErr::ServerError(_) => "ServerError", + ServerFnErrorErr::MiddlewareError(_) => "MiddlewareError", + ServerFnErrorErr::Deserialization(_) => "Deserialization", + ServerFnErrorErr::Serialization(_) => "Serialization", + ServerFnErrorErr::Args(_) => "Args", + ServerFnErrorErr::MissingArg(_) => "MissingArg", + ServerFnErrorErr::Response(_) => "Response", + }; + Self::InvalidRequest(format!("[{t}]: {err}")) + } + } + } +} + +// impl core::str::FromStr for ServerError { +// type Err = core::convert::Infallible; + +// fn from_str(s: &str) -> Result { +// panic!("ServerError::FromStr({s})") +// } +// } +// impl From for ServerError { +// fn from(err: ServerFnError) -> Self { +// match err { +// ServerFnError::ServerError(err) => { +// log::error!("server error: {err}; truncating to ServerError::InternalServerError"); +// ServerError::InternalServerError +// } +// ServerFnError::MiddlewareError(err) => { +// log::error!( +// "middleware error: {err}; truncating to ServerError::InternalServerError" +// ); +// ServerError::InternalServerError +// } +// ServerFnError::Request(err) => { +// log::error!("[{err}]"); +// Self::ConnectionError +// } +// err => { +// let t = match &err { +// ServerFnError::Registration(_) => "Registration", +// ServerFnError::Request(_) => "Request", +// ServerFnError::ServerError(_) => "ServerError", +// ServerFnError::MiddlewareError(_) => "MiddlewareError", +// ServerFnError::Deserialization(_) => "Deserialization", +// ServerFnError::Serialization(_) => "Serialization", +// ServerFnError::Args(_) => "Args", +// ServerFnError::MissingArg(_) => "MissingArg", +// ServerFnError::Response(_) => "Response", +// ServerFnError::WrappedServerError(_) => "WrappedServerError", +// }; +// Self::InvalidRequest(format!("[{t}]: {err}")) +// } +// } +// } +// } + +impl From for ServerError { + fn from(err: DatabaseError) -> Self { + match err { + DatabaseError::NotFound => ServerError::NotFound, + DatabaseError::UserAlreadyExists => ServerError::UserAlreadyExists, + #[allow(unreachable_patterns)] + _ => { + log::error!( + "converting database error into ServerError::InternalServerError: {err}" + ); + ServerError::InternalServerError + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Error)] +pub enum DatabaseError { + #[error("user already exists")] + UserAlreadyExists, + #[error("password hashing error: {0}")] + PasswordHashError(String), + #[error("sqlx error: {0}")] + SqlxError(String), + #[error("not found")] + NotFound, + #[error("(de)serialization error: {0}")] + Serialization(String), +} + +#[cfg(feature = "ssr")] +impl From for DatabaseError { + fn from(value: serde_json::Error) -> Self { + Self::Serialization(value.to_string()) + } +} + +#[cfg(feature = "ssr")] +impl axum::response::IntoResponse for ServerError { + fn into_response(self) -> axum::response::Response { + use axum::{Json, http::StatusCode}; + + use crate::cbor::Cbor; + + ( + match self { + ServerError::AlreadyInActiveGame(_) + | ServerError::GameError(_) + | ServerError::InvalidCredentials + | ServerError::InvalidRequest(_) + | ServerError::UserAlreadyExists => StatusCode::BAD_REQUEST, + ServerError::NotFound => StatusCode::NOT_FOUND, + ServerError::ConnectionError | ServerError::InternalServerError => { + StatusCode::INTERNAL_SERVER_ERROR + } + ServerError::ExpiredToken => StatusCode::UNAUTHORIZED, + }, + Json(self), + ) + .into_response() + } +} + +#[cfg(feature = "ssr")] +impl From for DatabaseError { + fn from(err: sqlx::Error) -> Self { + match err { + sqlx::Error::RowNotFound => Self::NotFound, + _ => Self::SqlxError(err.to_string()), + } + } +} + +#[cfg(feature = "ssr")] +impl From for DatabaseError { + fn from(err: argon2::password_hash::Error) -> Self { + Self::PasswordHashError(err.to_string()) + } +} diff --git a/api/src/game.rs b/api/src/game.rs new file mode 100644 index 0000000..c122c88 --- /dev/null +++ b/api/src/game.rs @@ -0,0 +1,24 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use werewolves_proto::game::{Game, GameSettings, story::GameStory}; + +use crate::{id_impl, user::UserId}; + +id_impl!(GameId); + +#[cfg_attr(feature = "ssr", derive(::sqlx::FromRow))] +#[derive(Debug)] +pub struct GameRecord { + pub id: GameId, + pub host: UserId, + pub created_at: DateTime, + pub game_state: GameRecordState, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum GameRecordState { + Lobby(GameSettings), + RoleReveal(Game), + Started(Game), + GameOver(GameStory), +} diff --git a/api/src/identity.rs b/api/src/identity.rs new file mode 100644 index 0000000..1964e13 --- /dev/null +++ b/api/src/identity.rs @@ -0,0 +1,9 @@ +use serde::{Deserialize, Serialize}; +use werewolves_proto::{character::CharacterId, message::PublicIdentity, player::PlayerId}; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct PlayerIdentity { + pub player_id: PlayerId, + pub character_id: CharacterId, + pub public: PublicIdentity, +} diff --git a/api/src/lib.rs b/api/src/lib.rs new file mode 100644 index 0000000..377fa95 --- /dev/null +++ b/api/src/lib.rs @@ -0,0 +1,111 @@ +#[cfg(feature = "ssr")] +pub mod cbor; +pub mod cbor_leptos; +#[cfg(feature = "ssr")] +pub mod db; +pub mod error; +pub mod limited; +// pub mod routes; +pub mod game; +#[cfg(feature = "ssr")] +pub mod identity; +pub mod message; +#[cfg(feature = "ssr")] +pub mod state; +pub mod token; +pub mod user; + +pub type ServerResult = core::result::Result; + +#[macro_export] +macro_rules! id_impl { + ($name:ident) => { + #[derive( + Debug, Clone, Copy, PartialEq, Eq, Hash, ::serde::Serialize, ::serde::Deserialize, + )] + pub struct $name(uuid::Uuid); + + #[cfg(feature = "ssr")] + impl sqlx::TypeInfo for $name { + fn is_null(&self) -> bool { + self.0 == uuid::Uuid::nil() + } + + fn name(&self) -> &str { + "uuid" + } + } + + #[cfg(feature = "ssr")] + impl sqlx::Type for $name { + fn type_info() -> ::TypeInfo { + >::type_info() + } + } + + #[cfg(feature = "ssr")] + impl<'q> sqlx::Encode<'q, sqlx::Postgres> for $name { + fn encode_by_ref( + &self, + buf: &mut ::ArgumentBuffer<'q>, + ) -> Result { + self.0.encode_by_ref(buf) + } + } + + #[cfg(feature = "ssr")] + impl<'r> sqlx::Decode<'r, sqlx::Postgres> for $name { + fn decode( + value: ::ValueRef<'r>, + ) -> Result { + Ok(Self(uuid::Uuid::decode(value)?)) + } + } + + impl From for $name { + fn from(value: uuid::Uuid) -> Self { + Self::from_uuid(value) + } + } + + impl From<$name> for uuid::Uuid { + fn from(value: $name) -> Self { + value.into_uuid() + } + } + + impl Default for $name { + fn default() -> Self { + Self::new() + } + } + + impl $name { + pub fn new() -> Self { + Self(uuid::Uuid::new_v4()) + } + + pub const fn from_uuid(uuid: uuid::Uuid) -> Self { + Self(uuid) + } + + pub const fn into_uuid(self) -> uuid::Uuid { + self.0 + } + } + + impl core::fmt::Display for $name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } + } + + impl core::str::FromStr for $name { + type Err = uuid::Error; + + fn from_str(s: &str) -> Result { + Ok(Self(uuid::Uuid::from_str(s)?)) + } + } + }; +} diff --git a/api/src/limited.rs b/api/src/limited.rs new file mode 100644 index 0000000..5c0ceab --- /dev/null +++ b/api/src/limited.rs @@ -0,0 +1,139 @@ +use core::{ + fmt::Display, + ops::{Deref, RangeInclusive}, +}; + +use serde::{Deserialize, Deserializer, Serialize}; + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct FixedLenString(String); + +impl Display for FixedLenString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl FixedLenString { + pub fn new(s: String) -> Option { + (s.chars().take(LEN + 1).count() == LEN).then_some(Self(s)) + } + pub unsafe fn new_unchecked(s: String) -> Self { + Self(s) + } +} + +impl Deref for FixedLenString { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'de, const LEN: usize> Deserialize<'de> for FixedLenString { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ExpectedLen(usize); + impl serde::de::Expected for ExpectedLen { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "a string exactly {} characters long", self.0) + } + } + ::deserialize(deserializer).and_then(|s| { + let char_count = s.chars().take(LEN.saturating_add(1)).count(); + if char_count != LEN { + Err(serde::de::Error::invalid_length( + char_count, + &ExpectedLen(LEN), + )) + } else { + Ok(Self(s)) + } + }) + } +} + +impl Serialize for FixedLenString { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.0.as_str()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ClampedString(String); + +impl ClampedString { + pub const MIN_LEN: usize = MIN; + pub const MAX_LEN: usize = MAX; + + pub fn new(s: String) -> Result> { + let str_len = s.chars().take(MAX.saturating_add(1)).count(); + (str_len >= MIN && str_len <= MAX) + .then_some(Self(s)) + .ok_or(MIN..=MAX) + } + + pub unsafe fn new_unchecked(s: String) -> Self { + Self(s) + } + + pub fn into_inner(self) -> String { + self.0 + } +} + +impl Display for ClampedString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl Deref for ClampedString { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'de, const MIN: usize, const MAX: usize> Deserialize<'de> for ClampedString { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ExpectedLen(usize, usize); + impl serde::de::Expected for ExpectedLen { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "a string between {} and {} characters long", + self.0, self.1 + ) + } + } + ::deserialize(deserializer).and_then(|s| { + let char_count = s.chars().take(MAX.saturating_add(1)).count(); + if char_count < MIN || char_count > MAX { + Err(serde::de::Error::invalid_length( + char_count, + &ExpectedLen(MIN, MAX), + )) + } else { + Ok(Self(s)) + } + }) + } +} + +impl Serialize for ClampedString { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.0.as_str()) + } +} diff --git a/api/src/message.rs b/api/src/message.rs new file mode 100644 index 0000000..390a57e --- /dev/null +++ b/api/src/message.rs @@ -0,0 +1,38 @@ +use serde::{Deserialize, Serialize}; +use werewolves_proto::message::{ + ClientMessage, ServerToClientMessage, + host::{HostMessage, ServerToHostMessage}, +}; + +use crate::token::TokenString; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum WrappedServerMessage { + Authentication(TokenString), + HostMessage(HostMessage), + ClientMessage(ClientMessage), +} + +impl From for WrappedServerMessage { + fn from(value: TokenString) -> Self { + Self::Authentication(value) + } +} + +impl From for WrappedServerMessage { + fn from(value: HostMessage) -> Self { + Self::HostMessage(value) + } +} + +impl From for WrappedServerMessage { + fn from(value: ClientMessage) -> Self { + Self::ClientMessage(value) + } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum IntoClientResponse { + Player(ServerToClientMessage), + Host(ServerToHostMessage), +} diff --git a/api/src/routes.rs b/api/src/routes.rs new file mode 100644 index 0000000..be75722 --- /dev/null +++ b/api/src/routes.rs @@ -0,0 +1,36 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Method { + Options, + Get, + Post, + Put, + Delete, + Head, + Trace, + Connect, + Patch, +} + +pub struct Route { + pub method: Method, + pub path: &'static str, + pub authenticated: bool, +} + +impl Route { + const fn new(method: Method, path: &'static str, authenticated: bool) -> Self { + Self { + method, + path, + authenticated, + } + } +} + +pub struct Routes { + pub create_user: Route, +} + +pub const ROUTES: Routes = Routes { + create_user: Route::new(Method::Post, "/api/users", false), +}; diff --git a/api/src/state.rs b/api/src/state.rs new file mode 100644 index 0000000..1fca358 --- /dev/null +++ b/api/src/state.rs @@ -0,0 +1,13 @@ +use std::{collections::HashMap, sync::Arc}; + +use futures::lock::Mutex; +use leptos::config::LeptosOptions; + +use crate::{db::Database, game::GameId}; + +#[cfg_attr(feature = "ssr", derive(axum::extract::FromRef))] +#[derive(Debug, Clone)] +pub struct AppState { + pub db: Database, + pub leptos_options: LeptosOptions, +} diff --git a/api/src/token.rs b/api/src/token.rs new file mode 100644 index 0000000..836532a --- /dev/null +++ b/api/src/token.rs @@ -0,0 +1,43 @@ +use crate::{limited::FixedLenString, user::Username}; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +pub const TOKEN_LEN: usize = 0x20; + +pub type TokenString = FixedLenString; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Token { + pub token: TokenString, + pub username: Username, + pub display_name: Option, + pub pronouns: Option, + pub created_at: DateTime, + pub expires_at: DateTime, +} + +impl Token { + pub fn login_token(&self) -> TokenLogin { + TokenLogin(self.token.clone()) + } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct TokenLogin(pub FixedLenString); + +#[cfg(feature = "ssr")] +impl axum_extra::headers::authorization::Credentials for TokenLogin { + const SCHEME: &'static str = "Bearer"; + + fn decode(value: &axum::http::HeaderValue) -> Option { + value + .to_str() + .ok() + .and_then(|v| FixedLenString::new(v.strip_prefix("Bearer ").unwrap_or(v).to_string())) + .map(Self) + } + + fn encode(&self) -> axum::http::HeaderValue { + axum::http::HeaderValue::from_str(self.0.as_str()).expect("bearer token encode") + } +} diff --git a/api/src/user.rs b/api/src/user.rs new file mode 100644 index 0000000..317cb1a --- /dev/null +++ b/api/src/user.rs @@ -0,0 +1,57 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use werewolves_proto::player::PlayerId; + +use crate::{limited::ClampedString, token::TokenString}; + +pub type Username = ClampedString<1, 0x40>; +pub type Password = ClampedString<6, 0x100>; + +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct UserLogin { + pub username: Username, + pub password: Password, +} +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct ChangePassword { + pub current: Password, + pub new: Password, +} + +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct DeleteUserRequest { + pub password: Password, +} + +#[cfg_attr(feature = "ssr", derive(::sqlx::FromRow))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Session { + pub username: String, + pub display_name: Option, + pub pronouns: Option, + + pub user_created_at: DateTime, + pub user_updated_at: DateTime, + pub token_created_at: DateTime, + pub token_expires_at: DateTime, + pub token: TokenString, +} +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ProfileUpdate { + pub display_name: Option, + pub pronouns: Option, +} + +crate::id_impl!(UserId); + +impl From for UserId { + fn from(value: PlayerId) -> Self { + UserId(value.into()) + } +} + +impl From for PlayerId { + fn from(value: UserId) -> Self { + PlayerId::from_uuid(value.0) + } +} diff --git a/migrations/1_init.sql b/migrations/1_init.sql new file mode 100644 index 0000000..1498417 --- /dev/null +++ b/migrations/1_init.sql @@ -0,0 +1,70 @@ +drop table if exists users cascade; +create table users ( + id uuid not null default gen_random_uuid() primary key, + username text not null, + display_name text, + pronouns text, + password_hash text not null, + dummy boolean not null default false, + + created_at timestamp with time zone not null, + updated_at timestamp with time zone not null, + + check (created_at <= updated_at) +); +drop index if exists users_username_idx; +create index users_username_idx on users (username); +drop index if exists users_username_unique; +create unique index users_username_unique on users (lower(username)); + +drop table if exists login_tokens cascade; +create table login_tokens ( + token text not null primary key, + user_id uuid not null references users(id) on delete cascade, + created_at timestamp with time zone not null, + expires_at timestamp with time zone not null, + + check (created_at < expires_at) +); + + +drop type if exists game_status cascade; +create type game_status as enum ( + 'Lobby', + 'RoleReveal', + 'Started', + 'GameOver', + 'Cancelled' +); + +drop table if exists games cascade; +create table games ( + id uuid not null primary key, + host uuid not null references users(id) on delete cascade, + created_at timestamp with time zone not null default now(), + game_state jsonb not null, + game_status game_status not null default 'Lobby' +); + +drop table if exists game_characters cascade; +create table game_characters ( + character_id uuid not null primary key, + game_id uuid not null references games(id) on delete cascade, + player_id uuid not null references users(id) on delete cascade, + number integer +); + +drop index if exists game_characters_player_id_game_id_unique; +create unique index game_characters_player_id_game_id_unique on game_characters (player_id, game_id); + + +drop table if exists dead_chat cascade; +create table dead_chat ( + message_id uuid not null primary key, + game_id uuid not null references games(id) on delete cascade, + created_at timestamp with time zone not null, + message jsonb not null +); + +drop index if exists dead_chat_created_at; +create index dead_chat_created_at on dead_chat(created_at); diff --git a/werewolves/img/wolf.svg b/public/favicon.svg similarity index 100% rename from werewolves/img/wolf.svg rename to public/favicon.svg diff --git a/werewolves/img/adjudicator.svg b/public/img/adjudicator.svg similarity index 100% rename from werewolves/img/adjudicator.svg rename to public/img/adjudicator.svg diff --git a/werewolves/img/apprentice.svg b/public/img/apprentice.svg similarity index 100% rename from werewolves/img/apprentice.svg rename to public/img/apprentice.svg diff --git a/werewolves/img/arcanist.svg b/public/img/arcanist.svg similarity index 100% rename from werewolves/img/arcanist.svg rename to public/img/arcanist.svg diff --git a/werewolves/img/beholder.svg b/public/img/beholder.svg similarity index 100% rename from werewolves/img/beholder.svg rename to public/img/beholder.svg diff --git a/werewolves/img/black-knight.svg b/public/img/black-knight.svg similarity index 100% rename from werewolves/img/black-knight.svg rename to public/img/black-knight.svg diff --git a/werewolves/img/bloodlet.svg b/public/img/bloodlet.svg similarity index 100% rename from werewolves/img/bloodlet.svg rename to public/img/bloodlet.svg diff --git a/werewolves/img/damned.svg b/public/img/damned.svg similarity index 100% rename from werewolves/img/damned.svg rename to public/img/damned.svg diff --git a/werewolves/img/diseased.svg b/public/img/diseased.svg similarity index 100% rename from werewolves/img/diseased.svg rename to public/img/diseased.svg diff --git a/werewolves/img/drunk.svg b/public/img/drunk.svg similarity index 100% rename from werewolves/img/drunk.svg rename to public/img/drunk.svg diff --git a/werewolves/img/elder.svg b/public/img/elder.svg similarity index 100% rename from werewolves/img/elder.svg rename to public/img/elder.svg diff --git a/werewolves/img/equal.svg b/public/img/equal.svg similarity index 100% rename from werewolves/img/equal.svg rename to public/img/equal.svg diff --git a/werewolves/img/gravedigger.svg b/public/img/gravedigger.svg similarity index 100% rename from werewolves/img/gravedigger.svg rename to public/img/gravedigger.svg diff --git a/werewolves/img/heart.svg b/public/img/heart.svg similarity index 100% rename from werewolves/img/heart.svg rename to public/img/heart.svg diff --git a/werewolves/img/hunter.svg b/public/img/hunter.svg similarity index 100% rename from werewolves/img/hunter.svg rename to public/img/hunter.svg diff --git a/public/img/icons.svg b/public/img/icons.svg new file mode 100644 index 0000000..4a7f13e --- /dev/null +++ b/public/img/icons.svg @@ -0,0 +1,5293 @@ + + + + diff --git a/werewolves/img/insane.svg b/public/img/insane.svg similarity index 100% rename from werewolves/img/insane.svg rename to public/img/insane.svg diff --git a/werewolves/img/insomniac.svg b/public/img/insomniac.svg similarity index 100% rename from werewolves/img/insomniac.svg rename to public/img/insomniac.svg diff --git a/werewolves/img/killer.svg b/public/img/killer.svg similarity index 100% rename from werewolves/img/killer.svg rename to public/img/killer.svg diff --git a/werewolves/img/li.svg b/public/img/li.svg similarity index 100% rename from werewolves/img/li.svg rename to public/img/li.svg diff --git a/werewolves/img/lone-wolf.svg b/public/img/lone-wolf.svg similarity index 100% rename from werewolves/img/lone-wolf.svg rename to public/img/lone-wolf.svg diff --git a/werewolves/img/maple-wolf.svg b/public/img/maple-wolf.svg similarity index 100% rename from werewolves/img/maple-wolf.svg rename to public/img/maple-wolf.svg diff --git a/werewolves/img/mason.svg b/public/img/mason.svg similarity index 100% rename from werewolves/img/mason.svg rename to public/img/mason.svg diff --git a/werewolves/img/moon.svg b/public/img/moon.svg similarity index 100% rename from werewolves/img/moon.svg rename to public/img/moon.svg diff --git a/werewolves/img/mortician.svg b/public/img/mortician.svg similarity index 100% rename from werewolves/img/mortician.svg rename to public/img/mortician.svg diff --git a/werewolves/img/not-equal.svg b/public/img/not-equal.svg similarity index 100% rename from werewolves/img/not-equal.svg rename to public/img/not-equal.svg diff --git a/werewolves/img/power-seer.svg b/public/img/power-seer.svg similarity index 100% rename from werewolves/img/power-seer.svg rename to public/img/power-seer.svg diff --git a/werewolves/img/powerful.svg b/public/img/powerful.svg similarity index 100% rename from werewolves/img/powerful.svg rename to public/img/powerful.svg diff --git a/werewolves/img/pyremaster.svg b/public/img/pyremaster.svg similarity index 100% rename from werewolves/img/pyremaster.svg rename to public/img/pyremaster.svg diff --git a/werewolves/img/red-x.svg b/public/img/red-x.svg similarity index 100% rename from werewolves/img/red-x.svg rename to public/img/red-x.svg diff --git a/werewolves/img/roleblock.svg b/public/img/roleblock.svg similarity index 100% rename from werewolves/img/roleblock.svg rename to public/img/roleblock.svg diff --git a/werewolves/img/scapegoat.svg b/public/img/scapegoat.svg similarity index 100% rename from werewolves/img/scapegoat.svg rename to public/img/scapegoat.svg diff --git a/werewolves/img/seer.svg b/public/img/seer.svg similarity index 100% rename from werewolves/img/seer.svg rename to public/img/seer.svg diff --git a/werewolves/img/shapeshifter.svg b/public/img/shapeshifter.svg similarity index 100% rename from werewolves/img/shapeshifter.svg rename to public/img/shapeshifter.svg diff --git a/werewolves/img/shield-and-sword.svg b/public/img/shield-and-sword.svg similarity index 100% rename from werewolves/img/shield-and-sword.svg rename to public/img/shield-and-sword.svg diff --git a/werewolves/img/shield.svg b/public/img/shield.svg similarity index 100% rename from werewolves/img/shield.svg rename to public/img/shield.svg diff --git a/werewolves/img/skull.svg b/public/img/skull.svg similarity index 100% rename from werewolves/img/skull.svg rename to public/img/skull.svg diff --git a/werewolves/img/sword.svg b/public/img/sword.svg similarity index 100% rename from werewolves/img/sword.svg rename to public/img/sword.svg diff --git a/werewolves/img/village.svg b/public/img/village.svg similarity index 100% rename from werewolves/img/village.svg rename to public/img/village.svg diff --git a/werewolves/img/vindicator.svg b/public/img/vindicator.svg similarity index 100% rename from werewolves/img/vindicator.svg rename to public/img/vindicator.svg diff --git a/werewolves/img/weightlifter.svg b/public/img/weightlifter.svg similarity index 100% rename from werewolves/img/weightlifter.svg rename to public/img/weightlifter.svg diff --git a/public/img/wolf.svg b/public/img/wolf.svg new file mode 100644 index 0000000..47c2547 --- /dev/null +++ b/public/img/wolf.svg @@ -0,0 +1,220 @@ + + + + diff --git a/style/faction.scss b/style/faction.scss new file mode 100644 index 0000000..f6889ac --- /dev/null +++ b/style/faction.scss @@ -0,0 +1,409 @@ + +.village { + --faction-color: $village_color; + --faction-border: $village_border; + --faction-color-faint: $village_color_faint; + --faction-border-faint: $village_border_faint; + + &.box { + background-color: $village_color; + border: 1px solid $village_border; + + .selected:not(.faint) { + color: white; + background-color: $village_border; + } + .selected.faint { + color: white; + background-color: $village_border_faint; + } + + &.hover:not(.selected):hover { + color: white; + background-color: $village_border; + } + + &.faint:not(.selected) { + border: 1px solid $village_border_faint; + background-color: $village_color_faint; + + &.hover:hover { + background-color: $village_border_faint; + } + } + } + + &.underline { + text-decoration: $village_color underline; + + &.faint { + text-decoration: $village_color_faint underline; + } + } + + &.text-color { + color: $village_border; + + &.faint { + color: $village_border_faint; + } + } +} + +.wolves { + --faction-color: $wolves_color; + --faction-border: $wolves_border; + --faction-color-faint: $wolves_color_faint; + --faction-border-faint: $wolves_border_faint; + + &.box { + background-color: $wolves_color; + border: 1px solid $wolves_border; + + .selected:not(.faint) { + color: white; + background-color: $wolves_border; + } + .selected.faint { + color: white; + background-color: $wolves_border_faint; + } + + &.hover:not(.selected):hover { + color: white; + background-color: $wolves_border; + } + + &.faint:not(.selected) { + border: 1px solid $wolves_border_faint; + background-color: $wolves_color_faint; + + &.hover:hover { + background-color: $wolves_border_faint; + } + } + } + + &.underline { + text-decoration: $wolves_color underline; + + &.faint { + text-decoration: $wolves_color_faint underline; + } + } + + &.text-color { + color: $wolves_border; + + &.faint { + color: $wolves_border_faint; + } + } +} + +.offensive { + --faction-color: $offensive_color; + --faction-border: $offensive_border; + --faction-color-faint: $offensive_color_faint; + --faction-border-faint: $offensive_border_faint; + + &.box { + background-color: $offensive_color; + border: 1px solid $offensive_border; + + .selected:not(.faint) { + color: white; + background-color: $offensive_border; + } + .selected.faint { + color: white; + background-color: $offensive_border_faint; + } + + &.hover:not(.selected):hover { + color: white; + background-color: $offensive_border; + } + + &.faint:not(.selected) { + border: 1px solid $offensive_border_faint; + background-color: $offensive_color_faint; + + &.hover:hover { + background-color: $offensive_border_faint; + } + } + } + + &.underline { + text-decoration: $offensive_color underline; + + &.faint { + text-decoration: $offensive_color_faint underline; + } + } + + &.text-color { + color: $offensive_border; + + &.faint { + color: $offensive_border_faint; + } + } +} + +.defensive { + --faction-color: $defensive_color; + --faction-border: $defensive_border; + --faction-color-faint: $defensive_color_faint; + --faction-border-faint: $defensive_border_faint; + + &.box { + background-color: $defensive_color; + border: 1px solid $defensive_border; + + .selected:not(.faint) { + color: white; + background-color: $defensive_border; + } + .selected.faint { + color: white; + background-color: $defensive_border_faint; + } + + &.hover:not(.selected):hover { + color: white; + background-color: $defensive_border; + } + + &.faint:not(.selected) { + border: 1px solid $defensive_border_faint; + background-color: $defensive_color_faint; + + &.hover:hover { + background-color: $defensive_border_faint; + } + } + } + + &.underline { + text-decoration: $defensive_color underline; + + &.faint { + text-decoration: $defensive_color_faint underline; + } + } + + &.text-color { + color: $defensive_border; + + &.faint { + color: $defensive_border_faint; + } + } +} + +.intel { + --faction-color: $intel_color; + --faction-border: $intel_border; + --faction-color-faint: $intel_color_faint; + --faction-border-faint: $intel_border_faint; + + &.box { + background-color: $intel_color; + border: 1px solid $intel_border; + + .selected:not(.faint) { + color: white; + background-color: $intel_border; + } + .selected.faint { + color: white; + background-color: $intel_border_faint; + } + + &.hover:not(.selected):hover { + color: white; + background-color: $intel_border; + } + + &.faint:not(.selected) { + border: 1px solid $intel_border_faint; + background-color: $intel_color_faint; + + &.hover:hover { + background-color: $intel_border_faint; + } + } + } + + &.underline { + text-decoration: $intel_color underline; + + &.faint { + text-decoration: $intel_color_faint underline; + } + } + + &.text-color { + color: $intel_border; + + &.faint { + color: $intel_border_faint; + } + } +} + +.starts-as-villager { + --faction-color: $starts_as_villager_color; + --faction-border: $starts_as_villager_border; + --faction-color-faint: $starts_as_villager_color_faint; + --faction-border-faint: $starts_as_villager_border_faint; + + &.box { + background-color: $starts_as_villager_color; + border: 1px solid $starts_as_villager_border; + + .selected:not(.faint) { + color: white; + background-color: $starts_as_villager_border; + } + .selected.faint { + color: white; + background-color: $starts_as_villager_border_faint; + } + + &.hover:not(.selected):hover { + color: white; + background-color: $starts_as_villager_border; + } + + &.faint:not(.selected) { + border: 1px solid $starts_as_villager_border_faint; + background-color: $starts_as_villager_color_faint; + + &.hover:hover { + background-color: $starts_as_villager_border_faint; + } + } + } + + &.underline { + text-decoration: $starts_as_villager_color underline; + + &.faint { + text-decoration: $starts_as_villager_color_faint underline; + } + } + + &.text-color { + color: $starts_as_villager_border; + + &.faint { + color: $starts_as_villager_border_faint; + } + } +} + +.damned { + --faction-color: $damned_color; + --faction-border: $damned_border; + --faction-color-faint: $damned_color_faint; + --faction-border-faint: $damned_border_faint; + + &.box { + background-color: $damned_color; + border: 1px solid $damned_border; + + .selected:not(.faint) { + color: white; + background-color: $damned_border; + } + .selected.faint { + color: white; + background-color: $damned_border_faint; + } + + &.hover:not(.selected):hover { + color: white; + background-color: $damned_border; + } + + &.faint:not(.selected) { + border: 1px solid $damned_border_faint; + background-color: $damned_color_faint; + + &.hover:hover { + background-color: $damned_border_faint; + } + } + } + + &.underline { + text-decoration: $damned_color underline; + + &.faint { + text-decoration: $damned_color_faint underline; + } + } + + &.text-color { + color: $damned_border; + + &.faint { + color: $damned_border_faint; + } + } +} + +.drunk { + --faction-color: $drunk_color; + --faction-border: $drunk_border; + --faction-color-faint: $drunk_color_faint; + --faction-border-faint: $drunk_border_faint; + + &.box { + background-color: $drunk_color; + border: 1px solid $drunk_border; + + .selected:not(.faint) { + color: white; + background-color: $drunk_border; + } + .selected.faint { + color: white; + background-color: $drunk_border_faint; + } + + &.hover:not(.selected):hover { + color: white; + background-color: $drunk_border; + } + + &.faint:not(.selected) { + border: 1px solid $drunk_border_faint; + background-color: $drunk_color_faint; + + &.hover:hover { + background-color: $drunk_border_faint; + } + } + } + + &.underline { + text-decoration: $drunk_color underline; + + &.faint { + text-decoration: $drunk_color_faint underline; + } + } + + &.text-color { + color: $drunk_border; + + &.faint { + color: $drunk_border_faint; + } + } +} + \ No newline at end of file diff --git a/style/main.scss b/style/main.scss new file mode 100644 index 0000000..4c5b6e7 --- /dev/null +++ b/style/main.scss @@ -0,0 +1,665 @@ +@use 'sass:color'; + +$host_nav_height: 36px; +$host_nav_top_pad: 10px; +$host_nav_bottom_pad: 10px; +$host_nav_total_height: $host_nav_height + $host_nav_top_pad + $host_nav_bottom_pad; + +$wolves_color: rgba(255, 0, 0, 0.7); +$village_color: rgba(0, 0, 255, 0.7); +$village_border: color.change($village_color, $alpha: 1.0); +$wolves_border: color.change($wolves_color, $alpha: 1.0); +$intel_color: color.adjust($village_color, $hue: -30deg); +$intel_border: color.change($intel_color, $alpha: 1.0); +$defensive_color: color.adjust($village_color, $hue: -60deg); +$defensive_border: color.change($defensive_color, $alpha: 1.0); +$offensive_color: color.adjust($village_color, $hue: 30deg); +$offensive_border: color.change($offensive_color, $alpha: 1.0); +$starts_as_villager_color: color.adjust($village_color, $hue: 60deg); +$starts_as_villager_border: color.change($starts_as_villager_color, $alpha: 1.0); +$damned_color: color.adjust($village_color, $hue: 45deg); +$damned_border: color.change($damned_color, $alpha: 1.0); +$drunk_color: color.adjust($village_color, $hue: 150deg); +$drunk_border: color.change($drunk_color, $alpha: 1.0); + +$wolves_border_faint: color.change($wolves_border, $alpha: 0.3); +$village_border_faint: color.change($village_border, $alpha: 0.3); +$offensive_border_faint: color.change($offensive_border, $alpha: 0.3); +$defensive_border_faint: color.change($defensive_border, $alpha: 0.3); +$intel_border_faint: color.change($intel_border, $alpha: 0.3); +$starts_as_villager_border_faint: color.change($starts_as_villager_border, $alpha: 0.3); +$damned_border_faint: color.change($damned_border, $alpha: 0.3); +$drunk_border_faint: color.change($drunk_border, $alpha: 0.3); + +$wolves_color_faint: color.change($wolves_color, $alpha: 0.1); +$village_color_faint: color.change($village_color, $alpha: 0.1); +$offensive_color_faint: color.change($offensive_color, $alpha: 0.1); +$defensive_color_faint: color.change($defensive_color, $alpha: 0.1); +$intel_color_faint: color.change($intel_color, $alpha: 0.1); +$starts_as_villager_color_faint: color.change($starts_as_villager_color, $alpha: 0.1); +$damned_color_faint: color.change($damned_color, $alpha: 0.1); +$drunk_color_faint: color.change($drunk_color, $alpha: 0.1); + +@import 'faction'; + +@mixin flexbox() { + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +body { + font-family: sans-serif; + text-align: center; + background-color: black; + color: white; +} + +.error_container { + position: fixed; + top: 3vh; + left: 37vw; + width: 60vw; + height: 94vh; + display: flex; + justify-content: center; + + h5, + p { + margin: 0; + } + + .error { + position: fixed; + display: flex; + flex-direction: column; + flex-wrap: nowrap; + gap: 1ch; + width: fit-content; + padding: 1ch; + + border: 1px solid red; + background-color: rgba(128, 0, 0, 1); + } +} + +input, +select { + border: 1px solid rgba(255, 255, 255, 0.7); + background-color: rgba(255, 255, 255, 0.07); + color: white; + font-size: 1em; + + &:focus { + outline: 1px solid white; + background-color: white; + color: black; + } +} + +button { + background-color: rgba(0, 0, 0, 0.3); + border: 1px solid rgba(255, 255, 255, 0.7); + + color: white; + // border: 1px solid white; + cursor: pointer; + font-size: 1em; + + &:focus-visible { + outline: solid rgba(255, 0, 255, 0.5) 2px; + } + + &:not(:disabled, .no-hover, .selected):hover { + color: black; + background-color: white; + } + + &.selected { + color: black; + background-color: white; + } + + &:disabled { + $disabled_color: rgba(255, 255, 255, 0.7); + cursor: default; + background-color: rgba(255, 255, 255, 0.1); + border: 1px solid $disabled_color; + color: $disabled_color; + + &.current { + background-color: white; + color: black; + } + } +} + +.signup, +.signin { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + gap: 1ch; + + font-size: 2em; + + .optional { + margin-left: 1ch; + font-size: 0.5em; + font-style: italic; + color: rgba(255, 255, 255, 0.5) + } +} + +nav.header { + position: sticky; + backdrop-filter: brightness(70%); + display: flex; + align-items: flex-start; + flex-direction: row; + gap: 10px; + height: $host_nav_height; + overflow-x: scroll; + scrollbar-width: none; + white-space: nowrap; + align-items: center; + + font-size: 1.5em; + + .username { + font-size: 0.5em; + color: rgba(255, 255, 255, 0.5); + margin-left: -1ch; + } + + .right-side { + position: absolute; + right: 20px; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + gap: 10px; + } +} + +.click-backdrop { + z-index: 4; + background-color: rgba(0, 0, 0, 0.7); + position: fixed; + top: 0; + left: 0; + height: 100vh; + width: 100vw; + background-size: cover; +} + +dialog::backdrop { + background-color: rgba(0, 0, 0, 0.7); +} + +.dialog { + z-index: 5; + width: 100vw; + height: 100vh; + display: flex; + flex-direction: column; + flex-wrap: nowrap; + position: fixed; + top: 0; + left: 0; + align-items: center; + justify-content: center; + backdrop-filter: blur(1em); + + .dialog-box { + border-top: 1px solid white; + background-color: black; + font-size: 1.5em; + + input { + font-size: 1em; + width: 60vw; + } + + + .dialog-main { + border-left: 1px solid white; + border-right: 1px solid white; + display: flex; + flex-direction: column; + flex-wrap: nowrap; + align-items: center; + padding-left: 30px; + padding-right: 30px; + padding-top: 10px; + padding-bottom: 40px; + gap: 5px; + color: white; + + &.full { + border-bottom: 1px solid white; + } + } + } + + .options { + display: flex; + flex-direction: column; + flex-wrap: wrap; + gap: 20px; + width: 100%; + + &>button { + min-width: 4cm; + } + + $close_color: rgba(255, 0, 0, 1); + + .close { + border: 1px solid $close_color; + color: $close_color; + background-color: change-color($color: $close_color, $alpha: 0.1); + + &:hover { + background-color: change-color($color: $close_color, $alpha: 0.4); + } + } + } +} + +#change-password, +#update-profile { + .pwless-notice { + font-size: 0.7em; + word-wrap: normal; + margin: 0; + } + + .dialog-box { + max-width: 70%; + } + + form { + font-size: 1em; + display: flex; + flex-direction: column; + gap: 1ch; + align-items: center; + + .form-fields { + display: flex; + flex-direction: column; + align-items: center; + // width: 100%; + gap: 1ch; + } + + + label { + user-select: none; + } + } +} + +.user-settings-list { + list-style: none; + display: flex; + flex-direction: column; + align-items: center; + gap: 1ch; + height: calc(100vh - $host_nav_total_height - 3ch); + + li { + width: 60%; + + margin-left: 0; + + .dialog-modal>button, + &>button { + font-size: 2em; + width: 100%; + flex-grow: 1; + } + } + + .logout { + margin-top: auto; + } + + dialog { + font-size: 1em; + } +} + +.welcome-columns { + display: flex; + flex-direction: row; + flex-wrap: wrap; + width: 89%; + gap: 3ch; + + &>* { + flex-grow: 1; + } + + padding: 0 5vw 0 5vw; +} + +.status-bar { + background-color: black; + border: 1px solid white; + padding: 1ch; + margin: 5ch; + user-select: none; + + &.disconnected { + border: 1px solid red; + background-color: rgba(255, 0, 0, 0.1); + } +} + +.debug-marker { + $debug_color: rgba(255, 255, 255, 0.5); + position: relative; + margin: 0; + width: fit-content; + height: fit-content; + padding: 1px; + user-select: none; + top: 0; + left: 0; + border: 1px solid $debug_color; + color: $debug_color; + background-color: color.change($debug_color, $alpha: 0.1); +} + +.game-settings { + padding: 0px 3ch 3ch 3ch; + + .top-bar { + font-size: 1.5em; + padding: 1ch; + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 1ch; + background-color: rgba(255, 0, 255, 0.05); + width: fit-content; + } + + .role-add-list { + margin: 1ch 0 1ch 0; + width: 100%; + user-select: none; + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 3ch; + justify-content: space-between; + row-gap: 0.5ch; + + .category { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + gap: 0.5ch; + + .title { + padding: 0.5ch; + text-align: center; + min-width: 15ch; + filter: saturate(70%) grayscale(10%); + } + + .roles { + min-width: 15ch; + display: flex; + flex-direction: column; + flex-wrap: nowrap; + gap: 0.5ch; + + .add-role { + padding: 0.5ch; + flex-grow: 1; + width: 100%; + } + } + } + } + + .setup-slots { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 1ch; + row-gap: 0.5ch; + + align-items: flex-start; + } + + .setup-slot-container { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + gap: 0.25ch; + align-items: flex-start; + + .setup-slot { + color: rgba(255, 255, 255, 0.9); + font-size: 1.5em; + } + + .aura, + .assignment { + margin: 0px; + font-size: 0.8em; + color: rgba(255, 255, 255, 0.5); + user-select: none; + display: flex; + flex-direction: row; + flex-wrap: wrap; + word-break: normal; + gap: 0.5ch; + + &:hover { + color: white; + } + } + } +} + +.role-title { + user-select: none; +} + +.tabs { + display: flex; + flex-direction: row; + flex-wrap: wrap; + max-width: 80vw; + align-items: flex-start; + + .tab { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + + .detail { + margin: 0px; + font-size: 0.5em; + color: rgba(255, 255, 255, 0.5); + user-select: none; + display: flex; + flex-direction: row; + flex-wrap: wrap; + word-break: normal; + gap: 0.5ch; + + &:hover { + color: white; + } + } + } +} + +dialog .tab-content { + max-width: 80vw; + min-height: 40vh; + +} + +.toggle-list { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-around; + row-gap: 0.5ch; + gap: 0.5ch; +} + +.player-select { + flex-grow: 1; + + .identity { + justify-content: space-between; + } +} + +.identity, +.identity .name, +.identity .pronouns { + word-wrap: normal; +} + +.identity { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 0.5ch; + + .number { + text-shadow: yellow 1px 1px; + } + + .pronouns { + font-size: 0.5em; + opacity: 50%; + align-self: center; + } +} + +.lobby-players { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + gap: 0.25ch; + + .player-list { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 0.5ch; + align-items: center; + } +} + +.player { + font-size: 1.25em; + border: 1px solid rgba(255, 255, 255, 0.5); + height: fit-content; + + &.connected:not(:hover) { + background-color: rgba(0, 128, 0, 0.1); + border: 1px solid rgba(0, 64, 0, 0.7); + + .number:not(.red) { + color: green; + text-shadow: none; + font-weight: bold; + } + } + + .number.red { + text-shadow: rgb(64, 0, 0) 1px 1px; + font-weight: bold; + } +} + +.red { + color: red; +} + +.player-lobby { + margin: 5vh 15vw 5vh 15vw; + padding: 3ch; + font-size: 1.5em; + border: 1px solid rgba(128, 0, 0, 0.7); + background-color: rgba(64, 0, 0, 0.3); + + &.joined { + border: 1px solid rgba(0, 128, 0, 0.7); + background-color: rgba(0, 64, 0, 0.3); + } +} + +.tutorial-box { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + margin: 2ch; + width: fit-content; + + &[hidden] { + display: none; + } + + .hide, + .show { + align-self: flex-start; + } + + + .show { + &:hover { + &::after { + content: "show tutorial"; + background-color: black; + color: white; + position: fixed; + font-size: 1em; + width: max-content; + height: max-content; + margin-left: 2ch; + } + } + } + + .tutorial { + font-size: 1.25em; + padding: 1ch; + border: 1px solid white; + background-color: rgba(0, 0, 64, 0.3); + } + + + .sample { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 0.5ch; + + align-items: center; + } + + .equals { + font-size: 2em; + user-select: none; + } + + .ok { + user-select: none; + } + +} diff --git a/werewolves/.cargo/config.toml b/werewolves/.cargo/config.toml deleted file mode 100644 index 2e07606..0000000 --- a/werewolves/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.wasm32-unknown-unknown] -rustflags = ['--cfg', 'getrandom_backend="wasm_js"'] diff --git a/werewolves/Cargo.lock b/werewolves/Cargo.lock deleted file mode 100644 index 97dfc3b..0000000 --- a/werewolves/Cargo.lock +++ /dev/null @@ -1,1572 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anymap2" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "blog-rs" -version = "0.1.0" -dependencies = [ - "chrono", - "gloo 0.11.0", - "instant", - "lipsum", - "log", - "once_cell", - "rand", - "serde", - "wasm-logger", - "web-sys", - "yew", - "yew-router", -] - -[[package]] -name = "boolinator" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" - -[[package]] -name = "bumpalo" -version = "3.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "cc" -version = "1.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" -dependencies = [ - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-link", -] - -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "gloo" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28999cda5ef6916ffd33fb4a7b87e1de633c47c0dc6d97905fee1cdaa142b94d" -dependencies = [ - "gloo-console 0.2.3", - "gloo-dialogs 0.1.1", - "gloo-events 0.1.2", - "gloo-file 0.2.3", - "gloo-history 0.1.5", - "gloo-net 0.3.1", - "gloo-render 0.1.1", - "gloo-storage 0.2.2", - "gloo-timers 0.2.6", - "gloo-utils 0.1.7", - "gloo-worker 0.2.1", -] - -[[package]] -name = "gloo" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd35526c28cc55c1db77aed6296de58677dbab863b118483a27845631d870249" -dependencies = [ - "gloo-console 0.3.0", - "gloo-dialogs 0.2.0", - "gloo-events 0.2.0", - "gloo-file 0.3.0", - "gloo-history 0.2.2", - "gloo-net 0.4.0", - "gloo-render 0.2.0", - "gloo-storage 0.3.0", - "gloo-timers 0.3.0", - "gloo-utils 0.2.0", - "gloo-worker 0.4.0", -] - -[[package]] -name = "gloo" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15282ece24eaf4bd338d73ef580c6714c8615155c4190c781290ee3fa0fd372" -dependencies = [ - "gloo-console 0.3.0", - "gloo-dialogs 0.2.0", - "gloo-events 0.2.0", - "gloo-file 0.3.0", - "gloo-history 0.2.2", - "gloo-net 0.5.0", - "gloo-render 0.2.0", - "gloo-storage 0.3.0", - "gloo-timers 0.3.0", - "gloo-utils 0.2.0", - "gloo-worker 0.5.0", -] - -[[package]] -name = "gloo-console" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f" -dependencies = [ - "gloo-utils 0.1.7", - "js-sys", - "serde", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-console" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a17868f56b4a24f677b17c8cb69958385102fa879418052d60b50bc1727e261" -dependencies = [ - "gloo-utils 0.2.0", - "js-sys", - "serde", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-dialogs" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67062364ac72d27f08445a46cab428188e2e224ec9e37efdba48ae8c289002e6" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-dialogs" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4748e10122b01435750ff530095b1217cf6546173459448b83913ebe7815df" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-events" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-events" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c26fb45f7c385ba980f5fa87ac677e363949e065a083722697ef1b2cc91e41" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-file" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7" -dependencies = [ - "gloo-events 0.1.2", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-file" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97563d71863fb2824b2e974e754a81d19c4a7ec47b09ced8a0e6656b6d54bd1f" -dependencies = [ - "futures-channel", - "gloo-events 0.2.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-history" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85725d90bf0ed47063b3930ef28e863658a7905989e9929a8708aab74a1d5e7f" -dependencies = [ - "gloo-events 0.1.2", - "gloo-utils 0.1.7", - "serde", - "serde-wasm-bindgen 0.5.0", - "serde_urlencoded", - "thiserror", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-history" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903f432be5ba34427eac5e16048ef65604a82061fe93789f2212afc73d8617d6" -dependencies = [ - "getrandom", - "gloo-events 0.2.0", - "gloo-utils 0.2.0", - "serde", - "serde-wasm-bindgen 0.6.5", - "serde_urlencoded", - "thiserror", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-net" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620" -dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "gloo-utils 0.1.7", - "http", - "js-sys", - "pin-project", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-net" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ac9e8288ae2c632fa9f8657ac70bfe38a1530f345282d7ba66a1f70b72b7dc4" -dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "gloo-utils 0.2.0", - "http", - "js-sys", - "pin-project", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-net" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173" -dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "gloo-utils 0.2.0", - "http", - "js-sys", - "pin-project", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-render" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd9306aef67cfd4449823aadcd14e3958e0800aa2183955a309112a84ec7764" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-render" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56008b6744713a8e8d98ac3dcb7d06543d5662358c9c805b4ce2167ad4649833" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-storage" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6ab60bf5dbfd6f0ed1f7843da31b41010515c745735c970e821945ca91e480" -dependencies = [ - "gloo-utils 0.1.7", - "js-sys", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-storage" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc8031e8c92758af912f9bc08fbbadd3c6f3cfcbf6b64cdf3d6a81f0139277a" -dependencies = [ - "gloo-utils 0.2.0", - "js-sys", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-utils" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-utils" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-worker" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a" -dependencies = [ - "anymap2", - "bincode", - "gloo-console 0.2.3", - "gloo-utils 0.1.7", - "js-sys", - "serde", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-worker" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76495d3dd87de51da268fa3a593da118ab43eb7f8809e17eb38d3319b424e400" -dependencies = [ - "bincode", - "futures", - "gloo-utils 0.2.0", - "gloo-worker-macros", - "js-sys", - "pinned", - "serde", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-worker" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "085f262d7604911c8150162529cefab3782e91adb20202e8658f7275d2aefe5d" -dependencies = [ - "bincode", - "futures", - "gloo-utils 0.2.0", - "gloo-worker-macros", - "js-sys", - "pinned", - "serde", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-worker-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956caa58d4857bc9941749d55e4bd3000032d8212762586fa5705632967140e7" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "hashbrown" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "implicit-clone" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8a9aa791c7b5a71b636b7a68207fdebf171ddfc593d9c8506ec4cbc527b6a84" -dependencies = [ - "implicit-clone-derive", - "indexmap", -] - -[[package]] -name = "implicit-clone-derive" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "699c1b6d335e63d0ba5c1e1c7f647371ce989c3bcbe1f7ed2b85fa56e3bd1a21" -dependencies = [ - "quote", - "syn 2.0.100", -] - -[[package]] -name = "indexmap" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.171" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" - -[[package]] -name = "lipsum" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "636860251af8963cc40f6b4baadee105f02e21b28131d76eba8e40ce84ab8064" -dependencies = [ - "rand", - "rand_chacha", -] - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "miniz_oxide" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" -dependencies = [ - "adler2", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pinned" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a829027bd95e54cfe13e3e258a1ae7b645960553fb82b75ff852c29688ee595b" -dependencies = [ - "futures", - "rustversion", - "thiserror", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" -dependencies = [ - "proc-macro2", - "syn 2.0.100", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prokio" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b55e106e5791fa5a13abd13c85d6127312e8e09098059ca2bc9b03ca4cf488" -dependencies = [ - "futures", - "gloo 0.8.1", - "num_cpus", - "once_cell", - "pin-project", - "pinned", - "tokio", - "tokio-stream", - "wasm-bindgen-futures", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "route-recognizer" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustversion" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "serde_json" -version = "1.0.140" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "tokio" -version = "1.44.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" -dependencies = [ - "backtrace", - "pin-project-lite", -] - -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "tracing-core" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" -dependencies = [ - "once_cell", -] - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.100", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-logger" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074649a66bb306c8f2068c9016395fa65d8e08d2affcbf95acf3c24c3ab19718" -dependencies = [ - "log", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "web-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "windows-core" -version = "0.61.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "windows-interface" -version = "0.59.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "windows-link" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" - -[[package]] -name = "windows-result" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "yew" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1a03f255c70c7aa3e9c62e15292f142ede0564123543c1cc0c7a4f31660cac" -dependencies = [ - "console_error_panic_hook", - "futures", - "gloo 0.10.0", - "implicit-clone", - "indexmap", - "js-sys", - "prokio", - "rustversion", - "serde", - "slab", - "thiserror", - "tokio", - "tracing", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "yew-macro", -] - -[[package]] -name = "yew-macro" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fd8ca5166d69e59f796500a2ce432ff751edecbbb308ca59fd3fe4d0343de2" -dependencies = [ - "boolinator", - "once_cell", - "prettyplease", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "yew-router" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca1d5052c96e6762b4d6209a8aded597758d442e6c479995faf0c7b5538e0c6" -dependencies = [ - "gloo 0.10.0", - "js-sys", - "route-recognizer", - "serde", - "serde_urlencoded", - "tracing", - "urlencoding", - "wasm-bindgen", - "web-sys", - "yew", - "yew-router-macro", -] - -[[package]] -name = "yew-router-macro" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bfd190a07ca8cfde7cd4c52b3ac463803dc07323db8c34daa697e86365978c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "zerocopy" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] diff --git a/werewolves/Cargo.toml b/werewolves/Cargo.toml index 2f88098..0397bcf 100644 --- a/werewolves/Cargo.toml +++ b/werewolves/Cargo.toml @@ -3,45 +3,80 @@ name = "werewolves" version = "0.1.0" edition = "2024" +[lib] +crate-type = ["cdylib", "rlib"] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -web-sys = { version = "0.3", features = [ - "HtmlTableCellElement", - "Event", - "EventTarget", - "HtmlImageElement", - "HtmlDivElement", - "HtmlSelectElement", - "HtmlDialogElement", - "DomRect", - "WheelEvent", -] } -wasm-bindgen = { version = "=0.2.100" } -log = "0.4" -rand = { version = "0.9", features = ["small_rng"] } -getrandom = { version = "0.3", features = ["wasm_js"] } -uuid = { version = "*", features = ["js"] } -yew = { version = "0.22", features = ["csr"] } -yew-router = "0.19" -serde = { version = "1.0", features = ["derive"] } -serde_json = { version = "1.0", optional = true } -gloo = "0.11" -wasm-logger = "0.2" -instant = { version = "0.1", features = ["wasm-bindgen"] } -once_cell = "1" -chrono = { version = "0.4" } -werewolves-macros = { path = "../werewolves-macros" } -werewolves-proto = { path = "../werewolves-proto" } -futures = "0.3" -wasm-bindgen-futures = "0.4" -thiserror = { version = "2" } -convert_case = { version = "0.10" } -ciborium = { version = "0.2", optional = true } -chrono-humanize = { version = "0.2.3", features = ["wasmbind"] } +leptos = { workspace = true } +leptos_router = { workspace = true } +axum = { workspace = true, optional = true } +console_error_panic_hook = { version = "0.1", optional = true } +leptos_axum = { workspace = true, optional = true } +leptos_meta = { workspace = true } +tokio = { version = "1", features = ["rt-multi-thread"], optional = true } +wasm-bindgen = { workspace = true, optional = true } +getrandom = { version = "=0.3.4", optional = true } +colored = { version = "3.0", optional = true } +pretty_env_logger = { version = "0.5", optional = true } +sqlx = { workspace = true, optional = true } +tower-http = { workspace = true, optional = true } +mime-sniffer = { version = "0.1", optional = true } +futures = { version = "0.3", optional = true } +wasm-logger = { version = "0.2" } +gloo = { version = "0.11" } +leptos-use = { workspace = true } +serde = { workspace = true, features = ["derive"] } +rand = { workspace = true } +reactive_stores = { version = "0.3" } +axum-extra = { workspace = true, optional = true } +anyhow = { workspace = true, optional = true } +bytes = { workspace = true, optional = true } +fast_qr = { workspace = true, optional = true } +log.workspace = true +api.workspace = true +uuid.workspace = true +chrono.workspace = true +werewolves-macros.workspace = true +werewolves-proto.workspace = true +codee.workspace = true +convert_case.workspace = true [features] -default = ["cbor"] -# default = ["json"] -cbor = ["dep:ciborium"] -json = ["dep:serde_json"] +hydrate = [ + "leptos/hydrate", + "dep:console_error_panic_hook", + "dep:wasm-bindgen", + "uuid/js", + "dep:getrandom", + "getrandom/wasm_js", +] +ssr = [ + "dep:axum", + "dep:tokio", + "dep:leptos_axum", + "dep:colored", + "dep:pretty_env_logger", + "dep:sqlx", + "dep:tower-http", + "dep:mime-sniffer", + "dep:futures", + "dep:axum-extra", + "dep:anyhow", + "dep:bytes", + "dep:fast_qr", + + "leptos/ssr", + "leptos_meta/ssr", + "leptos_router/ssr", + "leptos-use/ssr", + "leptos-use/axum", + "api/ssr", +] + +# Defines a size-optimized profile for the WASM bundle in release mode +[profile.wasm-release] +inherits = "release" +opt-level = 'z' +lto = true +codegen-units = 1 +panic = "abort" diff --git a/werewolves/Trunk.toml b/werewolves/Trunk.toml deleted file mode 100644 index 105927b..0000000 --- a/werewolves/Trunk.toml +++ /dev/null @@ -1,14 +0,0 @@ -[build] -target = "index.html" # The index HTML file to drive the bundling process. -html_output = "index.html" # The name of the output HTML file. -release = true # Build in release mode. -dist = "dist" # The output dir for all final assets. -public_url = "/" # The public URL from which assets are to be served. -filehash = true # Whether to include hash values in the output file names. -inject_scripts = true # Whether to inject scripts (and module preloads) into the finalized output. -offline = false # Run without network access -frozen = false # Require Cargo.lock and cache are up to date -locked = false # Require Cargo.lock is up to date -# minify = "on_release" # Control minification: can be one of: never, on_release, always -minify = "always" # Control minification: can be one of: never, on_release, always -no_sri = false # Allow disabling sub-resource integrity (SRI) diff --git a/werewolves/assets/fonts/liberation-serif.css b/werewolves/assets/fonts/liberation-serif.css deleted file mode 100644 index d985b20..0000000 --- a/werewolves/assets/fonts/liberation-serif.css +++ /dev/null @@ -1,39 +0,0 @@ -/* liberation-serif */ -@font-face { - font-family: "Liberation Serif"; - font-style: normal; - font-weight: 400; - font-stretch: 100%; - src: local("Liberation Serif"), local("LiberationSerif"), url(data:font/woff2;charset=utf-8;base64,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) format("woff2"); - font-display: auto; -} - -/* liberation-serif-italic */ -@font-face { - font-family: "Liberation Serif"; - font-style: italic; - font-weight: 400; - font-stretch: 100%; - src: local("Liberation Serif Italic"), local("LiberationSerif-Italic"), url(data:font/woff2;charset=utf-8;base64,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) format("woff2"); - font-display: auto; -} - -/* liberation-serif-bold-italic */ -@font-face { - font-family: "Liberation Serif"; - font-style: italic; - font-weight: 700; - font-stretch: 100%; - src: local("Liberation Serif Bold Italic"), local("LiberationSerif-BoldItalic"), url(data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAj/YABMAAAAFv8QAAj9nAAIZmQAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGoESG4GVOByTAAZgAIw2CIVYCY80ERAKkfIQj/IfATYCJAPRNBOnYAvROAAEIAWXcQeB0H0Mih5b0BW1FKKJuLusW1elqE7/k6mLggIilc6Ctg5vNypfQRlTzyAyGW3DDaQB/T5q45BGd1UIbP/kDXQOWwci+e0a3jY6CXtoEAv/////////////////d7L8iH7TmdnbvNndu73785OPICCI4CdqFFtrorZJbcOgTB1IBfUhzWJGaZ7GokTwASmr6iqEhmqKoQytdghBxbLrNVKfBlJNTsJQaQQGNhLV9EQeT7qmmc7oVAoE4wCmBMydY450vvDMeWVnjtzSbNF15WrGJtatwcb8fMNAYC7xBsZp2wK8D+rAPQ2HbOvYRZply8CWjqLju93l0FMKCKhJjSeTcza2crjvpoeKpumYwtWe+cTmEAHj+oSvr2lbCTe3TvwKEXcqQKFC6Ug3N8wH5QXono+lB3ZpmMnX9oySQ+I6lbBUtgHFlUoXe+UOpJB631TytNPp5fwxUqAnkJ4mtSGVYAKWHxtv+Ewq/CGWf24O091uRpEfODg4OHiMi1XcsYxnHOIL/4uDbzjMnwyQ2Oj+WmrPyOPWk3e8YPrq6LswjvKzeLDgNMgzw+/J7QyeaCaoGpRO7bh6oUMgpVdVCM9q+jrxfPYCCjT5wVSYCIMVvfG2bagCf5H2AAgEUlUGOJUdJGzUgxxAa3XkVtQb1J45alQcVxRum4fbQIHajvwkhKyXvzcpHeFv/YWn0DVOGFyVNXulBgfQB7gSjm8KFPpBU//mFaCM/U07lrogDJxLJS3odM8vWuEfgpSlP/idB7ySc0jLMjDX1qEL3FXee5qdMK/zqprxqmI5B0fd6wL37OeIvvoINkrJUXlCZ24k9CmNgpJXLMRz6WZxJCht2Z10AdbQu6BsKeqMPgxulmvjSgKaB+HRUTkQlDxsS1XyKXoCLHwQf1nzJB7/jen86XVFqXlMfFaz9pkdzgdBAFifb1TedsprthVgsqG+OPpiYCYsTNYS6FMCqQSzMT0KJd9ReBchppW4F3NHXgJBXpv/JznbKr4Qcrrcrej/4b6lTeKQYXYcSdOx1ka/jL8huR4LPGodfYwFpfbVYjzJ8zzPc4r2HcU8z/M8z3OKyd/JkCdiURRFURQFRfu8GE9j9DFGSo1/QwSSO4p5eeTzjILFWxEWb8X2528RsA5OvFdJVa3d3ogYWHtnf/i0/tPeXHbiFhb+Nt6c21fLmazWaGb82hcUzpb3gBTj1tVXAE10Q5SYYoltH6dyiduzXuWT/mvf81P93XPulZ6eZFl2FEWxFccBtoshUJGdfJdc8nTclIDcFEjTuOwCsUvsFDBhp19h6535z83+bxK8FNVgQXQIhDalkEBIg1WBIYh1HjUZ0c7hua6+7GQ5/co3XX1f/u1fi287POTt3y53kXvmLPeI3CNHxbAtaWmOM+Qsq+iUIgqNhooad+NuE/KFip8zRKXTfWxmxG3x+/X51V1dfWaDd18A0RHaOAKFNlGASkRFJXZV0KFQJJP/HfFMF3zRxWd11aue2RU60oiGAsEwxSDAIbrP8097/d86M2dyJzcvzwtKU62or1AYVZrwVUiMwDcJGgfZi6cd8oQp74/NkXk7VcQjLNLAWLP5vk3bbX2XipJXiBJS84jpzE5y3NWo+/78lhrtI3XwiiJWUTQzO1z3JIIQLx30TpKX3b0DrXBBqloALPrvpWoGf+mi+vkK85WT6JxI8XiiSCUq+Xk2SIAkRAiAsICSQ+6+6R2a6t8er/x5Zzbb60Yu0PyoFKwfrCXrgrVgC5jmAQIE5n+/N61zQ3rvv/6/uyVZtickLtcOGuSGw8ZUyN5QPHK5uHfkTSjSzZMj3ETQFg9Jsnr4B9nR+2ZKxoTEuhIo6gl3IcT7//dzpqFxKEFDmaUlXF/DxD4i9s5FdXoR+xv+pwk8+QC4K4dzNFAhZa3ss3bs5IxCIgoRkrEjY2dG1hiHG8447s5tx91262/uv0OV7ekcionlynmtgNvaqhGRMlDlCcl4KGIR2kjbqVjpuLPwIgWD+p+qCjqtUZl0QcrH/ZHSaXWpFMGTju5U7gBXUm5UJk9JHyucbXiw+5Y1y9a3eFUtAavU/77Mn2SYs2VZDrRNW8ypuFBXqJgLDzYQpewLWSoykTCopgkQLPUAEARJsLSrEi2ffLTsnJuYfl9Pzpq/P62ptl4fr9Iwfd9S6uou2UrpSpfS65dhyvz/907ru1W3qqSSqlQl2ZYptuTgdKe75cFutt7isP0I7UeYLKH9CJNHGD9Ce84OeDFZwniBe0780bNAydIXZWB/Tw6qqPFKmdpKeoS+DxpR0uIGYG6i9JI1jF7BYMBgbNSAVQGLBsZYshHRimCRVoCK0Zj5a1/7v95bv7+37/X3epRT29HaaVkO4azkW5fCynFALlhFJwW1HLtAaBeIfVcCu0TgAj7rA9RdZNYQ2rcCyjIpm1xOpp3xDOoVqMI95iUY6y+nmdy6NqU0TUYzu2lGMgygTRfAQ3gQCLziMyAeIykAXRAp/wN61mvdBKUAcx33H10xDQsmLhMXpwIQeHrb4eBwOkVRFEVRdDpFp+gURU0769EoiqIoiqIoiqIoiqIoiqJoNKWdj0YTbG9DRBRIJNIu1XvcTwa4XFjg+t+r+onzHgEGBAICHgACeERiiCJFij8q7q5zuMMfilpOuXLr794efedSsnMXE+VUbSwaO9eLa8zqv6pkkIamBxFREVOcmd298H7IscXHy80RAOssOb4x44b/XTIdOKTCWCzCtt5UJ/vG2D+31uv05peVL/Ol0E/ofCnkF7Kqfld3FxpA18zsxvWp/6tmjqIj2PcLHvUoCnPX8KgtOYbHCwA70xQaBCU2aNE7YXgUhsNtmjJsHucM6571Jz5Ood9q8EOLcxRZKL/4//39Z7nP3YfoEj6CjwXiVtXvQQ3992tYy0t+X3bEmh7OSiZUO4hasUkTllGdGTAeoMwRYg8AEBxEhEORurtba/ngkuyDgtKTsNcqdZ18kSVQSmk52a2tsyxcHYKKJxZAOnmbju2Q5i2Br/Ym0GgVhrqYaaKPp7fHdKkR8mLL3sLho2atDVOENyOV/10rL+/UuVOkrjCQTjL0FzJYnDeTBcpQFlJ0JwuqFiWBOllJrkKRcbWVGwYI6FxGHaBS6kL+///S2X+VheOwTx2VjSE4jdJytzPNZJwgHXqY9jn7lI7skizZsi28gBiiUu0fufMnhb8MJIwZ5hHIMJZUDr4DkNzm3vd4vrotHEVBECxsCoeJh28+gAdWXsslL/hC5wHhkj94gDzrFyoYuAiaRpsCmFn5fdCH4+lfLovMsZr0p8u0WipAzO43cpKv7eYoeGS2KyGURhsKGzuiMLWoKOCh/7XffGxteIh5VAsJ0sVCJ9c9hAJUHZuybzkouAG7q8AD/OVurNfYYum3xgTMt50eYIAHGGCAAUaYFQewKUul4MuHBkEBIMx/72a/vaBxSPKLTMWp5lf9pZ996X3V6uMR5fFAg6DmCeoQMRk07QkpKGmmHZoOIvEAYsY4TrHMfGPM/GjKh4eFqCexj6OpTDfTi21q6et1L4vl7re+WfzV4v99mVpd/69EAlkEqSbINmCbCaItOJYaewXZ7DFW4t6M85nvfVOZv7JQDiRQBYiFAskGAUpdqKJaJChq8mcC7EKRPQOSExOiWgezrs14AwKkhgQkNQlQPZQoC2mcZr2Rxnh/3NjDibv+dtzznoyz1z2cLns47V7PCxUOm/1OaTsuJ5SktFvo6hIVXhgwDq8x0kIU3bQBDHBBrN42C08wogA4Ic//nJbUe1pZqWwLgQFUX05lmhUgITCrZ/vNnEvaFsASgn0m0pXq/zf1k8oaj/Rd1pvaEfrVW9CGsV2NPHfP15e8pbfD/ebNyPL85pSOElQJyQlg+1kQzQkiATyAb+kAx/9Ptdd2MHfeBowCKVAh5KIlFVI1Ui7VlP/jYXb2Y/C4ewhACaRCdAhp12m4TtyOcmWXbl25Tn1h163/f1XtawHRcvjR2hBD0cnSptxu1QD3vocH3IcHQACTAMrmkI6iIx1nxjMHDyBnQZCeQ2n8j+P/x/4h5fVszl0Vm2rLauGffvk1e8/G9zb/wpG7ivKMcGBdv36Tboed35ub/N00ucnNSMhyLcEIylP1d0jpg0JJlIWn/x/m7Ja5ijMOJMqXJu1uku/yFLVJZGkKLMIhRecfcGZJ43w00fZQF6ABhDlOL+uhcVgXoNICQptIMIOV/7ls9u851uGwSFDHeZXJUq6Vkiz9R5izMvuoRQEP/780pdc7XqVUGKgTZBiAjWAIWmmatE/6Hrda5CrXysLC01lrrBZuGEICX7rY66ual1vBCOeuvZAAbi9b0QQcAvmF8N//r1e1th9kU2JnsSd1Z02WJuSzdwqrmbzYzixWH/Wq6oL/AyQEigoALcGAZFOgA/UphwOnelXwnA9QnkOxc5J7cqJBapoG6QTSCaQTxE5qz+Rlkj0hx2WIjAGHFIitGwyA8/z3S6cTeBLp7x6HtKU15bekfsVgVODrfPl3Zt3Wo/1YI1asiOjXs+b79t9UC+b8JHBFMEJohRDCCCGMEMJrjDC+xgQTTAjBDCHkvnb3e5c1e/oXSCiWkRCUJjrO7P52K/30j+1HNvP38NpBl7YUKyTBgmjFbjdxO9m+yvBss/9uoHA7Fy0YOWcGYAAGKUK/ALk/yLbohwz0ooxELCQ9mIBIOQbYV+VFf/X//ba+wI1MZFcJi7BAmOk7scp5v2/+0c1eMAG1otdai26mEEARscqQsRNC5v4jo3qg0bm0gIGDwsN8856nn5P6n50pFAqFQqFwIRAIBAKBQKDw5s+a7RBz+/8YB7af//XGTtPMtmmlTddMcTIF7uC4IfrGEHPryUPOxjbfcM4K/eFobrXlQCtAAw6EG42OGAgQyIN7G5K7wpsqGlJxmTovn9z7m/UmVIFqEF2aypZUdMUV7vzrJxl8a+0tR30g3Nnp7QF/IGFqbI1J8jwAMBp//H694XLVN37tZ4sX/eX/S1kp2bjIY1AMEJCmSvL2VIboqO4AcR/1GnVrEw3dOnqhru8N6obepUa9525w0zyCP7jBn0DQgr+uB7mJanCQROZUghYOP5U9wlGn6luOOTUg4fhTaxAcgN9Xvucqhegyj1dpMI0n6MpHaYXuvXdzLPLfgxFo8DWsRebHCoM+ZbAS/WtLBTe0w2x+f1CZj9Ff1+iFyoQqDKLppUxzapS0esWOkagg8X+XHJLhleJJ1YAiVfN7WCzjP2oQIIEQSaRQhTSqkZFFhHJiOSDxEiDMXY+9UISh1gf9uCCC8DDNXMmXah0to7II1kdmXsLnB5uRZMLPgsRXhht7ko1o6svV/GK6uRtAmJ8D4wO7Am80310QOmghNgA78u6wX4Jzg9cGv7tZCCPkYCg1dI9bPiyErYy4lcN3nRfWSRTSctKHqNyo6ejZ0QXR+2WX40S/I+PISnIPeQ/5cQw8hhNTE7M+5kbs7NgktR0jnNgqxACUlSd8BQg3NP0vcGr6e+Wsb1Zu81p++y9MPTu/hLVvIeg/j32GIHrVDAPV1wlhsv5i1LRFHLAeRBA4w31zWkQKAGNMDp+u2MjcGWpF23rnCxxLZvKlaqPdzQs1bYQhimBNI/ANNBFBNBZPJFPpTDaXLxRL5Uq1Vm+02kEYxUmadbp5r+iXVd3sH3IFMD7YQZg4ZahIVWpRjya0oDVd6UlfkjCLKsoeswR5QK7qD1sWZeXdjmSdVbWXgorJshD7m2BbpnXCe1jNTLxX11HrCnJ0nBqAlBYaaHknKARhbqLhwZkrpyPAUJLZpV1Cr4yzb14+Kd7PpwV85aJbng9hU1Z5Ll6jJ4TtVHnWjb9HrWuYHXorXECOl73hijigdvd+epHyGrLzyIfFzCOokaesHdXHC/ISuor3Q16XghDwlBe3JqR4GAUp9xOyWNnxYsHDsziLQ6JXOMo231XprrqDbBh7znAD67Gt62KT3UU3yFPKJ/kdWcgmCRzSBiuVUwoYmXqih+BpNJ5Nn8L72LrP9YAh8GDJz86I6qMJLOztowzKOEqKzY3MAH4C7wrtmUxB3bVEoYRwNKHpA/pZvD4/frK0Qo/jYMM+0xYL03xTirEuq44PEK9Esx5E5AS95g6CSnS4uWwxFgHmfz8fLl3xJKO3Egb6RhpOeNl/WN4ePwH5YQyS8MiYI+OFsWaUt6eIRESnFHaQE6k2qKmszhlgG8B2gPMBngDwNIDnALwI4BUArwPYCfAOgCWADwDsBvg0wBcBvg7wXYAfA/wC4Hcg7AXhHyBcDMKVAMvIjSgAJQZKCpRakBwE2IzdQ9yVVL3VxrAcL4iSrKiabliyngARJpStKnRz3l2OnGeq9DVm/sPcVQRJg5pV18ZqtKZuVUzNbEC3t6u9zXOQln84HMRurkiQ6B3dA8EDU53+0OzFYQQDt+5hLps1Xgq0Hp+tPf/IWc9P5R77zZJqMR94a4b8Ns/ts8BNs7xGfj+igd2mWTvNrmn6/oUKPr8nLmRWeKLjfecY2xxi5Jvt65pyGI6sn4dwtBA3rEZQ3NMGgSO+JIctqnk504HtXN/tDyCGBdrsfjcLkmuehs8GFzOJutfXzyiX+djTNmw5YrW3B/WRlMs79cAqf7FuLs7N0Swg+qW2HxGTu84pnBdg7GEQ8jc36mJ0IKmnf2xkkQ7Rk1XeqYjlDRQnniPnme6ZlbBoedEuJ6TQZCvPeCJ1aDozTp1flssLqy7L0IURnZ+fH5zw7IUjxzSFLBhh3+4ihN3pv8tTpEKVOh+0+KzPT4PGzVrGBRtBASYkkGI4QVI0w3K8IEqyomq6YdkAIkwoc1zuCV8qbfqP9XPyig9mm6Q63D7/xbPlZhkVBO2rB8JMrEuLhqtMVdonqIvSvc1JAx6biWU6k0/PQOGynaiM2mqWPBe1BfnbhaiBj1dk7SH3j7PRdp6PRL2Xd0Y+sGSK4NNQ835bZFR1JvpV4jxs4g+YCUbMww8BgrtTO/k7uSgKd3ovUbys60GMfeVPJdzcrXCr44hdfe9UgoHI+7U3a7/WsDiB8/AO8DFfR+gLS46lBc5DX0GG3DZc8lEHSmu81QzuhruLbJldsG3a3pezfD2EUCtMESW1pJwYOI5IPPgKEibCHdEeSXLHLeFdwFu2iBLissK+WAAK/iRxebsUCr6C59gPUCu71j4+LoFKHYPnri/u/qgtr6/y1f4uSCxU6vjOXmhmz+65Pb8X99JmbXbKlnIf5Gmq1/YXUF+Y+H8hnxpJkioLj4ScVgGLEhXqtOiCool0rlipt7p4RueKlXqz039uj5mKGy9FFYFYpqmjr25xo+adRVul2/auL+GxyZn5pdWN7d16Ua12RMOohNZpiXoHNjHBdGx8YnJqemZ2bn5hcWl5ZXVtfWNrezAcjSfT2c7ufG+xv1ytN1c2hJ2GusClXbZlWrFVW6v12qQt2rpx7dik9mjfDuqwjug7Hd2POqnT+kXnNL3LurJruxFEOn+1S+slyOKLwKNgtBgtRk+sx5ItAAALvQA0GEWjaLQye1oJa83b50H9RJAFbAkXuE7QJbwpNqISmD1EYamBASpzVLHesz4eZbxgbabD4Et3L4v3NiVwFxCP4h6uTflVka0kkmsNhjh4lUyyE/QHS8keF8KuCQk4b8AycVlXygl8V8Pn7uru7une7uv+/tm/+k+P9kRP9kz/65094ZAAdjS721erNu3mO8FpznGRK1yn87pji5/ugUUs/tnb7Bh+x/oR4Q06SeB1qbUsxJlMWgyBLDBu6K0CbnnciKPSWv+/fLOvHMiBX+TRFFvkeEjdUNIvULttzMlRPoEF2uiFPYuoJWFAwiDsMR+yjkFjV3toUnmPvCpYq9raSPzMUfMCz9jzTlQlO+1Kdy8LsZkSS+T30NH+fBGCw+/x2tCqiK7Zd8WtvAdfA37w4J2BZKZSENvcdgktPMw0fVlr/b96HZ39pb/33x7owR7q4R7p8Z7tuZ7vhV7spV5uVrN7tdd6t/cFrjnVTw2WhS7BKQ1Ad3jai173ro994Tu96xjQxVipvG0cnjivR39LnOwMfCgvoXFBEP5rNKz/3ehsfK8sMmEfAon6TqgqNGBcoRW8RB5EBLEEW8XxBsT3iVu3J/ZAe4KD8BTmC6e36BbYl6ygrEdvwgO+3Zz4AE6R1ahkoCKCz66L+AAKcldxaC27QoNHFd9WfVg0dL7XYyyj2uVeCcRnfZ/DdhDfFUwcq+UNHCf7WVMkJ4pdV2HgDMF3aJH5fMoHb02x5a4urUJumKhOqWOfBtrwvjxZxLh/suAHcq+DZ3hmfpGVvoI+ze9mE7IPBeFkqSeH2fsh/xmrtARgo10hyDwJANB4WYnks6Qta8kzc5pFZwog94Ic8uFjoAjXHKoNqJTk+02ER4Dynpn/WN2XPdbTYADSVsv66h7tAVDnF9g9X023e0teDe9oauOYXlLsGG+QtLRfNIlUnrKEfFy/cYo6QEUjD4k4KNy5KX+1/EzxjXc99uviGEgDe2UJiewH7Y/l/SDAVTG+oJlTyAdm8AiATEiGTjnAL0/JwUDEvrQ6Xxb3bf/+eHQ9BJA5Ir0gSxV+WxcD2Uu8yIelpnY2OaiJvpZ2Z09IxLPhN2Py1t226djUN3fzUQpvaemr4iCxuDrxATzZwi/G3VQ/sSiNnboOCuNOE2RXYuT7ePBQ9qoVz29W+2lB4hZxiaRbPk39foFRvU8V8aW1MYdxMlLlLRt6RCi+4cur8Ke/6qnDwNj7by5wd5ucKwZZuO5Aa4OQK9Sr9z7mEz7lM0t6z7yM/dV/e2Nv7e29ewUJSQSJZNhwKkCgaJBXISvO/zDdcv5ZW9zqWV7z9Wwu/3o2V3w9m6u+utynRlO4+VP5LVRwoJbPYrfq9EY9sjbMcszi55Vc4dfNFd1ZuZJfQXzWnVVicXf6urm8m59186tu/tzN3slrDg5XIB/NyXauDm6RLaJw9dfha/WyfBhKX/bZ+PCRfu4Ra2sqi/KosIqutgFk+rg1HowU7jJttIwvn1fvqzrebobMuEmbvyenhV5w/n3ZEl+HF2GRVsmqv8Bjky8eq+Ty6JJ0Sbs0Xj5fNsb/+sbBE88eMofiEXbkHcvbaXtt/31vp+z63bR/XuGJfa8pJzS85qw9O85vN77kVjePW8At69Z267sNP4k/GT353Dye0p4an+bv0nfT+6X7g3vJnXGvudffF59Fn7WeTz7bPbs9XyGAkTefDyDSTVfcuAhcd2757uMn+G3d/2zVQCbqkg55ndGwjHyRIBV4d6ReOLtKMORgxO+H4Gll8cTwhRsAMOyBk3VPgGyp5d2Yfc/FlE5JkMpQ276xA3vPnJz7Axcs3FgDbTtNWrTbTvvbKYIaH1W0Z52sYDjFudZ622m6rfLoDImIICLUna6DdCQKpCNY1KW8Ct3sAMFpwWcFEbyDG+52Z97uDa/s5ux2hkyZoCSNi6cHCxK1bEATD6EXzN/w8xbPu+LPfmhGeWMibj14amY2Z1J3c19y6/Zd48nWL0S+UfhuoNiC7dgJLjz2Nw5DTOC3JKi3BlqIk6tyWsK/fUOFh+F9Jn/FCRK5o0Z9IqVyXibcBiOBuoy9ZFZKI8mad6mGHQBYsOHAh58wMZKAyuy13+tmDwtRFz8oQHa4ConKRXysHEp/ASwSs5xTEqUyqXdH7lE390sO2U6jPHTjSfEL9zv8kaon+19trx+NlQRJ8uyRo6VijrsTKlKbljbY6OBuWcIg+rRo+K6COwh3n49V+OpmKXV4GulWTkopbUuyvqgCYBkc1HuqVJUgCahMriUDX9tAupgfPeI6QW43ArQiMcbt5Gra4RsJwEezCRbZXu0QTrtkb7G/HwPUwlFE+Ig5KYMos0rel7kBw4INH35ChImRBFRmktEP3Jobnm1c6jJVRzunTQc5S2ECCzZ8+AkRJiawD86e1gZTYg5agLDgJ0SYGElAZa6FCtor5/OsmTH3iZ2Om5cnc59BxeaVRN5xMdmHD7osG34zcdqKS6vQg1BtCLmMln3sYALH6Pp8rAOJQwUcIsqoWaezf8LGZzknL0umOFFlT4eZgdeRoNfVugGJMS124mhq3Blgpz0QXWlSXs8rVkH6ILY5qgrGAy4NAXWVGOgxbSvLcUVP9UcNWtv63Ao+Y069LKte0dZXNqwhSROCTjzFZNmcRrFucPbMqC01WZmxrutFrWQSmjFH3XuPdTj9l53pV8Hh61rLdlaFNjVoYcQKzKruHZH+ecFecoSJXMY7O7CLJ0ubZSMuyNjNqfxwh1KUAzQnFRq1LSfcDIh84BClzLLK6lGcunxCYz2mAj4RoUO38dQe5TfM+J5ppyROzTUnxHY/GltVrJ8dhGX1LCauh2/OMzWFzEyLySSWeuAGw10jZR50ioJcJwoOHgER5fHq6vQVnfzj2abUkVpe9tXmmHknw3cVU3nX18TxeP0KaREdZZw5tnAvjRWipaaQIcVasSH2Pqo+pjmN//bjqikxARb4Tg6uqjKd0ZAFYsQ1mZopvUjrwwwvFTj4uWDHDGf+sPCy8cqadS/X9ZFIyGYoZTSc2+y8C/b7p+1yZ7pVsrIHLi7cmB1t+mQmQofQRNSI6WKJOwphICjcb2CT2uZmjofFskuKd8okb7YWmyE2fTlKmNHlaFyLRn+ybC197Lk1UZKEdAx2abzNtfTuQrszoAzt1/i5uMZRQaaI5WDXJDvwwcFps/SWiOMMSujG7osrdCJc5QEN0csMrDbj8EmcOI7WqBnpvQfVLDWO0VJauXqrnlo4yCi1lz0o1IIeqpMYhGSWDi5vgUgtaKgEefhu3cbnuiDiuOMsssCZPrMKBQnXY/iuHdk7IVsuHmWwWNCitZX5DmgYpOqJ1yyWt6NhC/MVZdlRZ2lNKjvcK1rGeb1LfhJdVvhOMT4vQ6R4sT7l8Kln9sRSDk+gl8TVWpFP7mF6XAzVr3BSVpApSyPQ/VxKd6RojTGVkf8sZs8yEvXA5ScNb7y3pxlNnkxkUla1dSrWSxoWtbwWNaFkGLVqSr4iShrME07Bji4O4fn6bJmHUspuXc3t+9CcJOwn4Teg37T7GANiWWRSfb7sZn+H6ZDp5l1w8eFLL7PlkcuuvOb4ddbrYte63o1udae7PexxT3rRq173pre960Mf+5wlW67c+fIXKFikWPGSgWU+JP7TfpUtV75CxUqVq1SvUTMoOCQ0LDyiQaPGTSKjomNi4+ITWrRMTA5bokrctUfvpGoRLly/zGUvd0mdeRCE8Bgs2V39Qfakj59Q4aEtTU3+rvKNpCVbhP2f40ZqwVdDJvqrXVT9Rp6fxUD0hSrcedxfw4rZDAw2SIMEQDWlreyM/bEb/CDAFbxzQfb5yJQxE3mWSw4YQHEQ8a9YCFDSkz4+jwD4qNwvVfgF1vM1Lp1vGqstP4bCLfbiQ55+joSqWnrT6HefJvFeFE7wwMfZyV39Hi0PQAGC7DRiBd2b2H16CW9b0NRW93zoO1UUYc5Bvkq09K0pbArHI0bQW1KFy//wkpmfPE98AI4xJznDeS5xlRsscJf7PORxz3rZm97X4ys/+MVflup7rgWMfoD8bRTxYvJ33flB/kZUOQAMg5LKC3SskjDM9Yvs+a9XWpeegrgh6Ekw+LM/OCfVwlw0AfCvN1SLHpUy35KgWlCJ3zxb2EPu6WLw8/cI1JLRQsXyk1vdC3LPB5bKCUVAsEvw+Wj/CDXqQAOUNdf2bxHVh57a9BUt/l2P6ixTLybDFpCpUyIRxcMd6zjfxyIrI89XByrU6MV4azOKVnGDN3/1AJBgQQMtdhRNcjiJ9qX0/t1J/wYDFT5fHvpbE+/bPAIrAvHxOA+eOuwqqyD7fGBerLcI+xy0H7TVDmGkicA/+DfjKZSIo1dScUQCWpAnGCaX5q+R76UDeGgF4CW0+KzJtZLnh4sRLNDcRxZs//xY9LT3YjwmLs25+WMWDEiU+pl6uuDRfz9XcY9+8MWC/y9WDdOGXYPUuNtIOpTj5bWwbxb/Z1ZCivCYhAOKx4Kq63JNmtXGjnhvrZEq/8y1fl/iNTL4Qy4FMv0/yFjIimhYweI/7lorUP4LmRG/PzEEqJVFboWUFKkCnK5YBLfw971ccziefhnppplsU+XjH5t7gjq2ZzgY6bZ6BdxX60RHwsd4H3uuPsnanrbDJapzPvWiTfAU8S5ILamAgMRHiAj3JKChY2jy12QBhsyWfKmXXh0vbDlWmqsVjsm5NY2WsS3j6OhY+VnB2pZ1LeuNDWMFMaQSSXas3lvK7k1U16+LB5W28h6HzyJjA6SRfZXGvsWnonb07T0bw+BUmZHhlYdEuVdOhbZXXcH2BBst0qItrsW3xFriRnB+cWRkEqqAEiKUvRzqNr542VHurb3ibqjGSnHzyp+MsJ12NQsUnY3wiRbE3ZJeADx8DOoDn0Lo0z6Nap9Zh6gqtsRpKrlk6ITU7x1m5RaEJtfj+k9z0Sd9dsmBoAvuqP79PUXWz5+kM8zhYTCx7UJ2TOcicuMrxDV3/iO8tz0NTYEyVer977Nv/ho3j3OdVyQ6wOQWfSlXX679Xa39xdb+pG0/itPU7RDzxrw2Z+YfekVLWtCcpipTEzVWIzUUA5GKRKZ0Vp73mx0T+Vtm9MCer7747JMP3nvnraO9nS3HAsZmdDakNaFNUa1Q/PH9TA9tKntCP354jeBE+Twuh81k0GlUCnmkbIh4HHaYqqCRCDhsUKpnVmUKUNgExO3KXZydHHbbrMxiNhr0Oq1apZwCcqlELBLWo+nsijLE7WzmX+Yff/vLH373m1/94ic/zg/wve+88dorL73wzFMPd7esbvxM/1xbPjeKh84CFHTD61/tenu5sVsREaKuPFXeanQ1tiqeSKl1jZaq5nQ2+MsUvvoLsfgq33YMkg1FY6MxYGF1p45GCMDfsfRFRuXycmqTJ6BFCyES15j3CXW/ETBHt/7/D2QEDG7549zL9/LQz05DH9jQP5Sq4W1A3vjdALR7mQNovJNSpaoK1AfXNCqKQx4QuMxtJCuOf70+b8jz+rw3H8+kmT+/LLElt9rX/OLO65fXM9ZmbMj4B+MxHRthC2yHHbATdsGJeBAv4gN8gV/wd6xgNiYzB8tlBewHVsiKWUNWzgazsWw2W8YOsTMsIlmlWClRkiWHlC25pTZSuTRNWi5tlx7Kghwli3KMHC+nyCjXkevJjeVuck+7YLfZJU648OrcxuN4Ek/jX/FMXsAL+QDu59P4LD6PL+U/8d18Pz/OT/KL/CZ/xj85Ch2qo77D6+ju6OUY4BicOTBzdHbiNmnbvEgNZtwyCo1iw2kwxkaFx/wPxYzAfpiOo9Po++gH6Bfp3JpiXWydWyOSpEcZGzICSDCPDBtjWU0uxIN+PIyX8TGG8Vf8kxFW+/OKuiyfff9e+7ERzMcWsYCZ0NFCai116rqIRj8nWc5Y65V7bAlrKXvFIh7gO9uu8zstP7T1dPRt82YOte2BsyIYMKTxHbx91SgabAX6/3+66u28nXbcIQfVMWPalBGmPOTL/MPfz9Pd1dnRwd7O1trK0mwy6HValVwmEgos61KPq0IxlsR5U8j4XIbq8zfv8zij4YHTPj386c/X+8t6tdP/tn0q7ZmFxLmZI1NjA5+42ln6S1WVVYAfhTlM0EIDKQTgAYO/rBGk9Ik5xbo//If5D3Xkjf1v7v/7yBH5Lz/lh3yXb/JVvoDQ1sChKWiDDAg2BehNfX0YGJjwlwn/0UZQDCdIimaUrEqt0er0BqPJbGFpZW1ja2fv4OjGrTsnr9x77U3JVS294Oqu2P+ncVU55UU54aRTrNnAsmXHHg4ewWkOznB0FtE5Ts4jcebClRt3Hjx58ebjAoDLxEtE8dQLOV4pQFekULFS5cpUeI2JodIb1d6qUavOfxo1eO/DXXSNv4uC77Jb8l0R+kw8EPJcJaA9J+HPY3sKdPMR9pntMK9tZ5fcHXcl6sXwE/bOldN22addFnVZfD3wUEaJl8Qxcowes8fcMXlMefcyNZfpsbfVj61je4/usWPJ7Tt9zB/rLpEkVrLHqFKkeuK5dACdsmTLtApNGDmuNm1kjix3Ondkj8SVTEJba06J49d8EWjK2g35yErcFuXw31m+J4bgLXErA7x7hvjJFkTfoQfwd9czjwyEU9+4Mu72RRXof1TCJBd8zfZVof9uLQfc85aj9DgvLm1e8XNr/wS7+8HPbVe11jGDDbsK67Wmb6vnq7EI5abHMqciCECWVAeJTyHzS9uH8CXERyMFlZDR+FWaO5tXTzxaZcurCSkBmebvcxVYLDw3H9R4PKkFnv4+TcQQvG0LwoMTpKBbncEX//sLHuOoRPNOd0EU6clou/mKg71L7ez9Ke+coCehz434zjNk1A5o5UsA3ChQLPVC/QHk2nmivvz/1St6+cdrAhX2BNp3+An6C8pOv90y+5PE4mXkK+YcfDnqXAdsPSqkxlmZ+Cbeu029cKNMhrn/2Raf7cZnNRckXawN3tiX+T8xbeo7cvyls4RYX2p1AEsNPDJEDF1TJVHgOZahKZLAMRSBIRD4+30/qzSJozBg/Z7vWf7+9noe+7Yu8zT2lcvMnbSSIM5K7azuDIBGGoiPamnJmsvO/TDpepXEV9ecFkBLwqgA407HJM0lkcLFVKpU0ZFSm5s2US1UVRDSuBgPmeDqgb8b0znUWTIZef8FlvA3o54TYCJdzCj1AFkC+wRRJfuycqUiee0f+AVZkds7t2FQeFg4uHfwYJzN+x4KTAZCCQ7o0bAP3Lz/ISD3YV1uY3Op0IlUyr5Gu1B4EtMcKIZ4CURFiLM0KOQpA++O+sh3F+cq0S+iu9u8Xa4ZIGPbbDik5N5584U6QpATBN/+1c2G3kGEE42wuj1bjlqXJfB1EkDoC5nc/8Ad8eV/A3NMRLaDiV7AxVph2yhNpUw5Ldw7vJdSZ4fH5zdp2Z87ZHctl79zrgsC2DSAevfydCvYbzxURRWQthGV6XIG7dLqIAHrPqrKiuNvOsVqWKqay1EtmlcJDBQhqnlWqabsOZhT4vB0J2ZbpkPQWeQhoFqRBTwybP7ZCv3z5pkk6y1Y+f2y3LgXAl/Xzq4HoA7GmE2Ali/mKs0hn+v/UrHT1GikZV3bCEhiMJeFGEQ4mocCBJicdUadhEl9f5OuOFx7SCMceS3aXZp1AZUvqzpmE+oUwUVVSYOGyVBJ0kOVCziofaL1IFMWU26QzO8tEOd96DhebExySA9yQ8BJbgxdG2C0JdhK6aNsL2k3ShIC6gTTLBcA3+99RvLoJkLWJvYVhrYBgpnLa2/vwlnIbaDFLhmpQFlAY8tmxyJYMyv4EzTK7pwz9EyWc7a0YoZjQxnJb0vg06Q2JiWcGkIfJL6bZIasV+ypGxYylCa9HI87u0vE9uLUmkSwlu3NHj83sIpeBH9GO0nvJG7jiXrdDwm3V6vdwQcHQmitSiaVLQeOem+orSgW+wHdrHLQMTUQy9idb4B9bdZaqu+DW8jwDluuspRaNKVCs7DuvDq4AnzlZnrjonoIuwAufE8Q1d0GG6m83FgTgslpYJQZjJOTeLLc+VMsjgv0+boAW3pIDdfkFQPs8aOcll5oEQbumpre33E16rXr6W4L6wGNO8OVS/pBvo18uUZkQbUXv271MIi9J/iy9aQbvLWjRF7AhUqINKFhDmEILhax9d6uXSOokcdgEGA0hgK2uwwxScnKC+rSGCnBFBSGKucQUJslFjXBSZVvA7OrVJoEKcqZuiaJMUNN1oMGzjd9W0jdpG5Rd+FF2OohE/cQZ/wBBIQscORBi1CLzIzl0hyaXd8mpQOd5SmbQ10zkV61Yj6hAIcTfBCLq5sNXa84u54paNpeO1XvbeVGdv/tAYZK2BdVBIA8kyKx13k8BIvkL2SenRgLntgqNtU0FRMRsY0ZQ/BZYobp4qKDDTH7qlEcAn30QzrV5cKl+Siscap/zWIEwIcowvWCGkHRoHtG2AwCsj8BSJwAdP2Lanaa9g8Y8Wvad5/rGDwQ1OahoQcNVy+XVDzV9x7RFCKVYVJmy1RNPQB7O5WciRYKXslGRK89MvuNvmSbvGaLgKq2RL48ugW09wdK1PHxkIC4MhpVkr0kKdg9ztRwt0i9SN/RDITUImEGpFEJB7eVIAppNVQkrvb9hGH4DMVjPl0GgbLSl+UFsQJlKhFJ+qEmhzShQJ5KEKIIQ+Yn17RwYAUwILVQaZImToUQnf7FxMfL3LQaAiPScNaxWR2xRQTehmiZrpw5W+ILNqukolyFxfP6pevSn1HoOrWfpz2gmArqm54VmUadjaqtIIfB6KQaAV1z5aum7HAifU2hLkwBIE0NqI7Neh7RkUH0wRmGC0zU0u5bZ8bHRXpcUg7VQR5KUFOv+2riagF1KxM1QVqHHUHD0lTuFafIyWhcCdaptZ70Pu0ZN4bSUZmpqO/3UMvFdazdJVwAVFmdYvHKVdwzYIHDgg2JM/qJs8OOibkYoQyX0xMwTqb+BVup7FZagu4sVlUg1tqzR/wqo9cf79VTLkWvoofx3/yfjLAvYIl6yy5LCpbOsl0AG2JurCSyjsAsl21NbdWlp6m6a4Xe99kDAElGvTIfIGtAsgvuG/e9rCh39l5XguWq7ynriiClPDEshTyiDmYgtOocPxmvhlPc1s0zlwgP9x/0cHHpfVVpLbevcV8yCswVes8ttsHTsYyAyGjuiQC44rCFH0I53FjS70CHzCyf/rDXmTjO0RH9nnki/6Hanb7DkLHI5jRlqFHvUjFjLOYMGZIKl7r1QUMpZdCIOaaMpSV+H00iZN7DPdZjRBey2pGBrCUPT9/ei1g4wUTKeK7JtSXVUOk+CrToxCNoqjTm9mxCEbbZPdjVMAxiizgz9m1ENI3JZZpy48GwOyKrV96bXCmdphUuSa7RA4jiG7lmkRiiF2mkjhY2CwuuNvsy6YGgm01DQYqGDFDRvy4PBXQ0YqzFOVXvBXx2YzTdt7uJRo0llRWMOsDr6nGvtvH1fJzdHuPQt49xmS8rGWPu3LWFZ67madpILTBjE0p1qiDtRHrSWLEkmaAOCfv+FJuSRAfzbbjxGBDHDgOELrmSQeU6UjuqmTpSZQXv8Pyp2cWHXkte87C8GYx56rfH45vtcL0Krk65tb0dTOWggG/FZZpkEyJcswtTsUTo1dbGGJGME6J279FKdGbEdekp/YZ24vDdQapvfec0aVFofXwTlwyt7RyEkSg0aQrAGGPcv2g2IhICGeEFZJ5zj1FsS8OFEJyLkQtAkXK7kZDWQbD3cl6B10FCYwOnb5PK8C3joDNLnjFRA5Dx4VFrkVjdYOW8gBL0jks3Fb45741EDeWUbQBkEKGP0F7+660whrHayFx5EKh1CF7H04Z84ZwqjsgzntAd74joPEB3PMK98P2AH31/B8ht1X8djRrRlm2Uw/Dh/IyT42nd/NRATq9j6YKYmt/l9/6bh3xb52RKRn1e5uugg5GijfVWqR577L9MsxjFVXng2fGKoWsBOj/FzgNmkME4UAG6yzXMkX52umEwiEfbXO+V5kYY0VfayRfycZVezoH94Jih05/Plkf+4hufkjV5T57JT+GFfTBZRtm9LsjMmuZQBZtn3/0mz7reeZfZjIBm1P0F2GkdC1CV1zEjWR/Xcv1y9bvRT80Uu6qzQ/n69KGf8uNVvYq27Y44L+0+j6uY4RAbPMZh2prOLn0zjYORgiDNj+1bj2/mZwaDXunz+7k+Pp39OC0/OI6rmM9xTLFVcUzBNZvtB63nPE0LRc5rh1pxJoAvZIE6gYF/xD3k76eP6yyH1w9+uIzxF2b69l8irfrPT6+f193n+P9l771J1gSWrBaiA7K6FehsNYRI1HmAnmCBLBN3JzNwR+zDCY8iuPY68R4OkyyJgLwSQlCMw8Wf81FpApH5YdcWuWIbw2gw99rDP9LPE6NAd85ahywrVQhhyU9nm05W0OUdPWGlgx5vWs9q00v/5fXQfQz6Z6YZhOjkJWZa6Pykx+I7+6rH776WL+OiL7rgp995QY3P6XobVY1V0+rKoEVjEXxp3pZ5jxpEnabfbuYozjDndmpEh0IgckT+VqRpmkpZAMBpyVaIFc94VmbccltmTvbUybC7UozkrTbPU7gAemJ1erXSQjE+n6ZzM2iY4NmXLalbEzR4JYMONybzfzxT/j6cnzbGkuSfwBj6FM0j6+h93nZLKOU+8dttEANLvumFkAND3Q7SMamNAVPUVyWYSY5qXT8ZVcUqXrXEE+cZQonI3eEYYzFlLL3duC+u1FwR4AZKS5lqyG4UjMk2Ekwy6HHuiuav6APyuytBsJLkzXFmjBB6SMFGliQpycywIUStibRpeR+6vr9w+qbW9zAMLLKxKvQCDaR90nXRZxnmbmjk4Fwtj1Dgi1xKlLAkXHArs6wNd/HPvI0MV1w7zpIQCrXdcDAXCjdjFjjXx0r5XgVIIUHwtVKmBiRECgJJwcGSIsIylRp4AJumTZASfARwPMmmlzhjhZJ7xnANOB8z+3SgVvWqbk2ttv9+NbKcJxx0J3DgudmVG09XXM5Kxfn+MbKLhfurtTVgGbUlV6lw4sAMGZiGjgUD1lsLJNqEkW0Cwb0zm4G7yoD+Vpvuq+RkH96ke5oq1PNEhT31Ey/3Wk8iWpS0SdO4Rf5sk6QMLLa2wJIXZ6ssnFRbvNPUVQkMJ82paW5tB+JUSnpMjuJhWKlRTzsFOdgtXkZvd3vyOtRBhKO4Bb1hYRWVf0HsHcmfUnk5JUyW/sNQuvzf7rVA3Z8dqaWEA21LujJJQUGZiiqVsdEHGc+VGdEnnUoLo3uQvsdZHfqNLfmo2pc+FewIt1IJ5DOUijSayP5LTniny8tb/NxZIkaqiKFBOnEi1usBgk3JqpKjJb/crmXmcfLA6ae1no6bZtwy2OVnm2QDNkssIoHxjCx7LBQnPVuK5NMe9+cMXwWhj1nwymmn5V8Ilu6GH8FSyCI33bLHoOmEad8hjDzOspiLotwe+jbvbVtbvrqjsSx32pk7CoU4uE2mFfKmOD4/09N67eqLuqhK1xfMZwtddrZuc9gZdJFqchfudJtOsvYrA4U/LUjIPRtA0DdzcWemL8nt0u/XjdMsw2LiFJJYpkSW0pNLKvv3sXXXRyq5rZ0+4l7LJ6IcFgg3tsFHSQU9IhbNxRxX8AzPyMbOFeoHM97EESh21aTdDZr8nbNWa/f8PdnMHBTdb3uhsfalv5IwsIfvVkB07MnFSWeXARM65WEDFK5XkthtoL2i6KDEqjXbMHGJGe4X1FRMhb7rSBiLrCYf0RchZiPhZFKaqQi7N/SKUlU6zDzJkp/ML3n5GEpqutggIg+ozir05rBislfaRDkM+hBHVZzcIZsc1WVN5GYi3ijCBY20a3mmPT1ms1Nd90o1TL0djTp2E1weQi6Llww4q95ycrqnI9nR1FIvdY1ttTOUEkF+nTeh+2LBZ37MDthJbkZihrtyUXW7ozsomLhSPh3BWoM+MRQpZCP1Jk6+6KGkNXrVqKsoZATQUG4TEs0skMuLJreqmCdXn6i1Laihjb7HIkjS1m0drydnpMKwBXvEqBiwRH5vORZNszUm4rkZ4OPTdIcdns7LYITJE92nSGI7aoVbww/IVjWQXHNT8el0aq483e2ASTAObU8lMSVL7oDQCnfxnpuTyoC3wjqyErH+/UKfdc8QemLXO5w2AOMMxANQqpeBApy0gwj6mUIvotgNRF6t2/no0pe0X+pZRm2ONpFQ7+vgEsMqPmtwDSgq9MKYZWXSGxyYH4tUgTSAPzLtwimhHudH1DLLCVf3a1Y6jONDr4CmPaddYlEPS0aL/bIhnFVKrW8orHrQCGSTtJp1bIDp5YIJI4h+7Y91hW6vwMjlh2qQsh0Ycr5FBjumunRndhvQysgFPeU10RtDId6kp21/kQPyODhf6SD1dbcxspYiYR3PtONIxaEphVK4E/+fEWqSxYTH7auJ/W+1lpN4mgFmIN5EvNhd6k14e3h0vC6e/SKt4VteO2M3wv3zzlal0Lw8oO9SV9vfMB9HDHv8FiXH6H2pxeppVQbxJpItOn23uf5EeYM/ap5HU2qmhXb/zGoZ6wuYUWNEy0QmEeNOlzhj9thigBgwlqwFG3XJ7b0l+3QGQNYhdcMMYtJRCtImIWi5Can1qZuJRBIMayLy5maOkss3FvnkGEAU107dD4Riem6yRTaED3YZB4kC4qQAJCJSSODulginxTJacI0UNVnH4jDeXAiEXmWBN3fqTOv3MUnySAXCCDJvisjr2OLHiwnuFyuicMvYUO9DG8AueLhG+AdAthhJCmlT9OEqp+AZbxpnyRkWCjjNtubbfRhq9R2c505gEqflaGb55vrfx3nDKOSNCW384NrzBL5h4csGWFQDmKaj162AzKDLIpWrwl8zU4A+5Xgu9WtXduaB2JlzrNG3Ly2IH65yh7lv1BgTQN682prwJX3OoNvwKF1mnq5EoGVVhrIeV4y3j7IqeLdfHBOWQNg4563MVTlwZp0JZdNfvSNBL58uE3MTGJowMCpfNzhBW6DDwidclb7oVtbnkShEkQheMqPB2OKUw9sqUCuIKYyOtsotjHCkIbyfCjBJ7PTUnZiJbFmPTO94OMP0BfkBIO1zmerdii8sIENw/qJGVdemaaqmqlM43xbkgahBEhf74XQrv4Hawy2LJdu3/AWK1SyGpHYZEIdch9wif++2m84s/nwBl/rHOOGPMfKWB8MFueR+M6IZ1t85HIkwd3FPq44ZKWrSmyvMfxj3NHVVBbHbhyI93bZWVqLoAQEpTzqD7uxUqE5cCcvxWJf2kunau2lXsWa1W/SfkM48MO4Ol5YuTnf0Or2Ho6pupt2UwBONf8ssV5/pDt3KAPFOjKmUZ7G65pngbp085BljAURQ/iXngFXO9U+/PM7XRJADXdpeH7wfV7BUZIyRRRGEtHMoi4Qfh5uoic1gkH3ki0MjETkd9+FJwhVVFoeV+4jP2znVzo4+NZTaDWHAys4bBxPdQfwlaSwmKFIQcxhp5Bg6uwwUbSGRIw8jaQkiTogTChk58QygZ0XUVnrUhyFjHhBflMq1QIf/MMo8DZsNE0LOCw+4BiVQJXCQcFKcqBBW/DKuOzdkQL+RP06SXPwe++xkRRTFVOxXiOoZe34BTgynX+fDh07UhJFdMKCZ8w2ZZ/El9Kdvbv/C+C5+6IdbDkYBSKfc/Q2pmHSK6auFJAdTgmdlw9n2wtpEK6VpmC23JkMUqpW8ivc/6lvzNm/otIDCYgBgEjuJx1GCI2ecqm/mykM8vApnXSEx9BB2M9Ibj2fw30bjCiMQo6Hn/GlRR7bZxInubr0c0VC4h5ggh7p2Pi+BwdQrJtA7vMIKlHCLBLS6pHcmgUcedAQXtv1PiX52qqRTGzfJXRR2PbfbxcKKJJDvSs38XEDAw5Gcbh7Qz0RYRfDLPYFwB/tWaXy3Fp13FrPxk8vSu35zC9QRSgp8AvwiZmhGqSSnT4hN/iyEiRkvz7+tEu+qC9mtI3wx1Keu/O1iYafdPQUvROqsu2EmFCCLv33DmVbgg98LomzaJoz0CE6Lo6Pndvurwuz2gsKgCf2tfvUQkhb58FjV5EGVh2uZo4E6DjcMSW3x8AWybYk59xNgln7Ndqm4sV5GGFgLacxqEgmOGJ43d2GxBNEMgiYKqb0y3gFyuQIj8JMBDlnL8wxfuTFLaPFe5Ro7Ie1Cy0+4Evk/Z59XpVmXIDoQBW9jkydjyq/pphCjC+/v13cQ1otHo7HPhM2MiFKlLvWL+RBmoRhf/GU03yZkWYgiJZZBcWtfk6ZBaDQER2TVY6rUF6Er3tIpu5m2vnCQgAhQZtzpOctVKP52l+F2WDidL87ob6wJh6BAg9hbS+eU6gwZYGJM1u9pft7gur+IomG+VAeSNd3iUlWgN6NdJDDGIAV3Q1WZB1QGFcV8O5EzEObXf2owhDPH5vyXTLWn3dszc4TyV80i3JPuG4yVP8qp5E9peqz+mU9EweiJhZJPCjzkKdeBMW/vG612s47Io/HXiVULwimfxMyFDHg3khL6ymsCwoV3hWJzcKLwYWqfddBYgKcdZ6wW6i2LVmKV8/P7VEWMYm/gUaMLSZcoRdwrUAILX5jRz1+APsiAK9xBv1gh/huiXCsMiSbi17DInFAyryIwvWXrQF65wHB5YL0X2jJlSsrZXBUK+c6cigL5GomDHnGhxaU1U92NpGic2/hvUXrit5+09MsvM4qZVGr0u6WmcSIWktqnPSIscyrNR/CAu003uJRqbuHVnU7zSg3o9ku/R0hp0ajzWte5dKYw2rHIweoZ60RAPMbKyJuQDKjbM5VEA68oOmnVT826FFulGu8DLdqa0GkPE3Bj8WWDV5UNQC5vfd39XoWmzs2SFYLxwB6qPauLS4XlDpRqVPsXr3zBfWHa3HL39xq/r4SzKtu0hml04+pOzbEliUDArGtMRPUJIxKklpYrUiOZGS8wWQhHiqhZuualiiONXE1M8Yvd97EvVxAYUWpeEMqKqqF/GKo3Cru9BhUtVw9lQL2/75nqiKnuzrUgfzGRzjQkevxGIzWHxbp2IxwyCNJ/0ACdUi0qnDbEgLTQwvg86X4sPLZO4GMGto1v5zW9TZqcrnJR95b8c0kbUpyt+mYux9wQeNwXN4iSb1r4Y2efg6zAsmByySFIkhChQnJum74vcVyA1QWCIpuVJaVsIj14NFobqyLMvpadPdYz3bqodbCRkyP4kWCAZctfimusMN3u1rX2s6SyuAa5StVvg2hQQFUBPAjWnEg/x57Q1d4Ksynq1SsGHoC7m5UIb4QtKklkEmtAMjSnIOuE8sowFnqwSLjcoCmxmDuB5y+vu6OCR0L/MCmx3pDnvKq23h8ZvKDQAN2agOnSJpKBPLpwlKB8D0PoqGtZ1CnE0ZbZdjIp3J5aU/HrTqVBqhb/g3cfQmP6cFGqsZ7J9gJ+JSa18YMYie4tuxq7bOBMfXAomU3avXLzcf9ut4kQJsOBGKuWGgq5Z8wQbp2g+cByC97vT3kf30CYo63r2WZIRK0Qf0QTu7SwafpK7rnQZ725dV0BD24FVFJRXO0tVP4yXwhkoio34VdBqPRi3gRXl/9pn3x4PenyoV141TOrDfsy04h7TLXVPsvTmsHNblEgjLhiimF+81DngWuiZZdqhRjkV4q2u4cvf6v1wY8jxOysjPznky0/OzVS2pSmFGvV+pZoUUhwjdKtrZ6mH/s8UZT+U8TfY4l6ribX0InWfNggZO2+i2RU08KMEU+Um0iFD4P+5UxcKETVuLiM18/o2Fw7xaoAfNV9wpB9RQBTGWYovIm+8BYPv8iZlk9Lr8XL3AVGfnTgUNb6C/WjIKlB0XhL/dEqw5BHQ/HIdCzUkJuSfgfHWZM8ulk41VJWedQONPSbSppb5SyjENxcNDmQLedAB/38Imbt3Tnp0Nfyvt2ITkeWxXtWvrYrwjdQX05OaVHzIYnnk0rrmyugH12TpriVLtnZWAhauQqyRceiDyIVuvH5RUkXf6msnym3QkVSu6HBs/PVYh+TbnMmWQRkFJHZcnHjQRdP8GzGAPph5sI6FX1aMFiUa2f8aTCBS3cyqg82OEwzZMTqvzf43YCg7VpxH/4A1k2U2SmZiGZY6ikA4yYFEqfzjzwtEHKPhfWOSNHB2aJHmBDaB6/DroJH1ghwa1pzmO9FHeTh6Qi3ga0P7ABmPZiwNtQlQy6I6skoYYyhU9udPI+kFXLrmDlJXlK+U45BvgdLnsJbexB17hdEo+YJexBe2CzuoupBpsvNrw5KtYE/b16qCGfbEJ5h1cvronkHUqvr8sveuAfScOUMTJjn8KWzDtQW2vfk3crfqPTUAYfYD5L4UVXpNT6Lwh1xS0bwkaqhJ3G6Z9gGy0v7+sfmJAHJWIjcwDiDES+0hmtpX4FT+gaqmn2Cka5cZZGDWamedirHEvher7umKM+oG0xOLhzF1T/FuqApex7cjFyPh9wFswZqfA3aCb4sTvgSHzaKoxzR99fcWNwvsvCQclB57WyJmG4PHLOgZ0PFtPYgKYZHzEA7NhDlx+HSgred8ZLMTmWBjoH9xO+fowIN8H2QP46ShWr5hCYi5r6VWNzYdlpSbCSJrSbwAWVaLawe2gcmWEEWSn60FbSQeV/zI8DXV+eKEdTZWEuL5+sCVDuiCYoTcD4oyVJjr7hOwfOBsxtKqsHd0TblPUFn2n3YS78QAbfwzQ7fawF5ER+WECtQiaJlOO+FnYrQblhh/dedPDzuup42lsvRF9wX9iiIPFv/pP6xaUfqV+BDuZWTg9/gkv2dVjcCq/Mid9sMFAxMXJOXOZznhrRkDxy34c1E73VNTgzX3R1qx8XTAJPwG6NI6DR1yQUttLWqR5E/P+XeqMqBffbFBnhjXpgDIuj71cD5uQoyPJbHbbuchLrP+TDQeVmEAhkTRsKIbyf51YtYi0o7vcnAOHTDl/AGAWnLpLda0cQLay3elSTwtQ4utYndWL9b3CPm0F8wpqA82Y1jdxkKMot+JFTgw0VreR4jI83E2qm1vFgEtJtyC1StC/W0swmlwi+kT111l+XFfeqQX+QhtziDb0YWJsqOY1xvnqEkCRxVwum8o/hLeQa6vv8tgMDd0PJybyQM6LGXcQSxmK2zn1e4976fISPYm5IrBhFmvgE3/FEI2hURuCTUl9lad4+tdckVzHC+bwEccJuy9ha/GxVc3+GLDgkTvkYAszTkSVpox3ckbGg/6enN/ipeEppuj0pOYbBp8GKAFAOs679xP/4HHqAYRCjxUtWa3QeJ3rVtvGRl0PWDXdUpnMYy5Pi+ANY8OIfn7qfrj+gz86Ib+LtqrKvzdZXjue46QEF93DHcdYyw7v9xQ/bCfh+8wPiU3V/T5vBOAyL9zTHqn8+6WC3Pi/v+fOGGHCzUqcuPSPZc2ZQDiJRS0k8/GQ3sCwO/Z0CcJB3bB6C+g/I8HoQH+bg5WikSzlyhwZIhDgqwjK/hj3RbIAgu6WC8lWtsyuEXWZYOOMBLiqrVFXhTXj6WyQhHuqJPVtDnO+jS1SgdT10VryGXmIkhEMXko0iBYRQAZe8LGgM9AoBGmNdz5YCbvssvyrEQTHNduOGNGbCuSpkv6NgxBXjqqAEE5nJXkr13x/LBUcLiEpVqz+p2dsyqDLyVb9lRZI4qgbXq5aTphayOlQq2hocWp/smN+sO9XFgiDc0ixts1TSVQ1aDzFNV8jGIE8jQiPfokLfQqtj3RYIlWMTMtsJuwgBXrHOq8KXaYMfCKvzRges5kBnqww51UQWXqBCBgAKBWrxg6xqaNctVh0s03xwCMCODre6w88aM5oelzDkL/qvDWNKsEFgomZaV+waF/HUCLyPRBWdq36ZNCs75079ykOJH+opRM4MM1cf44FdT5gy/snDjn31zOEIvtwB7gKJ9gILQ4EnEWAlWfo3bSXZsVbNf/nnKtcKpmjbbJoG5Fu9rVcJT7syEMjtABgi3G7ldjZre6cSFKlL4dg47x1wd9myq+JlxCarTa6e64ssEg5lfKDQeXEOgrtKy4re+Cn2tcgLtgIsXklBzizbeLQwzZ1bx3oPOd7+nyyW2IrTnn15X78lyLeMvGCYfZVM0novBgUx2WUY4Yt6rGSut1QCKJBFI4HfiCuWc5LUs3No2zfOZNLJ86KCq1molhyCoSPwijQGNG+kaOieNAqp7Wwv0lpXlFpcufM6y6lzwIgLACePl4kaOYiZw+49va0/3tOgCK0FQ9jvKXynmwNgdPuNxhOYoZKlbN41x3eWdqa6C3vHukUkc/6V5DQ26QwLycUOVA/0eKDT9o6jiNGJkDWDYJsDxbXRBGew+ill7g+o+wG7MC23YaTALJts4SRN6p79eu1ME2QLDTxnlByS4OMMXQKzuBV84BV9URaTzMtrQedIdPhe7yN7vtgvHmip8NHI5NtOiXj/7u3rKNNLTnYrT3vJEJZC/MhijxoHgur6IegZVjcvpdRGURp+4nDNevjYlTgLlpObmTEzf4TC+Aldpdq10qnIp9G+t+AV0RTy8KqXmIXHkJ4E8sP2eLCHZBsjAVAzaIhJxNEbfXjTQPPWPAKsXrHC6fEKNSELxPPkiDrAqOzNX3gUNOEEgfht/Yp4zDKMZ7uSkrxwAM2EamIovpbXnmiSNk4BjKyAQJSWUKvEkgpspk3VroCnNbJKmI9Fyt7s4wU8xer1L9O4Yydx7Ybm9N0+7OpeJPfoQwQFEFMLQEozSxpD0qQ3kBeujFyBeky5T74j/KOv+HPxCz19G1vM8AntjNkl09dayssS2gXqiRO/yB54h6ZWwKaQainCSQAToshMVd7P7SzX59dcfCN91FNUDxRfW/pLT3nA/sk5oFl7iqFscrDSADH+m9US2Q5GFnmwIdH2BgUu+T3gUq/DT1NQawK9ZjQlDahr0tWz+eg4Or9a+TkskwSRw528Yj2a59vJk6lizd3DdTxHy0YDvAwQaZp2N1XuuijNnGo8jTCPdkd1rEF58uDZZOdIGblsCXwoQXuXWarHDS9U9V2QumXEZSGC53RFof20IPc9HrZu/dmvCek2WcBIRL5RcQ442n3EkLQOBMFhO5FwZAhojLBp7PDhS2BdNwohhYDiO5ZJqsNfnyLxdKCTGy6eW0YK9AVhrHBaHASxjEc20Ypc8ziz8iuaYt5eVX8LEha9zOuEboH1NuNz8f6ZTZfJLZmOg3bxvkl/hhHOEkYM9iM0IrM7O9CK3t7P0URFbSI+MrwiV28b9TcTw0fNFyyfYIEoUTpEhv8A2F4UoXd5MW5/0GcGKGa9f8EvWVTDfbyD3/MMLSVS26d7NsdUui0EpQYCan6DUVYhsAG4lue08oVoYE0c5uoYeKPeOyEc+lAIZGmzza1RkV6t+2lEzjRSrFlAgBE7BOmQ5gziM0FmbTJ44D7tIAln6lqQfysoWBlkMH5nPZsgtiGdOagdD4fbptHnmUDFhP4Iwy4J5n6eHeP8cEMo2dijBIthY3uGkgcaJ46dlGql+saQr3gpfcRQn+rtlj2IuEYRSzBN9Y3OcCJr1bNNfl2VWP+gM72/o1hGqYZylamxeLnPFQnGfUv22H+H65sdutQi1DEz4g5YCESAr/KCKfiTyzf3UHTKWQNOWKLgU99BMJL3582vpl19cvQKQCTnH75E0EwPN7zaneAgIIBp7InTJIWP9jgdy1MRV1BiV2lWy11XnYXqHW2d8psdxPJfN17R05hVsWqXbjOR/pb2nuesWsWbM28e04fdLRZqKAi5WNS3fM7tse1JllXDzgePrVKcXUU0mXaNLRd0U9hcKnh0+/qUaDrhXOa4Ho2evUnMDBzRaWCWJ8h11+fQhSf9Zua4n4F42IhHVqCRE3bz/wtWtdJmyRWQDF9ZDv6wMnIYAr8MWCepj0l55xhvEKvj7nwx9H8NcCu6J8bpUl8RXHo69bAYmksRE3MPVPe1BA8Xyf59raPuPPUK+lJ5v08QEaCGbO5hJkZ6p+96naUXsHFy/An8r9pCDdADkNnrGQylGmwhpg0zHXuR+6eRR9oxBQuf+PwPQQwZW07CgMARoSIkSpPC0CTYnuaaaBUEG40XFaXQH3BCicTEPCzV2IglIrzRazcd3BMUbG3+4LP0H+hwZsPT/wz88NHCjgQKjN3EWdv8x43G/EVHcZzaM7a6Uca3ifxBwEVJ/dj6E7h7hMSFY+0R4q3yPWYD016kxFvUQTD9OrJpFhjB+DM5dxSRmtf07RYfGFt49nn16F00orJpSviLqUCCcdVmX5AbXxY2It49oQoFVtAXBJf+yWJJ5JqamKpOkYgFanerweKkJC4pd4ZAIVg6J+KSabannMjfKlO9RthSoEz6D2EA4ZD31BEYUTKTJ6InJZzffnatQHOfFiQBvqgIvFfze5hVZWMLNumD2WuuedWWGlxotuLW6WTII9G7rltROKs9RAmmnfvIrxpGK4KWWeKfqtXADEP6VhCkXluBS1C5pNNcKiAaoWi4YP/mAI6KvWNYEQvhLLhvWnPAT+mnFHJjwA3bGYeIIPPdCWMYluYrnPYrf1oLXsC8juU4i54XO4tMkPt0+/9crwy/rBkfeRcCSyUYPmIKKch6e7LKaQm0INtRxUrL2/Yq1UCWEab/BJLyc5pO5Z3RdQjXyikMZIkWb5U9BiKw04kshmg0xVtf5pyWYBhMuW5MTYCLaMkLJO/88kF5mXr9Ju8gJtlRsfzucNBgx3bGgsD2MMTjOd4rrYLb3ivRIXl2SobJhCfP25ZCo1kO1xWi5bf4URCyXbLkM6HvNAf6bEdhIiv9fAh7blQOpbAvyekrMm3CSXYUJtdOHj1d7wVK1fITTg+zT3uKcMG7/6cB49qbAKubiEvfO7HJChMpsU9KI2rihreGrZOL8xcH2Pt2dFw8m+6sJVgOKuvaoPPmExBNpMx05Jvt2d9KUBPewWUDtLOcxUE2eWtlFzbN9byGIwXdTLJ+QZz27vmvCUrxqLE044q9zDh1z9+Pe4apd6h8+nVLBdIe9sT8Wzk5G8epRGLuW1i32mw9Yqn9n93cvmvJqa+pie69fb+YXwrn1UKn97KRXOKKrp5DHpIcRiFPyafRnul0VvPSuWpY93evpTp157dvXSbnvK9AQVoF89J01r/q9lO15zXBL+SrnYKtABNcOYsg1Ty0KGuvDqxEe0WedA+Ouf8noIPgyH2cilacAtxCv+mCyaCrb1eqMILhxgJh6nMrgT1CX2SiR7k2j/Chk40HX5Mx6CIvk25AdaD2s5Q92pGW4j7O2/eMDN6nKJSOj72k63/6T8O/vf+C9Rq5x5P63OWAZcB+TZX+soOYUYj6x700z6DqrUoNMC6gxKS7JtKWNTrWjv+1Jd2N6UWBNTuvOIH18DnNV/Ub+5D0L/vaZ5jr9Ubkt/VY+leyPlcBc2aM9v4CasxH80FATaWGTl80IHUSB0S2rBMe0kNKq6YgiUX/ieQyoeZkFsEepeT3rAiBQ0Bc/euvFw9I1aw0bQyre1nRMo5x/QYXCT1OpXXow5Z5aDrJztodrYmawpVGkBuq6IAs68an7q074zf5pS3qf/BHvQQLgUgd9Z5RsHXcPUu+u1wzSJfrq03EbgHmGcimF4STOca0d75Xii4s2bzw2WDS681gDonXgej6aMTdu/oXkJIwPH3yMX2BSs2MusvByu93LWdhtx1Fb52Rh1+UKhKOQAzc3Q/8GXZD7HkBzLuPJS9eb6ru8eyLyuS+gAty7zhlm1wGRlzuTkf45urELfRurzogCnOkFVQXrCTi1WeGHpoV3JlVy6VL7PYw23hLWjJiZ0LZC2KzFJhitdDifRZLJReUEYz8qRdG4poGIRXiEWD0145AJmB0Dza3UVVpIr4APktXQABHMuzOg/ewVVhgvUruG7IDvry10OWT8oJqq0YK6Q1w9aBVnfsrzqkRxzP/dT4dOVlC5ExcVVw6X2iiVdCu+VrhS8j0vK+5tZ+Bp3yHKgJjw7hU9e+gIuEHO07waV4jI+PPK29WFggoUbWycRuz40MMwh0aQTg3wyNL2JCT3KTo+2wWyAmslIP9yP9hLRZk20BHoDl1KeHEFHqF6+D3xSCwIwRcM5gyrM2qH0OFqFxBBuBPyaw176hI2zZx2z1heqQr3CYiaPIhJXqhSvnwEuGGhD5xwGOaNhCWj0c+CGY51GfWicXCQO+iSr3fyzsoibOhZUHKCZ/kacBW9PCN4Cgn/ehAAYfDhnp5L6gP3mgjPkDH6nZm3W33INv1TG7VgqDgrHXh3c8SCtZXePq+Hb4dqJDncJdOFisS4OPPxDW3PxCYMKsmgKHBq2pq1aHb+lssPeDVjJXlDrbsoVCHy3kMDfgE5DBrp8S3KhRjABwynQKtvhg3QG23n9dnboTCAHsu7A095NOvvsZ0qDljObiIKWFGJXRiKmefTWoufuXY+pOtFdixi5tBj+Lhg6AfCqKUNbdQwYx9tFfNLW0oEK4NAjdQEg4hdn1LK+Kl7Dcan+ovh4cvP0lH5eFWgL3vHHv+3e4Z6tknPShEm2SeqT2CLggwNZE51+vK5rkzeiFu6yE8sxcE+obY1AtnJBWjmypZ+ZaBHsU1UaQFbyF/ukDZdDoQNoCHpbclo0zVLCy3kt9CzEQ1BHaNrOvVLrhOUUjaWEk3ZCFsvkgVXCMRhwjARKMmapzVf6OKE3ZekGJH15SWRlSmncw662vBTfq/SePYz6aH1kQD5MJ+fpR3Mm+kLnj34Fg6GoL+C/G6moK7ShSgcNwgDEAwPE7rDAophRYFAqOe7nNf3gdojUajTEsrDAC2sh92rn+EWDltuDvQIi9cAj9jg9/+imwyW3OIo7siyr7voFVY10Bxyy4PO+1OXB+WaB5hojNfXTAdUDKVZ8mQsGrckTI65E6XOLxNXDGZnsTsScCSMkKsN1Hf/zUItrXujo2mbHj2Djws0pgo45QwyWo54CiBKNT9jUcJPSGcuHnuThGJVPKiKe7oJy57gYN/EaUGlNi+UlPuaJgTc0aTp4YWlo17MNuoQE2sKcT+RvXDk5vLC+V2TSig/xVwvPt2Ed5Q1mQea5bRyKuBAf+1zhESg/ADgmTEoUEbQ4nNVGFBTE7X+ZksawKPyn/OqczA2YJ/V017dqBbK1le2GRVbA9Ia/3o7Ub1h1Qozx/k5kgPUxA/596rwnaXc2e8fX/KyD88HWK2m4B/78UHzK/7rb7pIfrIzDuCR6JmStOmSxwa5blnmbYxHD8QHRO5peHxat/XC6W3aFOHgWezji0l4Gru6paywG40v5lHzUtlmugjv01cFNPmSOHC+/FygMC/KPn60sFtnPJOQOQ5fKe7j0QPyMlMi0pVxhbVeNFZ3AqFSFCdZdEUhfscx2lVRWHXy/vFCVbtO6zaLqK7erRJJrLuY6cID+ziARqVXs6IqlRbQXMR61srW43q9vrx+gow9/jf5mI0lelMsIjELqedBJtFpi/XAolM21e5bToKH5S/bA3IHwFN6wIfAG/V4d8sVzV3AEVin50lugYciQy/44eWpd1DwiDAX72BGTRs9uhuUvHxJQr1r9ScPwMCTTH7wMwC8n/bPuFs8dxJDg9a/Huj7X+ADAFX9cIZ26y58trAdRPvhCTcH7forGD9XS0CnyWR8lAqPSI8LSrvpFQV6F7nV+NbBA6WfJYgJxV7caqJ88SJ7558sA3VD7wONdpU+9RxvqKHvt7cbqVWX0ebWyvdGn63g8Wflp7T86qtOrHUmLKMRuaIo2mUu/Xo0knWLT7kbsMnqZww3tpS8FExOl+bIq1TRSJFBajIcn7xDuJkieXMha9WOJcI9CPOd/5yUch3cSW/MpsE4EdMqmB4lNH9K3WBYIwEKmQ8Rmk75U0pHp980GBrufHcosO5Ltat8kv706pU63IzOlapKGVWFXAaiPZVnP0UDdpgfbSw3Lr5KaiZsijDK2vfM6Nmx/fRVlzz+tOwNe72g1fb5YUfwpsuJ0Bzkor85bc15WtK/sASYOd9yIydoIo+oRYO2m75KdzQYvvwB9MDUkDuejUuM3Xh1l5lT1l9+jVEoyd4VbWFUa946tZ52zpLZlLZeDfz9AJKwDZck/6rbebl7b9+2r3vKbh9X78IHuqvvvWG75vdmS4/7ucWo3G16RCkUV+93qR6wGY3oUGtsXiY77NArD7238y9BoEsGiMLkJhv5Dw41Vk27ZdBW3FmH91UPHYscDHc7RvYTfOZudqnV/9Q8MPq4Lsfl1GDQit0tsAdkBTZQDnwNyn2OpPvFNwn563gS+i9b27wquAmJLisGb7yrz7YX3Tbb9tyNYW7Rwr3/jN6KN7KRARuSkV0+5vh4kaeMDVqbnqBWNYlhDBv3U3omSnetfKrrT1DklD590alyt3QQDtFCx2yvnuy5SJUK9bZJYDDUkU0vDe+H3oeBduilwMrK/ZF6Xz0zDwdtvcN8u8zv3+tzFe82xt69oHgMEi/NQQMh4AEwYdB8x723zbgRZrJYHg3R6xKt6inC721qskdMBgzi5IylrfuNtN1Zl7DJWJt+0qq9Fu3ln0OkGcaXUK7Grqq3yMv3GS+0lj2qUxwgggigvE69WFUxmJIZy6WMdb4un0u2kdFobTsBFq/aPPR41DOrwvld7WHdSHL2HUJ8EKIUDSKcSxSxsgVbheIxIw6MIzCOKG4wfk/DQYql0BRR/cbRpMnA94UEc+1L1XJYwgxopJpir0q7cgyr8xP3pZHqyBM7fdv9ZRSCgC+K2mjbrQiHaJ9P/sx2GeUA1cCtjstSkiVvxxzf94EqsWAh/4W56H2rpG0RgnMJpxUbS4nJnAjA+RFYOVQgoDsgil6xSIRcWGjUcbiA1vSiay9hnNSgcHEItKtmGHZf/xzl6CwNF9F1/A67gRUMa7B6qoYsmD5E1QpkJh9KyqBbWDgmayYziwYamEkxwl7eVkV++fMWfjbIQ/VBmHxwAVw889Jfqss4OSq3CaRoJWv3pmCqPS53jiDAHJnC0eQkk4wsHF5W0GMyENa4riu2rWbybiZpxyGXPNqbdwRHfpGW5qzbJT2ZmSfVp5/RUp8AdabcteGa+ZPFmiXQliu3exsnD7PiNnyB+r2vZJSH0tQMGFwkVEwmUe/NTNbHvRmEDGD92QIPeeU8o/ngLbf8jV+s9NoPH93aUc3U1Gx2bhzyxmhiRs02i3Fqjkz0ib06X0ibSCaK4NBBbH9MyBH29XI1Ws9B/va6GH9lG5OWIY7k/QNfHEAbj2I2bwBwujUgRt6+UYFhRkZpyH+MINzptVSvgZGD1fLABFOO1ON3B4ztKOG7o09MJwbUSkPLE0sWNbJyoF7n8fUVe7XVVrsVdv0cFtXPRCiMc/i6W5LDr+XJUBgUJ9Lmy6KO8K2AJFcvYbUVd2CT3z1ieybG6kemRoaIqoHuQ+EP9SWma6V1wJkGTBS5O+N1sX4o5r4izGUqsyr+ytq6o2E1B4m56AGHA9TAlWMJIogf71zWj9JBMUYoMQJ0EJXgd+FrTAWJGgbayaAoi5jcPrYiVlhc3BVmY28gSv4oBFaCXVb7DhrPRp7TeaE+bDlXLNM/QG0TZgxMoBDvSssUyYHM73zDVRd+V/mpm0h32qT+dmGYwlus1a373tAutgXeuCm0nXuxhTsJX4ec9pVNlM7CZXDhYFpSRQNBkwNFwd4/8a3q1zC/Q/lCHUVvMExumDbPzXdCdUPpHX7zo56Go7GaNxata9A1wC86HhuEsq8kzTccuvj9zYYcKB/alGkj/kkfg8tzPkH06nyFstrlwlFdoJBAZROGqob8quBhrlSGboxTnp8xbJjxx7Io1MUC0rD90sEdYFFJdW4Yt28PG1TB0bJYPbR0sb0hstRYzK7fNOmW6XJnfTG+HL7CbTXGQvljtv/0ZAbDqZ5T8vYC2dc8h0NWb2u0pQvPTQ599oqMx/f+/OfyfvjliLn2yc8ssJwXaWmW1Wd29biesz+WpqwudZWg1OvVM/7Gc1PqHbmUB1gGr3+/Luyk4x+pZnYGo6+TGhCgL41yCxWo/yc7eiNzMP8Hc+Ght2V58XSxSknkEhM8aNHm4JkSsMtHrEtth9u1jlfZHznaiqhu92On4f4vScwytFx+s/w91qZ6u0dHIXHV1c1riOMpzwzfR9gHbw0cdu2cFNAzp1y+f78JlRWcQZYDbLp2+MbgxeURB5pmTcg/rrbgu0p2brR4+lQeLH+FeIO9Z1XCbbJnT7dqahr1or0tjTpwt8lkVDa0+KUH0p7WZe+o4VXKKTUpnCzuQq6rVIpr30HEbWyPes87STotHbdVndGZjvGeHS0hsN1w/UYTiJxZGGOrK2zq5R9sE6S0D2iPoAvzJ9gqEtyrjxDSvp+rO4cCJR9/tRja+VwE+vbC937+S7sJTX10RieAxPKikGFSW/52Okz6le5hnxLdIbuHy8UgodD0k66TIyhFeH5k1Ii3jn1JRqaCLmzTqXnI7lJNIrbmNc/9DdL8p0yimoymTsn3h9WRWChR/3Wu5gWoq+VaCKPpCGHYV5eNCI8zRB/grZb6uCc5avWED/H3TNuNjq6Z/JpRiJXdeKTDsGE1zSWNBpgeYBx57dF1aUp5aJ91UOIBWvhcrtt13omXJmt8F6MtUk6WN4vRB+6GDk0+kSm4fw6glpWPuX2KspLIK67cjhGuzFEmnRrKVSTbKGygSH1XeOkrFAmvsKRJ4uKV3IeQ0dWljvlk6QZ7rSk/632MqIJHwZPqlVh7xPRR8arbytjrYZmzDEgMH6NYbCp8f29vvIli4BV2UWWqYG4WCTJK+EERbNpjozGI/5gz19ecAf6rw0revYZiOha3YC4leJwOWqCw3MYj4ZsvQnhqhcdP42hXhvX8ULUoFivtDJMDcp5XaV0tJJAUaNjFLSyBx65T99RTJNWcBKbkrRY5lsqWZrX4xQSHKeG6YfhLx8LQ5ZoXcAfT4ee2rVeD/Z2Yq469unNvhD/opgQ67BZkkm7Q9m5BGk82ZxOJbCMQ8IZhFSNkIT9REeoih6O73CHBmNjTNG+zaO30mWqOvVWTTf3t60XxDa8w9B8VQDLHicsrKmbSMlcWN+SAGDlUAbvyB1CM6s5kWIKpzZGxtaOPYd5IR2w2MMEpi9G9uCgurAFuYmMfKAoEysmiDlJsxxYda0ZKDpSb0O2PPiDac2IDPnFzDJhst46yQpj1b4f88xfuwD0f8Dxxp8M34AV2okaRoz4zzJgkWbBMtBGpemmCHuw/vOQ+I89c0ELGVz1kH6FecXVnD/N80LYksPsbzzg4MDYYDwrhgYsi3tECAYtKOiN19iirMzT2MOOUJXU74FsytAxmtdPcaLdycAFDQLBmdBNnLzDyjF/NyB2TG+pzWonAjTXFNrNhV7FX0GppeF5sgfKoYgmG0SLd/iQGjcVXrhiOljo9bfNPfIq766DdepNpFZ6CO/7a+2vg9z2AEUVMr82232zH7BLaVwSWGRb+bXy+o1LERcdzvl8v4EdWfQDgua0mxi/PTayroVx25UjVUo8mFoLrtdG2n8Z74BPUEV7cCpdBz6DBgRjG1PhJOjFYSNfaeXuvNO1iTDGLa6euvlvaSxqphuOzfvP1YtoVgRN/Hh6pVMsF5MH8xMb8vV3bs2fh9s2nd3cWoeCduO+aL59nNj9mGJ7c0ebjGHLG4VOh5eCb/2xGz5Uk2NOuULts++gqBExCIKh0nVvZYpykkjLJOyQCIvmnj0Z4I/UMiBXUEA+pafXKKHBfyCeKTMP0RBQskUy9v2h1W9vJq5+vAyLH+AEckukYNSU3F2CkGddznmMizMKFag9fU8jLvtxkfW/5+B3Dq6zX12Gpq97D53SRB1Cl5oqHWC2yNP3w/aTgLfMpe0w93jTJj1rz0GS4T1T4NCa7GujYMnxjBEhTDZMEU566gX8m/oP0PxX9HdXf9O8etFxZsTcPwF7OSnZWueJADB4j8jPRWVWtzWWQeWUR5hkaUXzoPQ6P9UxZ2XdeqW2z0vR3/T0aETCVqGyFqeBkxYBNwVJJ3ACuS1asIXCuLy/iF0DXnpNO7EpJ/E8RjkNGEiPH65MxeKjsuyJSsO5ubhUteZty8T8xEIxA4XF5EegUSHDOrIn/HcEGHq/Xp1i053jQHYKO1rE7LRS8Xiwy4EoH+oSTh041TYZyAxgUpOHrUhsEu7VrFJJGVYGTpQYe9B9HdVEUWKgKSlPfirS9MJvFYBPfyDfne4dNW3mH0eVww9gFRifId9MZqEeorhz+WoLVdxolVO/0TMtXoyPVE80I6fcSrAvinkcFrCLFoT+uUJRbFvcGGwC/P1xe5ZSBIwpRZGKbtyX7SUVo5SCYS1MGWkMnEMDVpughoRivKffem/frQ2lHB2dNfDr1W3BwyqSVnLulOukPyIgLr0KN8I/ApAgtBkz2R1g9pl1FsjlGyZ/iL665OYd8pFSc7g903+mODkeC+i8kyVLwfB1/sZGFzU5KcUzL/P1kGFzFPJuqlLBTQ09361r5UcC9IYSzjfZZOPKUQIZ1/lRHimCgZgXvfawICAdQEfS4YLpnRxUyE2St9VwsNcyXr50UegdcwHD2Mrpbq8AUdU7KtibkTZ78jPUhR6Uj98jwqUNZzUZAYnUnaQ4iZgXD1sGvbBsmQFzySGpwhz4urWjque2CYLN6phIaptbD5vUw5LlLpBq7O4iUGO4sfsLrfFOb332JtVpI8QrjqpsUt7sAe53kKYcBFud2jaHPtu//JkPDGEX520ORjsF7Fh/GxHQXHpkCcBsLwGD4A7kYpwVeap46p3EvqQ8OfwiJkgYrMs5DaZgk+SYaakv6e42/bAvbpiRYMq78BBnUxm5QL+jZCM3VPsmqKY7NHi0hY2BheQTPZvQO920dYFCxlLVfICog1AM6okEFrX1ezgHKzE7DdNJJHbjWIaq3plUkk/sLNzyU+9nVDvLQyh6AMzOPd4/hN0Ea5kBHBfTR8X9XWmRyhZWBSp4iMBqXFuoJgq+t8Be0q649oZTi0cwCQKJhFN7QbDadKOOLn5w//m+3WbH7LcXDp+xFTRzW89dcXGOsNtqGk6XCiuZUTXo/Gny/yC+oqabfowAOrXwwvNS18dqYAGChsP+G0FxFWHxkyLnSF1N8yoGP2Von2nthCvwwin//bVGAczDcaMKrn74Y2p9uQ3B9R9V58wrl+DC3Iob+hcBKB//kEbWyIFvAtzyqe8f7OZky+GtNInZUHaF59LNz9v3gPpEWMj+qaeK++aiVXI9+aMOy3OGRkhcd1bezu1iaAOULPjIzZK9YfIG04DEca9ferY9DDofwh+VLYzjdk4AFZMmA7qC7RUCWDHfPgNip+itNapzVFXG8W2XpeN986YKaJ51V79el8MPPNfovNN//YQOjXJJ4rhiSz9YNtH/g72LPjP/PGF7lsmzGfhy4xHr5cQ42lZP1sjJlZwbVdNuK4mhwlzvcl59EgejX1148DzG4cpZF2RH8McAX6v7e5Et188DYKkqPl7E4edhZVe7nRdBb0B/Ply2jZe/WpdNGaxxEEHbeVuqjw646xX2ArhP0LxQjHM9IJ/tO2xtdaT3Xt2dxIptox0NjgwAhf//ZPf4Dn2zg/CGivz67Ivb7p6uvi33QvwNe827E+6vvr/+Ap+o9zAWV5W1MfJv2vs3P775i512e+odDY8jJngwT7lATVr66vjOYfae/UjTBEAfWat/DJK0UwRQVNgMtVUSPyPcNOVnH3z0J2PFud1rgcccbrFqr4e0WXN/NMpADaYA1rbzDvjXoNq72XJ/FST7maJDFyXLYFcZrKrtqSNaP/IGG/cGWXFmPV4o71BaMeeLkrCvpHEYwANWNdQw72CKjIlpkJmXZTkkyxmbppQWXe1sDd0rrTpSYrNxhLAXA3TFv4mtIREZuLFZIhgVnAbxqV6SRS5oGROHL97wxmmoUlFGOOF7JTeTHM+/Ist/8YRYOVKqbdSaqSag2oYouM8pqWtqqgkVinTlV14es8mb0/z3iNqqouEXzNLcI0r6ayv3VjK1UQH0nCjXZtJ9SM84IF5DfkHB+P3BEX11s6ymsaq4Orc3NVdJ7EZjy+9EFp+IFsgqITjctX8fp1C3o67al7dApTNMsfRDlgqOiCajDqKv2L+ShkwZ5+ORVfPLwygUvI5H/Kybj9fXzilhyk5sRRzGfHPswVxezczOz9fAH5Yh6ZEAEjj9e4HHGQiWgT80Y6DDg0o/O64FrXXbIATnrxqJLMdU4DWcCAafpcOcR+5zlVtR+hz5lCjm/ZXH+F77LpACjFy4uO7sTAo+IyMSIchXo8eLSY/BmKI1b4mXegb5VpH2nsLSZ55yAUDcXQOmhppaqan+DDVec2O/gHaBPCnDl8Mlxg9GiaBk20rIxIddBvoNa7uJe4GpupbGd1Yyb1bOSrTaYdzOqk7sTBUX6gU+WffsL6GyH6M8igVZWtnnRbx4Br6yqvgDvbvzlhcLpkj/T9didxn92gupP+i382W0OuD2NN1D4c8AVKelblbqksdgNnUavE5jMBZRWBNkgZKXjkZ+eu8+9G+6XA+UD/HgSSHrTPv7WA4ziU1srV7fr6veGK4eN1P4nFvQrlUr143WT9LTBfFdWivBR7nDFSC1qjyXdatCJ3oX7AKZ76donW4s3W0+BkvMpmDXuyoGsuqX7Pyr5FXtH+jemJ/ikFkgCNkZVAywce30J8pilvta1Lmc5aqd/84pMNPITwSWzW27+PTOb+56xdYu72QdbMiBQ4rmjAisgbALhTlTjCvOxtgpMLGtdTdD08WtAnEimuSsflA0DHVLw/QgMRsQ1opL7HgIR67Q8OrLzDRYubAICaXe3FeYOM3W6vf7GAKcgzlZ75nFbmae6DdQsSFIrIteYd2kJAFckKMCOiO8BgstqIV/+dUt4Z/7bI6BQWETkk7HHfhGx1d0W6lEWF5UppxH1UUfuQlfqwn+HxOJCCvQviyp8v+5qTanNWFL8bjsHwaiAcXTFCK4LrBFqGNaNfMlUWEtKaFaYqkrgCR/AeCLFR13Z6i70iSwsVkDhG2K4qmrjSafTO1m34rtwRsbSFX1Z9lZAv+fWxBRXYdqV/WKF5LuSFKHwy1fFCs9nax2Y8WU2k/U3kYK0qfguRjWcrLsgaCwjMFuEcvSidw7oMYtwlcqLvNdclvr05H7pR8V30ZHiTdst/v8qMWG457YFVn3CgxhLA8mLSEq1j9UatvZGe+1/GjuW/L3kZpXSG2HPRjT8Bed7SX7jxx+fGt1cTdfe9Yy7vO0X06eM/yKRxc6piCqZB7xKZF9fDPT6vHE0LxJ8m68j1ajNCWn2jb2oNV1XxtIQ8AD0tMdfcKPaC8rgihUtPKnDDQa+tUAV5A0Knm8f/pcmLIfSVyYNMktPhLXC6Vec53G1iCU6yddhuGb3qCucfy0DqLu+MWXGEsGCo+GbPokoTyKHVydqzgPb6yzFP39Ecuo+aEh9yWqENSwrfZsaLrkN7y+6WYcPW7GLZhiCgWnPlVMZsbuqfy6eieOz/SDEmwPZldXj0zkQH/CUdC/cRTtcMu5cxQt6bqwS40mbDwNeBufFM3M0W3eroGrgerMnB5nMNCgFfdRcadz+3OsHN5o9BncmydZdcKuzqoHrgSfBnSZPia6bwBQ1wEkOATFpJpZxKwB9T3S5ULXSq+qarIwjOTgrMut14xKgE+/2+bASAAdeTAZe9bcTmXpzdTQHjHE6E6vTqlFDjvbTDAB2sR0OCGiebZltmd3MLMm8j80+Z0bXW+pm3dkhYJdDrF7YrhuBsZroBQfIGAF510zAuwMVz8UZMp4r24PNxDSxh22BEX9lHVeUmc7wdjjAwdkhFO6iHTzNsH5iLmlhBNyOiIM9MgAS1sORGHkIIs2coxikp2dWDg4gYBfBAdwMa2Z0PTsA1ZQkxhSda5mlK+kAa8fqqq65rEquaII3+tnh4RrAtrg44e5wugAvGSh6rkReZQB6NqhaC5E4PRCthvKiZiJgDwGBDKAE/hytt6PLZEvUHJnRqoHIAQbOzKElao6aIzNiZGqgmezwgB5rh7Nj4EwMHGDw7KquOcB2R/923ZCcCgJuRxw4mgHUUY4wzlEc2jxXwmlDfUCK7hBfznql40PilTKMHQWvZEmqJr8T+LwmHpWupoMthKTyvidK+Hr86oTqg7tE8pEhQIDA0pYxifgwP7iE6TnTzsnaI92NExzOMLFQYoBw5Cumynt77P69c8LTlokY1lERVa1XWTeiyfMtDLdEcBBFEJsn3ofrUkRx16A7FKc/iqNAV4K6Vo9jc4gRhLWb8xWhAo5WrAa9TkwlCr6Qir/l1dRTIEEyYp110LWSXTYoj5XHrXXbSOwbMsZSwlkZpUKIVVS/B5NsZL6Uj5//iLK7Yzo42NBwqOhkFaVd6a3aILrHr+OExrkM0TYYzSa30WA1qPzbflRXI+ONdUpRxkbj/klkuSLfCDhEm/aQ1SqTsj2lN+XT9QF0BjBOzxJpd963/TshWcXfIOwRhjWGZdtl6ysSuR77Mx6Gcf8fFb9Ph8q8ZzP6tO6EwczLQXGKt30HtUbZZufkZIauVd30WfXQGMDG753L9WjvIXueadKU0Bj55iIBv8gsQIm+3dCZs3rX/cg77ZGEs/q+uaa5wYUIDDdv+Cbx9D3hYb8p/NfK8kZOuYACDUjjUbSDGvar4nou6/5JoY9T9ltYZNx10Yk2+ZQsg8+Z+64AxWyVV5k1u1UxdqCIGAoPnHuDd9I+26n3+Ll3g2P08IHOdSovzurQlZwRwWQ7PdXx2YxiTpz2CkW8ci7kSNaWbaBJ5pH8rJHbyYgJ1/7wJS94tABs21ou2PPHm8cPFJXm3M8owaXlV9O+98ZG5VDTdHWJtzweH9ntb/41Osy4K/l1bbrV1iamii1SVYlBO+9PsILiyha/9SBsO8eU3BFta6zPvWeZd/R2eZaqX9wQucLYZ25t7eWJ2ZhVaFU931ejKc6Jdotr2vsjz1WkwmnS6ryaOrq2OkctyU+T5Dhb4fQK/55KW9lIX1spTjsTN2t2NOS3rh3148croeKtc4jHCfXE6KUzYhl9xOOezbHf6beXQ2jfJ08aPu7zW9um+f0nlFovE8V9ppxCzT5i8chSNWIg8/Q3UTj3mRIzLnuP5T1bFVJ/1kmpDvI4p66WU1vPqa/jOGpdqzburJwkdSiYsVIc+mSJU4yKbeDy1Y5SXMyg/JiY/HaJWent8NAU+H6+VphhvrTVmYWjqi+/P83hJ99Uvfi5PEX8WFxqXOmobXoc+KdWPJXvnIsNSHZGs8tfwYU1n4Q1X+FAxLs/WIi6836BmZky4mieht7coWirWWHg02SnCEZUFWylpP+RvabikJxD9VM8v9U812nuj/gtX02LVwC+o5sZkTrY1NaSaKkyA2oEUGlVvq+EgXayXWNk0+1e7EFDon6Hrzazm0cW+iTzxDi9qee071JPshHx8M/x8NjgpbozjbtCN9Pa5BdFehX/L+l26Abx/CK4Yad2ZwYfqX9FSJuBjVLBH5rnQ4OSB2pXJj5toOjI3YHNM7NKO8bWZYZAx0XYyvbn4Y/Vvcbf91WzNYyoOr9Tn093bUB1Xpa4dCzrH2uvSnl+Lxu6p//UJqzefW04Lb9CJCyOhlRjoU/WCNwOAzhX+9Y7Piq1BpadhcxcULSRpKgMNQ2GX/7y7sJsZ2vnxVK5jznDxCMvzj8YGq9UODkWpbEfbW5M1BTsFXqivtocU/XdykITo+ayt/I57Nwhz9/1120G72e7iuK7MkMbmNpPHo97n2ed2zq61MdOeXCHBb87hjvv7Fd2YzRBUSnJcZGAZmx9rcBUJBAUFImEJjOfX2S+XrXyBkav3DD6wvbgVYlqazFmdN/k/I3/mrCIxHmsVLVYlWNNnEUXa2kf51/NTfWHbSf6kzJsiK2zl9cMPFFZF2jHUqPQ75Pgl1ZVcdhR9CmiGmmVbvP6zU6Vgu1wMOKT2hPfauY5b/tiFv77Cc+IY732+ZJGXuoEhq6xdcWPUN+uz9/2mSEUAZrEQ9vDGMmy7loPzNL3/L7Przs9Xmz8f7lKEbJuKXKPSqNDEZ8mXRBPtu96Sjq96n9P5sOlAR6BkxgnihXClWV3RNlcWewDzv8varuARaVgUTiWfPbpB+GnT6ORYJEKWFSCtDTeW/CPrP1XlTrfZ+q3JbQozVZvUN5wqhlq4zanL8laklAUXuItYei9OUDRFBI0lrIJARa5PlepmBzsEG8AbesvuGa+HdMGk0kneaxDKbm7P8a/6SfL1af9G3W8NwgcqHa/sbfwYiDknOmu210fW1UVARbPFHj6XOhQAakD1b5RXwLtmEmGoigM8HonIv3Er26+M0DRZOA4GxEgkSWm7kfUCdIZ6nzve9HgW6W+fyJMR4miFUTPJQh/rwP/e0Md3wNU9YVeMFZsXpt7gDwgfd6/h3AXTMguMfm/FPgqIC4lBZQyNxPzzhB5yrP4gP9uMgt3f68/tTKmqT1epxq/7zh2uNL7583h+615UTHc1o1yQK4vkFss57a3RhsY24QwDrdAQeIJBGgseSMSJMqOPCeRvq9fwhzIhdsFkjGQOFd5TiIC0b+zNipB+rXQ89VmEQkxJHWpCN2f/q0IwScaKncBfx40kkPpCSrPPR+8JE47RGd+K3QKCRSVNghLBokwyh+YDaxKwVDMUsSdUcr3haP65KllFFCKbkfGm9+AtElotX7Mioa0ATTYvIjwfKoNvlUEnFEcv1e+H0T+LUAVFXomCg6aUYQJvQ2qA84jL6MYsrHD8Qv0vmU7gqcOExVu+QFVXzC3uikpgw6NwFO61nDATr+8lZt+ZKXmVlHmlY38xEed/TxvVfxo/7SeFXL1he56+sM2m3QelZexbHyxI62uO4lfokCUSzcfIgGiPoCoCwmaStmEAIpgX732Th+ov4e7629qLTF5z5+36X+oPRCN4vqCcqZ6ZQ317VSXu3BVk+DLiux3tQGT0+pgFp0ZlaK8ma1y4oaxDff5r2+0dXCvQ2P7Pbdby6o9E/XyqaVubl5adT2/ONq6E3Yw5XSd3lwRjq1ipI1ZxkjIy2VZU0vSrbxcQ0Jt7kHASZ7yXo07BMve06onvitYw9Ta8pP6XRtyFQZqtewe6knsAFB0gAT1xWamDoJvu/4gsBvy2A160Ke5WiDVAtTHuIYEimwAdV+2SPmTiLhFErn2QOC6S2My/YKjwCVhb2+dxtfyUf6EvPzMFbx3EQ1rrB6xDkJlAkX5SG3Cp2r4rR9BWI8oecCJMRkbVlvZfVxa/87gH8kF+T/xRODlduDZnzEIkMgQJOpCCEzqSN60ovr32qEnDXpqYDIGM4jn4Zf+xMZZoKgReUnibVD1BsJi9iIqYzIqJlJwLkYjouMx7+ifHlQFQClkbw/uWGhG6PWsI9wP/XfaC2ANuYiY0qTHrs7m+pGLuDb3T5sau3E2tAv00f4G0Vy+HRpJqys9wngpsUT7ZhwOgBHxaUkw+P6OWSDnGkpU8906CshBKRFgFLETzCeGuGBWrNk7HMq8uB/ziUVxkOuL/vbFP6VG6Sr5KnHFZBMTaBMaECUTaVXGsvDmfM955pgx75z2wZnOiWoN/i1tpXEUBYGxk+TkNSVHF+e5LUmnPFzb57u8wRxxdXGaGASTbDuFmJQTEs5vXuT85tcR44mSDw5CP54vAWAxpNuhSWgZU77YV9q0YLplkq3/cthrDmx0Zal3iatwbE29yzTSlhouAm8JKMibX+7xpiJO16qRttDnrnmJvvcyRSBq5k00T+VovxyvZLCC4wCF2tA1cCBrRvi2aUjgETefRebuS7wz68tS6+NJ7rzlFCJNGRzOq1tg/5bCmP3Jv7fhR/AqIPfkyznX9lTbcYL4iid599LU6Gi1yvvB3NLuGICBCVpZHxYzT9qx4RIG/MShG8gbVJVoJpy7NTUdwEWSHqCBlQ54OtuN6QhZdQVCuwp++uNAs5LFzWpMwpv4l6Icp50kzfOc3wtsmynWezfY0PNbHXBmTeXK1+Z7gYtqQagvqfgew/h4PteQyLDAHJgRCRdm7oSfqH7BTFgwd9ay9afBye6C5IACE7wWA2LnhaWiaqOL87NXlakQXAoAZIOBPwbAZqiuynVEyg0NGAC7RMiKs7hyeuFsa9Rls/R6VrbOyGYZ9ALrXmIujPTIBl6fFZQs6xdLAyA4HQoA9gzgzA3F9f1t4MdBgq1M3fsrSKdBA9h+AHYA6t0v9xEeGADbfMMFuiO3AwzZZxCAAbIZZjGTFYTPGVSWLOPcDnbBm/IkrRMhScASvEmozX1KQYvtz/XSB4LYLrM3ORevC7IZbCUeHkkbG360ChsxwGRClN3v21/b/R0myfzcfXc0bz0OTXSZkwN7fF/YL3b+lri3mdktS1y/DSWK29JZjaOO/4m927J7a7a7TOTf1raxGlha4hr35Gq8Hqvx5UWEAE0qf24hRNJH0TBg2zQ1leg9j7W+MnnBjMC5SMumJJ61Lzi6kYMJEjXNt39Fkl/pWiXiSnKPRDCn3auW6v4auXWoLqz+vsG7iXoeAFOlawNEDUOzTXM5Wq9GAvY9No5amZpHJafJU2IHsJVSmrJEBfa34uowAHZqzgyqcbd399SkYrc2P0e414ZYrSzWsqOSWZ1sYkVm/hzv0OaGRXIabzigcowihiYTcFOi0rnWFFOyUkYprN0aiZMGBfFnT+g4VDSU2OJhxfn/JgJYFaqlN7kqN9shtNX+X0QUqvQ8QeHd4ADWmkpFb5e8vqQyaojvzncMiy9zIED5IVEtnIKqyUFOjtVW7Jh9jCyOwHq8vQRkvahHkZSdM70ZoDO0LQDbSoLwFXw2A7K+vjAjcqqGe1MdQVFB/YC94WvmIHmyfdjQwFZJm1I3xDcJ9ydPlVhHeSDDlgJZ9//I41lKYUbwq4uFPoEAluaUg13tS0WHh7qArFseUtJ5CdfGjtZ8kACWjjaNVm6Ud8/vklvzaovdZLTzQPJHJqJ9jrblgpKYw2Ar4TsAW3dJ1ozmiHJEeNL7Pp/06ghuhIBRAl9k0exCxYwVytuHqFJbse8Vu13E6cJhSHp3enW0PQEuD1GahLrZEHX47J4QRDUjLXD+YH5LsbDWmi/nQTQ2zoCiOcVBcE+JqNYh5yUnyEMyk0VpWVAtbnCJR2zL4RHbrqXCoNekvLuR0KUBxb2FwUhPoYiBJufQYuWhmcnC1CyItjgvvc1Nao2HyUOWzPFB1DGeLZHw0pR0zNyhkhYc7e2vZsx0caZGqKRGClkVoJ4K4THbJUmqgvRuizhzkTqdw66BdFTB6u0nEpTfcKpvd82bb8skFgylLZVTOE2SOzi+udI1VyX9d5LLFzpCCtvOAWmlL1uXIUsM7P1IBXX4nigMF9UU9X1wQjaN2z8qNa3aVd6JFGspFOo5hsW4NLh4HYSqD7IoH4j8LpDJgtRJ3bvY17oZGnrZz3d4bQIw6nse5WL5QSd2xV9kCq+jycErcVrtdgfH1tLKsdpLnE6bu4Tf0FDCLymxW51unqOpked0Oqx28dao0fpI11htpGuiJso9XvcP75f8G8g+ALITg8pwWQQXBsjGAtl+iDrnC0jYV/i8v9yx8tVSOICtAWBXw5WvHoOFzWqBY7uJF02hS4FWhbKF0X5P78ZUxvzwz2R8v/vQbVq+WpufA+5F0eIYerdenG6wtuaUclzDxNqJPraiEzm3VbZgt3GFvkFa/UjbpbAshPg8lTg7ga/gE+UUQ6IqN87EbF05Uq2KyxL3/C8iFillcGgiRQlVDHQHZ9Ok+f0ofvdJkSApScSjJvK5tCS+YDz3Ik6gCgWJXQXUB7Jk7arVZTRz3/Jpm4VF69WlWUv0kbVlm4UFm5vPtp7cX7l6785eSp0M31VHaMmAV1BaT+yStb6ojbnponRUg8DzxyxV4AeefPGuTkRvTydSbG13p0Rnt1R3d4ek2NQ/HKHX3bR4V8ojvVBcUG9x5e8YCCnP5gQp3+rvdY8n5hRvyylzoU5hQvd62737WH1hs6xAtt4w1ebVl9FHVVrvzdnzQWVhnWaVYsCN9niVl7O4mPVN8MxXD1woku6fLoWO4aEpQSs7Etw5xlpd8FV5R2i6JF+pYjchUjElRcK+f6k7rKmcG1UKwicC+6TwikVV+MBzEU61yLsKizmeyp6ZGUMXeXmNVlVRm6fwXJU248c1PlwRUFXLD4j1VTcqlip8iOiviOpNea0dHqOYZAorjr5aOzEr4kQyVtHQYddJcvqq829W0V/y+ldFYrEXbQV7G233riZW+HGPg5VH+QIb9b7EJh/WScmKPElHGqr7A+WHLiriAGpfQeNB7r9jIreCPM+IhBrOB0YJjEZdzwTXkC9DmVdJWxwze4eJ13Bcet4bzc/CO1BWpEDqh8rwmwTrjafu8yBGygVajO6Wlc4JPLu9tPx45+pLjEHBTk9eCMFsoSac0nB3+WjOB2iU5wH0npnWTUnscdo8MJBzEcgpB9sshlEA9q9C/wT0GRddQT55hUerhqc9X5DK4dvbOiqK1VMNpCJZesnyrtZvsX1peWEeqwy63T370ske+fkakPq1MbPl2uPW9q5cbK0aGTo4o+ePAe+ihQb2KyRNiPWMg3ZFjfiY2FgA2uDs03IIUJDMJWl08LJtNykgRfn7AtlKLvJmaVz5v/8YmHTMwiafuhibcyXnSAqGQmAQCGFqqEXy1Th+X0bFmduIX7crF1KQwxiYCx0qhPfHkMzZ2neAy9MgjjkILmTzuDY7l89lO53sGL6CcAHCSnI6EA8bUpc31z19mlhxVcTYe9WY399f/eFj1NAGX1J8/wPfcmTJ+dAM0Cj+PqwbeXDRadMw1DTRgEIgMAhas0HRl9beGlOi/P3s3RdzY48VX4GGpQeAVG22/Hzkl1oVlIDAJcSZAXzv+Cr21O6ZBc9K7CrFB3ai/bUmtjKTmhIooYjZMoG6prJpa2gI0GiooioYIu1mlUNA7SIZwPbB+PcGUb69ndub6OrpMgLkJjeaTAgUAhGMSVV8wfkNustqM2P8Q5y7ryl+j5yjZD2/PbbQ0N/wK3gdiHuy2tJSQHPg9OnHfUVXvCjfhNen8tf5mrpa5ttGGzWEt3eaNitv1POyM1VvXYx0F4EonVOJe5dVyq/LprRoXOj+2e1EnD13ylYfCi9dolTknzYlnnEj5saO+6VSp78nugb2Lg/05f/8UtRhWS444FsZOCqeOduTEy60Z7Abxh0/lQWwirKzmkYxb6KDEc9vNfv0e84i59DENCcn9Yy+lNvXVJIzDsvxZ7rbOidXvV3rSZq9PP9sZ1Pb6kW8e836kEK5Sbulk1Ssrpz89zapw44fedLitisy1J/eHKiM06kzeVpvhrkqofD/xZaof5kcFT5R04SEBHhyTFSKcrW/prp/UuB7mk0LPbJE0WTGAUnloqZBx9f/kuFyATGYgAgUCnEsL3jmBymQ9k1AqIplBpG3EGy8Dgm/KZ7bCRqY6mFY2ns9QlgUk+1Mb0mMLJXP47xcJxhxDIUk1OhCtd7bIIxtctNZBR04L3ZALmkKGWuzto/GtEFcf5OsvVS+8iIqb1A+ac8/hOOrxieovGn9IX1jEuexCgQRCIldfClcKJFDzP1a/TITBpPyhX4URHiwPPiKEtW44M3Jux/qCSLc6lP2lP3UBeuKBgRn/kRNcVb99PXtL3sOO3to7MxisH8tbu34c4ehAAC4DCReBR/rPSRReHyAmlltfwkS2CtlOA0vhGLmzge7C02W0DQYil/Yqhksx6Ba57sWx1iwhVI0D4qcUO1zHEXBKHg4BuGbKo8c9wlNgBm8puRtmnBnYlmwIsKmsbq7NCD+WzEEojYBicfHMWnDSX/jRHO+/c82kXsWCrgKYn34+2qPnz4mayAYPMMnzvmrGZM/c+fSdKx41Z1Rr68OgUAQgzCtPl+NcW9erTEt198EMHyDjDbKI3O3W+AWxQkiW8/MpU0+QaHFXAyI4P4YK4TPubaVk3J0qfpKD/G0KJXzFnyHD7yMywrOx8f81VvTM35vG112783uHappolO7unxoygypacK5tFQRL0/Lsa1ysn8hiFZJMgyBQW5wplNSIEJfjKSFMtN+X+DI5kD9P0oKpv8bURYEGb6oERlQgAgHOYFp/93EhZuQdbxClcQ/JJgS4s3wcqDTlXYsTMBGnes5NsJiNet5cy3LnPEp3BpEQ8DtvwcCCh/IrVxf1j4roQ4oAqdkk2HOenQHp8KId3TTbKhRv4m5mATJRRWbC+ERL47rrEdaHR2X56LECJp0qaGl1MPvzdakhgx9trezxrZlh7aLaVEcY/UigTlSwy/qAVSfqMeo5zq7XnwRqsqprrP+6Sf4MHHRv/947rLBloMpSDSBKFIIRLNPtFd2JLQ2DNgbJHrgeZ9kV3nn6X8mJXC5IAnAtkwihBS+WS/+vv9ByTm7P9cKPW86cnaemaehhK4c6SzOloTGvJf619z+T91eWwQptGzQmZV6DGk7xY4JkwsKZSP1rDcejTjeg7dtETF8gwliMsxRaJQoWk5WWmbYrb0BUj+uWJtY4NZb2g3nmUo+/egd23W8r5+Hu8u5HgUzXvJ3FNNBiuzR65EshaBbMjbdSiuvKFMnnfSZw09imaqEYE3cKoBvXvWpDGAigBWKjh+9oQvtdmnE92cnNs8OTD/jmbCsri9Nu1KwGjdPReWhvUQ1Q4QhMyU8ET6MzxBaiowFmuPRcypefY0aCJFWm1lnGM2smi6D/F8NUdwK+eSCTnI+6B8PqEflg1eR2ZKCMD+vUbLmz6u3Y8H8OwEW6gaTeI/hl8T7bbMmMO2UvzX7s90DGSUQcPaJDMuFl2LKKP9SZM1HoNxxR+OSmOGS3jeqWp4nxTLtIr5XMmGlXkJADyfmuPRZ4QO9Kz1O3I+SonV21XEDNAVir5oTqLQmn+ETY4Mt9x5pZQbtJ94hOfC2q+2+/Msg/RUYP21/+6Y7+KSfEC/uuVVBLOgJhll7PhBzWl0QDWGNNGDv9SFh3qiC6q+I1uX5qpxTcP9f0FJVk8ooan7QoNrD91Da6xvLGJ7EBEz4qSYB51tjQdDtLajn8uxBaqynihDJ1dEzyDs9H6lG+z9//RXJXyC5fNb8ThC89o7weY04LxBXRP/rSZsyOs2838iCn8mV1iFbzCRBeSYLrZmPrL3SNrs5ndJMmpZbgwRDddKes4sD0ruyyVYzbaholWsNsUx/S5/KnuapmkQgRqOQt4gxt3pdP9GhAzJW0N3hE2o4uRLqpeC+u39hk0jEUGYreMecSfbYrwmoiIP21bY2+8AxcYf5kbYbqg/RQmU1Kxad+psIoQ1Smac6ljSRkgY2WvuzK5SFfugCai30KWH5CUo+5og7UmgqsWEdDxcRnIlqoclNkMQbC2TdwXqK5MQWPP6kLwcbtChYctJzheqSuTMvXY6sZXbHVKSChQA8l40AiaLqRQQBaG0AtpzVGFiF/EtTxQ6Y3CL3kPfAom3EHR062h8TwiywP0BevDvAj2TEAVMpJjVxU2H4Y5HAH46QDdP1XbqhiBWG2gaPqv4SJVutKcAA1cRHQuwqS+oTG4YGSzWktTZjXuWlH+QkNwFYajcPjZCpY4Oit2lqJgvpqRylmkSJWBgJxmGOwMKYu+PIDk+2F7EeBWFtb09m7B6LMvpT+1yJU3cS2q57QpuEOF9hY16gmZI1POLpOgDCFT5R229CzGgSAdGSVLgnIY3XTuzaI93ueUDKyy8JLYF4+5bDgazn7sdW9K3WWnsnAL2Qe50vhPBczNZTWQqO6sj2RZHyXJQgydrPRT2+4OPR1SwPBamovJzxdWUiaH0c4cqNtemwG2rC1VUtKjcJgObmMo+nNpTgGzT3Ugv7dL8DX+ch2S+OfJISY46u/xV2597oUAh9SXjd1sBpgyGjxOwsVabApWoajBPnHCCmZP2gMXzlWjM3Wb9rJeOKjRO6RyeUk1EoOPEraMbhf9wdP2tnfvhbUkn4X4GW3bH6VnKvBj6Pne+kOEnLtRl84pu10uGti3KiC5ldsdoawjwdgpyfeNwxxR2vTOl1jP52rVreflFDnj989CPW7pK7FhQw8NYS7BDAc96IoTuVhcOO2MSzoh55Q4wrRxurdAqBM6hsUIohKysZ/1BZWyig4F9hRiKpDnLIJoWthf0Ko5CMng7upK/TKqJ2V44uYDVsHaM1zxUfs4Dqw5+0sXLjjpIaAa/gzw+3y4K8qeK6AGfolhbPyjm9Fxyd+cwYSZCDuYeYnOAOXZ/KSwMKwH0X1b0MofxQdoDsjXzWbo/KDBR6khZZgKrRJe+WCvvPTJwz8H2j9QX98suKwJ3doJkKyaGcTeR6N1G3xwq6ectECyo0y9Z846LkNPHuG9CboozdcUFxo/aUak5kvwf0hD3Avaj8+Enj6RUJ8shLVfs/b7zSMJmFl3UzLnqL5BX6Kqt11tExxMLf6+M9c5GaWxUOkFwyLqKXHBcRBDy5DEkBcuRaiiMFQdrEGmnMe1VoV0SNTex7s6NzVQ9rNjij5VUnW8XA/gN9Mw2bzGpO0sYeIgrhDulRHQkpLa6MYklTzkHmvodhI+mLWay8pAlNvYszGFbriMN/5inVAxpiwjhhwbwIdxObMVH0TpyZpPshlIcpf3hbMqUOykbz2uJMr/47cxhCO71j5tjGngTWdYy+u+fj3n7grHu9/HxGzdxS8PczLtL0/gMUfMf6/KozzPUbIu0qAca9QbSQa+Gu/zR3WDN/mDR2XYd7sfwH+v6JQTEhKRbmSsuQG7xveMCupygHwVzC0FmROutLpsuNm5A+2g8kjuWUmsfWpYMXZ+fOfYE+U4HdjBOgwkWey+Uo8PRzv5tHggzT/70uLZADyexIO9RwxYc277YUNr9cv4EMBils0iv+81oRzNpqGgnvTOuTE8K7qvzGkCkqPjdb106fJ9YiUcbq8m/QVQyXyIFlXydRFFxQR1PhK5aSkM0H/RcWwYOO/g1Bi7yRzevLa+ALQ7FrA8NV6J09XBCFVCLfhASK/CXbSf7XBQ4AyrIz81PywCrcIBzIvmXhLYUtCILbVyjfXNB1WdSW2bLp8cTj1lpFFVQedJtDlLaspHpOJSv7FNlrVbXU6pkgjJasEE5RcmNlTl4QI2zbYbEskfUen2cagGwmBpw8Go0Bsrmywy5l63zd7sqleSccxeQmmO1U1I7XnVOaBhLRZUnX5Sau5REmd0rYvhZCnlWQtuR1bpy70XnjXPW5AiEU6xTLB3sJPgIQK4S4ANhhgvAao2H6voo1/y3Rpp1h4m09hfBe+ZUzL0vBH0zEwhClSrNfs60PU/JEjA3WKQ9pHaHN/Mt0GeMAkUlIlB3VWyTeT1BY0kTrhN4LkRY/Pz8MydYDsI4DuToZYg5LUdEGrzGF1gSCxEUJ85H1b1qe3N9MTiWamfnIkpuC7KTDV0GiMSSkIXEjAii6obhJoF1nRC9rH++5e728Hx1qCn5ahJ7vdA3gOdjjiEItdtockOcy+vllaKMQCAQA4Of3psJbo2JpYeTMb2sJ7fbOgWgmD+/2/zRYAv5e39l2hncdupHQ28n64ZXo2956FYh9i3l6wD+XenXb1HwPvYZQt6i3zXU5c0VpWSyicIVjnPe4bJXdm8LKs1xnN7ash/xHyo8qBWHlqNxBLHVN+kQwXY1W+vnNmzE+5ivs9V5Yic6QSTmOw1Qg/otqwpi9mgFFN2CJ6zx2aYd0LirOxoNcuuAPn21PC0lOZFEj8SV1hjz7mqzemLacIbYSpiRtIskBTdBHX7HG7W9PTbdX07L6g1b+C7v0BCAwLZ0Y/lOO4VzE9wih4cuXRuWbRLbUpd0Pf4KDBm/u73l/7apYBnqYQ50Q75MThdrYEpmtVbY6R8Xq3rHuwVk50eS9qxsTYwfy2Xm/JVn2iP9FxbzdtzY3stkvsN4QF6Jv0Cy+vjwCCrEbIN9sIOVZtrEqegztugGjhdH1CwbyVP0jilYjlAoTNIzijpxbfpoqurnPBg+fuGjqPLLibzPvGTlPUFHkxCgrs4QdoqpGRDWroEWfYajO4tVIzI2+RQeLred8V/UshrH9/EAAUsgFYDAQVqea5xigOfZRfoKPSaHOdXV2LWQgMA1JDP/JPchtSWwtrF6sZbN4Vwcx0/CRE6+HcFTl/qdMyi3kHonXOZhi6BTO98nxyjS1pGhZMmS/TMEkEGh3wOwM24/1gCKq5422TefqPhvhkJbVHvPj8QKB23ZeGAFalLKK7b0ob6FE72lv2fM5J6g+ZeXXIHsHjSTJ3bql8rjYMF7toNM7k64IN6MxgW8dpBBp3OAQXs2Qw4ekyDMbW4fqEjUMfqNWImXyyNH8b4TrpsdyFqPqX5Ses5jIoxYH4m2E64VUjjPFe9rGCkx2IfRZEV4sukRS38zLxnQScXsiosY5GPlvgu+1Uu+/d6pDIduAnhYQn5d3OhXYPuEF6vwZkDZ5LIV0hgHviuritsHak+NsE/kFW4+qTFwjBEHNwPySEtpyJtoNU+hmiMZTPj1piS3FzlqZKq2waMTZYSNHS9GKxd+K9c1mUzCqDCNHDrTWnou/bwdtBWGTkoNqkLciZVKXE80/VTgUsVNVuuhPhDUZxzSXa8XPEu8D94grzjAySPenbnvNomrPdK/ySySKghR2In7uZRPla4BMnI2eoQq3Y4sj87xMIt7wAg0qf3rpSlghylQRogvJTxHF/rhprk6KUEkqxMlDhQVcjpjU333r8fnZMx+FHxu7nzqkQfJeZhJJ+JgMmoYOP7vApiwIzq7E3TVpCIibdciZVwJkR2KSwjWQApESPGMVenTeho59z550ToBs0jh/9lphupfGg4q2YIBsp7keP0XF72bEmHuFEIZ4yvF8xKJ/k78zjYw45vZT4ujEg73u1+PvI8OIcfcrxZiLZMbVf4a+/mpYihxldzdWkKWjMKH3PmrlUHLz9fIbKS4VWTHj/JKA+Tku4H595kcManB3z29tP3ClNFPe1uvRtooLjqeGLBLzRe6xwXTG7E+sN4vX5b3XS9VzIUjFNWnIJ2JdDwa9DOuASIsocn0E495L0KB1VkDW2VniHzFbvF0QdN9fO6KgsQoByegP5XZ3qutVDnCQmG39/i7Bfv9t8FiYs0pxZ6OrmzoEMP3HbCXspCeIA7Uv0EMHH00G4Uknz7zS+6ed/nst9dkC4JQ0meLzYdoxXIYuAqfKUoMg/+8nVWwIDNHxDGSA96hoQDy9NU02bFXqGe/nkFnRuT7TANWVR57ZuHWoDqwTWqGWXBJmzapiRT0KgUjW9OaWKgOkyt+jZ5i7Pj7gRvUUAHE2e90cgDE2hdBgiJoqoTgVg8QVENpCl3VgcVchhNZv5gzKUc03EUYr69YVa35ruNpKGKy/Op+2GpB3thC1+okYMxy5UrdkBgpaYmZQHkcqSVKXwZ3LGGrkClYse74uGDfYuzoMIyCHkFUp8JVbUQ7QFr7ZZsYhUi9BhKThWQYMkO3vJ3wTal3f2l5e3hW27ILLWb58Xgzbsa5GVU1Lr+NEPe6FcwDkl7gUT2dSl+WhqvTBgxDQKA6v5+uMH+z5zLGcan3OXoq4FtUa/QyKzmT6VLj1HHJvFUOryvzJUHG5q2HiPqbmvkBPbGpFdX+EtvVC8/B8kCWeRyxwUOZ71gVxT2QLjYx4Ui5VatYlAFlESRz+7ywqWncIFlq18Enf6UazSL/YQkti0QwgS/6IMXbMNxsPqC6g4eEDhsQXLs+tj810sca+BeLfggpvBvUO5VoyuFqpubqhAoQNr5HwLIrA3dUw2JLFoB1W/5RyP3crWz9zkH4g+qI+x83cuRNTemz7vI3EQf/ehq+UtSAvLhSxRyZkaX1oZh0aL9jXcOHIO1a0+t0fjEjA1WpjVCnIxZL47ni1Nr9IRxDzwYHsuqe38uKbuBVwvDrCstvirrKTO6m5sqWqxJYXPgIO0YR3aZmUAmucSrgZwnS26ZhBFpvwMl5p1cBqTLGuuKGE6MMW1VgVK56P+le5/t6rXx71enhc820tv36dtq7nMoJvTG43lASvie+On29mRLbH6b2sgiy+GIkuDdkmQClfp2FCTENc+tuh9sRSa3dFBNyHeyKfJF54Z3p6dH5xbKxE9U27LfQmJikIJPoKEkUF1S0tE2cOGqOeP7x3TWrK8WVFAYVhe7abkd8TpRkXnUJc83yhOof54a7YtIPq/PCb+gXOWUBODd0Im7lxcXSsDs6/qs7Gz58vugFI+S0CDO9voUJG0jX/VLslNan58fGfol/4Q5Elv9Q8MDTibhsX8DZLyn3IsZ2ANlmLYZ9rAwBB4WMA7HUAOzKoIEAPL0qBwQ0CDhHtNW0JGDQn4ksn/LfBsCEp00NHBguMP7JPAtmBKIJasN/cef54+l0gu0/bL8/aPKZYIX1QqMq07I/xLgAXnqrU2XkEEKJAr6Yh2l2w5OxDZ06/PKpt5zSlifLtCK7amYB94ornLm8uU2/gqyquflTx3IOdWT85LMruVjAMda9EenVno34+mFcFzHouhDZi5mSEY+K1nDSjRYJPvI60ivMPH+LF1+JjXLjFzDlEL8VeXRWnrjcXCf8clFuCG8kepHic+92gom4qcI6wvNBtTwX7AYBhJ2masLJWMktzxE740ztpvlNSXcf6Q3H7nYorBY9YK050VHNM80Xo/pUumAH9N0d0NpaIkygVsCwtfGhs/OZWBqO53rQi8XSbKR1elL6cmgaePXI0j87kVN9U0kNMcj6L9iYU3oHSUmrI30ti64C8/5qwokK4wTVFtR4dISgBHRzIjnAq+AWricX/rVt2VC+/bmyVX+qf+zrYVO0QNKGX3RrKq6oJd/L+7nSFWZyiGYAlAzyX4n4TpL1MZZAwOGK4YE0e66yq1AKw6UWoWmXKe6UFDeCYAzghaH8rrv3UNiMGd4CY+ahgzJzv/t0HIHd3fG54Ey4RnZSt8c7UBcr4lzj6T8EN4/vUaJKUdMlsd4EJumh02XG7WzauaR7/USitB98Tzp+ffSfDbngU2Os8IjU6OzU+uVPIwC6IE9SlMZvLw1Tft4jkXxHJB4qcDwepTDxbw1veta2MN3sFFVumw8czgyaw5vVDq0tne0TU3OE06bcq40+BckTjMzUSH5wmM4rRH3XoHTVNehN+4+TSf7qkyJAkghkDYP8IYJdikvDT0dnvImoLx7zg/Z9TkZPvOYjK4uXuyN63Bqxq3ffJJcuZKrVo47LqXGoeGlkTjVkW+JQBhuxLJtdOjvxByXYkB+4cLysph5EoST8oMpD7CezM2ffIAMOAdb6v7nzvD03CMpS20P9mJ6t+9IW6FBrWgoVi6vob4mQxUw2D0FqXDmxLiTz1686q7UYU0vPcsg1V3JPLAIiRSSMC1O4B8EnCOGl0VLtEUb/w4HTXoRxTGskLh/zk527B9H/yQwE5txwfri5gN9g7Wjt82NY8mdgWllkQWdlWUiIYHQWyKzCRXFkwp0aQdv4OkFOK6v/khgGyHwDZdRgaKZXdtUoX5GUWRmYWhDU02kpR3RmfxPalGyUpnaG6mI0DTJEqqK96AwlA6mp8RdxUWQ/U2QMYPf1e3eG6RID3jxPr+gbCGys0VdkLbZDAz8wcxzbBydb06Vg5VPcB+MyuNh84k4hdVdgQova0lK8eeVeamD/QEFVcfaiBE6FJqgWOhUFAasG4vS5nsV2MyWDLpuK/LwSc9YyIZLpuXCsryJJT0mwe8No6UlNZUR6AXwQW8nlK5ImZgjS5XwIH85cEjZmKQlNqpmQpAbPklGgJQLikxEIRHmTBcln4nqZfEE9+7Jma2t3elf4RI+HOYvsyNFKm9y4p3QSpPF5Es7jzu9mzk0UJ6ZH0XeHe0kANx7c6F2PEMl7cl37WuA22flMTV9qXpfrZgAGyS2uHXUOzBRmZaw6pe5ZG6+JDdiWbpBEn6u4Ry2yDjQ6B1RwG6N48qQ1LTGf6mimnd+nEJtW8Msh7cPOUFUSfluWEPxjaMAC2j5NrwVARK56Go3fIDe89D+0y3jUKAbFg89FJvxqqtuDrs9d1QEX8pTrKNNSIa6aaKtPlvEieid9nV+XJPFnS01YanC1WbT5us+xtNDpDw6cVH1ei6UWJGJ+Tk0h7OSmvgR2dw4stEK7Djzs0p2Ylt1ta6Wkp7zxcSNm7Jqc9gEvurmira5hf57af7q0Ms8tBCwPGnlwsks7HpBVTjnHXEuP9c0LPkJXHthd3XbirdIiee6IfIcrGu/G1h8p5fbF/aZ/GbY73N/ivNUrs9XP//rkibl0n2WWY7ZDdkCRET1fpHYpfd7iSfjhh3Zrqh+Fq9zHUO7LaQbBpl5fkSWqam6pauqlJZqgEG8K/eNo4JtWyHq03sNk6owa0oRl19523CPnpCXIR/UfCbaMjh2fJDktPxpCk7xfkdHVp258ZJwJovbtxzAJa91DCO262yWorbh01stT+rKmvljhoQQu3+b0nPq1XJ+3TcXwLVAQ6smKWDB2xYLotPwtzRPUafD795kccS0kTgXTm/tqX2ywZ4EbORUUOfwKXJBZMaqYlYj6N+W1kNdgqsn1eOHG3JSKbG+JWvOjZktZu09duLyniPDDJLSmEFy1yVGQlEsihaIp+aXGBaWdqVHe+93zUCkfZsBtYuwUrDQ/17w14caR2wemRZ87ZO3xgpRHHbyweQsolT994o2jcHhKOkYtnI3bZr2LNv5JfCTIWtvX5EHl+j9uIKMlu/HU/IXwaTH5VHtp8W850aIrPoiiBGZ9HCTdvUuP+YDGjxcnTxiDxkDnzPBiibuUjW1/LU1Jig9DmlijMdm1Xt8pOkE09lIsaM03K/ANM2/EWykybVS1IL0Pk6P95rCHO6rruIUlvFDLDqy7k0Oys3H7c4sHyiegBZV/fIH5MXENr6Or/TsXIk4Q5BHPW0otVl0aPwQ+je34U+f6OaAyJXxHnvA0x4lQnpXArqv3YHxfYcmjl0GC/9utbsAMZVaQtrrWrHAqcA2B44deDuLO0Nppcs+OGktNP63SKBVhPfK0AwfvlRiRdjP/NyUS5AcBN5L5p9h+5aBUBso+aH4bYxuBSfzWzFGis1JEg58wlgtKXMxSOQxGCgNIrpZlpIoXSfNmsaOTvoqeW5sKEzuuOEzdn0sE1W6+0xoGm1TJSW3NqPG1VW62Zdf55L8gZeNmEEJ5Xyy8VQ25nsryiH2QLvEJR5REkt94tzk/v7kYVX755dG+9RaHBbVWXrfF3Tc9IMBu7zhRhklkzx4cGZhitZvWbgRW4M6ga7cnncYKCUmMVOTVmOwklcjNSQNpHmIVczvc6VNhwVWKPrA87HtzqlX1K1lgB3ObhWTfXTMhMh4gyTXxw4+9MDViETE8hFWnY2ba1gjfDy50/JaHMsnDU7Chv1iskE7sUO9pHqhuoxltGCtGs5t78FlODaGhtrMrMUKNiGD+i55DAgt9B2dilZlwRQuftkCDqepm+3G/qVhKJG01iREVpMuDWv75pWyq2HnchMkhB4cR4ZtnXEf/ng3W/pn6/xVA1TxScvZiYoFchLBK6f8jKqFJocEEHGoP3D0Tr6cWLbBOSHU42ePspn3DzUVGskwXK+768McwpAIftwp18Hl8b8yEVSbgOFwqZ+fFjnmiJ2zEqH8GI4rwdd87k7LKTO/z/d+7HDi7imBylZc+mmIweTWClUGU+21kOiTI3lhJyoyRwMQEo/TmEoFNnl3d6nHbuC+gs3RtLCUPSHYN/zEO9PRqhkCZXNzSo81olp0r4WKzGw0AsSKxEv9gvYK8nzm91QenJbN+dyMDe3GwuJbqIHrw6aV5gUnG5xdWTsZseGg+yQTPh3NYet5LClR2DFQYtGETwarpPETNbIF+WWxbk/w892QptnZ/hhmbzWJeGq79Wfx2WUR0i4Xi8vny6ZmSmwPkiTTffp0ilaabKHWREeOVVcCpi/JCdQeN1UQgJcngSIqYD6DCM76EXxsNgGQefp8JDI2hzVVuNI1mVh/7WbQ9UypTkK6WC1OKRSQaDp4stXdpY8KzyWcFS+VntBcPWy38IaGxceORMR53NmkiaEMF+MDV1s5qI+mafnol6w57msGWHB/URdOB8bvWbSMgtvK61xWhsaapBQt5oaGnVpURtidakqD139OEsj7HyWruVKxgoKvigUc+oLkleFqrMT6bgZjiaIh0okjQab+WEXaSrEm4zQ4kjTCtxSX8hA9Bnkh9T/s+mjfgqP6r8xaaLSB5c4Ztv1kdZ+tHIujxSxGTBhdAILa/oCT2XpKS/eRAIBCoUQsFQCAcBNJEIAm2J4OgZBxFLUS3tVAsPOjFeLVDdRF7DxaelHH0ZfliuNxhdcMCgFAdvnAznBDmFYOdLvyeYvXuY+MfTgGZLC6kGMRS8MsovV8NLGiPFsQlWRoaSvvWxvQEetDjKl33NPzxuOhLz8X0eJVlCx7yHWxTfjyDhfY5+NiRawdlcmfYiXjsTcvr0q2kkzNvRtQiJU/JanXOBTMc+T5j/uWDIFfgXHhyrGn6qRFtDX1z2IfjcYUslvRhznUPKdbmMTAB9DFNWIyxVLt8OV+DFnt5IBH0mEX9UjU1xhB/vog8KltyQBFWiCiqXFjYVWgd3vN2V/TYYB28L7tQgC8kqQcU+ihZRfxtC+bcduz7eDw5RAXagE7kHrH5tsfTPh/zCXJha9KqtPuqbCsQxsA2Z5p4HD/ICoyYf5K9mxhbqhYHHDla0hs05lLD08ebjxhrc2uDlRnXTsJTsv6htR1aU3VcXXlUuPaoK2vcmmMJC/n4DEVglPj5D8QCvQMQHB9InsBOeUWowf6T/f1qFWd5pYqCevqx6do8Hf+yWi4wR8TFhFkOo+6/xDLnaCEiqauLN/p8AmAkfs+H+SByY4iPPRZPl8VCkIML36dGAZ2xDGOU1ZmIC1Yj2gLzUHOjQjNdQ3/N55mocdda59c1dWY1EnX2WysCRy8vZBLU9bOmhISVP2yHWmckZORBPj5IzY1E7oJPBSeJ0QZZEgMf+3VB3KWA2rJYP1S59KsnvVgTyuuHD7cUF9kpFCisBH7zhsxGfxfnoLfbKAXlGdF7GqFuB64ITVTx8ZBR8GfxwGPz44egVjjxGKLpwRsxs+OqxCbASEfhhlQSoAkgQlRgUYrWGv/TvKAsdYHml80O+ToIrQS4egsCNqXuMA3BIQQR2vDYy57d77/XWqpF+jIw4HHn09Z5I6t6Vo7Vs6RzC9chS/Auk2Wlg8BcfTZ2WQN8B17EYvnvf+Dg7Ra0WMvPyOI1nVx2UAvG2qamQ21/3hybKMlBRz8IaAAuPwDwwI+1I4HcO/c1g82sFrASt/2QgECXJEwXi5LkEczDlgDqK4HpJY1eTh0mQdF9pKpgT+1zOAviRGv+yUFG3NP4LVX+F4jOO3/PZS7yW+HUeprJYly0EjSE7WVERUSR5Y8JOeEVyfiMImSyFVmvbG3AAsSByfF05APV6npQD9YWuBKzc8ZXJC20fGskaKf6Xh40DoUPP/Imi84U0rBxL5Uvo5J/O4MDc8nyJM0MOtp2iMn2AAAO+ZRcIxoHOXWpd646YlJ9XZxIDi/mi+IxX9BAaawrFNKTDqq6Q03UpPxwEIbwXJjxktvqZaUtDkHVTZOYsSciFXw2btx+hzhL3TTuOlUmhvIyPfwgtpLyOXXg5OLKq5h0RVMHkHC5LZ4ZsWIUcpUdFhz8MlQrjAeC6DWNEFzprFIIzDkebesK/PzTAE3aMALxnqHG1capGNt2yE65yKdQ78ZpGVoqDHKi2EyN8Zw75VOrmK+BW+vFdgGXuvuDEXDw/8XIIouwvII9frEQClkT0E84aOAloeZzkfHWE8kwm+NBeDY2BPkl1pdSpB1aU6UcCR0+nCjrAZQ6ge8ClKjcqr0epXDo9qgZvIvb3F4n7EsZmFPSu7s4srTya0bWPAx9SLK5VfNUPCh0SPzQ6Vp/fs0HQ9xP10L/KA/kcGcYRnSCxQqOHPk/4PB4aPsb4dhjo87h7BiC0NHDYbt2kmnogmk0LBC5jKqUMCEPMITTVsT4LEYHbblMBmh/M8LZpXs9vqqxUnzGS59m1eNo3EOzIn+RE/hyKiqOo5oYr7fjX5zDvEpoFLGvthDHREDy0ejBBIloXF0mxL0qThDMXIhmbnvD6YVLjA0OI3pR/2lE3rbiqQfTB+FVJuDWc5Hj3Ms0mLR3XokRcAfJynLh45wrNFg2wmoJ6RsxoNdD1cd9tCZRe1rOcRCFrIXtbxmx2XEafk1LBWqQfzyPrwleyZsJmrVqYBlLKPqfsvaMOqKfFCRIUP9876WUxJ1BfKTAVbyTpLLkyQYKnerDuYZ1Islymqhk3DWjH1MdOtqg7mZqzH0cCc4P66lytnbdEjem1oZwKmjMrEu8+02JPOtdzXtl7Ry3Q0McbPXigg6Pwi4lMYh9cUaZfrNwJgQcigdc0NIJ9/ZhCUG+UKNDbHSX6vU3hZg0L6x3ZGiX4RUo3XZmuGD3paDqsDpn86T2TuBAQXckQKlLH72QaZFaXVFps6l0cmlxfwEu77Chg9ssOaoJFCxtCZU4B2Pma+H+M46fyC2reUSReVBSPFKUO9rMOVWNJIkPcCjyfIsGThHryeJ96RFMX3azaUEcqKvrzEBNLl2B2e81NokwadrZ1rd8XNKTxJr8rsHGOqQuTDWowl/AhDS8tvcEiFIlgrym3Vem2tlAMhBIwRXqbpqDjs4nENVPols6miOSpGyILMAYiT1lS6M7ZX0rT8Km+Yqn1ZIjjuN8TxfHQ7/i0IINR9CMXciDmVY0ZZtkniWz9AU0e+rSFwF5zEuLJM3NNgtrdmaFYa+kN4iLTKaESJT2rEzV1d547ZvOurUtgM6CqlMbkLA4TILAqKJ9ldWmZvs+TPXmLyJfHYHb+PK5FktnCzMwAMVPK16oxqg4dqsO0msygdsGtgmchaYaBtKPMpFBvXvjQOzivPKeNY1oAmQTU7FGRo6+yyC25DSeMbNF/IZng/q3hGnjY/wj1EjVvsMw/ZCh8GVP9qiXe5XYPhoeAZcc2qvtsDSUzZYnBwRCed2RLTSiRXUHfhLh+oSVpehSSDultCOZlBG/u/sGi44xaPBz98RLIRgT1xZ1A2PMGhPN0Z36sgb0+SXveUuwZm7XE4qXHBw4aix9fqGaeWOm5VVd6tF6TErAOKNV+9+FGTurFT0wIu+5H+8dbxfHnebnycXZe3goHb6tKnPW36tvdY2e8cGfecpBAURlQxMDGnn36i//W04wceJbfgrRI8wRRwniqnQ6zGiv0Ugkn+tjLvHbGgrk9+OLF380W4z0n6eDtQmfob7xFhIt45xF/9hHcIQ/or6EiFvCMgNohwCKiB9C+qVIbkAARC+BNHdJHfyPgwpZyibRde35eiHt7HxEW6EfyOUIqPWINKcTgEvUIy3trtdH7Xhj4ADnzB3Rt3+2z1QX9cRE1V/9+Oawht7Avltx+Vcgz0fn+74Fzr7UBAbmiEY6vIII7hViak/kzz3Dja0MQLBXRPIUEiiKAomlkqbGnbRfS6Y5wGek0/uj/hmGnKa2/jjxzqbUJB/EsXG0LAmZVsjoKUZIgERuh8TtGELWY1bUAlToLg0G6Z7YHS6F/eBJk9N1Pyb88aukxDF/+e/PxAQWDCUZgwjHZi21BLKkwLbDOpWYFwzI+vjE8l49401Kxr8vjPg1sdN74wW+R8EKNc0uyl1sxm2xsy8YdQL3xySVk4bxa7DQP7RM73t0231zU3HupUlaoDN6+LvUO//9HcZgExTVhKDGY4rGpboU6iQT0TVJ9Qp5R2Zqg+LRKI3dtcG9Mp9kbWlxwbNFCe1CG05z8fhsmVjr4B/SS36nKQEjfAuaLKDGAEOegh15XtetUgCxjdHEMLDJlmZ6mIaYSH+ZcTgwm47CJza2xhWeAJ3bVLRzW5ZK1EOe5CyV0QX11lcGkPZtYXv7xW755+Kmys68kdbOa2pLmCq6P49YV4KznHNth79X3HSRqIEJ4lMhgVFDjlaDhJA4gAItoEWErQMtPtrrKpLz5ueR4bpHimKNzarw4o2QhJxWO5gbJ3OzG+0UhcYLeGjkdIeG1UGDo8s+yhxAS+hw583YZ2qzID3pltxp7YnzeFJ7DCzTmM5KgPOh2na4uIo17TlV8clAUDTVLwIxtKAcuAu4wfkOWxzuDLHO0umbp5OrP52OkRU3Au3mVg5PvHr2q+vnnx3iorfWzAbs+dF9qP3oedZPC+fz01LZk1yJhqnaeD8LPbNQEl5ZXaHOa3nrSwZ0Xw/mb22ZkLMBvG4+Fxgu/fk2WBIkcjw9l52YYnSjY+T7Egx7+GPZR87HNS6QO5La0pXvkjuSq7kN0Cp25FYg7uR359wIMPZFVGXqYlG5qmjNCSJbblsXmxUoh1zSWx2p7n964ryxRGl7ZqW95PnlOSvCoHXqQcNJNyKd6RHauI0HNd312RyZGoIflwUtdwJvUh9oyqTSeOcGJnsUJpy4WY7g1xuBSt/k+44L134TOhyxMtrAjamns8TR1Hyb9pRLEeT7Sj6XkEZLQnO9KDNzOwrS0yIUeZ0BAz2fKFw82zp65f3i2r0DgXUVrRPMCvnvwJntJR/DqUwdPW9kO2mv4ndHNUeWtBa7Dk70G4hJZVKacahiSH0d1NGRNN2jz7W8oLVRWe4GFdu14YxbmBDwyv+ZOH9Fa79Ml21cn6W5zc7BLtr4gXOWDLQW/3hbVTe/eOXssQQVs95l7ivnaZBN2dvJp2LsbD0gg+vENlxQYFqf0Lqo1xczAOpYnG7zj3lHvJEkCWJkZOPwlKJOp5RmznNXAp1TtGRRKOleqda8JLpJhlow4z6mf6NST44dAxd1szOQ8+MLOeFPop4tt5VBxhSxSt0CPX5uZ1+cIcnkEr+CU+ZbQGEUBJldehd+cRnTcgmmv5PKOqZyWZiDrtjZMaDQLXW23HVMSHfNX8X/VfX7wGQ5kLaEDbaXjzY8H1XXlmaqT4m5a1TYgKyjQ+FF+D2zxuWs322Xd+fv9XGtQjsNqQiCQFV6AB7DRSotVBprJYYu2RnXlI7jhPBdjPduhqOPWsnLXe8WFag7IXn69YF90hNsL/vJv7hUX0oRH9zW5vo62T+I5YnA7nr3G2NePLjdw69p32TKISkzlotwnf9d42xXjx6N0itt8T684rNnWde/ORLs7zJ7QImEvXVCGLZ3JZyWPw4uTFgLZnuzadKYh5m3UrL/YwtEhBSADHMDOrh22yuiObFmmcM4mmm1raKvcuHi2o6Igv9wJM+iLqGY21IgzFb10XgqXKo486RCq7XerUWSRkfnYpsOvtP1Objb6E27ZZVxDgkTXQaIDJHYnWO6xPsbrdCUTrDTKiERQecWSlEKeLyCpLi13ZgZ84/pAXcUxz8keEUkP23X9NPja9f66St5v492i7gdBk4IPuiCCk3xdWsMo59rivAZ2wJz3aaZrlAOAtQ5Fmzw5UBPa45DTW2Ek3pG9OO7p1aySFzsjmW1zzZ/KU8FH3sURzjZb08/FJiQuy/8YI+wCTfXy2sQ1M+6N2w2WrpoLS+mN8yv2cdflotqRm6TqNP2e8okYprXZSpgTrDDxIOiIktLy5CudMAPsRrJFU34aO3glrF9EqzUuQkR0y64cUtBSC57nIadHxDEpEv/9/O2kN/yn1R9K7+j6R7/dERF8Z0XGQhjMnZrGhxV2AhFs7t4nnuJ5ZRtqcD0blYCZ7X7zsfmSjmVhBcx779MA+f04OqVqTCc6p448YXTX45740v0rXtn7frx6Y6fPNnqfSiLu4ElwkQ7ZEm7cXEN8xALzMF6aOqP+h863FqJWGzFXEh/Xax6/Pdn6V5Z+LFdJLcQasXoDv+9K7x1dUZOdmJuTTBZS8xCr1fKKkw4060huno7I63PK/EjjcI7rI1ArJgSqeufUKnbRbf4QusAAHMim0IgiDyYdvBlrjvnFcsgl95iLRzmG9qjNSQ0CiT+jsAL2xnCfkD2YjJQsUF3zf2L5/SJ9z1wuJwk2aUZC4tPa7qKCUFxbGxVdN1YGzZADl3EI3sKKJ16XptPefHto3HUuXrZsunhyNYXySt33pleheGZR2GOf58jW6aOSkx0PlGVyj3US5u5kjF3LGFGAVex3OrgKWFEis35xpPPMM1/N2oOhGWtVug70kr9/Cy6Uk/34TbfeIvOAarjEAkbWafGG/XlbkWMvwJvD4gvbcgIL8BfL2pWdRgo9xXH5uIRf6pweDbqZak92Vc1tnG8E+FWNO1/bdsEuk2mZBwHz56+cmWrP+fi3skE/FX5R43+DX1fRgQyh9tVSYnVTZdV+swjpCBIkigaLJpCgqeThva0FX4Kn5yzrGV1fAkNyHgSQcdQnLqABY4Vk07Dp57b23HqN1BLpd1MF6MNS3cxyA+tdN29TcRPTBeIZcay5uqr9ZjTpKiRIlIZLzprKQEm5p5GuW9+4Vyyt1laYQFys2hf7omLtRqHMCLwodbGUlBzBkaPrbJW86L3+VqLd/dutE032LaZym0Kgah9xLtofX8np9ws3ZKuySxbWZ/5/q1LgJs3NrsqOGbCglrFD9zIIiGcfnnbp1zpW8vazdxsjXCWGlAryTrcDASlZZzV6lu8McANTx2ity6Nuhn8lA9hqVqe6vnFzCSULl85eapWtbZo4JNinINZRqfzZVvmzOa/HImRuoVkeK9jgQkXtUCyfvz7dxuDuLaw9qvwSVRTdWOaqa5yv0eqceNXUQoH/U/ROvFF2s05YlCpDPqHAqhSIqoC77reVqSk5xNAs5T2CmcAa1GmuoxVVU4qiC7vHo1qrCoLSBN8hx8gLiGzcGP/BdcNIVY1t3m2jzPeZqsuETyqlKvRlx0WXRKwUZcgqCsiL5+rIJZnaTM0QvsQsQiYGF89+YuytMdQUUToFRiPm6RYr8e2FMBxEIUyzahC/JCldpKJXmHrBxahcOL1oe69F84r/oeOwuzYKZWeqJrind5SgYxnzMw8sUFi/41/BNuJHWgCRjWNEb8VxMYN/z1zhNEHLEp8DygEm+A8Uu/5Z8nvSp2RDcX+nsSFIQEqqWTnHzZkF3sIcB78A9C00iRC6yYrRJmYJJOnPcMb6UiYtU14bpysKXNiPKD20a+dCLKTYyoTZkl5WO+ecg0aGNIEsi9Q7aTcdPglxHaqB7ChM73/fDzn/8X4UBWSHYnhzPjnRFoutBh6ISm3yt4spWp+V9+0Ch9h1Qd55RQzHngy90qn7nFtUR/kNFr7qFFU8WxhUmbccMiWRkpCiluALBAJjYIlfldBe6PDFK9CmEeEb8/P8eGGelGV2GFZJ31MjDV095XyWj6qpbPWv5VlLDDsQdmU1uBVO21WUdyys/SJAdOpozS3v7+vPdtPwCKn3cMNmHnp5e3ZTUTU9VLtEXQ8kCwyZl7W2WqnBRKw5xRTdWFle1pofBBIf26Dug/U8d/uh8xcEf5zI2Q8pJE9rMG3WV+3ouXD8Of2Gn+G/l3UQDJ7EG9FANqE5y5Q1X3rxw/R/98QgF/1WRcbUr9r8rrv6vXi+znc+N+4qdo2sEZBYqJDolVY3KJdAUUEBUwe03bC87MRXqPNvma2gaDr4wZ36juus8YZGjNNIMbzMxjPf2filGPVjggjzvMnayiZag4jkfhj0yLv4rNDyUvQEJM+jU9D7YuEKRwS5W+myDNH7PVXNBuSGCkb6LKs2rvc3O0PU9guU7/2Z3h/wCU0KVfmsvX1RlauwRiEGVMTq7eal4o0wZCre8+PllKxLPy5ehDXJ0VXbOOLkjopo4u9voYyX/HzNG9NPB+J2WNKa5gyPc+6YTNs1YI6itWZD7dhCdJwOM0eRx0q2rI6i3Zsbv80t4v0j4j56HunzTA99zfOaybr3HZdqMgL3n0idxcyXBod2l7vfr++vuK5zHn8MC8QcoY0PIEBiCswACCZxwelK1/AFaO6h6tKe/4CL/Fi2VRKZzliCNGbAW0m7x4PbXxjw7nIHNNVn9XRjm0RMJ8oPYUidtXmWDJ2xkMWQpt9dtnKGysYUz3uHKwdXcPhXIsGi78ZlKvArwjBQl0fLgZprEjEm+ZoB6jenzg9yIFswbWbv+qxfyJfzUnFAeyToAU8T2IoteyrlqlT1H0LqjF/lLgxIFPtXOjFF/ZCDBImsQKImJP7RjUtpFSBRElb8/kduKQKGK2Z6kBJZiJyXAj3vNYgAwGyAA3D3lEWIRo7qswInhOK0pBMiOlbrf2QjWY62pLGXG+PqDvbpOQELGxRsFejursfnGRRx5eEfMid9qYhybL+IZPthC6dxbXoaUSZa3575vfYBFQwRjyC2YJBZlEmkEMI8ytO3J00IAJAAsYVqCVEIX3Bef8EQFibdx6p+X3S/kBde8XSu8QyjIHwqBel2PaKfAT5fFIUAcU4Gowz6f+ubfQP9xr6kdHgVbGi+jMvtkmo3kdxzpn+i06uQWYatwqHZoXV3SuTKm3Yk7fuxup59qVkfUdvVHBTYTgbngBC+GK5OrDxzHXJluVW6DpFZI3BxkfvIcTP9Q+qdU0nR7xw9fOpdhIeki8pEVeK8/PacyqkezySQ0Sht3vAmtcmBjQbOkkJDteWVlb52NIf9Ega1epQUWTjJs4gpMWbNWaIug+qiClkXBZMWQWjHbppTS3nDM+zpj96ZTqLHnwQNvouIjuq7MWKUDUJjPxE4Df+BRU+QPs8o0x2oUCcQxWTOTCcuTJ5HcDyiolZh4bukYv4UqDKq7y++vubrPlKTytpxvAmderqjujVxZFuHDrr15V43yjuruHHEbjF02fxqp56SfvEHY0yVjMhdlKfT1TdRauQvj6GMH3n59yYOhzri5Jy9Pmn0i0YB6sViHZ+KCn508lfwF0o0fgn5vj5GWtoS1x5Z7fhcnP+z/eOZYo/zwjTy6YJbmUkntlOYR9ZzrmTshjzHSqnO6cKEgcsg8Q+qWOypW0Iz8gr58LLWCon5FEfFCWxRWM7pvsrazMVZPZG7oiQ4Jws2bn1TQ6kJ6D5RqvJBEFhv7O5wHofMw+rtc+cgqk7QAo/E1Owinpb154m8amwav8mbaRjp33e38czqxc3ToxXQn0u4tZ1RBsMIN1c9JqipKdCv8dQcew5Xr84zOXN8NRciYW0jIpPZpfFfI3LmHPpdeBZZXFyiT8ZlqRQ8bk56ZZ3uQm3T89w6dkxJV/a0lX0gxyhLY7KTtM6czza87a7W7opYCY62TS0APQZsJJwsiTYwb0DJA8kBhK3fB/Odnt5mO3kwh8fO3ZjrKDj+spo2GC4szRC3jTt/rQwVlXO4zRMuX8wvk2JY7TRtZeFxTvNQcf7gnOJxdqfz9Ffn6Q6t60fvalnNFPIsnsTEAU0mtXwQ/ao6Jrs9+X4r7LzhGS2ndU7bvkX5ate8/PBTxvH18+sdiYdYkfwwyeKjng3PGaP/o/I6MlqK7CbDeE0M3FGpt1qsGSwhX8alpTmk5F8iYMWA9IX5NLezsSscUYLg9o6OB8JwoM9vfCRBIrvzrek1tGhp40KUlNMCgKzQ2CdB5mSWns5tiBnyBNAnaAMEdqWR+RVwyaRC6QOdXvPdoZEG1nWkkMq9CANiJwhUvaNZV5y+IcTet9KJs2UnaPyxZywEFA+CAkXMzraFHgWS/F5ZfGT71EsCWXRDbV2t9XyvJWYK6M/FVWKA7FyX1ZYuq/MtTEsxy9gNoy6fsv/Loj3IWs9Dw5CqIHbjhPPfOd9TI/NCO85xOtQcemCk1vMUKX7H8ETzYq7evZ4yPAuebkDAa01SujjOPqfQvSLNcXWU92O7vAwslVV4NxifOtko71EiTVVRD78l8usNYyem687eC4mtLkaCjL6p8wxPQZYrSz4GKbJHSpX9kuOLqDhdfhUbvCmkzFlRWo7x452EHzZAXxxVk5NuvhccQLbwi3qYDnaunJCgHU2bT8ixZh913dw9CfQAMKgghML/klPi5nPXDUJc7BzQn8RF6ax7JykJlGJefvuJUuM1Gy7by1NCnM6v8Ns9DKeX2+lvxWFt7Ie6OjmAH9tR+WKH6YmS7HWPxi9Pb4w3x1e/bhgvc/3stAObFE65F9ZmNOTmj/yeLa6oMsnt0tgjMA9rqbRpx1/sH0p6SQ5gHQVnQMpmNIcXyjI3vBx+SdyStIf7e6anYCDsQtnTH50mtvSW71+Ib7N5YKclwCdDYoaaHNdgEzFz5OOPXjx/eq0Q/HdF93QegyxZjsW5S1ZPI+sc4I6s4AF8PyPFjNy4cXNOUqATMyWMLh1HtJpFOY/8cPrKm9zdJaLfVyT0fUzMaFjuMrs/kdvGYNaMOfxLHeI2P+Z+dHgBOwX2RzgYMX7sWG5fyNcCDyALj/Yg2uDyWv2k3kazRMitlvtF+NvsFj/M5IybeA7y1Pll8vjXwVE/4mYPWbl+LSiy3B6YerHk/K2LBcAnuLRAIOumvpwUvCECbiL6cx1fw5JMkWdEQlUGgYVpiNpqXDKuVK0ItUbkRGPfTudCuDrNBZ+qSyl9o4SNuzZ+3UhplvzgUqdm5p3HDnUmWrnKulK9zOlkWtijJ4dmyqTLoY7zoVNy+QoMAECOc4RjTtuKJrbUfE21ZVZV4Rpw8IzaEX6IlDAkvYv7OCbD4v+GMFwuX2pv4gO+TDNFF29d27Y6SZN6vKYY12ZdXIxR/YLuShoh2+0nHId+5UVfiS4/5yK67WrRjYL6MGPqducoWhlxE5z5QSzs25fPaem33mcsiuJQM6oHCONwk2c1iAfJl0bbfb3Z0rNVXRiNfBSFzdyoh37KeheiVGAcKWk2T4eECac278ACMmkDDw0r/tkZzwx4upofCeM1hicLPPd8qwephVMsV3ZrgL2XwfpW0HOz6YCzpGPjq/yZNnHfY92gcZpp9ss7hFLNlVP+yR3NucWeCwdmO7ifLj0JTtxT0xBuUTa9osqZWsDH5yPyrB0J9krNLjGex7JM15/2GZuJfQvkXmcWP1T2Q9M45LqZxT7b1m1u+/sGoeP8Ef1V8G+DTqsQCX31LXec0OHbpmUahAFom3zZZEHFS9KONzdnJe05xeDYwUpduBQDZKcD2XhMAlweatlw4mE8EihiGJpdDwI4kplf45wwiemzwR/+upoubIxYMA4Q8e92j++RrDIf/zR+KFklbtQ0zb98/Me4K5YwGt4Kwzt42CNRuqy+7EFbGazJ8rgJlsWgv74uy9TwpuZl/mSUqEfO9AXp4msz+0dybYP/JPlUXBXPqQWPGX8PQo5cjgSJMCBRL5IcWQLY0uC9atJhECRKxa7/Fbqsr/Wca6WAnB+cNwvO+8V/78S9WcN9i3cxyNePa3p7UlRreZJxTyXoMr0ExAywYACcHQCHgWEWqOcC4mwntZ0A7IDAskmv1pLCXlTi7GdUALsDwCbZSmbVqwjUlAH9Hq9A+hN5/eelPVczucs6m+R7oBstEMrja/U0jTjekLvp2hIon8DnmerEE5cA5tkuvlbUcvJEhP7zofYraFs2Na4Qlxs36NljEIsrx10kjQWKMsjaEClxjn1b0+LciNYTjRcgsugwnrBN297sHUn2iKZrkg9Q3DgvYZcX3bCq1FETRuUlFERl5krJkSdcJhzTk0givJJsxbNtZfU1zZva2uFUaC5BtxNje7NxbeifK3sk2ymh8Wy3djW5rgkOhZYv4y07xc4raCm8gSJfgtpEl0jDBDCRSDnavj7+taQB4UNoZ1O6laOvVFcr+c1TgcT4JkzCG3XiVj3hS3tF0utIV7/ZLD54Z34jSE9YWye+d5YltcOP7QGIzLxAJNKvJDeVHUj4KQMtHFzYSvvOSrdh+V8/ZnI7NyuV8NhxYVNZgaSfXMjjbhZRWAJQfnx5cRvCpcaSZCSpaZESi5u3YZvqru7SswpGhC/f2lhrrIJvv33dSIxNLQojPXSVbMuLIgniKy+8NQMAOPbS4xUHGYlHLyWmHD5ddJuVeGwjLflYd/vX4uIfHZ+Ws1RX77V/Kyn62fphrfjUd6Sa3ERgiRKeEi7FPVS1/QPybbJaR81nqRj8j/fWaLYH7yQMRBRyVEHN/1IxhPsPNuNCbr0RVxTEA+v+yAdcLJC+fbOAuKm/YidX0o0Tic86m6109TbLdW1bwaU0uXvER2R1FvVsi9TYRju38Pe37k7x6/+rk/+60CE9tt1cU/z7e1en+PpDwGgSV9hK36gy1eyTmpPJFbXHr1Va7XdPVBs4z/1MQ+6YhVFcjBqKABk4pICtJ9nijCRqmiQdw4qhGhendkvksUIzoclJKUjim6SobLimD8uesnKpvkOvXvWA7dqyT1Y+fk5Jvv8k85xGRKYm6S+jRDw7zIMluPXS1sy9npDbzm4pw3ZmZPkqtygOl38aEzE9vb40nwF9WldJb8FTkWL46vkRpGXRoKlIQbJygCAaCd1sV+ooFgz3av6+SjB87NqOoSL7laKXD25OSiLEMWNfn7R7KqKTLBf0E4H/khLDPVafjr6++3byeD9/TptQLmv7zXwKA7J0owWTmdcL58yUIFs1JtbcpmVaBBHcEcF/c6QUDtknuw7bu68u2TGcmfSnB3lg74P2ZIj7ymLz5lrrLMIQ1IDHpybxRFS6mJ2iQyYK+FQqj5eULOCl+mEMi8CcH6bB72QxpZlzA+fTPLzIov248Jjy0iG+xWbidR6I5ysecksWR8tNJ4SYFn6Szm5WBXo2nOkCIXzlrTrnzim2XC+cJx/WW7VY14tAtfzwPjBPv1Td/LaFavZ8iafW+IZPT+RTP72nWk2/9B9y6gU9ukZ8aYJbrnnPZLWM/r3fM2fBtbF7/azuVkJ2I56OQY2JKpJKY2ksGcR74swavcfaz20ltGbjG3/cFeJZYP93lLEM5kdnL5LqyCxHHU+cXn5JyTEKaUIjT0vK/iyP4rCZKtyRF/r1COs6h2d5+lFHPHgGKODKt2dzkvDnqOEvZdu1y11uOy2j+bm9ZS9TWZmgLDXnWfkMXtDq4LcrCHmbN6pZ3d3MuKGPahG7mzW9f7nUnLCXL+9sqP1+tt1aYm5bwfsfijEfmWEYZezM4VBr45vhheMLO+Q4Qc/dsn+5wFXgQS/GVPDrhT+6yGyi0WtgzhriHQHi7QoIbQEZnuPP6x8oyuu5M7o7Nd9JDAdHIa5ffsJ3yWbm+lx+y1hEyJxktbmOZ5iPXi/KK5HGNo+HNiaucXeuRrTC1pzDrZrrQ7KA2Y87RWfhK1cC48mSuO8iUOynkh7i7skvduGURf+AI2ccTXHfFFqARgVB6bVh4SLjevohR9/iM5gSk+Yhvt3nmUp+kSTWXGiOOYEIO/ssJKU3jVo9x507t/NEjAdXpoV31DevtAyuq2dYPXAUdqaV3ql098XrbdYq5/cFhSQsbUlQTEjRo2KhJr6FHob+/a+hKc8q9jrpdeFVfWcQDOGHM8evXZ87ni4VNlgqqxckhEwP+o4svpy3mx1u78srfC/E7ShPKlHIPQ7nswpHdFiHuOBF1giPaon/b80+svV/8lrV2vRMDou40TBjrl47rdcqPRabR4eonUKyskVyfipd/mBBqFrBzFDy7v+uHcK/pWgzqseLUtR3A1s2tLWI3aCSTcMcx2DqwockyDzJnmCubbuGIQUU13USaNHLFVtZXXYTOPWmzRY5oF+erFA7YiTzmZmXGe9XgRjWl0g10l5nW+UWYjKtlgLKMpVj4cusZXf6k//ywzUhLtE/5q0R3XtunRblyuPRhWqJ28SY26S7T6AD0lqwaCXqXYKTTjwgRx18DqU9I6vGOsFmFANvhAWh0+6X/fr1ePxpgE1rXq92ohGCTwEJ+DNm+6TUoyOTBaW6YF+mJLlGaxPLa5+FLN7TMDFE6//kGlbV32bANkZOapgVWnTHaLEbCgI+CWE3NkB1jOj2mpLVrmyjySwLjwAgod2vrtOUYsWde6eFTSc5i0iOkU34yk5L73Wy+Ke+zi0fZl6ZSbeRnjyJES8nvrMtA0gAxlv7U2ukBvf9aKpwLb61KhZ9sEsfk1UOuxIot0JGKxz0z42kqi3wqTwt7W8+gtHZKGyib0pjwJGBRxXwKbd4/QnWawHUk/HzE51T4yoNLmyMUUvWRdHNFamn84jx49TiXCfCcBl2Z3/n7GQdCFY1XTGupvk3BzsXE18wcQ56Ny9ojOh9XjuVvXhsrJIxh+U2mbe6xyRiRNyAi//fCkvVLzdHZcUGGm6H0PaTyLH0VgMfbkqfhzbkn4Te4zodZXLV0rKMBeKYlClV56SlqgavqT6V8A8VJydvTX3+NMw3UUGvHOfMM4dIsS43JUkT78a5trlFspdl/Z9Jm3EWfZCJD8PHkOf57A4Eif8Q0dHI7yTGb0dH9hP0fqrdVYfhJkHAZD5OiBX9eOp60ZPI5kR6IhwudEBSFgNT46LRSxIFTj0sUmJWCR1yZwpwmrfXGhr7Z3m6+xSInEyRzx6bkJO5qv5YJGl+GKI3xD6qCGux4riZUdBSI6Y3zT5KsrvGaywOqIYXZAt+W+Q6gmbU+vOOG9E8hAVvOPDasjrPpyqlc64aheMa6OFYS7TmTuUGwXj+wj5sUnizWdJFvSqX8SmTNlOkgzUsgmPEUKYYPJh0qQkx9XYwMbwISrgVo/g9vP5WbyiXCkRVmAIVXjZ4I9BcYwrmx/S7zxp3EkvlmFQ6whrHTwhe44+o7EY3MX0rpu4+PbNx3rI0zzMVpH7uwYEsquJ6HLTT9zcVM6QnSWwnWRxAI7HQS2/aS8fme8hfuIKyX7GbFs1z5+wiNGm11yraXobm8pP4nyilVjABCXBW4MLz3/PQYX11ty+nxUT1V3ZvFv6s0TVAkkJ3tGkDQcGin+h7T6ZjtG3KFk85kKbSra84Dlo22dZIy0IE/bZ+dtSGSO5p6+H6/7B7977drO2NXw2OyO0r1jadjPUJKudwjKJzwUZpmNm0CujyNFN4JrDEQSKfml/bW2fIR4lINVj6nerXI+842h92myeZGNOhQ4Gu6PlRlhdOXLUnm3a9gDZAOkaVXcl5Mio0mRz7/6x3Hwo6297VeDSluH6LwlnHsk035eK/cQaM15Dz/+0tMyxDKXOCHkptpx5cns1k/H8EORcwbV1TJHhkOSgRxJbUL5G/e4CBF923d5sMah/mfJ8G48mGap1JkFDzn6LXor74F5sXmP3Ino3PSAvClUU/YfynI2ZuFyrX9cX8oPdIwh2IIGVjQzkQqq4+yIvCYcdyikjDOWFmxUm4P1LIz9M2tXB+tDZyAbO4WsnK2eFS7gNIlvrRE98VUTNWGWqjMCRnzg6yi97KxtalRL5tF3RPK5RRcwCAtspcC7kilfHfzD5uXk4j275hdtwfCb0pv1IqEOPi0EQRAHAr9ACp9gRe1NvAymfhcL87w5t7deNxp+FsDTv3IlHI+8WYB7x+cHTneZ63jWxAw9ln1OyBYv2IGff4iuODKAyvNWXoy2PmDdSmFT5WqCJaZiAyqb95R6Ktuavbwn+VR0LhenSSs4mJUfndGhfG2zwGgwhmWmn95BE1r4iOT0BovdY8RyNiNI0tBUL6vOEZxlcffPYKIfOMTXlOWa1Yu/9wrhiHo6JEoMkHjr6lpXIxe5O2v7GVs0C7nots/sqJoRezrBDVjcd43vtnHRrzv0FhlkCeiEOcj5pQDVQ40PQ/xHlvMepbFMKryLjUpMBz8Lo8SNSWlJR0yY24cKLimvtuS1LNDxouhXBkXCb0sx5er+3acCjAP7iALIWRrGir1OZ8Mcku6EBUSbebT/VdGvDmBUXwyMUp6eq+msUI67Q1blukQNYu54+HItelQyUEuKnmgm7l5Ogk9tkJ8tD2VACEtK0wdrlxb3DOzxRSxqlPhaxbFrFrTwUS+K2LXd5G5Crvg2VLxvpTeyvZXdapQLGc3mxy+DQIINPqfesFu7rZU6MGScHOpEUtvEdjcX+3pKx5cbtFvBqak5eAU2Pmalllc5iKgnpkc37qdQuzNAM0XwcAwW/LjZ1pPJ/VahBUE1YdaDTKNXyzl+KmUmNGnhhvCjlPDeyWjT+wkT228OaAVQFoTUh5dO5cvOJwwworEFmQG4lhUrGM1jFa61sB+Z6F35rEbGtzzJvyHg1QGZuUKiOwy/15Hg1PmES6/WVl1v9J5j/7U+a6ePoAaieA3Ciq1WTlev1q68fg1scM6bY6/exYis/K3gJPXKqOj3YvzC+PDNWbHIErQPXNGbTa8t48hJ+eTG9ktGjZezLWpp4DSgutzkzJ7M6c2qpIYobUttOROywF3dkdKaysC70PuSF1Mul2mZEoYbU2DiW9RiEY4axdsO3N5e3Rasi/hrrJAUtc++o5ZZuLVhT6vKnLzO1zVed3i7MgSgqBtY4OwrThrt5dQhPVN/dBVgDWfiBXK4vHZj4Q1iFbOnh8Ies/tNzcO5eVa52aI519O9gFp5MJWzcLRd+aUNFJtL7SybyMbB1oa1tJsaKRF5tpnDDVwyQm0zQBRS/E8cRy/erCcFpzwrSpJkCe/CvthxMYxfji/pXTKQ0Vi+viIN48hMbMR5wyDwfmQ2PeioBtD61J5lJHYxcBZpO4ytwmnjbTwjqVDx67qnpP7PmBWyUkIDnB4FEVR3m03KpSsEKEGDzoEs2XiZoB4Myewup/VxYR87ej1KIhWEIWtovdD9dmkkUt2rlxUOMpbQ4gILBfNLAKUYeJhHkvUE8lR81VV26OJjcZfMj1aqGn3VAqr/Ilqm9UtRW1VB6u/TLkM99nqxCf8Jke6XMX+DSaCgTXV6inRpM2aqhMq6Ka4xHkCVW1CXXlZnJ0cxiWaNkzmA/QgTG6G0QH8xdxHBYpT3klIhaNSpZWNGQ1EVQQ1HOenw1dp6+cFuVp00CKcZTTVsTreh6pYrdbGvPi0cU/Blj0RhWNs1bEoiiX0umSxOy/rPusTOUY0Z22C/xwxq7JmWyYuTKzdntJsCom57mO25KytIGDIU41wCTuV+++/xkwgzS7wdeg+cGgcaWzyigG0Oc4v5YWPVJaYrFKYCgXZNLiU0xs0NzcnLL8dEG3rh4UoyPiiOfpxhO6WmVh68akOF1IUTENy5MDnO7i/Pg0mGOOFalfIn2Lkqq63ogQJ89tEpOYUFQXti70QsLqAyN7zDFazNCu/KrwrK7xhpmrM6dv8/W85BevIGTpmyGEDCiEAJs9VXrUAsyJAuOZw09FVvYha47aMuAlPXCQ/wZjpxGBVuqeAKqyA+B/5+6qk1OWiBLMNRXrpeeHQv3DDZ5isI9uYRwwRylTYAxBbmZeKBVR7JJ+RO8cw1eNMSMqqKvxqqnriy/UvXAxSHQTkFU7UeiaY5LzMzHzwyc5+HCpMpQJsiuZ6aVyqqUSdQWYQZGPUYCqw3w7cOeFtJEctYlk7NcDlFXXF4+3JBCwFu+dQQSPbhOscQV+/7Qh65yBg3gYAlHn51lPDH8yAUEdlZ9JaIx4e3FL91JP+7pL6xQyDlcdIwMc6H0+6eHCqLp+AURZRug+pt8s734hZlAUHr0Gu7nxMKX386x396QmUI5Iv9Mhwl85g0DIMxfzeKbirOEKXoSFJhHXkje/yAz1eq41grEfUAj/Ryz8IKPNs/IL+ekmGelXUeQlECSAk1Cf1yLEh2bx5h9bn92cV5UBCghFokNuw915KfJ0JVOV3IGaJEp/nvJdQ5uPiFmzDj64C6RUBxQk570vgJDWmxcVqfF+BYL2YsOyHCYtDiJ/naXYrGRgZajTlcoyZZkw/dUwWOVOSkNz25GShPraVUzeQFTXhg5BaDPmBMECsZF8geX3+P7hVoe82WXJYSoaxscvC59SMJsSkADPbglJoGoyA7riqtLmZsdz0zLCHUkcVAAkCxu1xypKU0okB5Q1Pcac+qMqa0JWkR6RfmyDheSmIJXmVFxNih4KC0AS0kKLBNGxYbn/5t05bIkou+zNIAfJekFoL140afCAg859J8AVEg+1KsWHPFIiLFmIgIDcSDRxnoSlhhZt9SrJLATaAVbUP2Fb16nM50OhUH/B/Yhp3E+oUUJjZmGPDByhFCVJRAkRhTQuDBGQjIz4LiqPoA/sF7c//gIOXGnrVRWwEFIsMDOQCFhCXA8yxrfRp4bVIUyUXvZvXKmFQw1167AbmXg4JnC1E2qN8fdZJ2Bq42EwIhCvTF7DjossSZYhoPD0ELyWLaEiGv3PlOuagCUBUIBfrX9sxFdcEIH7S3i4Hey/ioQlpnLixwI2B/mAij0gdcwzAJB/x1/RW8HDiNvCHWF2iyZLFi/tJPos8cEigK9CzFIeO2gAAM4kiwhhgWdwdfpqATMgJ0UgyhJNyKDg2BDCuZhDIWHrYNVWZkDEgM9f3vtATaFILRUNhVGqcTpEtN+glxprSNE0BkvFmWOguagH8PrgXGmWIDKyG5xjy/JtF/WZ/8J2Mz9kkfAGKQoV4D0IDInL4rfwEkIscP/2p1iCdAgkB7OVNuz87DV/l3IzefOi5W2i6NyZgltpJpnZvb0dFzUj+W5Dfh7SVq4WrzLlxM6kl9hMLTwY0AH2mRIVsK58rxnxVwqGlpAjF/QooQJM6LBAyKhasMWdKxyXQcIZEVFEjoCBAUnAhH1zx1+8BEIhWSAku8UX94YUdDlkZg7fvOlZkvSoZyZ/iSwSno6N6naVZlIWz11rW8hcu5UegoM8UcpXO+DA+QsIway9RDhiYSA4mUE0NqGQAcEY/2+TChD8XtodF+obP81kYw8phi0/opm8q42lWQ5mbkACKzMuLjdUPzyxHdvjUihNKBdRZ62ShaOsyowMbp5Q3K8QCKIG4jFzzEUDDCcu88O412PMAFL4g1jshOM0SR8MjJ0S9rAnm2MJWYbZ5iuKStodHgsD5PU3JnW2tv3sdyZRTEAlhmKZmnuPoeexKc6SWlFKLQ6NDMQS41i8NBp04yaYL7pCbyvB5/u7fhottGm2u7vCssF7lXGp/IxYpPwhEeK3wc+vHOi/Az031YEHFka0hTT/ovPPPa59ipUMKYC3oUbQY8hFsAaQKj5uwc/Fj3lPWvvLj/v4+LJyNcceQgqAXHvaBET4i8e0xP+/LQBgZETQQxyRtU9e+FNTCJKINrh/Cg2vYO2R5aUFp9KFXNE6BHAuKDCEaeQc1CTFRTlUPzayKH3NRJinMoMjoUU46UJUQK8fFfIC6dNRsX/tekcN9OyWq2e3r7KqX7mL5m5X/vBA5tLjGyumvLwc4uWQ8PdBaqQzvoGiSC9bIkjOwKTfzCRHGP+EY5BmJFHQXs5p+iOcRV6bkxqgColmLiJzm5pDttyH8jDhARy4IEBGTg1X0/nMJ+ykSDUBgQpID0tM5I6YRxHgglJfv8QQVGIMGW9O6GMnUBWZovgAvJoezeLE4CoS+DAUPDWM9I4lDLyZQoYWgmaaHScE7wL9VH5MkBe/xRf3hmg36s04ZH9ozufsdM1eJSQCHVpKUzNAOwBR5W0Nv9lyYoUh1g5t7k2LXpNnSlBI4fAWwrxuNXJFmgyJgjPStIWygTIRRFp0lf6CjOefTGbxKDh3Ih+OhKdjo5ZX1qQlzB2bH9hJGRdrCUn5XFhU584ZCNZXJsoXy8Ag6WFpooTefHIcsQzq89MfgNh7Ew//eO6VWok7q6XjFLGAgAB/v1FQ5En9YJQIgk83VaZIBhQhAYGY9Vjx6wR2hiW3nT1HYSRRFwgH+H7xfCxjNUZgzNQaDBqLM/Ub82qDvef6qJHhCc3qQOQvKEEY+jn7tYqbolzW7ZEeEH+TmsVdqAAJMGETM1gRSQRSU4Df1ktiCWceBi57frUQj/7m0SDbGMhBnAT6A5786nzoRCI4AEkFTB4U3S3fT9xsyw8L4+urCKNwvaHRzLzew6UwhMQAKodJoZhClz2pe16dl8StKUgK+Fm07dTX3GicLUkYgIKnY6OIEcKK3/vEkAvJuUwghALbjoF/pSKfTEZHyeHmmGjZhAgwCxh8NweiC1Cx49k0mcvxLaIAt2idOCIdd3E04mg0S4pR8MVtkSBIKOo7nMgTxSAR66A+ly9LsjMHqedJ1qGtC/c6Xpr4cIFWJaIuhQMD+iJUdz/F0dMSKBVg6yZMkvDe3rV5oeBhcDEmTyJLYNGws0jCbIGXIhiP3YaBiB5ZUkRktkncbD8cpkaLs7nSGKKNxg6AASySkcQiUwzJVjWvsNVLw8OBIQD/beqJmtO0wEG3TiWrYKuOjLo8GAqu/OFcIilzD18VdwiA+X337aiIW1qwFOUcDqyv9YLsbhI6aDFi0ohBhHHtd4Gedgf4ssWRGBjlGSb1aWzPBlVArYBQFAYC2IzYT1LvJR4+Q35pgoOq4dLkGOks16Klr0nX4AV33o7NhKoB7FK46r2TvXdWDgkF8fUVpmJKkiRbHbd2i8/kCG9uolC8+eTrij9+aD8ok2Av7quN6xXPNH4aXglxhMq04QVCbmJ+AA90COMDguGKoAZyKsvTR54T9datMvf8e8SQ6GaZwky0Z0s5ATv82D6z2ApVGFmuXTZQ/Vsxe61DUqNrX2XEl+bMrtIEZQ1x0rgHH/9GE/adok7i7Jyc4oIC48JvTM9Fa4hJ87OsofJ/fiWzhNk7gOxg/yIZmRLfb/ssLz3nDLul5/Fbgo4IpTK7RQxT5m5xC5ng2kUl/nrXHpS6/QFeLbcYFEoFY+qB73GTkShbrwEeA2F/wDIVsXUarrgEpWexDfkZQaO4ukAg6ziQFRNoxqdmuEYcwogPsILtmWfgWhIugHWS/wTuSUB5j0mdIPpphDGy1kkXrzll5H8vVwvX+nwsBFEtWskfqm90BRvWsEU2WBNPyZ5ChkUcvR6KpHSE+qDCqXDSG9XsSYMwotK9gR3sv/zYi2S/pOS1XvF/XzOoPpu60CCGHNeN8K7P4GazVrB5Wo/C55E4rJH0zy6vkROHDya6xVoa+FcM39ya6xYtbfmhiHh9uPWxehHaylVYrjVY/qqqWMub5NDoWrDwJ2pF5mBBgpJYkz5pjH+jE6bBfa8hHtFlFdLq7lrqZJjXHtleekZBg71tf0ukeuoYijg8cNe1Klq48mwU/uveKpIwEBA3zY9jKNiW8QnQfHsFWOzz4vVkpuVOFbY8rSucS774bf/ZW4rC5Ea74AjVbHTNIxHECKMzZ+mLzjuTc6mN7tZFcYETjgZOzd6Es6CAqIc6XpxyLUfoduZzkH7vhXTE6rKOll23i5IH9pFNPjkcaarKvV/pKkTz39lv70XghBAVKv3XO1p/Zr96SMUJICpI6BROlC1iGMrPKZ5DTa2Hp89LXdBm6LTA74xQLc6GAbAXSo8iI1df8ClLT4CMSQI4Do1mUFuujfjeDWDTAbWjwwNTuczDb2wyLbmInfa181LpCfx5DGNVV1SWiCd0FqarthmROKLDc4N7X9VKAliuANaA5KFGSK8KuHADNjE8aw2st405RyFD4VdWgYUbUdEYhWeZ/li1h8GMbFUHlaIBHFMAJwSlRjIU7BXI4PzsoTYC8YoX4HKGpJ4Nyh0/8V3z49DIWjNVHzDqhKllg3pmT9WiGCvEXEjro9pBWOKv4fF/+1cEwF+53WfcKLfwDvNP6gSL8HmmVonrpCfgPK4C60DE7WOa8L/4Ah7mJHTJQDTAW+xsWk/VO62Fs86WnSfFOG1EE2ytK6aWDe7ZxCeiHEhPDmuInpsoQgLkpNKalvEfQrVUnSusCMf1ZnbFV/B13Bw+VIsk56zlmv3aybuE1UoxLlBlrMmudSN2naVTLIMF2Whktdy74HhlpLZqSpcWstumGxvnwVWR1sSl3/ZqW1jAQiGq7OV7V7u1lRv0SkPW/XdTuDyxhLYYaXfT74/fRqf10M1yARr/Qyao5QyFVZyuyC/us16fM3l9b7SHm12h5i1PHs1LjlUrORwKPq2FSfhBgeYuhDuXQ+16MO7AlhZyC43YHYQdEmyYynEB6OngYzOTHt/mYddY6dKJVkTsx62LnHyUPWTNPwK2UZTZ7XiZypwt2eiJycoROei5BszhodRtTiWkgjI7CsAWYkLWhG/6p+6c5sdBxM7mgMLWl62/LH5dteQ9GtoqblVCCdeDy6+zLLs8/srB/x2pBri3K11O8ezWO5topC2ROnrMR8Ys4xZj+mhjUMZYStKjNaUuKOHaP417RGirZ6kE+i+M0yXeNSTt+eV4j5mIKaAnBsYM2Yp0heJ8qZGXxi/lX/U8VeqGNm4Lhbaa8btUJXYz2OjntMg7jqTqdmgbj5DCygXJcpPCXGI3lyTOA8kMT3TIO2TrvaSy4tDlKen9c2f51vhtSmmclyf8M7p+FcZrZPr2E/ClG8PrDsEeb20fSw7e0ttDIa2J8P5gG7S1EX+ZMbtbP4inkaZxOnrsR/ps47QxvWIZInOMkfhodakLqvqUeCv4UYrP2IW2pUb0GzhjEyqcrbtBI7UPstW7U/CXt7e6CmrBPB9a2Xj2kxfpS6rKlSMO0jxoYkaDaXmM9kpfR1m7LocVFP3ECi9xlijgcd7b6Js3rgxZwBLbSiBN7cB3trqgNDIxgjJBaXdGlaxQIW3dLBcklUVUdBXiTC3nKp3uW1octj7EBm2tay2Eap6huteU5/uditifNKuUkhjz+3SspNwNLZ1Dd0HFt2xutUIZaYY07qJ9iyRCgz1ulOdBS3/f1d5SJqvmieYL7uFv1E9+NwTzXJjRBE2YnRjcuz+upQRaGmYlHWUBhYLYreOAKhqk10H7ouLE+uAb99aw1rx7fnfkLo82YVS91MsrUBqWON8BadwWAm3tKHVDta8brudaEenKYFI5SFkXyQ0xeJS4nVblDHNcH6Umv8dL1FKf+7S6Wt8pF7fWyh9FjEyszFVzkp7dzhySdteVqX/8wIwijFfDIGu0Ta0uhNHfqRf33Cy+4nGheGFWO0gM1qmy9qngKzVgYU42U5DJKbTabdZS5IofEhpKSnrGnl8sLQrm7iKVlBVPlKtnWYHsuG+xYukE3VxqHUuzl61guPrmKnoDglRz9QJt0NamUsvm/bMz7HXccFuBtcMc2ETWQUvftKkD2bZysz5XxBPEpEl1E3qlPSKN0yrZQiBlLJn0aIL0iO47dtGV0LiJBS3NBDyLba1tdUG480B5pLVrKS0OmE15swRSCm8thMivhizbXFZd3ZGXhmkXTlklKSPSCr+8/cKs+i8H2qpsNUOzf/vrg6Xx/b35YGirZ6sIWkjEKYxzRo7AqbRffmfd3tZw071fg85kyfzthoyg72Hk3GbU4gt+eiOPodqbOAqMFjCFjDhupM+4rCUhbQXZnWmOo+UUVBaUFOztDjfl8ifhHMoIuJuNxQpcx1JEf0UGi+muiPcjLg+DKRnKNPHlb5xdcLT+O5VB9uv1LHf8FDIVvmP4t3NqolDjNpXI91dEcO/ANk+uUwSrk2qTNPma7//EFxlJWWXlbuerxX4F+sw/tgi01VnZqMAuMpi3Xy9Wk4gHP+X7xwFFsQqfAqyZ8oCskaUddBq7aTa1IFOhlkI8c8JiBF1eOa+IHGfYhU5RWF5OLj8zlafyiwwF5YQGqXwk/5OFBazSSGls4AI+qqKxMSutdK6mpx1tLFxOF0NqfUQnEMhlkzYFYRRuwUxbw/DMg2L3QklHFrp1OKnfuCFoMWhJJCoXpkhjsyCagMJ9UsbUeL7GLQTaqPDbdU+A3bTcuGrluOooHy4stPvfeTQUyiJHP1uHZr3emKjcqNiNfRqORYVZ1xBuxY3fe5WgdRebyQ6FSLJrkfU9qS5cKir3iAiP15naBpaFIqbhwNOroafqHH1/Zhck+B6iuGCrLKAoMe4oLoHhQPXulFw0UV+6v6PRgyf1ygJHlnHZt3fVu3dCHBTKlggGvR5Ri4+u3RKVt7+MqqPXMoJ3FUEcbMfDrutr1muzleJirVBVtjJZtAhJzshLl76M4hj3eaRVonJPetpr5HJM4nP8yhpJU4S0Zq/94gJh/dBcXo2FFKZITiDLgPCdv6szJ4CzryZ6dmZLbEjRoIuyK5mVZTU5nnF79IWsmGmwVLhs7JOjSXa0Q3l7u+H/XEdFAM/hFPwfd2hRxAxW2N5F9qkUSkxSO7KN4CsKxhIKWxmSaHucpa2tJFcn4ySSdFkKnaJbMjo4AycioNpCBdu1t/urcgPnjxeXhFTocvUl/d5w75GwwfkTDc16hxBXNXRqogFaWJzQQhaq59HSGKIflom8c5o4nrxs53dxf0JPeNecYtpoBK1jEQGSpe65aqMPPT3qW40eiqlATaSGZ2dE1/0R5Su+QI1hkFP5gq0PDYpYNtWSei9TeZOj8M77sCyuNn8oupJngG/eHCdNUfVGlBjFpdwNNt3REsp/Hp9dWbl3g+s/5xL+cmNXoD8zH6yxmHP0xvLCDef3hsFnj2ooGehWpuG8wh57QQO3+ij8hzqTHM0e7XqnW8+SBXtxAusZXHEah37O4fRYq3+KFoXumPcoX+0ynmWYm73A/2aABM78e9eokuOF/s4eeYsXLvVhAdAClIUkU7JjmPFs7w4/GyOxSq1ElGY6GMupx3HUJHPMq6SYzRHxdD3lp7T8JI3KmQhjPiju6Qxy90SPRHJxZuLgIkWVSw5QBArUGf1qqCVEgtQGWpD1c9Lhhl6iL0QNIt4a9ket4aW7cIua5/h4B61Gy1gmqHMGb4xm5qL6cUl5c+EWN/QRIgOIN5PE2bKwca6fN6B3BhPyGNe+7Cw0/giajR4qm0f0JdyidXpxK0M9LET5A8nGzC8bIPr0vj8QzR+Wqq4MpjOA/L5yHTMsZy8gyz1xiUBqqZan5WhoF0vGHTpwmoBvqlcmhqj59Qv2IB5S98aPlmlbYYgq2zyqOae6Mpjg0mYDiyVJjXNk8w45c7jp6jY2Jc7zKCcWw9gC8EQ2DyscA2RX378elK5sY8XS6d30qlDw3/17VXq4OJ9SIc6v+84EHs96YEK40M8Tqr+/BdGMCJBvN3KoccDXtyYgfG9S2PWeTYua5hB8ANbNlEg1VZOsaC6iKonyI5KNWVA5QPCmJ4Fle/XJj/NYmEXlc4g+5NfOFDiVfr0ZjABiIOuSouDMe1rFXKIPiHSBdobFZX1EX7XFZruhp0l6lHBU9N01+JRcioS4TiX8LRlT+0hjimnXW0i8nDRp9Aa9+HsZ7yYplDp8/0eh4CxFiFzcXRI0m3QX4zLCUukD8thyBrHRJ33Asgh6Xnl69f8D6yKJ/6EFRaSVQ7l0bMbKdz1F/L/S/Tr/onll6qrBbJ2lf741mrg7tzNEcBe3DCTxGePUs4nwFz9sjBBNsInjpeSIAMqbPEAONIG+QH71Pp8wP9eD9OOvqj/W1mI8NHRxYvQMYNYbCkMGzlVlxaUUIQt7qTuiH4DFwVeupi89U1f6/mdBhqWg/Z8t9pjymKed8cPviglMi4r9dHx8II0iD9v70TJ/L82i0xTaM6AGSNgTJroQlh+tZqTUN8aVuhSAiqaieRAIR7yZKm4gtVjKMSmBQ2XcdgQPkWCoJKLdTbD2irAjXYFsw3PdepCfkvlVjtZBuwSaQHpUWwN1DG1lnnAJ4QMlBWftR6aRiWukFRngTn3iFZ+3u2wIRX6TvkVdE1Ma59G2ATylnXMesYyRTMGg0P8KeiRiNGHumEkZcuqAUjvMaUvMVJwMTsqUJWbuyCVlLYQ5F4iWL/zXFcqUm6thtdKAUlHgWOsNxJP3La1wEcwpJTc9X7VBchhzlO+fZpdmoR4LQlZh0k/fldgxJBES8jgSJUXZxf67MbA1QZvWpEhhTlFB0a/W6nmp4b0/W1usxt6zEox5yx7MIJQaA+cRLgzvqHIKBDatdTF/QLSPD5evCbBw5s0L3RB9Y9GGyoQpjVGGGk9UrQmuoMXbTqbgiyHrI46sWClNafjMslpwSQjjhWgVnbILnIsZEE8ypIaf/o4wMrqhlURLNAsLTXVk24qAasOdGZ7JMp6duu3Udkl1vj8Fhncm+X8JIrtuptPdzR+mjXBq4f7sjKF/HzWBzQR44aN9ZeJ3C3YdDjsT1zgX+1ZojHrAa3r1g1MRTHkbrBxZnx9fruVF5DaliarZ72pyl/6laf98KL0+Yv/Sc0xjllGCG8KhRhNqTrsZZ1CxcxJgYfuWn2ee1G8EXppP6OO+m4EugChIvJ1BMkPIxsjjf15eIEmQtQB3/tkGBzYpf3zOM+zYQ6oNke0uUTUzOXAh7viKpRIH7TvfSw0FCdQKxcTPZbY7FLI17Nia5WMwsy+j9VGxe7+iLWUYUlZdn3B70XoPYs5xAscAoogeDdbD37EQ6ZEaJiyzVddnQVTLLxGCUbGWFIUr20GX4C7efBoPkqyzPeA8OiWEUTGMneF7knlj3hxb3i53kELCy4MjzVvojzuasmq/Avj4Ht2pk6K6CHIZUNjAqObenKj5eCQzJD0E8And2uB0Z6amITgHs8Cd0OqnRKcswp1fPgnKkOApckKblhAsIv5oGWxgDYyxSxY1+uqKupuykgbGL6LuNSLpIvr/yR20jvdIPrErAXxi1xVmTgqv/cL4OYk8gqNNPhyN4MAlUZfqXt0kMCi7lrhNPrkSFtRITmBmI32E6La1wDoIDnnGoLNDXKbJqUWd5hYDQ5bfnuvqVNrk3Qkj/rueaVWBd9ye+Q2OyYsH8kKMM88DVpxiLaGZVpt/uiL0oMSKzM+V+u1NZGOsLeBzr/2J2bsUSp4oqdszlxPJ4cozkyVN+Y7ywaXwTKwqgf87UBYrD8G8jEtnOgqCUc9Av7GALANcnXrUAhJ3cFoaLl3oetB/52Lr1vXqKLWP5s9pHUiSVoZn6shbpLYsXEZ+1HZZgd1vilTcbEODRaiGTlcpYwjTR/LhXEKFd4KlsMK2HRl9P/NlaNWaEj1mK7JxfnJpZgxmDsmb/QDJxC4FK2q2J+QeJ4CdfOf/4nXqUi0yeF20r4V5LUimNSGrloHtRPr0kSjZyT6nruw1bMrKQDZeXUAV0kWpYbt6VDlHFZlF9zvcutHwzuzc3lSENNOai3fpcZG8mBPvqbi3vf9fTMBvxHsyOD4Od/ZY45+Uf3XbCbhzFY7nsf/Jtw//URZERyWTouhR0UL5Z1K3G01j13MgjveSbZpxseh/qjJkSCJwLLHCEe7Y4fl9uTPMuUoFoaqSbsfiLwrBjj8p3/DZbpHHy50/hof8EaQbo5UKpak0vlOn0Og/FiEdAZYkPkjkjWdH2wjROiJBQCbYgs/cD0FVa8gfw5F38z6fO3oHCfuDwI3C9McwTE6jLljuj0g2OZ77P+mwkGHOY2AJsia/QhX7I7o/CszdIsrDDs25kfqg5/lNE1N8K8vU/9AccZRtKOd2z/MVjkyHHhKnoqT+iOknOTsnOIULUUl3KgqzY6bBTNGKMYc+RWFWtEN1d7vhS5bjJ49htsT+ZAdF3l2WbA+0cnFm5XYdBv1xEM/OOnaWnfqc1yeOHQCYKGGAIcRvdPbMXaVXkZYXcyh43VuPvcrZDBmRmAsWmaOi1kram4KUZtnLnQojxeQs0IVLRCtwosVTMs7H7JhO4rzzlog2UYlc0tMSBdCWUO788bx7YuAx51HaduKXgv+2gHNw5zXrXcKeIA3YgeVCkfRlQWM5JO6WuJxd3BB7pc1hq5bt5ATb76XBkunliNLNwjpK7PKa2wmJRfDCzWz1gpRk2qJVazNTYrjzxx3Rjle4837oSysPzs+Lhu3YER7t+Bq2YwDUVXkqU+tr2V5uQuEcGTumQ5gn80zjudvDnsQV2Qs10BDCD9F+ub9eVUs7Sw6vmnTBpIoTi/riS4T5AYGLo33Y15aExacRI04V89FMLt09L60NCBRjtLSAQusjDuV78LBWSzKxS+tXQKuGWRUp1XSBBNav3EdIRiki4Wx8yroAoCUICUniI6sfQUYqElg1YocRnd9pRHU2bE9h1wJTE3AXICpkY1kXhjSZlFU10/ljYme2pC8Vju5P3ZEaeSxX+yzm/Xbp/pX06I9eUnYUHdHxDNm0XdQKFTemkeYtDjOVLGLnQ20Q0z6tOMKGyJgtXIC0ydDWoMuvciaQxN8FbIlEbIi7zPNWQryMYJdT0nZ6SCMg/bGWmcI87khyCCEpzCR0cQlPlgnkp3KEYOc1JwuUyiJeyKaSzFajPkxDhZscz/iD8hIJp9yaMS1L3xGMuUTQxAUOK9IFQkUOlzpt6uizz2hPfHJtS0n2T5Rof2WpzuIKYkM27XPT/mKQx9K7KfSbtMj3PlpfLRGapIb7oQ+zHLBLWRKdh3YQJyRS8hL9NQ/Tp2/d8SnSPh9OMpeUXsSVJa7TFZQO6naGxWu3aqQUB+5v58D1RVU90blSKTNV9RBswtoOrru9DlRBDaWKoa0xLvlpz1oycf04/YrvhiLs+tUR19G0GJpsp9zUKYkFOS1H3hgItstmhYj1SvtMAm97HqsvScQR0dqzwxjiu6yaSLPP+Ej0MD7+JWKsLIoLaPPsV6R8jeU+l2buO+LlPsIsOeQ1y0giIogdZB/fe9gbsABUcag/GI6+zqxLJNfhEdHVFB/f30Mew2H8RVgfRK4XNVj9tSbBSuJQhAkFhJhD1zXNBZ6D9WRNjCW5IUbqzEbytw2+eliwcI1jEYnknfoljaGecWwRB4FIRiegssBBCuMrFqkAC/Ipw2ro5XU+DVveqKMiTSR/m4FWaA8NfNAzLja67SAlPhoTcTgGLcRwEG78zc3qKPVmA4JL8zjSz/rtdKQfKlqdpEb8VeiBoX4f0oQsY6QbCFIKOe7FmkoZRlcDQOEKdfa2bJoYXibaI+B+JwNaIEDbIcylM70FnwMQjRsXO4sDmkuKmzZ2y24HIEZufGhp6b0vND7l+ANegqYW5k3P1UiNQDZvKFxxelgSETVyBLjg6CZIyU9DIGYVfX39AQY4LiXdcpKukW66RhiFonz6T+ywt45BdnsdD8a+P4GKX0a/miwA8SVIcRwp43CVMzny5MrwfcCo0JB/grjGVKx9OXJKrD0mMHukdOdET3GIik/IWa9IpGWdvVo4m+KVFeq6hUmgxhKGYP18g4vwqDHCAYHNUyo/vwx6mnAtNAS9KzbxSsodrgwkXqmRHFhHkDdLvvmjBV+sG4e/3a4zaUPDw4kYmYu0oiePkiyN+STIigxHY0SFAcu68vn+Ktjb48Ux8VuSrQH54+paPz8IxA/Dx4xpEfJRTWG1zhyVuYpHLSDxcwg1DljQwfd6QUhZmxUOEzioZXvtQ6NRucHNoRgIfE7Y3vqAoP493uc4fnLmfGNmyo792Ym3g7sEtp/8JXKBkwMeWF4q+cn2QUAPm0k98AblG4ydXPUw6FhqQREpkWPoxEhGV7FNaEI9njR7g6+HGqgWjmHkAA7u1B4I16xOx/TAYD9tesggNAllSHilCtTg5M0PDsPzWZ94EE9xHohx18nDmRQVQHn6A3F0sQf3aNaahJq9R4UjzZHIvhEb557lkc0I9w6fcHvlRsdYrcNOx21o2Iaf+uTsMrxemSXJSDYVx+mvyJkYC2QYWMFqrbHZXOacSnkQPgHDJn1NLWFkPmXHpInPMeHznrQrqvrpk98hqt/t+G++pHd02ZL/LLHhG3xXXNplc6irbeaLlmND7wrLOm3U/yqxTxnP2G05Ez0+CxzvUoJPH8/aazMVW0TsQS4taXHC+s6kOuGXgOqVFvixWBJSpq9O+uypPB7hU7wHYvyeh2Rwco/HzwcWfmuVuPCTaxeeeD+5MH1PFmJ5lImXaQk/lYuhIXt6WqDO+s82czE655POMisy9f+/97a+VWT1MPeFdgoS81yxB935kaKYRElpzDnrPPG9Sz/KZ6TN8eQqUrt/UeB+K96LjyIUoLdR3rVHklAPf/unleEZPgKXggj18L34s4wHvcCS7l/TDPPd1E9M/8yueIcXzhOHetfK1GQ2hXDF9dLnPWfKh/OIV+vjYKMQ8lTugvgFj3senO1esWLMhW7JmaPS5ZY9NWSfvDCKVDcYj6I+4rMnrzWwzfeLjC1rJUGcnX13DyDeBz+TWQVBlckBgiRtEk5HYo9Ue1f04pgvrPiCWiUJIhdvGXusGv6r2hMgxx+N+L++J8HWv1Q7EGTDYE/bnmjQ4k3vchPZm+yFU+Pwcv+IU3+JgbOr00YKq+hflmujdcqgiP2G/LWx8TkNU1KVuFhZvs1ZpBUO5rtN8Vu1bXH07DaHiMGOjV0iyMP6ExzY0Z+S/dlzTyYPG0iJ0bxlo53auExlJpxR2VlaZLXX6uDrDPwY7gUZ86MqTIrt3qzkjAoj5QORTneYfjHeO1l0P5LE4zTbsN4CRk9Tfi3tn0VOtFkeFL7f8HhdTKq0diWSc4qQW+issCoFfXmum5ARiQ2xdFaHk0flxMU/Z/IoIi6aGxKMak62bQfhf/eGu/wl5Ma5ZpgMDqDYQskHN3630oC4DxPr2b6UiWrGpT/JvoRxTtS1mtd4eU0MTTTXRE+/yTkmUxE3KbuPiilYCO69kM8FuwImNPJ+Fnqk+a/7C6v+bXrhVTj6sJ7RGu1EesR+ZCCEEd9aoEiPqzS6l6XvTRwz/7irzB2DPW1yomvRFYFT5ZsK+emcCQdPkMjea6HgWss2A+NKqt3/Hl6IHtteoCxwVFghuUBNiKhhJp/6+Dtqqk6q91SA8YIasxBhgleMPdKL/w31nOmnEtY1l9rnTNf0abv4CEWxp00Eu8DH5bwMVa7hlEAWcIuJy5oOcaaK+GNQOGFPfOPK9l+qZegUdQ2uJQNVWmBdXjBY8M46pE23KZjqN1R7xrdo4UvL3rCVjeu5t2cDHwlLVWYhKZX1ZWZTUZMKbo3X0auHkvrDSjSC/cRsGrOqMJ9PY5SaniaQONzG6ooCNq9FPcKR5LF/D+w9u7QiZbXuIddN6Kr9K/Ec9GZVH1j9/3de6CgBkOHdAdumoflJ5rXA0X9FVEr6VRRNxEgWzXZfMXebN/nKrseNCdWPFkBr2mAOEkBWhko45HaHOIEvuxHtXPG8HiW3W+UfYbWp2J2VfgI2XjpCAOWIInDlr1JMqc/jojd5yhN/cog+9P1kLfT5anYW97e980pirIyRVgtF9tgzUbpqkZQXk7fHJy0mIW17PGTJtjPuRqrbBEPS0u6wztVCtf6LtNkTsBp1J4N7mWYCImWIyJtL9F4Akz/yHBL2XG5uCv6Z2408FNZ+dkPAZ3dPSUxYDNzQa6bok0ph5TBbdmPUvqSn5MllaSPy9ba/5+xNswReaGyRcWX0LH6zAlgl/jOaNlfQMTJzDki8Hxc3/k+KGVbDUeaEG+y597PEN886HbqdvVix754XpR6QW1iAcA6aSDN2dBO5Y7JvhmbRfgh1/wmd47MXhxXqDxw5JOj46L3/ltqZ9JoWjyVdjORu0pgh+Mt2kLwLH49QL6MM8iPLY6SMaFF8227WJvsF0tS8xFq7PUcTXMGqsjv6Qn6Oc92cjAWJPoJEJCxoLMUcBBR1fHre0k/mn7B20AJWH0Yp3yoVDRxE12gCyUfgWqbAeXZwWTknmpbKT0hEdUy7YLdbsuM3ZPK6XMOX1U+coVuaighnwpVK9kGoN3wWBGFU4mt+E9nrpy9wu5uXCmJLwh74DrHdMYpfd0tZutXQAzlUfpdkT7x0n++gheGKA4eBC8G6A9d+/NeouCAbln8cxUo7pHzXjmvxDAWo8/lLwTePGQACcFnGAMwhxX2vyBXu+VivIkVFFgKB9Vlot8Lt79iHgjd/mdHiA3Wa56a3G4VgYHaGCQafJ39ASLzo0SYw6qFRZ0ICpECMervdP6yyQzALeUwLeTdE0Mi/vmQLKGIAee9jRG0NuX743z+HlogoReNCDLPGXVgltZsOdNelRW3htgBTcDjMFuJZ0EVf4d+pzkudIqaQt+qNXb7531OkYMMwmhRGnH12aNFZEjj0HUyXsrsvLP/K616x42XCGb69/9IRla8pnudRG0Sp3L/IbbrgVL/fG3cHOU5koXlDadD1k5XqxQztfANMyo8lJ8lap5IrbtNakwAJv4hHbC7j5owcKoC3rD2jyq+RFLwfpPhqGU6aTFMxLvxjU9KnltURfPg+12ELztZEP/6e6opclX5gaFJx3O7ofapNk0W1Tedb0DDiufxvSQi6psgv9WdWWHqbPbfaOtkWGv0v0KBvjYlPc2r0NGdsXGqpde2JG8aoXmklD2XtElP+WoZGIJ3HaiesJ3bTXqgq95WYt9/LrNYq1I1cSRedXr9ztBrtrjRmpSyl7GTu1+m1UWyfF3N2MyLDJEaTfpqqaWO8RBwzj7oK1ZSAeiufsmYTQj0vxjzHhecQ1RC4y/rBxweK8bUwmwKYPuMEs+nSq316r0rd9BNrLj5h4aw74jsXg5nreclQt3/AccYR8G4znn7tFQCdE47uvMl7zwyaow7J2uN8oKecGB+dIre1IxzI1WFNvpi8is8CGHY4ZuCEP16K8WS6dJ8lBprJK0He3Ei0aFmukvwR8l4I9S6a6cnxUUnZb+qysV70QbL5PJhZ61y0gqWtq/V78eTUzHoSda/P2wnwW1Gbi6VoyvKHUd/XGcZxMhVpY0+KE8UyBtcnns2DvoboGI0DZltLUO6xqhalLgmOU1bL9rG4bkTjjaOFYVKwcCwHKuwbq/Tvu634+MufeNDZjiji0InbGhW4fbMabc9ZoKdVFM89Zr71xNmTPuS1ToI3piT8Rd985ZNCOGgmrwJxcC7VpJgG/xJiE25/tZ5qwWyx8c08KeJ3oTYd7gva0HVaUFcifANPEnFEKJg16lDkLQvdSI81gqWRr7cM4MbO1zZaY4a3o+XpQ4y7Z9MSqG2w18r7xkJdo/bpLhdzT7SaU5CdZoze/u++morKUFhq/u4J5gwh5n0LblHcgOMtx5NLWttZpXXVVai8yFOeyOYwkIgRXBCW7xfIbW3IxTIEVlSr7GCF4xapcXScyMlVEym3NnOYjJhSBIyujSNz5J73n4D6Oom2iCXyn2YjkI1BTKog/3RBhoprOFkaMoZFzQGPV/lhZLXHeX0feGbNbHziX4HOM8fYXyX6wegxFQbVXlgVCpQRzE7ouJzmTTORMeffnr9wjh04gYyyY9lQ5paCeJ9ZOPVAMR3QBUN53H538M7u4BKvsqRDJfN6hr+tXdrfmaq7XCEusTMe3allduZB9zC8St4rAL/92LgNKSS1gD/vAL95PH8JY48HlHkBecg/+O2sFK+9Mnlx9w7N/tFn76WHGY3t76sKBFaNlP17n1jT9LGkkHfagiqctFf0zdIU3RQJirAerd2bVIeWh9AbJPbVSUaVf+kX+uuut2ONbzvojtIiKGnPKOaaT9LpkONppUZ8XRakqNRiu0EQI2KUEfLDDMWirpGy5kRnUORxI4EKrEqj46dFyWguvCGswCIaXunsth2V7Cq/T/THANjf7Nlonj6mDLcdYJw10EW/E1KrRq6siiPvQplyMrtdOsYqXQgLSSRGXFKo4PCBr2Koaq1dareVy1iWaKFyRNeQhjRUXH+U7m02RurKMesEzaoBNX210CIpBU1fYc5gQZ2PPB+B1H7uh1tGuO9L+eeYnVJo/Kj8pryQycb/6em93avfF7Uv4CE9tww7Ny+Eblewlg4sj7aUad+tZwcuDIlUennWHtV+rKQ3qagl4+643APrYgkUWH5TU27+eAkFNsRyziMqRspjg3be2giWPvtCUabuN/urEh8DvbyTCHtdtyJ4eDRGkBjTYp5yBTITjyJcx41QBQRKnOT62NhuLu3rXhYtxs9HJqeF0y7SlW6qi7xmhNVqMz9OCY/67XZc/xNvmJMAf71Xer+N6QGXQketBj2hsx5JO+73j9Ctd98wfZ99vfxEdtZkXuDCiRsTQ1MH5ZG7s1ndNqyVWa6Fw7dVGPK+MpsKi/KCCl9z05rMpuY1UrDUoYJK/8KGtayOuuWhiv7y94iCraBIt+l7cfFZHgsSX10tyMu/np/ytpZnD3p8/aiz+8zj8zyjPT+FwAECrpCjHamCID3iTyGYLZQlzuen0fkrWZ5BGB+2IPZ4OfVIc7wgVIE+JMgUMzGQPF5624kZ3/7bQavPLp64wzFfEvpQ5XdAYNmCwHdVmktCzziYgyfqbX+t5yxyLPKmh7vmEh3YsR+/50xjL/ylGkRgFzi5T4t0XC8wOeMV3C+qbhpvPlTK3v85+nArnuCKXwLNdXGDWE7E4njaMSEMY5dlXD7ONmo1XIv7V6Bt6PFTtX33oUqzrlJFcSZslEdMujDwNStbkkWNxhPDLnx39QlQnoNzheBIW8qPt8t695cCC2KTw0yIQhIi14y+fCoaaum8608Yzn/jISyT9hUN8yT2DUvM34caXsKtVizuH+1xHD88ohh916a5DftCuD+h65S4BLxS55Aoz1X3DvocV8sK7OQYckUT/3suxfy3JehAfOiSWHLz9sGwfPRNd/Slu399wIPqtHzl/uqjT9R+GjPEhY66fx6WeiAEqrevsq5qDwoZ/lX2kPoBd4cfmvkThn8+RQ8jXJ1MvNvMmQalw2r8fvmoui6jFPIAvZRSkjGiu9RRV2nEB84D9yT6RYyGvLPekJaJI/4co/3qiaw+WPEzVYZi7smsAXRFtkUDVxlaANcL8gEdBm0WcpOCtT8BsM5FiX78iKv3uawdhM8LoRImAmgsQPFhvXPCZy0MZz7ENXSVzVR3WUBjwLgo9r/nxW9YHFQlhX3tJTMAkiK6rxLyT370JPtg/vmHviKnk2MpjNdbgesFKcmsDggx7mEYd/H8LJK1E11+6sM+Ozjgdtkdl7kDK7HuAT71uBJLyargcL81wU6Ls8Jc4ratJkPV1SKn2blmzFsFt8G6bjWXht4a2+NetRiT4tWUkmLb9BY7K2TCpFKBB5mrxR27yGeAvUY1TPvtrwjLnArWnsz6AR86s0q+5EZqhUfaiktwfR68r/ZJjxLJVa41rsnJgpBVnHp3EQegrgFMXpduNueqGXLOefY+az3SKk8F2iNzj8hJMWhbrrVcLTmKnSbVXQjQVnUNYHJ8rPrkVAsXlXGWdfcvmqVUKdaKSsLkY6cX44ukq4tDjozIwe/nsIw5hVihE1vswRs9duBW7xmeyvJCucdhd7Eb+el4t9kd6bZ8s7nUzCWh//5TpZbSyBDPSRO6r3a/ly33icvkdrH2O90W9606s10XdcKtl91Fgdfo5jNG9rb5VpGiLdpT7ojiUkW6ZQtOmkpNbkAocagrCvwIn/1X0mujIi3CW9rWHxE4r+E6UYRIvr35PON9b52Mc19XRFzH0uE+G69QB7sjfUs8eGfUJPIvgQeEx7+Txn82U48WVtLxhQ0ZxrA7qQAVBF08QHUUrlYpGFeh7oAgkNvcRkIwKgxmO1uj6K1oSNjU6FbPaory+yvbV3E7Vz4aFLOln1mU+c3la6EtjT9cTWO2/JCWdoPJbLp+NTWj5Vpq6jUfpqV4up9itUyTrZtDLMVbhoM1EuwdyFr11hsbpjIYqcmjmkYJhZ4S/ZGSkkLng/CPTbHvuSYxlEMiYBuxBVsGKQZGuM8WF4xBS6OgntNk2GijoaYkp7orglNgHCbtS7/7EzB5FLLoKfdjzIBBEzSqbnARd12151fMvcT4+1ELx2YdmD82e390xa3bKRKkM99AMNkjGONOL79Bn83u7OgEqqIdJwdPUJJAeWv3VoCMcaW7bzDoMALj5FxM7b2DeKDwzppjbsWk3OE5wUHDkLYeNfwPeAZjkmO4GCWlHjVZNqRrdu6JJR17GbENqua7y/Oru770kj1ubhKDqnlzOQGaOwmp2KUZ1R7g3ez5HMVdiDqXo5uVpZV7aPSCdZvztin1l3aSUxsuJydbKOt2eTciJemSrHks80/s4uLNQ8Ehgx+DN8TNTNMkrZC20onyYF4li1vNd45UhTkFYrFA6hDY7QJETlhsk+SYSsKaeJevNOt/PLuuph47+2DX7NnFUYZPB3p6d3n+pjc1Nh7cmbDyR8dgyifigbz8lQhclvx8XU7+2AT+Ql4C/qg4WjpQU03Y9eAlB0Fysa4Q3G/N78BEsEfWA4ce5WAu9JgXngS5DtzqGrGEqKljFnb3bY9bVI8uzV1aWPCp8q7dt94XZUmKDpwG7Jszw5B/cT4Y2E4TtYqOzIzOLZyyQtvwv2CAnR6mvQtxR+cYsirQy7KzG2z2+fWSMrLZYh5kr29Y3rXFAtxYbrO0Y3tvQoNSo1G2lC/qigRt5GEBD05gtoAXV2UakJxqStO2NCl12y95m6eaCmiS7A8eaRrDSWA/Pd7PkyuaoZ9vAQ4QNv4Oyd1jI0S/BVNm4Q2n3rzFe5a37xhLqtvWnd40PZQuVMYskyO2NhuK2ut1huY2va61lYfzuiZJLpquLy3P5PceE1C6s3WrQo7zrnbf0B3YK1gnqW7bStFurRY2rA0Tu7MLDPq5IYrBlF7OJ5cMBZKaOcgGuqkxeUwWltq4O9mQ04Xlt+fUDreRPCysSUSW7xSpeV1dfN2aDrqWV6yKeqeLcnFzRNK6uhW9San1VJOCWeLVTl1a1tiRXI3MLkajNMZ9E6+JLRIrvYtTOsgO0y2MJzZGNixI0hcvLA7R6o7FDJRN59xERtR9J2zzK2kesOcnTihHlQUH+UePe9trB3j14Xh1D75NJBFLStPG43PaanMpN5Qe8mPdbralZ6NHhusDmxJSO5uaqlf92modqVcvQuJz3/Jy6VUtKnFaf4KiuSKXOrxLZaylfqA5MW0sTvbTtNTLM+70m6UpHltw8j0McmOXtqzWE5d4LOxIDBQOm+fGEuxPRtKPLkS2/56EYC7JCR2x/wmGzfgdVPiDwgo+ULbvXgDpvuLCTW9AGaHTomaVm65BiG1Q7uBwErtWlGnjM0b8wRyyvwyP6/dGV3HHr7A7FK+3wZx2kNgOd9o0T8xpeGGZB6EG/Fm+6kcDYdW2UUtFv16v06iW07EfFZbjWkoKRv7jRD/iBOrPStrtU58V83emKE+43JDZfWR9dL35FvDYdQruauxLRyzO67C9/EyzOEyzOk8/XUHv2YnKqot9CgN1GYmHTVUQYYvXVKyunqd0j0oStt2Cq2hy4y/dFb7nBzkmRkhP65hYhb/5E6Q0kJ4H/r/zJ31JmJk+qNKqA/vqatZcyB8JdTat7fr9RMlfXyanEeMFVe6P00IlW92GSLF1ZYWaHGtXsHkoR7qdNvNWrJqVZP1A02GrgeQH2OTt28m7bo9DuALtAnP+UwTP3L+KBIl+kppG5CVxKrdjAbXEj+cgnaDi50+0hCdsHZTlgu20+qrBQitnsSgsHij38SLamkQWka2K4BYX7d04Ts58VvmZz05Yrhr+O6+jMVqKY3SBo7Ojnu1MkIbHk8K5Xr1Z3XcvELGFjihzPDyP3bKsqthHK2BW78jODT+f6PileD8pvLW2EH0fCxLtBNHGgflQgKOVPsHqXtcyNxtyzxjyemYsDSN0DCdWqOtHiAfJL4an8To467HiKMxvQyFRpDnMOlOc+eObyw0UkXA2TdcF+N2K/XSz0SKvf2K6BnIHlg24/IQkHj+JyudTEwX8SNjdUKPxwgXDK3/6FekkPi8xkcv7uiQcKQB3f8BbHggiSc/ZiREKX1DVs48HPqTmmqaw6l+GeV7zDFMZGTmWFNyERHIkJ2OrPheBw53Zo7Qac4muROCb5JEHaTNaZJ+WL/YVFZj563+b+cj0meYRFKlv044cksh8/bz6eYuQadyG5mxL/Siv5+811+z3BHrSNReD6Q0pTl9UaHiwsZLvRS48UbnWFFq1BP+duQD2/hcGEvwsyc2LtZ1iFWQSP0xsQXC/OhohSl1rZPEdu96fy8NDvD6BxZaxEMgbUwXLpWtH0BOSW6JfsODVv7BCKSZ7M3Ypso7qAUbwflIOzBZx8sXuPP0o8gpkHy3ecusgKAiLqO7X/BA0cgLiPJHETskTRzY8QQ9e6lvaUl2SZjrJbG7k5euBMgTr1LvLqj82ipffxSzPCMRAfHpfzBcsmkIEdOxmhdMIhja0g00R/Nga5kebK9Q73hm+ticptf7B4iOcpjaXYku689iuqfn7Hgoh2DznswcEv75opFwv72fQb0F+JI5eLcWCFsYdZevDjpUp3iaHZnijJr2+8NzlTYuaVltnQYFBAYykQFDRjM8xDrohrMwDHgqse5uP3hQtKKiA39mz0nz0fcxi2qVkErh/QyBmmswHSKtRLHLlap3SBvc+67m5GxVUyOgurw7bL79QuVlWbuiOf99Dswl//SmaK3x2yl4VlN7CWjP00ErV/PCTe+KTHpgAhrsLPD0mPE0mZIMbBpSQudSkWE7RY5PxYlqPtbXqTdnytEWTmgvDzvJk9pwAC8DuXqnI0adqI2ZH7Ix/wreJ7cmkzFMnOBvVxocvHdyq/r5+rHo77tZW/VKSWbtseJy4mlSon/jxQu7DyTGbTcf8rRSq5IL+O+f3DSF5RZgaQ0LQu+LPERmKbDKSYF5r1HOrDkRpkNqMGFvAAyEJ0sy4b8JpYJjW8qMkP8/XG8a2mVHIT96Gj0aQJgIHa6Ny1x4n7o+JnhNN1kZHuRxRy76wecbRjuiYCZL/0yzTd7Z0HtETeffoOvXVdAzAi+VydnJjTf6tzzpz1VN4pe1TW/qscdzRaeoZ7jbP8l8xxDHw/VsSrNPFidRcSVpqTg6DIZOmZEsksfA7hkvyDSqOF9wFxEb9DS8Kr290a+N52IUALAkJLWI+Uh5gtwXk0wbsZHLMACn1uBWLD/8EuIePgA74pBE1UBm+YaPYlUR+hoAC9zx6lK0IN7ecacv6AsyZsVL2rAPRVRXFZoEwWTmgrJjrr5eCCnuoNVL1jfPUqR/n3tNw92qk/tfio+s4TIN9e92j0H8H5KsG2rqyDVZhVLSKmFLy9idROYIIYYSfWhc29ziVmGVxFE3xoMVvblui0FroZ7KHwsWWNReT+aNL3zf2Atepz2zgRnk5nUEifA8/SRAKIyIDEchefEiyoTURWYs/eLliq5aQs9HtyajeQJp9j8ErvrLc4FuilkQMrTcYVh0cepUG3fyalhhImwZNy39xFgT3eXYwsDdf3rh1no2rGvgsm1zQkojsxeOtaEf3E3ZXeoOiLQF5U5YY0WSJ60O989rjUaMvxBBlXRavcJwXSqFUHRTk09DYst3Srqkw5V/tFAyvX+DzfLbGgdtSRFWXdlDy5z832ciqAam/933Ek7v7QS0/DSRCs7m24kPI8gzXJTmLYLQvTxPSkgdi8oPqzi4Vf7XTzcrW/4Of2Y74W0l9ZG9cnKjBk+eBnssf9BHWM2cK8p+3whWWrEirPrvw91HKgHc6Kqgt0tYcM1Acl6keQFHVqHj7e4NOKJiwmOdpT5gDqz80lYvSBDFL1pKLQwlmje3NSWfB8hZyUXq6rAYMUDfQ0uxeX5xPFheaKs7UHj8JtPQVNOqQc83yJn/LztH91nxWjLqihWTLysoXX5FB1gYHjxbX8RkOFDc7jKXNeSHyibBekGJK4nM9nJiZH4zXNzALtkiliKZMfQuDaEHYr7gCmAw2xSZjuenTImgS9/Di3HW1saMcvYSvJGpiB0jdkRTK/yoEd5EhHQcTt4+oiDMbgFQzYP7kNmlogGHG65MG7wbN7HwEjmyWDrjWENw5V9k4OKqgZlZIGpo/hHW1Q/nv0/xyJjiUfq6ScEKV4FDmEqp6yLqeB0SaShCUsHEob2PC4ayAMxWyzmZlrzYhx/n4QLLgyI7nLM53jWajYSt3e8T5u3kLAYk8vbX2wFMpR37NKYxnAWESml20ziqwrWj55o35Pz8+zfZNLWTDmz7urmKHR6cR4uXKlgbKgDU2fZkTIyw3GZh3/D/jeoDK2a+WDgYV+v2PQRSHeybHmbMoL7AQ5utsfjugr++MFtIWdPvbaTGCROO8GSWVpcX5kuxYIXvnzEf15uJzpTLDoUGSLT5uyAyvw6xnTt6JkcQ8R93iBZ1pI3vjdhZ85Peo9yUvYqzbCLOgmoUWl+QyTYmC/J13c9XAj2NZBlBLbLxcn9/yux+fp2uwQlr6AcvSiMmmxKC9n38oNS0YhqIltxznNz+75eYNcGjiG+b/LVQs/l9hYJCotIntrccfuahi8V/mvLmwNxfn/o/daECfzbv77OiqAemoc1J2nmIdnX+wQ1ibwiw+iE2OwTz6z31+MrP6LnO+MDFuSLEwWYB9IhRuxYjLOY+/EqRT3F/aXhHvHVXLqONjb4qQvaW+A75kYm5gYt/nrBG/EXB3pdtptGjUwpoB2aT3P5/sT/2rnjxje/juSnZb5HG8Ql/o0prs9+241K8h/UYhrS+SFix98CnQfsxT2g+StWshpGnuH+bMsHGIm5MrzF5d6RxwZ5XTezdr1Jn2AbnKOdJp/rjmaqKAPBiclPF1sd4bzU1G+7f5vL4FyUR9CiGNAvyIOXPv3G/jLZvkuiHe7g4gSt1QSOu+mUUQJY8MaBy41lhfWNKgBR5KUtdIDz/N2xaQyZ+7tIOJqtvY/SvlAp8xvP5MSjBKJUxJDXPeFf8SZWN0GLgxsa++gt0MQN38JzM+1DsP2UskykKad8Vu3mUlhGxQLBzhgvZhT+7mxAX/rRqQpTtv3ELefJnFCO7zFAoOLcsXxN4naYnB6jSVJYIaHwzD0HpbCvNbIlmudts9s4lyoWnU9uTQOlZSx9As/YbjkbX41sSQZMMePmiAFE1bc00tLn9ykVdOi/JyNnDj6zMDwpnvG6NLyfw1F4MtkHNmi6B1eaJw7qHfDRuUj6OYZW7J9iNs7rpImnOEIMKdc8yTm6NEFeZ5jfDwE98+/DXqt72OaF/ERI2u68DIn65PL8G5lxU4T705xxJ6qKbCXy+5SqZvskBabK6qKVtszZmWGZtvPs3TvvMTgRJGGazrsleBFajn0coB4UDk53mJqu6JNBfFfCBfn2/uEMqtHpCueefTDdcgk+0DBvn5q26GogJV91hU65HopCOOR0BFxPWhHqqqPYPU07xt6L3rZ7sbHeU9oWLdEQp/Oa030OFX3kz5prCqOrs+lH6n+LZT/7+mk3z63UjBrNlFo31x/L4hpW/uIC10Juh8RgKXQ6Xy2PEJHFYilcUhzJUfA/urq/yJiP2Vd7jIMn2vaI6Zofo/N0fhP7iajRL9R9lYRdQ5Coqk5rjFxkIgyJQYWvfRX3TSGDhFFL/L7UiAaK7A/0mPqBLwi9idvUDGadnmBkoP/H6cp9R36Us7GK58fircjWqLtIl/JO16WiU2zxMHOrdp4vX9kgAWFcAqDiyKjOEm1pveg9Vt5eXaALZwqXGCzl/8w4Ko2AAhaKkptad32N9xTO4AbzDT/N8g2zd2bDju2tdK38jRxTE3Vr7yDFWSkni9JjT5WnsGd4FRfIR28qdgneQbyp/5dWVyHv/jM422zGb+q1f4py3dL1XwfGUWza8hFV+wjtREF8ixkceY3vWUWHHVCuk5UpLYZCs1zevq2xE4paWntZp7SaQJP3ZGV+cr+9cLIuWWULHGU9UV19OaVxPx6WBltFURxOYmQWuiqHwMOVcUKS0orbR3ruq9Km2LryUnZrZau/3i+5vT4hu88HI8yu92pRCpUWhTaGkWocX3Dce30KGHpNMys+MZ32/UKaao/ksD9Jc7Of4hO+UBX5bO/XFMuL8euZ4F9ob6c3ZMGG36EKrHsuXQMpjvy0F5FbmRE+9y3wpgBaRlvyTFy+m82TuSvLm3/tCCqNCk0Fwkks16cPJs40k09UrLp5aWN7GcsHFTmMBxNSF+51oNbtiGitBozzcJcTscnrcvDdD/3MkJYpxpGooyoEUisT1Lo2rNXC5B127IUnjdhgZxtk8YbQzqVE+63sQjJ/XSxyNiRYnvOuJ9uFPEiBBCeHxKhvMUOt/xpMRI69zGTx0kPqvtCZTjGBXOJI22iVbIiL1uJ56yZ1LOXjx2lkA3KvlrfSalbp2bscLH5OP+TMpKrdl/oVYubRwECfs/jtWb+B0PiVZPFVktWM27UhuARs1i+fqkQUToimR1skaUImQUhBlDbVZZcE7ws6eiyuKo5MswZRSPLFCO2UZ/FIe6E+L/vGsJBIXbtirNsjfwkQJkgYQXwQk/Ems9jTBxGWdC5LlRyfxzMytKhAUHDVN/wFqK1RHkHwf37msdRubgff7xu+UUyG8/yA9k1JMcWRmKEztRPkpdakcE0JwhxYNBO3zEGBLfk+Tb/uDxGlDx8cDEK1+23nzjlf1xM3gVh/Lu0XSjUj78uK+dRwFoSgdHvn0tNIGXt3PocnLDC7dn8RyqtHE/UOwFENwSmoTxlPA8kdgDIZHCBQ5Xi5fsYhFhqMV18WNjRSAM7hJggWD+mTGjnioa2kywyRy6WlFkdAKBd8E2EtHWZJ+hGKCJPFxhE03YzkGB1g1KiyxUNnnxFikZV0i7wBnOx6WMNM2U5zRsCywvbulNfxMKaMKDlYV+VBZhMdiICPpoEvhNIilphoQkkC8yK3w00mKL5Hyc2AVfZaMVGnFkvRu0FYUevWDawjtKl8Zgl4akVbZMEJPlGzF6GLku63nZxujYrfQJ0lq4mfxaZyJgPdGlSESOmFA3VEYXP8UvrXMwu7GhCu4aROJIIIxLxE+Qm0nHqcxaJlVTOFJdl2sTiT1E9XmndasMGqrHQVnTEODSkLOT6YOBqq3r+IZ5TuBGfiSlhUwhYDIKM1ZkNOilnPfIYaz3cl47kN5LwYNKtZQHDsr6RVhaNwuL7P0jNWPIQyqOHu/1i5sfgeWXpMc3gltUjW3pnTlll9FRmU0Pifqob3FHLHaZZMaiacLGtfEj3cyYtWvijkpERWlm9KFIIVb6sofPlTdQ4XBq5MVZ1Rsss7C0FD80EGYhB0i5EqqRwc37YBpAFjz9a8k7ZbYCdUUzCZQSoI1EylS6uewockGXXuwYD6lzm2eAuwCQmkCkd4Z/U1dZbyP9FrDPGoUcK+VeJggU0IRt/cZTUsHB1kneF/ym0c2K1aAMFNPqIjF1mqVVT2EiwZbCeCObH2IOAL5sDJLEPAXoIpmylW4WR9wsLLq5bJ/kYtqvCiWtGGnloEQTirjLVv/Fs2QSy4BmU+rROaePQEhhkvYGLkapDiaudSIPB5o50k3k4b3EkX/KqGH/l4uTeZ2Xw4Jb+EtBn2+BV2dRbZyX5mp33uu5IBt5ajfbWm0YG1tcVvy2jtU6zdeCuJqgHHPGphmOuXGSKHK0Zc52lbiZfKeKaUUEFImoFsrSiJWXJ74qYINWEigzgWWvSOXUzIP47TQPoOy6OEX7WxTCUzC83l6rqDrqtH+PAtIL46/HaTnVVDt7p2N4Pl7L9IfrAbi2FFBUIT4k7CkzzD2MBXIIavRAycTrPAuD6kXZbNU1C3wpKExYtzYyDVFBTqxQ0nS8wRsKapsSjEY0LT5ECFVTpirWGCoxYicvjbv1vN2mfkadOA12flpNUaFZ1jPUEhUShV2FhmoprH0XGhfgedRi8k2e3d5tElyhF8f3FJi5e3q6BajlbBHbIZ93ZPDJzzjpQq3dr5K2/ZXrSve72hffhSrYBeuGWxEkDF/i8DLUstRsN7EG97sQiu983ACsdBnRcQDeH3EkcFd6BAbVuEU9OFENpAmsahppRZICzJFEo+orw6xcaJqGd9Zq45R7A2IvtaFIbr5BXZvIfyXeFYK87MtroZm8MsrEG+BrTL1gMLP4X2BakUmCytVUMDintXBPcjyGDR5EFQeTJNJaT4egcblkNi2EI9y2cSlM2aMcMwCe1Q+HuAUVqOBE6OIvXBOaZlk6ANTeaHkneUzpGQvCEYmGyJWruXp7UH3h5j5m2/D9+aGcHOn3g+ZaYX/9vjkz9T91sbLkpb76W9ejvP1Mp4YFHPvE+BebAGGz8s9gGF83aRN8xJfzXqljTKaELtar0WADebUWWJnkR+vQO/puhyGfHA+5fMYm6n6/en14RB1a4lUw01s1wQJijOaRiVhQEA8qEpEEGlLAVBmnPtrDTaCeQKd+MatdptfAJn6aYBv4LFR1fcZ3vCkdTEO6bTTwSnny8co6jjFfQ2wPVbnZhJiJXCRq7D7SWCyf76s35M/y0brv4NsfxcsjAXLax7U8Tv4+pONHOHBYxY4bonspAKPY04saBIibRDm6YjV/r50+o+nIaLWfotT6Pdk/C8OqaHZgnY1VUJPY3lnYOdBSUh+REXk8RKK/AbJ7h97sGVBU1hBAjoLfkX+kCIeIoYHWcIash77o1dW6cK2cefFgINvMv80v9ebTO5W1qs9e7lS1Ru4OfRP/X6Hi5WhEN5Ne1UTal17bc1ZRF4Nmqs6Q1ygrwiGBWUA4kJ32jDM0GODn0yPDjgglOxX74daQs1TtQqXA7vV4klJRlnX0RuybgDtLfXMcDQ/T0WJG2cza/MJ4XAelJIJ3kzjFSM8sj1/h2UXdO/0wdvIp55x7qXyWo12uw9E0mNnTp0v/+p75XD91on78DE88wcHNjdY89076rbd73YiELWbQ5rjsaKsaZsKuIWONZKiRrowfbFd7RFarhYw0iX968R1+KKAy+4MZyREmEXOwRcHz01XA1KB3kPHnQ6+74fkwDZS9ABHlxLX3/HRttJ1Xx/i6c6aYjoZ/QRPscdmOuHSTG13Qmcxu2jVZw0VUtivoyibDL0unqKOe2rmC0p1in0tlhVAfkNG47vnG+YvPvTGX8bNY4igpZhzUZYVCHpTyCe+oQD+ZGJ0qwtmdVYg7KySXpUrbLEmZvcWgahk8CQM1M9v6PW9MGx5/aCLee09IEldOQelyZDJyNkqFmNvUyec5lvGtKvFMR5dwgwZx8MYm1iynfA+WgoIakCJTEDKyHVvTRUj5GJdRMznocjOIAMYn1OJLfASoo74rQS07cHfZqliwRTfSc8Ehnca/uKM/iN9eDKhbFjWcPrm/7sdSgvvr7w3O371YWfTzRZUCfTIdI8UO5K6qZrEqDuK64JKZdZiEv7PBNhgq2fVA9CIYfRupZ9zcJEHpsmSyYDFRvCtdv+4xp7kpcR/hQvP5FzDApbmaDcc4N5Ndy0zMkdeiTBbNFBdwunY1F0qkbnBZVNhmZd4+7g7zzZdz8Mat/XuPF+JkeP4I45F9rxtPQssZZHX5OPaTOe7GDOmdTox4AaJfG4TSuXibRL8oRNM51IqhMqUdA/vMx09cGorl/NioYa/ENeHO4Q24plx0G5RHbN3V3ChWI0WMouCgIekryAiHDGkj/G0+4R9NtpKbn8X3uQt3LJfvGIuV6eew3P6M416Xrv6PEy3FOCacGuetcb13UUfGsCBnHBPj5HhCzultpcvKvoIVdTCR6WXSuDQ3M5JcDjVdTj52WSROWPmfrytWyUX91ZsKDIbPj7P30HX9Z1Bz/HoMuFcwR1fkZeTLUtGdfUbK2eAOLZPkZ9CbAeLCzU1qKV2lypUVbuTBteHpclGghFYIMpHVNFohmWKk0npeAm4p8eDmJp49116byZjSBQ8kfcrFUaNkppSjgCQqJ1yXtC6gkEKpjJSJB74PxJ6SlHyURf2w821knfhjrok+Svc8ETl+uy5IgzllycyOfrOAuDpy8zPJthmlK6nobUkJcnGlVHtbSnxxDSSlpfQCadQs5EFe17Oa+JC9hKYUuYxnLhNVonIUSdlcVrmQM7oXciSPRnLpexpSMz3g8hVNc9WqsSJqPvoSJm54CDQfI93Fk1RtDkbjCZNSUlpKS2SJbKATmQzI0xIuaS8/a/ot/pNq0zuQP0W3YYoGKE1la6H+16BStEgLlL6kvvAl5bqUklJSWkovkEatRDbF6E7GB7LSFE/o+6ai40Mnvv5TiY8XRPwkwFPsniBwxicMIo4JwUwbEEOA7k9Ty5Ef8C+6gTrvroiyq+85jrzWkdrSV5McJZ4gAHoQU+DFjiAiGLsBwUsS/9Tm/tuTlbIJeNk0E6bNrQLiqlIGmyspGWnGvTnPOY/z/CpvGthoqq7pRotS5+cSlNsMdJBbQLjLxOb6K21TCQvt3jTrtDrqNjejn5tv8zUjYL0ALjM6vveV/eVuXGlV1QGxTIsPFHiURiXSaMwy3AIUZszq+VV+dbWsIKI/Nx727XLIKypbcZIMWVAw8cRZRy/2SV43AQejgwkgPYwtk/AIaoFuK5UhqshFVsRi2edNyZAFkum/qoyKyj1d6Gmbtox81b36q/w3bMZXBbCZX71aUVTi6fuKhC6a00FJKmlJ2SQBxBFiiAWTtO1GdcTYByB9B78A3womBmVAaQ30vfM0lQQflALGygmlm+gxNy3a6SY+0s00GW4BBq9l4lMJ/KKb6Ph8IrVhFInPnWN00y6Tc85WXqaRe6QFuN3MdvOZ4jJIcQs46DJZ474iXVXykX/u3oM8OgzipDsqH2DtvZNhHGDtbswy3Ve/hlVlWJWjJiQGFF0UioGmrumAE0steiXYBp8oGEYmNOmm/a6BFsI2zfX2+N3cZHIKMbCeRarqeOrsfTFa+xW4F0/jg+Q2L/SQzBChbtSH8jEbYoAdKiB/iInR0CtMW5XtFnotxdnLYPt63dbijPhHU5HdKBiL1yBslxDTlmFrXR0J24sMfUbZy63HEDjt7CYAbtrHTgb5gZsOw80E5iOllcTN8k5iqiewThXWwRSvLXY5myaevkWIVzOqCyqZcW3PwVRixOsOjswbnXSZhbqZEcpnYojB0FABfwWYZGJBzUBU1sAZCwvFZlWExTXFQVwKX76Xnzo5GAemQN39FB6JSmZccHMoK3mOh+3hQZMf/zi5XhMHQXgC2cx0e13BS1cvB2X7Ma3G9HPv9C0w2Qe8TUaZvunyqeu2uWzGfrKCOQtXG1ZdYdPs4IkM0JxMkdVW6qEVbBtvmkhdZ6HVM2h/hC+Hnwhugi0o7WfBUn6sjuzqs9L6zzHCQDHqglZweK6cP154Dv1L19/HpqHv70cUXNvbNk4L7mhFysG1cy2U9lb5siJo8hGunXDcPTw+KeOzDYiE32bwi8Lpb1WRMzPbsCz2diTHGR6FzyJMk+PoyCchiEXXXF7Tv1kezKyf1fLapNNhgk81hE0qkaOS0IibwSrc4kK5vA9WUMY8fUFdiSewd7Tu7ZOlPxdZ8I4I+5DYH70GJzE4fzfnkqf4eOa3rNYiXhpa3p/jEOGP0sFL0HQeVDD4Yjmo4ttloy720MKXy3GIX1+Yjwxvx5eAVgNgXwZXvDWBf3cCu0XkSbSqZ/yfo8Cpj5Dsl/zpyvfxCcDMDgtorhHfPy5A/fVLaMLHKz5rtOA3/xEbDZPGvbJvu+A1jJSXb9rq9ea2HP88FC08fxb/QzgX7ZO0bThWEpP3R2+LEOUBAAMcghDCAUjzWtj3yL9Z8E2JN69Ez993jePS0pmG7Jo4ZmT5RSJo3svKOoBZ9u3cdDoMGkgbdS4NFBaVBnZ93Largds0NAgLJeIBVPFlx69Pr9lW/Htb11dEEYEWoIggUClCbExziznY5lOlEWkRAznkN8b5rohpx/62F3GKFUojeT16hkVSYym/W5eOto4sU2S0KSn5sIISAmT4F41NEkQqicflz0fNteet0/nHbHgmNAe0sxO0wfLwCOliweZXx1cXv9qB/cvc7feDIjWtZegvG699X1fdfP4t83IJvRRnR6GKJP57oqP91VHzS90Drgv7MCzf4G56Yt//XQ9lL8YIpRdhxrljoY3lyw77ndnL8qFHhAMRDkSq9wosC+XERJu7Aj8YKLZeAKsjMUzXZEIuRzsR+q5wOFJo6wVw3DoDwmuZUE/eLHcVWEa6efNIsPPWGPiLiLBENKW3gi0Zx5HEsTUGphHvC1tlhJx489p7V9HgN4pXMmQJoN4/rBky2hWPLazMDpe90iFLAPX+Y82QEX+mU2wA8zMfCeCLa+fVbuXDdWLv/RZFrOXSew07FSjUXD+b5rncmhB+xVxehcc1l/Ph9UsZD6GNoS/vekjTHHhpAO7X918/O/5UQ5Plfcs/vcyrq9L2GydsEP2NAbBG9nc8cl838Y2/RUJAQImcS8LCJacIwZ0++oYBzYPnxv3Sp903YnV6OQB2b15v/1P7D3DypV/A71uAmPy+3X0G8RuCb5b78Z7PF9i+D6D9QsSg8Dg8Iqy460Xr/fMU4gvnPigfPdxs6v4+fWv8B0/u5vhgN//N5gMBiw2r9xsDauaWw3V5Ly0vHjSGZvV2+n5i400EpnL6wG4ISvqkGYLiH2uIB8t7ytUpxAHogV3r7WAK6/TbEniGYHLMZrPkbFEQjGMj5eYVgPpnHwaTY0MW02zXIZkT1w7vT+6ATZYq2sLTDNydVjJhzeQIdC5BsZdaIQwmx6YjGB7yV0t7gb2iwioePsboL+KAwn03nK0L8uOYWG5A14v02SPMtrWporuXGU4AiIoOKJ4XqbS7dcPo/gyJGVPxCkfE260HetLIR4PePUCd3SD1bOmGkUmvdLP+YFMDh+8mw/f7wpcYTRbJt4ZoIeysIZbYAixpBUce8t/xZnxy31bD5sjk+wZe8Y4yiPQLG4ZI7pG5bOXHyZYpYbCek618g+P57KaHiCVza4jHcmPuV98glTfx3yFkh0zWEfLJOqytFCHbR/bjPdBVbxGXsm7rg90M1FD+qfCxY3EXQW3tIUkU1y89ib3nlM9+QwxBVu7wXT6pZI3JJzvS3dttAIMhEJbYIVNedKwc1hAdCVlPw9jgd4WZPWRZmRlLeG7B4y1/WAk1er6+FjFfeSMAYLEZt0IN6dRrF1XWYc1CmNu+Cy4Ma50bnDOlig45AHWWlyW+n16+xGiw1rYof82T5qQr5Evcu8nKp3GOJ7sWgs9yiQXT4nNEnKNclSa092mvKc2z4LhWrjneiXl6HLFEsH3ID9hKpgX1Jc83qKrMwdcbXbmyAGwsWOwqoios9pv198Ob6WdKmKym/FUL6Xc1g7O6QnRriJbMrSFuxAoke2w9T5srS2e4L5Icu+TYu+Bt71TBHnLbLjYXBwbn2vGiUyddHngpcztQKki/GTQHDxDWKmVQBA9Dw3uzPJHF6/JJN/pTnzum7afi4gqwrrB4DDkvDeEokoa2Z0nTxFkUT5biV4BoWjvNPWBwirOi60t2oN6JXyrXwuC4I2jcUrpYuZRWNdKQfM7JjvdV5+YjQ4rq7ovxIm25cauVV2mA3UgyDOkC8e60ctsP2DuLJgmryWO0pONqcyBbnbVkgBsixzQifGeW2TqubL95JWHS2IBqjqmDzQgBX8Y5vRt1pATygJ8aQydfE9U2IvLbsT8vKhivpjlk98N/3Nli9bX81RWFWIvISDLZfoHfjCG3rIwMdiKil1Ek5HQuA+F2A+QlAogIyogw+GykCiyOm0My+ajY1iZyehFHGRUGn429BVA5rFlrOyLxHLQ0IQJA9+nJzmWlm+r1uekYc2RoXUoD3EaOMcM7Fy/PER1JvTbfRXZ7W+j7WdkngUg63sjcCd69mLV6gUjvJIat3rc9DQdV5WFWAB9lJ3g2I1tDhh4JkXlcweJ/p8BszmSovPDQ5EI8+E8dLSLs2FhyVYqXpmevvgv3yqeiYppm7/kvZzj8Z/9C/BLrKeIG4vnuUtvxPacS6VMTYllnwqvsaKZwhHuRj9l6ORDSOMjMp1RmE0+M8nzXYl9QxJsNoOeykJhZXUq24uVKpKlCuSK4tcZ7/fpUgI5PI5rdOa7Z3bSXDrZJIMKO0U9stHog040hrqtkylptmQU20k90n0SYlx3TYOJf6W6RaWzmpBblhYrXrBSXCPrOBptLhdjE+ZmKXZfL13JkHsHcrS4SX9Nqgk7rrsb7EjxWigjgcGhmrw53j2CbWJL9abvWfFbs1vJTy02rXrFI2b3kwhvGO2XEyflDVit64FJF4nvXfWZBeeN+gDtf+1C+kr8EHyVnfpvzliT1prrEh1nawwpbu1s4Ek2M/3DYEHLeWaY5rFcD0BNmzzpWeCZxG5mvPFchwmh7wQAga4QUwfnjgKb34Sb5ifv7X1ELbnms6QKp+WrIxprdaP8EapTaoC921EAkcyeUTmvOEvX+7hWhC1Hkvo2JpjnViZoQGc78u1LmIg9bl2hicJ+HPW8RHTa29mp/qPxvrOoS5W+jOxzyzcp/TGIgKziZg76br8ySCBAPq7Y3cKeXKIv6BPzFyRw03YxPhV+i/09BunP7TjgCwAhYmVl/VB3LEs/fLq+iRRAHlb4IkEzN9x3YIeQSZsw6mQN6ak+OwslcZlQtyI7R94kDzlUV2XupEzmcZoCM6++F/eYnYFMlYyrC/SYEPzTfq/7j7VxQ/b8tEhnRfjx2RmW528d2/kaMG+aUk6LCwYO1TkRDegiw2QLv1E5a3UV2quTxikB0qqZhhTt9cPURwzGrZuDhAOU5fhI9rCFbCPP4kGmyyYqxsCqxVlaMo1YfuUJGyCPDrvEh02ST1cRaeViznc9NnIFjmhlKJ+f09UbyYY2RS/ABcG4sMO1150g6Vo4tBNmLq+DGYAjxXlbZ4ftVylSJqBZq8Ox8g/5w1SFgPjcG2+y9GnNc5+pxRPC1gSven0DrEhgPVEpuyVt+ndFPPZeFrHa5pcaPbhPZ1nzw2aPJVuRKadsaMseK9itHrF+vcZ4IgUPhkDB3BHox3/f91CPqaH4idGvIlqysIYdVTFLUg1WODUPPsEeTbeIILiw7njPfE0oRJ//tR/PbrO8bYJ7O95Bfe0QlkzOVXj9eJnJDrqME1xHYWnn82rwlrtjzBCMAWh215rBJbiGvtV3yRU1ljaZGv5a4a1sA2NNqqZSXmlStIVsyt4Ycr9wYO+0MR6yNG1ziEoiB4rlZQ8ZNGzPQDDRxBk6rguec6CNDsaDbByOR0O01o8QahVdryJbMbcf4s9oyh46G08wS0z/J8VxaveSH7D3bASyeds9iZ8NHs6ShW83pleb9SNaQLZlvMOSIs8Jkx9gW1MEy5D0wqelb/u5+qusd4rb3Wjpd3HeULKJmflOB45q6C/mCCtQuEdhcQsngOfLqNqWS7LOVPJwTir4XvY+Q2JyiyVKxtrOMrye/MP63jPALRqN5Ta/Cn6/MhcTvcM7oWYxSMnCVy2BYuG/AcxuEX12pbjsAvZrCL7tDvyX2HZAGDl5/BplF2fym4sY1GQu5qyK0a3sTUiIm86I6pu6Y1E5+EPvMCYJVSb7jq6u1KiNH85sZZzZ74fs2WfXApr0SUMztMslQYeY3FYfk+0prlW3kaH4Ta7NZJZ6tWVWPTU+xbTCHeqkI7jDjeSZy+N/mftxoNA8sKDzvG9H6V6HoqmbwfO52AnV/WS9RHEv1qWCeZfakKGB1d6xouDZe/WY5feue7PXnZAcXCPudrJbyhssMEjNWK41otGmRiTLFnmfb4yNogPX1OQfBZ3Z+klKs9Lacxaq2NQVYSUW0aKDqVOxlj1UEM6IVJw91MEWeY9AMvLOiEIDfr/VQkMEMErNYFd5B4pY0omHTIvM3HSe676TPyw0VhJ1dU+ccNIjKmWxWc41o2LTIHG/6/oKSbwYRhq869TbZITq+HvgeiBU7sEps1EyvQv+zelzxVLUdfhyRoOwu6xsGy53x1bNpZQWUV3UZt6CbDtSWg9hyrSTYO8FBkhkC4Jwk2O0g+lFjY6WOLS4CCFhOB0gQMsLPALFF+BdB0gECFjSZNTo2LTJRpj5AgKCZPRwEzwAAMMgZqQKSRNBMuo4t7gdIEB4mn4MEMQAANgwMFpQIhISZ70twb6KvZJvUww8fU+G/MLyP+QEkkPcqhF0TfQWsVepUwCsR2N59BzyaywLWMLau1Qj4BioBtdvDUj4ILf6VxFh81b9B6Nj6FRWOXAfHuOhvFgqT2+9kZU216jPX1M+nJomr+neFe4aQAwRwluw/s4oPPeUg371EA1Y3zjugx5l7tExmU+9KnpVWJBMbcEHvpAieQvJ6jtxuF/Fyb4X/ci7gkUjndqogFiCddTjyvg45/A106CHiD3jjrfo6BoopnhR3GKYQNKrDIqWTeWq9FIA+FBaKBENT/SWXM45OjkrozoX5x2QIVTzv8CiH1JwxLUoAxte+UQ6t8XR4VMJsTpsZxdD6Q+mnth5nF0SKF22ZajcBlRWLF+ABW+VxCNUcExITOd5bZDYNneUidg9lbnmm5cN+g/PmauXXFhvF9q2p6SoybAxxvzkiId7IqnkKkHfz5CahUM5l++s0loyXMVdVjf8Ly7iZ82tV8172lFSqEVc9wz9VAxSZclh7KgC48Nb6e4L3u1qfhO/LBggyl3mJKtIVEPjiFaojuvpWvdCp7OXZOHNixPLzvL9T2nmTdGIVfmdPj7lR5z0Ms9N6qRiy9yO98SfmbllzNeJ22lspU8TXcAFAfq8N4ODlMnbN33Sf9FhF4FXPVh0epYkEJPEl+8Ku8lvP6VZeD+87Nitw1yYD4deORFa8yWEk3+YwiCax8b7yorjycfUu8p+nryNObjFS63THQpO2P2mcYr+/9/2h2tf3FN+ULMP/F/p97qWXWIrkttuWh8uEUVpOXESb8Nn33mzqdTjc6ecoBFhmkQPRR/CvK9OwX/5od1lvXF+hJOpCfqq/zaRsNr514UxK1/hhhhezfwewiNVHqk0dCkvLCBZJCPMvMUHvra3vv0l+WsVqc39Nw8JZJYNkVhMBdnZsf6PnjXcTwO1dGqkWMNzUAIBsqXvPf6c7J2FDEEXLqc18B8QKpCXcwo3+ivvNLJt5RCxrh7hp+1nTI5ZgRNQgfzZHnFgxoEwcHNukPk1q0MXFFXuOLWtgfnBZin47KaKFSz+bWIsBaVGVB+oZZ0RoHPNhtvAD4pNyZE0UDZHpmHKA5ryIEjG/XD6RJ+iqarDagUiRgMyy/psKaSdpKgQSLw5WLReb29nkhff7/CLaduLiUw86mzV1weVwTF14mTYNbc6tt4XCmHAIgIsOutKxiKRoyimgRWOOyAChMzl9uPPChISJwts/fP6xl2SI0QIPBWCkKDcSKlvF8fyAGUELsOB5JVEMFyKVwZXud6ghjKXQ1uo7VKKOr3/KpLGhpSYFjIJEX8vxkRxvy/HDOXxFDp+Vw+/J4WoJWQsuckLnOTnIyTTHOMdujlGOQQ7zHKYltCWEFjxxUwc2ZKB6Cmkb6Yku/5vXKRqMlAaLiCGrIKsfuURdlr2g07Bhdzodjy8raNPUFGyyk4SN9Wn3JDeYKn8EnVtvTzsbA90BsYxDEa2dLdQWqXALWyIVpBW7sJrZzcm5Nb02kMNiKKjYJWxpa4WgSDxJYfGoaqJKZ3ypKfVoZo8K7UJxdpdymexHpDc/Y7BcFhp0Tld3NuPFw51E0+HmoVDXywLSESmCiizllnCObCQY/yVXUoCc6Y5TX7YmQeY1uurFC4PJI2oNHm9btRyGltAjbWnX0tVKqhntX04BSiRGFDISI0iCdi3o1KBIohsC2DOjTQ5/O3CTsWk/pbstlDs8c8ohSai0CDuIhBzwx7aSBiDoXgXDQEM50BhXyLh+bVHbiUS75Bq2gcAJ2+Ryqxl/+WD6d58/p2m00lWyXtERwdqZBmrZOREFwvfA60UM93T/Vqi7inAyCM8G6HTDnbZBDjRHhwl16gctDwGu/8g5nTwWaLzlN8vGm2N2270GOZjDLrQXZdZ99WUmlLgXq5zfILbzplO0UuPDhdGrD08oyfAZJsDLXjHPnikoPuijK6EbOZiisgS2lB6LbjN7FjUGaKC16HX/Cukd7ss6m/7LDuH/UG7KofN1CsB6T8cxKCVA4yOCms+37ebAuUN8LkJNJfA07TSXZw1Z4t6s2ZiEV6ceKwQNCd9BXP7A8jcMPQewO7c2uH0b6Rx5oXtJ3LduKmMksF3h3q/bdvlsCzIh02k1WI3wHukjqArSWEYOmQb8Zw1HtZDbswGXkHW9smJ7KwWOQ89ebMMJjhvb6fz90zT0kE/3r5tg5Qtw/kMD3KxPnggqiV2rgIlpy3OZFR4NvEjDYyZTxR9VokCBxVFoE1KzfEv0HyKi0Qqs3CLYEh7eMaaQMKCt5dr0sKEta2PIynK1jiR6tkewxT9ChGSgFmWZv0uZBj0UEOmNixIiVNebTMaLixqwRXc6TmkMBRmPslM3O+vcQZ/61AVCxHLlMm3GbEf7gBp/lHT+IvMNJtWa+o4QhFaitNW4apHF9qUQIG9vsg/0H9y7LsKasZQGIkWV0JC1vAg9UHyRMCSAKgQwajW5RUIV5oeIWKSnT3Xq+6IKOo0+OAuDxwTDIxmIR1Nf+ohGEUqNGMXDEet+hnAhZ5LCAgOOE/wQWX6chgb5wMLTm3EfPCv84qylQoSQnoPo8YpMXZb8UdVH+soE+z/5hrioKOuSjSvpuEufdNCHMqWltQRgofpi80wHqyMxepGE0Itehu2e5q74umqccRwBGsWEeNPBFgojzuVjBLYGCsSobpmDNICzewZiCZuKsKPPblWsAj+RsKFejhLfn4gjUOukyNEkXWXjWFViUobTLDh8l13JKUMnfklXt32/yKdA7ilBb+kdvaf3/eEJfQo65hG9ffKfD/pu373pkb6BmxL6W+/0/JYlBi5q9Ytgwg+wwv/Ae9GnRRH3y6PY/SJzvBRcEsLN1d6ntl7u28OIleW2vBQZYY4uvAuYB4vkvqaHxWqBNwLBU6Hd4/n4Ft/he3xfH5rgp0odc8hbJ/3pwNSWJhf8PQdrP+JGww2mqZWexj5LXqZN6jQzbSJRvwBEHvdndeGIYhqkn92W/Rs2BAslWuJ59meoKMcJHAhzHYdsQs2ap+CJmcmE/kL9yGUSRObTIpQvWxvhxsUC4cUPv56/7++kLf2RnBt/onGj6b64ISSj++aWiT6WnJIDdzb1H6gBK38gwCZ+z6O5Pidn16ydxdM1VWMe+bCGOhETMB7TtqZvpVGZQ//qPioPNMjNvUhObSk1nr5AI1KEQDnL8phZIaKHOc99WjyihLjRp8EKmtCzJMlmEPf07y4kI2TEDA1JyL0D3D7vuVZKtuEQBs4jlulycAdZzYsGCU/AIyBIB4VouVFXTPDIwAK/wOUVTsHLbUajplMQrnhMfOZCMHvdxmrOIM66MJxD9GtKoXMcdiUAeQXklkW84mTi2QuxgcVSeEVWGK3EFQUfRTrjO4sGHyelf+jgExl18vpj636SxiqjoLd5DelYoTRJX8icJga1TlpDXzD2CqpaeZGv8q9lP4PVo9F8kA111SM/SeDMxVg7Py81W/iACQLDIYedARanlutCJFx3FKTEIYLztlQgA4/4e3qpui5zDGbUU0o9m59dnMVIOOVnXoZL53NHbsnvku/C0mvK76bEgCQSSgBOx1QzD4LCWlGCrg+WpTDkT9RQ3ar36qJ4CmvlZQ290jDPnD1GD3XyZePfjaSkFChHnDT1g93ETSRbAxNdS5maFLuxqpWOmxeSoMii44sCWEwlMjzLGbaSuJCccZDd1M7nEp/8gZd37osFzhKCcPN7GtK5MF1z9FpnqJafRcjAbsPZbwrkISJz9XkBgcafGFOL67k6a/lMZVrE8YXcqRxW4+cCd3MOduXZC5hDtjU+1YxRk7WpYvdWc+67zM9Km7URy5RMIPKKhRC4sMSppvnUh4glQwiYH+EJBpBqzVOKU2fOcpT67OL/e6bsbkZ+uMKIQ8akhEdRFk6JLasDekv4VI0dcC6NbJIgKukbrRSlJEpNSWKjzrSbeGuwplByeSZyAjz7jR5o7imQVgMq2Js4hDk5588R00gqFbzIh/t8PCuEDyFDZ1GSQeWt91cPRA5t9geBvDqxXGxIXJHr0bOCLsxK2jYSnknPazhRkYNLDGAlbaSE0Dqi0NlYPoqVyyi+QsOsE4U6uJDKUZRxrW47qWT7D6AxeamoEyjBxc50V4yXLq94KctdDXDEwY0Fuk9qiQWfs430GzDWiWB8iTEnxOR88XAAmBrwqGkmMjImmcJt3PMbXUk91iKUoXGB5d4tTHrg690+jar60PxcST0lY3ILUKtG/0jpsXWhfzL+EF/H/7aqx94qD+TZCyS38G74c84RIV8eeyevSv52utKSK1BLr1PGYJIoU6V1rpTOoMZHCeaBbqOOOzikHL+Xk+/hekIMJnMup4bWjYw/JRnN6eAMVxBBYyCMuDz0BL+11ixhEYEhM5hoi0yws0KgoXkInraP/DOIlEF6GUIUMxRfOZS4GZMR6SNNpIbkkWckTl3hJo7EKmEASnmXwN1gIqNGf9dKI2ITJyGsuZ+kqGhO6oNZIt4CItvvak3gSYz0RkuKzmc67i5eQ4qsxxYBW90pe5glqN26yRmJBqjfpcijuq0iz+M/PK8XBSXU2aarOo1qb3263mihes8u0ERxzULhF0ImoXDmveTeJGgtTUMkNL+61X9UD12KLLQOU8EiWOGBCWs74ZdVzQorQup0NihyijHGThBwiwYIqytWFuFmS/y/PLC8yITgrADgs0pkPodCHIwjY4yNpV/LMBE+YmEGRdC+Lh9looiM0AYt9PyQn6HyLHfcPWu71wCJ2QkzOg10BKK3D1TezrCkSLgxNSpqu48cOhIFq7rhu0FTFTWV1xnMe2RWFAB9Qxc5dG7rb7HptKwF9zsfY7lc8tCWF/tTq7YwNw+9bTYry+lmPlO12SQI3H2C2PNCKbJ7eRk7pZoRkEX6HyYJc8fFP+7Qa/HuCEKiRhrXfcMpOELcs0z+QwO4wfmCKZG4eCSYtJdJ65KWSm1UsZHaUxS0AWxknprUA/KgnbFz6EXYdqs/FOSpsLk8OS2ZPJbQ1uCyBFmSdT0muBguFNGrwuqZsIJwD3q3+ASjJA4ok9SdJfBFHDQSliIUGQETaYYxaDTs4SvSYkHPCOD1SVGFjzvOJ3FjM2OPrAlxhMTUZVoMdgnqsQnDCbBEob2ropGgegJUHXxT/KOK/o+rMii2e1Zwig1aO3KOIozzwkO3+NQqb+8VMPXh4gKPQcS6BN1z7XykOfqwHYVxqR300El8WDbfBDxDQ1u5ig8ZZGA5eu0Fj4ZKthckRvJBGip+CmiqsmZ0LOOfZT+zuIpbKgiREgKltdJKWlBScYEUmScQMyT8SZfepncdvj7bl/q1/hMTxgjy3Rb/NiLzW33y8zvVGA0dnw7KPSqP5EJU8GUZlcBtg/UUioLl+W6/WJMAD/CVtZxUdwH0jj6Ov5ZVqNL4hOB/co35XueEeSiC5vgVO6DrwzDY368LBjrYGs6lSL2XrPSH2sgzBpSCp/JeWjIA2I3PlG58spxfk7itnd8d8aW8VnBBgSdoO7A4utBcvF9IiQLAQyxEmv6KFDi9FwReLv1nAq8j8lJYt/gm3A1yaT2qdZFobUzwfmqF/RUCOHOSBxCrOroknOl0X/Ef8x06IgyqSWQLgjPh4H7oDlzOCh+RkZLwwAtB8RkKQplbEBTlzJQCgkTmYbgXXuSGehx0XTxpPeSkGr0JpEkaI44QL/9weDt2AYIII+WerkAAAptBYQJSR/GU0YHutqv5zErUbeu+0mJVlvkrJRbsjECZiMpJ/NMccYICzH/5Mw9yLceyPWuyIO0pTWGkyUhsguOf4AZtqILBgM6sQXYDiSTkcKdYJp22glU268WU2aPAFe7nM1Tst6PLxyh/RB2PpKCXW7Wc5PsmykjWIDci7qApNNB9ir5aMSOl+eTYQyKx37n4yEZRS48g33HFH9RKXv+r6iJzW3hFqvv9YSxf6ocL8IoTw1/MM268TMa5FDUATsK0tIqfUcK3NvHJK0UUwsogyifD+bmI3JLfZbtQNn8kou8CeXYH1EFUuLLcPeE4V7wir/7PHXzXkS/J5+QRhxN1CVqWrgZQbDEKXvKp9nIWK+83zAr7jMAU3aPIFLPlZzDrvcUFrzqO5Okswypig1xGH/RByWBGQxF8X8w6EWADX9GynU42VFadhuM/yPC7Efk2+Vx9Ik+11jRTT54CDy4CJiWZ9c5lfk6KewQZ6coM5StPzkwy21cIwHjDLNP88ZPEvI4+vL+ey6vRU3gcgtIUUILD5p8pkl/38rPbzr9YPn/EEJaOZn4Ja9WesdYJvWNZbxWG5h4O580egtV/d4XbjXMOyItR0ydn13v99FsWcj1Ke5BOL7xGx8FapfoqO3e+JgRlKAEOD4LqL0xH4tsUcEjgC6UsWOSuXMY47Qxp2FnJz0jEY0bVXgbhtu5bfBWaFbLpbE2QUSF95yonlXG273QmgfBv1a/piORzxlP+XRelux6IrE8t6PmAEL1kGfqCkyJFizSDr9LKC1/H+Coi38Eau98DAGB5tXofWMJ7NjAEcZ4HPKRN0yx9Y7YgLLiXd2rOzMIilWIAqXKEWL2oOnjW9jzcuf2HY1BTatJJjvNMFsDUoZrKlkk2flnMVJzZMiuGf9DD5z18wj/ekUqdzlc9NOHT/BPkUVfrMpMAPFWJSu6FQgUCFuw9TDripgSUxxT2X4YTQjTZxyKeTdl7eOAcjqkMMaWIF7s6M9b8V8pssd6sZWnz/3FhTsCBrwM55BhV99iGtj7PIZTXB5Zw25ETMicHZEq2yYCkBNw3FdWCVrsMWJpXIjltiyKk15y7N5Qa1ayOHtWYOXnaLFIkI0lAhAZEazReAUWsDCyWZ0arvJpditDAwrw/oHItWq2NVlVW/6e+9GHMZUkCcMxHDPzH7AgaMosPDS8OzHKcBB0RfJtAWDVV0UeBRFj0fT+aaaJgQgF8mxlbujfc77o7l0e97KM7t+4XodKRhXY6mTV7E+xFaEN9XR2ZhGl++Ipih0Hi1FHvUNk3sR3HnweT6nKqoGbmtlI3Y+Eg9arIduRSkNxZJImp1bKCRRJDC5DVHho8TuxMC/yJ6VpY05oiWoqB1BBAgliq/SyaQeUvfZLCaIlQqv80hkrFs9SxW1/7eySU//HPHvVCD7S0xLtooKv4jIJsMZ0CI1urZxX1NN1HNGVBuGgPpoImWFMgUATa05P7zkhXzVRhWjNa9jELAkQWyi4udzui6dvxLhEGc3fLvedyIXzQyMMCw0Y1AqX8Ikl82xgZVHHFmRasgioyFaE8DgoHGvRCYmYwwCBOaHmMLsvdoqq0ppcmiaGcIHAAi32pOJTWjTQtdslupLQP3bkYEMMAY59quCbRtVskVcBI+UnHR92o0QS4qSPW2iZ/ze/75SA35JmRtHybgM7ZCROJ1LZ2km+xvx+T34h8ydu8wvdYxeIWm0eNG7qrjGwb6PVypS1lgRMLcwcxreIchBTAsxf/XQwoNWJFKqr+6HIEuIop6UkZlsaSk7Ugq0EtJKayLiR/CVZadivLhG0sw1iMUg9VhcWWq25P9f1V3CyzXbJ5i0VptEskLdumvrfdgD620jKFZU8EYpeC0BJsGS7vkk6EI4vtehE2TNVCw17L063eFZ/COj2fL2qUckKky3jw/FodQgDCsgZuCp2YOzC1bSAF/TcVY0HHLkNeuqwkn9Guiui18v4NFaOa4+gxxsyD02ZzSia5eGcLsfHplesvI+5ePN8quZdWYgzXw0vxpeLcOVDn8nc/d/5ieNVFF89czS5evXgVNbPB5wiWbxb7BfdxucqOEOQ6qs/QqEFcF/9Y5ZNRWVsKH6YM7HHfAP8E5qLAC6TVyC78EgFkPWPbwF2DGEVUaL1h43d6HH6aF8SIjcBFPQMuXLssqyDOfkagCpWo+iNCeumpYuJLxuZEkmhAH0dkpe78KdkFeZPvIbNvHuHTznv9lNd7oQdctanONPRIm9iz1euDjiwSVioHo6mGl7OykqDkOzl3IYR2TZO5wPEuuDi5yAYhTXrI5bFI5KWEMRC5WWjIRuaU3iTqMFZTa2+ROoP3KIfKndAM8gKjmppDAkYXHpuuK5XiSAjlPDBaSen9KxmumGEGNzcEpxTTjETAKQBUAfedeKt7Hhg5bxuBg3Ao5gp+m+DnegToLBwVlvhS+n9FxXLSHeTd/HLNWBjqV8GdOrj5qc2C6mq8+jOqaE1/RnUdd1nohz+jvh+meSwkxFv+tn/TlyHe91/xT/xahOp+7NtMZT8lm7GLfGO5cHwGHz0jX4L4iLf5Ya/wPe7C0p8VttvQkbZtoCfXZkHMKeyE7txLEFFFg60vpJPKMvXudpZZmYmSptFC0rPzvBLsaVxgH3sjeYbndfP0CyUHhDBO6C/QHkgCM9jHDpghQ0xwjFMogQzUgtR8Qai7EYAqllWgSncm2TLfSTLXZ4Nj9FxyDtMb5Moz/nNESDrm2xRU0Hq6mR4MHfc+1YCWHgUOIdXIVpYYt4j8k5Vh+R2CTz6O+kPtm6zZjZBETPv1X4gw1Hecjphb3TgFCsSkQmzRzB2uvFs6dr6VxhxTEFOEQXRpabJ1MiRcXGlASUK/wwIsG4LMk5PJMg+hyhu2XK5satN0EEh0bZDbWqunaI6vmUXpJYdKrWsAguFJxsr+UcTepOifisPPIuNHOC0jhKOgH48hd0cPzxLatgUDujTITJQimRkUwQip1H1I5bRIobwn8aMN+4iZMvPc05kWkkLxmKy9LkIwmdaZtzzas9uLnVavXN7cfOhoF0S7wgqdGBaxvaYuVySaliUmgdEF6xVdywGcAMAdhX1DylLNnf35DxFA4HD6vu1Q2VGp4YkyUQ9Vxn0dDAdxaUocIlpNJWw6qmknBaHU9P00jKlW1LZ2zyfOXIRbhjSfJWggG5Tk8hrNeuIH1u8j6yiCEiI8tFRztACm2WdIIxV/rHSO9SLkv+5ypP7JsLX2PY+6LrWEeY73EdK5YWemBh/4hwlmopBX090pSjawUet85GrZyZs3w37kqdSTa/440Slg9Tw8ucSFEQQV4aq3yJV94HeyZvC8wxNWTNTfxKHsvQeqD7Ozz+7NCgh+7tzwurITLeXTedLXe3237cW6siyMI8NQXTe7qoqvsiQxrT4lTStJTAzsgxkENpB3cJywbVeWlYYBqeshmlaq6qsUBQ1ZDkkqUfTmnOdhWRjmommrb29QlDqljkm/VIZwTlEoyz6zG0DCXMu6ku/P9DYiIcLl6E7WSUgvEeLGwYEy/SwmAHlT0a2SNN+72ZtRonNIaBECwXEZNilTc2FVGZ/btfdfn9Tdeznt27D7PPwmpOuMhfbmskP7Jro6e0jogeSRttT+oK/L4asAqQ1BZ2MDhnt9sDExXChT3Ztaa/Zte5INpdEbFfKEa6aGxrb0q88Lwo94TuVI/oLORltdGgWPDyGfHfL6et+6Lns+0/5kbFLIRN6PzA9yR+5didn/AaQxkPteR2tay1qVSvEzIWjbXK0AIqU0dvABVBWUqiz9jBAh7rrP143sILO3MoxQum7VNspt5BbCjrgtx7IwTNI0iKw5ggCvgGFCEAuzQKUfCHKU3gooLv8KSl/q1ucdu2GlWRrps6/geFn0QujgnnmdXGvKiWFHk0ZmiMQKJQ4cMWkZWARrr6bzrrGGW5QR5Vp01b2sj9FvNGVk71QIggCXsefKCt77psaQVfctfMKaaA5oMj0tySta7Vk24Y5Ghrb0dZcL6HJrQT2zWa/Pm0t59PzX7u/PgI6opxXLMnbqvb5HP08wPgIKhBUMSSyM6gfmcXfmMY+ZzTD77LZCtjViBIm92ObRz5B3QpwXgniUqI+BjwmkgrIu7XoYRRLmuLEXSO4a3Bz+drC50Xpl1vRd2FU6EuaAGZ7/PdcvWpOzkSmjH/lrt5wZJcVisVj8ZnX4l/F6gBUH3EnOudEaSNcQUogTRazBCszbaduPDdKsl8RgrR/DY22cpxs4iBujrNsddrMYEMuBssPeUjpIZbE3wJDZxDpj+ROV4s6hbN/IHdQqPXWgIryeZaxO1QNVSOQLNMJFuxLPVFCtsxI4+QJniZE3zVRgFL7EbN7xIcwE5zWz0mXzW3F2xN5sVuXYL5CcsVNvtDpZUtbhq2UhUAPHEP+81gzBo0lKi0rWHyTyb9ak5F6J/Np07Q5IIKl6Wd+0SHKGrf6DYda8x7Cy8Zj6hcaxQPKxW/pBhOqG0nXZLQAX0jIylBxQYCsjTLxNWPcJo2gAYDWPpxbR2NIGoRlXT0MnRWUd/kayYQ/Yos1PgPTdaeVGDFs96eZb/Vi3uMa3BwdZG5EHIWrOw6/Oh2z+YnhL3ZcpCNfzBEWlB5wAtlGPD9IQygIw/eyYQ6Z8zhfcxdiBZi41Psw96atSVKEc58ShnEW+7CQ40qLRShWWQq73rPqSJG4dBoHPYHVJ0EakCm4wzepxhjJNrHCAhkC8y2rZKQcWC93mt2VGrXmOLOWyxhrFV84GeckntPTyXxMVPXyAG+yIJbkeE+JzyS9ZjSz2Q39JiTog7IhvWZNgKnEJL+FCiCxnfEnMRdEwJ6CqiXBkzx+UtV3rDwaroBat5OvrnnpGvfuCB+5I5fPG+WpOa3Bj5VkaciN8ltpOz6JBIGNXGL7Rp0vDJcOauhua0oH0qrxnRvsIC9jw6uQgK594pda3ZdrfNT85aqTwxFP6G91b4C2LsRn5JmP+3SXFiQd/B8R+tb7emGgvXRqlsh2R9vzMhTmZ50h1tX/1ulPlfhXnBCBPC7FFSeE7TpccG/fDiVAXkowzFRJ/wUewOYQEzqorpnPkHSIwIrr8mofLgQumw1je7T1a9L8TlZ71lgL7GFsu/tRBnZHCYrnhy84YCh3OsNXfafhrntNQUvjibvgLbQUUOct+lNCg29V5FdCaGqpeaJ6tBXA5E7VgwAdzwrU8khTWeMRRECSosVuqApF2CYFk1m00YUm5zs5vnDALO7BGB7BTwayC7y3mWmnS+JjQ+kvaSU4CybDVv42bW/2hOF8zKvflRMbqhTdPenmRWbapcAqO4xBKaCMx2ZQ88KxJJSde8HzFdqx/jywAx2bHIW2QnurMxw/HKZTV+93Ar3xZxNguttzbH3QrNw3kamZV55l1FjTnWxIjlZoEqpU+XdffFWdcu0MGB44bycyaF0WZzMRr9BWDcZdr5QOs0CPrnW0clAMT5q4SgE2trVS+XGBg96Wexct5Na6Qx1eqQS7y6+RrrEqi7B6AvZOHC3V5Hf5Ripo7CbhH28AMmji4SZXyPBPNiTWDpFikH0j6UwstTkT40+PKtSY6NR7BCDw09ESbx0FjRrYN5OAOF/9dSDtSes6igaq0094ROFye29/NpkHFLvudECoPcEWOp1OSYmOUJAYMJJ23U3gAc48kLGJs5RWPrWYmcKNQGnnFv3JLlKBu1qImhe/PCnEoyjPEL8lUQn+CZqCP+l09UlmHa03WhT9T1rRo4t1tSagbqSkrfGk+Ib2I5KRN4DWvmKwiWnPxAIkedBP9aFogaRitaNBfiXpUZsijczHeejfa9RssetK2dImita91GTl1XCuQbqfStd7ZkeI1L0npFjs9rb0zaZyErj1Hi64B+ujhITYE6Twhb/EsDnVYyyjz5bLCN+sAlqNorW/559ZAwWdzit2MMVnCteBZ+r4ENrMRLXFrTtgqt+m3XSc9lsnDJJcAHAyCbo03b3jpfgefRkvRgcY1yLYvJ139dLjGu4oeK7XVm+nGtb7cn9O1a301KejmNd5XjCpatNeHeUTan8asGnczc229lzbv+LNZIlVJV9u+NCj0+Xmjd+d9UClFz/1itmfrEdvqL/Zm13pkcZuevdYX8iG9u+3ds5Ve1bV+cbGiS2/8viQDAQORyC9fxY3lfFAMBw5TqlWq6Dg06fU7zJhmxkPPE1J1tNIP0bqzvk28c8smPSzcRfaGYIMMJdDWoRL1hrNhQBEnDNRQA1uZuLXyBhNQTEOT4SvpdxWM0kzkckF+Aq54sp/N4jyPQgWBLVdCRIQxx/NIDa30YgTYpQzAoC3nz1IFaoI4S+85VHhJK10n4FiNOhZ0FDHnzO4mG5ZmKJEB4hyyFD927O20q7hw/43sGGWaUju/ZgQ7X9nwdv5+u7x9l174lMDXFXJquOTKJFtv/YG3QYQ7NjEMdS8rRhHiR2nCJ4QZx7f6uhG1MDVA2jYZx0UibCt0MjBINyJpUnkd9mv3ED32yS6QERnaeAMgCTdsEbnWsYBKRx451G/0/15oodry4F7rBpLnGd+UURAsxZ54mWreK9vKXvRyxIymz1F3o13EJNawyhjSst3UGssFF43e7RFk2XDxi6XtAg5m0iNtYtRy3yBXuKMpTLONjrMNQpsZVVCJzVSaQNBoUkF0c9nHCOcSmDgeHvgCEYoa0BJzcepyscVIGt7DjoOhA2fVF1PfCcYKz4O4S29aTSm1cBREeZQiGZC983rTDiO7mxYJZQJp0RHS+UJaxAWSBNCU4azKUgVavZnduch5j1E7xDgMBl+TQXDJycOuGOnqyCSZucUNj+ip8VN6HcAKYiZiMiNeEHjVKGScLQlghBkBYiGVaKGFqoRU0Ke5cdykMknSiahcL6VSbPO2NLF4cpDQFIUF/dBGyAVlXOb7lsqOUYzr3CrOTK65T0GZaQl4SsLzSU/Sdjd4gEaZUJKMJOv+3ivbcvrjNfpOUTiIpFYqPUQedazKnpcd3bQmGcNq92xnsF10+++YVWbrqWCReImvD/FI6NXBxSqhO57oRj8qP8BZsHRfIAcxiSJKAyk2lFot/XI4ikmn2XkpZXItWFKEQj/R+zpnQLcDITtBSC/eLDfc5Z2bKCVjoqwkVeViblb7PJlTGPIYeR4oePqpbQ3xMBmGcY6WTSSpQyj6J9wN0fbZbqZfIa7xtliyUs/bz8fqkPCa3s7nBzvr1hqed++3uoNaVH3nP7JpwPwkuxlGSLPk/f5b/BQ+OoPCkBAh+r0eanometm6H9JwmxgOoY8hNdJCbFNRLQk38nQul/KGVCLU8JydQqaFa9y2JMPa9XbPGBj4+oCxMTUODKGUuzhkKIlA1v7FRQ1ZmUjiOb0cREOzmLtlGXIaF/KFs0XBz4ESuPies3KXzp5NceP8nFIiunOKY0bHlIa+1yHhM40pE4Stzon56TZSK25cx9/oUXpcNJq84r/TQo4sEr0TeHOv5PAZ7rO1o6ppnLk37q93rmhT4RAVJbL3R6+uz3QG55i2TjoskyZo8Xlv8/eKBzin3n4clYPZQqpWomfu8F/jmcqAD7f5mdmSusbueF6RQrgATyKyICMyID2SkzZJia2ZVdkejuZmUmZg7sLNsdMxt3dVwHqsC8pJf7E892i6+bxH5uPswWLzrJ62Fqko6/r8kRdHvuEf4CBdCHVAzFk4qxLcTNjZm2BM1y6DyPfjeGd0Tmq00c2cOjqItcAZvDyBkLCPKiDAum9uc1FgQghXUhxJzhJga2LTL7XbjicF4zzWLKlyAHAp6fbwKrQocTzdpcr0RIUzwbZI+EAK2SWFozAu+lqovWBiFDRBQ5491m92T0y91nZ/f10Xk6/xY8Uau2urT5P5Vn84Srb6UDZ63sdlXyrv3s99mRTE389PSXn3B/xp+X6Oonm/rpx796DmUjJDsSgsPycYoTezyYUaNfPtXh1lhN9FzrwvPaQrb/zH5YYJ7YmVXvHyXqaHXN77Zv7TC1x9yryZf/bKwOutkz7qRXfRxrXe6h1YL6LVNf5B6LVVnOrpzLQTGuevhh7QrNWscpIY46yNJO13TeoG8E0RVglIuaMDajnHPUGWGrMcQiol9grW601PSMObZxDj7CTjXBc4kTug3csZbKQwciUKG9CaRVlANrqs236z4WQYUkZHpRbES3d7vu23/QvbreuPgeePUo9JdwU4pckJ+E5OpZ734hBu4plnGpO+WA4FxT58qnaOA98fSe4/Bm2aAkJtjKP2LLwqPDx/x48eTQkIZRxUW/rxBZ85dKnkmAUebg76sWT9eJk/Igo+70IxWFBYPk4tELpJTqyWgfeYwlcIBqsv6+WIclUTrOUebKxmqG/t1YCW9aRHIVyyiXiBomMw1bXwj3M6etmhHbryr6F5FOLNfcJ2y6/grTebJntlgnyR/oj9+Af06ZGIMYtXU4PW6OhfrNgFjFe4LvvyiV767ZRDhJvWcI/V46yPxV2Ma8oygFLmZT7raPUCZdL1pxW3LwRKkUcx4rmEWJ4Ja7BlLQsqKyFilVMva9qwfiEUJITsShGCfoSQjFec/IrDbsqS5dsKD99chiGe2TR5NGdgrPeNSfTl3pQlv1CCDcaF3wcJOydvcBEu8schp/NysrFTMaoeo2AZbKJNPkbVBmJVw6uDCXbBveUyBZNfKLzpwUIfD0RELCluhji9LnOKpBARlyZtq1o4ZHC6K4V6VHhSSXNFSElekJDwR+7L2ewJPhZrrdZ/K9raSyv+XuckTRYDq6sYK4RvsT2ynvAZ3xbSvhM5AbCHfwbILqsVWCX6yHw2AFhv3For/Rn+o/zRVpmtB7iNts2VBYvilYgy8LFajn1BIoej6MmPTUUO80QvDAC4HFGWZi8UxlRu1bxQysrVjzxq3NTMDzq3Jq2zH+SCq0S3TFKqlEcYA9DGqZj8PRTl/nCZPQIZflGX3WZ3ib+S72at9Twc6sDLO89kUaNP8vjYqIPFR2pd1fU4DOiAbvzbtr7S4hYv9p/rbPBqz66EV9627C3WVckfHCPlHkdONOlqe+6mVwSmSKfWt7nxohPXp4WrlPPCI/QswvI4HjlpmpAoaTHXtDoytD/4rBBIW23KLJTiPd609PFkJNECL4QzM7L9mBODa/mmrKMUzMq0MwACNlnLjd/2Q0MNl/xKx9qSlbCCbPibZor2oEpsOo5i3n59qQxMj24ynJ9OB7jeZkIUBQ9EPutQU3NBUseBFSAQG4ds6tS7OGrC68vdEbLUSqXFi0MIgVIhIoFKqxOgtfAh92lB+bFhGTw1oZ56F/nx6MnSQigFJsAJNxQ+JW2ldEOEqKXOIVpvqIpGIA9Ca3yQkMaH7/E4UtSGd5Auu+/uFAwEVaDUYP8pokLk23Fs/N42TXK1A7Dfn+6Sp2/e3u33+appaB7c2bFD+Oz167DzmRD1N4TZDoCbHL7BzcGSRwwrUIHoJ7P7BKkuI6OlWAarqkipVtfhaFhL48/Q5AMYa65EvZv00JYv4Gyo1zOZGz0d1X0M38rwyv0g2Ou8gLj0Hbu9rRSAW1jwOCXzlZZ46vJKPIUwOWPOmwWC2Tpp3ujjEure9jUcD0ebaBBidUGEERw5Bl4q77Rq2X2MAuscmMUwVGlumR2nqm97c/3KDi9YWLvqSOXF+Aw3EueYsgPrR3D3iPV6tZSJKYRAZizGYrPowUmPy/CklBz5+GaLks9eBJ9hdw13GlrOhw7MWoc4wfkiu6dHXT7PaWyjGD3CKGfy/XMvF60A5D4CTfo9B3A4BruFNl1AS83rrxdVNTXTMw0ef6lHKntlVXDzWR53l/9HruHJmCOIeVaaMWyGPqNwXoOMHmCN/ThOzAzmhWzxwpAtM5RoY9mam0ZqvhJaxwZKx6jADq4g6BDkEgODh6yF7f4wZFBhVv5DBfmT8Af32v03Uz3mTEp0Jr3btQMHvH4KoMXDGsAEmBf/7R+AFUOf7l7XFrAKC1BstjbcEbDC428cqHE1LpfNmaW0BQmeWLZAjMb37CJspPCHo6Z/ML0B4j6Szo28LLe7GTyYZxUUXCl8QdlgdiEg8BJhFX85DLIf4L5pJjfiadLWRqVYrnTf9BeqR6NBmcTgAZaBOwnUTwh61kucE0CyxgyYRL2Zi8Ola1wImKikydtCKVt4SsFXEUusKpPswK+7qhpHZCOGSm35MpvX3QU0otHXL4QM7gY3BUFC+qVz/rqtRgsAR67KF3owUqqWKIJhOC6lMYij6dCyxkdKURuZGN62B0+IyzUZxhFnzsU13h8GQhbONv7UguX00rm8UqFohT9QRLDFBauEOc88QQOcVnK/BrAYo7YsQzY1ARer8HJvIjmuVoszbIVq87p3m7Iuz9QiCCHb5CA9q3OaxahOR733frQa6mmakeB8E+HGUEO3u2BTzSqKYMCV66UOdy2T5TAWUxOuYAXOJH3hRmgb5GDWxUjkBNXvkfVnqq2qEYKCw2ZcLJoXFl6aeXtWIK++IZgxkdEnfJT+gxxnQjDv3FDXAHjA2NRS84KgnkMlrLJnMccCb/OGp4Gvw53a0iixdrcS9RPGCOBDTEtBWusYqPOx9yiYdHBfm0WaZ7lFoL3XZHasLE26UsdVJb1CnIQwUi3LH4tJYjqaM8MeJWZouPK7Ts4+1NjhSPLf1sJPOOFdERkqijBW3LEAFehw6WrsygoJJ+4xlyUn2GfgrHWBFKA4A0ogm3ryeDWjoBHph6ymNiooUUiadKi6XvpJMsdlic7KEtSGKvqCVBDkWXdZBfZhsP0KUqMd3yfEGA6plPOC8wLizI9XOuJYIO6N4wBAVTJgGnL2HUH9RvmRIEgJbL3TijgUJbQ7koDnZwIO0hgp45koQP1E2Wc/tJZymrzTTlFJqzOLu7i3293g/wwu4mUGTXYvbzQoFSrRPc4Fgk1Vu0/HrlAWk5YzjLhOdFOpNqQqUXOlhh67M58Ssqg8QYdNRPiohYKA6CbOBTL7N8RZTdZRr+C4GjT6462pHwYlZdxRqHA9g+IFAEFr+n8Da9Bic5ArDJ7Nc7eIbAZHrT2IFz1YDqKGEU9izGcXcpe7eXlBSibjRNzy7jeFY8hpD4vlFwv5vRahOG7bYajm1TQBqKrcHdvVvHLLjI/2jHR2pvC6AiS2FA48MUztPRYMReGHmlAbUWG+XH6g5AIVNpJN2vySNBozZyU9yIvLdSTMhK+9XQIkQ0tYpkgZAQZSJRwIY1aZ8LREFLMIfAYwESZhmEztklirTxWaMM4+RQPNNUcLJ1LTxexogaegsgsevuP7DsOr75h/3pZkgjazejphuS/dmymD/PJfcUaucvG+4PEO//Qxi+885txHly7pTDLf5KUfdJBWG1LZH3zz0E01nqxKd2ea19nA8m86PObzD8HwK78dfscmzbX82bRbxGMZQWHMGExgWm8GqeR4GDU/1lWzT0gry8oLb0t5YcDBVSH4ra7dkz2qrxi4vS16WS2SK+96dpPrA5aE4CS+upcLsILOCsCE7XDB2OJWxkP2a4Q4SpEnio+TW7a0boYVbuA79N6KuTBlT+C+LTwp/OfKQTyONv9Dtx8uzq9kbit1Rga3Pzr5z8B3KEtNFj2XSQXWSklpoRO8rq9JX5Va6H97W5p/i0qRG8b7Af5EuoOgnFOXTrHOQAGcmAPj4El9vIj3kTysYRIZS3apWU/uaMqyqd1xt+/llZ7F+xeq8gqMcGJgen7KgaGLsOHQfTG1ubjBA3JqdZUqCaUc4+P6Av3UUjVYzivz8TSTkczT/DPsx9LHHeXUtgdI0HeW5SgoJ/npQxc0dVYiTfve6FDnZutcwGQDC+5jtnXYxV5WM0xeSsdmP/GJmLuYeunUAFZiZ5vvPNyShYd/abxIsnnsdqASB1wsghsEKvD/dfM9NrQf2n3D3v2/m/TwyMK7jwP+1t0vVvgaa+//Qv9hNA0za0Oe+xubEUw6Y4ILrRek5zu2GFhsDg9c4JZhp6/eY1wudL1myNllhajrNodyq6fjKKOPG4ZxnHV9mzH7cqMnaij8Yh+lVilQWC8l45T2duw58AQ2yYqrpC/6ynzmbJV6L84KeSQFDZxBBplE4+ZhoPUiHsa0NUPHahk+cYhfrfKMNZDTqx5hUDWnhjvaFUnBUbYvibGZxXYYk1JETfQp7eXkCoMmFtH3F1n7yZi9+DlcE6FPjuU69O0eXg5pxGy3G4b5lc82bwHM82PLmPeP7nBmAuONGfl7dMfYWq6fkbLoo29ciIb0HfDOMxjAUXPDa9eB/EJ/giOmTloWZ1Ru6hfLSC7c5OpgOd8W/krpK35KmnWzvqIM+d83TOw/WmhUA4xZX0lzsLoC7hr7UcBxu5DjhXrC4QXN5Yy1+ULDpo7nIMvsIVgBUHUwHm+6WBULvrjAOewQ4OUFKPTJBCFRPcqOvqcbovAgZV8FujW2TNrkzFBSxUSQRwH+qfk+JCT18hqwknFKLENCdKaiSUzuoRCRzMNc/ieZ7pBwWl7kwHcsmUR0zNbSLtdNF+P/xKr++TpG38XDaD58uJK5/8ZXP+bTDwZI7Q+8326uTcNW1pOVgUNq6T/08O2IfJf8mrf2EYQiViLswWAu/J5XscLOoxgKDgDicqQ2m13IBtQG7TM8sKmZdjyNpNDBgz2VnGHvVRyMITvuvZbZ25iE6av7wVa3T6Oq2q3cPjNJND6a0OS9e56x12yjIPNo2i+VQiNjCKX0nHrEhQ1hPcOR109EBQ+CylB2Ib/LEHgFFgiqXFJhUdHOfjo9ZUbefGdkbM0N4GHvHdeodml1A/d8vcbx2/dw3uUuDhi2sP3q63p3oZYrzmc5P8OlphwUEYj3zFMN433XncCzZwAn4l7XjqEPLoZacrX2ZqXXa4HevodJklFxjFXZwA++XGk92/kZK6Fot9j83evl1T3Ep8HT2tsEEVxqnNytgO7J2oSH/tA0unJr5Q9V5E3QWvVdK7xCc2Sda6LAyssRFQkg7iOVjWle6FPfd55qjdtkitZvUahULvN0vcM/tSb4cUILzwZjruRdMUhIC8gswczJ76vJZXRq5rzCXhqmuyEUFzs5z8t0dwXnLisMXStlQHvFT5IJmDj4oUQ0Bb9TE3Ttmbs0VadLUc4KwEZ71OXtAIwE60iqIiVZCak/ObqMsFJdacu2aYhSpcfYkA79QFNjJxFY/ggXFusKDIK2l6V/qCH2o/ydW77qxAvdkxDhuV5uuwx24IMvu1fwsL49s1vjLAT5ChrgeMZIKG4lTlzghkLRFLbb8KSr9arPrAQYhDH0ef3cgwr1txapQCxYaQP7K5noLlQmLwyEaB+FHWoCcQyc0y0owBmHwmp7lrxGCL3Mt1DJ7lMK/ywQJrJ0S1spiBkIIaPJCcVuAxramNDf8GRI7tAa2mbnXWzJWKx8qRTdFb7jXrE/DIHgb3hy52M9THcNG3kB5jKv4DLiSupSFV1jLhYRleEdp5jU7gp1W58dHXmF71lgHyG0NUR23ph9SqemMnWt8khItg5WYyhsne1WMy5tSWMb6scC6y13iu4bOMsEHbXdw7FujykX6RJ7H7S5FHVrVbXtwMflEolSgOUM0XAuRDeUq/XIXshWY+eWg8XcaTVV2dF05+5eCPSrZOhHaoj4j8sraDHNaKYGoQtzhPtl7Q+Y9kPp9ZgQ3nm0sFU1gwJc7JaDqBasFtS7H63BFIU0V87xB3kl3w9+0NeFP45Ye3dbo8yFkn4z0msQapWLDHXcluYlv3/p462uzBNXvIDz6CIY2U4tHs9F4q4sZYxlvZjXmsWyHn9FDTDnjOYBBQ8bLS/o3OskohdlUY0bQrmNwMtje9wkel2XrNwfpqX9fGRZlbAGOqUpyloRQ70Sn8ltalMs3uvxm3LihMxzypLOPW4nznvVP6NkwgG/Xg92GwOms7P44lQLARsygEXvtJwThxieButRUw4gUvLRECvq3OKFtCgzSse4hMbzXmYmXbguwhSxtKBSkiwAYExI6ffoZXtZgiTOkVSkABEk7euGGOGz0evQA1gNsKeAdLjBiTDccDajDWtMpesa5FoD8Nli0IylMY9XgrFuuipScgj9xmsfNdIAFeNEoVJY5grn9EkqHnvQlOI3totSS0KywFFUT9Vy2w3trtmUykrIhajkZgOmorf7wwDgsAsaoy+08GhMuqtre6ZGohJOJPuQGdzPsaCCLmuItkeIHvxo2psqFC47vtnEleQ3f7HbuGr3757ykXfyzyIQgsmJMAwVWHgbVEGKNmsqReqtW6Lu72y9bKnvqCSvxEVlvEwmKhVBwAJA56FQbJPiYcDj6OEQNbDZbAdKW9FiKQuz1HEJJ7DV4k57ErSIooO8WiZIkBJxf0pqRGUA3H4s7uz5aXtSW5Z6jfGSUm9Ra5lRpehADI6mF9EfTP3CI+l06w0c68w2FIWnI8Qnd8pafsFWLgPBFUforb+sC7BFXzLCi5eMG9hP05zoGlWw2u3DqZqIvLiAcyL2j/kaTNb2YOFIhmO6kTRpUNjrSJo+TWQgVOpzhFkLTlqMKndUDN9fv/FWtk2h8RhLQdoPXpMe4IVlUTaThEyEF3a0iJuIo0RF9S/u7nVl5rltydFnewLStw/NYIdf4t3o0nJFV9YcS1gvo14PL4vL+wu7Za3uQZSHI5GCKXBsx2jAHClUh7UoNtXAtu72M/JTHqAAs3gHUYtD1ba6S/oBf6YHje+gm3BIk0sb3ltv4RC/+HpYL+7vj8e3onj/kVU/2x3utne/5Oi3/ts345szi3GLViO6gDCrW6xu1icEDYpAHMguwEO8GmVVtejgXR1aFH5k0nmJnYhNsJUfrhBoB3D4aena8el9zvyYRH+zb6CpACPlE3FrDr2LTz2Jd+oN5DB42xYHkcHWgKe3u51JeZqB7G3nBvO8Wh2eWUWSyIPO0WwVpY1jOp4pQp/Dbi9Oa8RhcK1ZOM67ElpYfZ5sCZfzYqi9c6UFQmS6jAERARYK3QanTPnhJbGujUkiSgBQ4DqVSVU3kpAk2OD3ZiH6Ylz5A/nC0IzC1oqNdLjlkwPYFsj6PzffyIbzSBLmUz9tO+IL9iAteA0RvAgN1x8bx/bHAKj8HfjWGOpYZnNeXxPaPd+K1xRFfcCHqqmZlCPOx3w9994JWDij8GImg8u3KWmeSSJrgh2hTa7VThxtAr5drES37Pb5Lr8+bmvYcuHspIYpa+f1iy+TpTjheeIucRym9ssPJkqZBWMAIA41M7+CAQfmEdRkXXDedO/KNMusc00TVTQ6V9DbRGuer8djRV5RWOwN6tiU8q7UfqxZp3ldXpVPNHYxKWzZw4taRjQEzBsBaQZFrM2KhbKKNtlsUXMffTsiUnh3uJXx2tyWd8NkvQiVb/4sO1ep2BtkR+ad+npwoYpFf1JqXlVCmC5XywGhaxrdLJbFvMvvdV2jW44mdK9BvTljQSPOaDFr9Q1s8zL0wWyWFDn4D3WhuwIw14EQRtaYEBYt6UC3u+V8Zonqus6TSByFspX48VlBUHkmYbzZbJ4kRTWKLhenQwP16kl5cC4tt0ejM3oSSRz+FMAcHSlW3b9eHS9sV35QeeW6NCJDLZWSZK02PP3BXxvaRvNSJ9rnvEjzEUBXs3qxHLszo/Ab7XadSeMpL5dPiBw1pbLQVDpU3f0xtAJQSxKmq3XVdeZCZ1V1busMyaFRVMEZeUj6MJCie58ra7BCycLe0CKknUlD6Wu4bIErslJkm2kq4wg48OO2Hi7ULM8B5GY5YmWRWXS2FWxNVYkLlcjUxt/Y/H8vLODuAgyGei4nwLaCdy5/aN7ng2GHu44QDOKyXJaHI8bTdgvvbXGnknXyoJmkIA4SFcOx4KO2NLkeauylJMb1qLxKelTNYwcOtsuxxvUFSRg5wxTGU5UMF6CuYroENOrlLLtOP+Rd6sFnqIKeQsyOj8n9LCsyOwGSSy4DuvI9Od2914VTroYyzgiv9HSktjRQ92fa2wCGquOtRR0KtVCCykCp5CQeomqIs6H3lgFYai/R/LwVOzJsDoURuZ5CyddRE9InCtPvjt2gVn1NARTGzJMoLUuBDS7NxwasFepnSM50uZRrKoRSaqVCJDk1CeVcTHLBAx2pl0QUp6kcsTEpD49M9XMBABGdmY0YVwnf95ETcZG0bqMhKgkp4YX0Y4NNp4MTYwJjmgupupeGNEKO94ISNMcZWbLGNEgdjakhpGQQeVdmpnCTMjB8ajnClrrE3YDS2CcpyYSOLUF12djsRKfrtrspXbXdstokOw6DlByHhc1gCd5+Y49wPe3OrFYTTk0I8iRl9Jpnc775GBx/t+cpE5pxp6a2WOuqLlKyGGmk6CECcTIgUN4Uh0ObtxWnhAphPQSYZtMZGXLGSlxs+jxI5pLkRDilXgfp0yqVNGWt0InsEE1ztxy1FtH8cNOUH5v/GkbX7L2pado2yfImNUnIyENZa72zi2fSqZ7yLOitAOXwS0SFrfnAJGLmgABn4mj2PNKV/60JqjXJlAoBU2IrGUguSF0c3ZSiuG4gJVlrFylJCxXh9evamM4WNVcX6GOFo+mqO2ziKT+pXqpRyqqShc+aNX0oWuP2EDtUq0GDVu5cumCVywflaneImOLpmbga4nIdCVVT8qGHxJFO1M/4PcsDj3Nla4Mt3MHdZtvmfU7Q+VUU5Cz6N9JyX/oeB/HMDHgMvq091WoW+VAEqNho74fvGJD45h75FUi5/sosfIT5Y2t5ZuAczsfJmLoW2tVcxJ3JaDArOdxFpYIJqdIwIsQuABBzqqJwQgSp2w0gKSeJHhWAr833kepK8My7nGUVFDF+TtcxKRNbCt/p9FDbqV8qqhyQlKXjehBMVQWJeIYRtK58fBjVwPSMSqrCudLjBjEX4KXdmv1qdByc/HAozguOwbtI4XMmMyFKyQPnUOWFF1Yl4BmIA0vBpm9dsnhtXxiYkS8ikn3vDAwas55zRcja7oVHqoxq+qURn74OiSPuHpvaeD5cUys23uXvNlJ6UqolgDRn80KQWG1MdcaYOONZlt0jhKIpKePyTEjVo1CJLfNsedQI2QnILi7urTK5w1CrthMQZ0Vr8vo6gUpjiT/RQkgE3EYwPCGE6JlLWuVZej0MagenJjXr3e72bhPV6nY/b2fcqPRfGQ+HobKCLvO6A5uNbzebLSrAj+PLjf+yZkWczFaoh6nbHtPDM5in1yKiWjWltdhDHJvSo6SI2m+lp2GnhwSlWY/KMavIQx3W18wCkEJApUYihrUCpQhaaY29YETg1Wu7OBnGeDWyUk3IfMp2ydXHwdhVxniwUpEuys81IPPyRPNK0KY6a3u1v4eSSfRQUzcZQvcgjKC0A+UBkXOYDHA+ZdtmoZpDpZblgE4Gr5NhFpY9I4sDLgyP66vUOGaq0TApUJi7Sq3nbFCVOpMNlQxpEmAryLCwyw8GKtYbPCL/s8kDC2UttDskzZkED2s0QFoxad8Xp/K6fGFdWqr37YdbhG8xaLm73OmTTCc2Nd0KShoqHjbcLpe74lbud/DyeJMVZ3B2uVwvz6zXQIjh523DCNaLpyKIhFGH5xeaF8S5JJEiAG5i22FZ1QU5yfxQJBa9Z7rEOJf8RIrSafdShglL7hm/DEDDBfROTankP5idahigoBRLQgBA3K9N7vbt/CtaICosn/CiSLJfkgzSKR5llfcF9pN4ZRQgFsBcPCJEyNgYD4WiI7TALnuo141hgkeF1LqmiEXDJE44yCICSF7bs0iQtjoInlX9cGpcZlBMJ52+dvdL5RUcYhpFXNf7w1Kpspyeg35SxOS4lXQn4sTxTJGrxtKUAn/wcAdZbxft0DTj6AkpC4ibxeBz9qANpoizX1Kk4VxrdKKd1VxAzquQRvFgCs0itaOtUlXVM5+RpZss+ind+EPd8QU7gtUTGiQ1YJVoJqKolhuWiwR/HJ/mPQ8YGBtybsOnnKn9nuVb7GxmjNmhZmEZlq/u5ZEfz3Ck+njhdp0eWuUm7ufZIZQun/EqLUZC2d6LMThdgVloDUfU6M6Le5gvFju8h9cHNNzdxd949y6zYSnECmEK018clozZnbbDbvHt4cytMO0TpqIrvOJdlCag52Xx3VvwrmlwF1IPglul1kJreEeF6jyd3cclnL76auCclewBf/EFUtfZer/3L/nmcnm/zZ8dv2Ij26ZvRqHeHafoa/ya1pIK4klu0hf7/QYc9eYpQ3K28PlZTz8e4EA1mXEC3Rkd7+7u73frtUoC6m27aB++WN8d7y7sH+MjqqFbjW8VHtm8VKUP2HlPiS1wQym+JBRiYGVZK8K7X6TmsqpY52639I1iYAWrAdBZi3Ej6tpnx21rlY9F5sj1lbAZ2r7zYdm586GEz0eV6tOzTjbeX+/t/Ycv3759//716RTNO7wpfFQw3sys8rPd6csHq7w9fBmYTIcIuUKFy2H/9nH0gDyYq/SVzWovOSjPbo53fdQsSZlhNu6ep65ArM2fErn2Xg2hzK2NJE6NRy8CxtSz168X8Wp8+7C+ubBbWzg1YA5e6XAihvAkH1CqL3DiqN7nUX3gyyowCrCNUe/o1hCJZby8XK2mvzy7almL9QbWY76dzizAavW2QwtAVbEsJflHb5QHueGYPbnadS+fghIFjDgzaUwMqfUwLkZoUM4LZIwSjVKa0o2v6SOP4GxPzGm40nTrRd+t1qJtainbFRyWw0Azk3OglSR1VblE59AJ581waL1eLofOfRuGSa5Wdc85pXkihHMsLNiJbDd5JGeRrYCBQM17+HjSigJZKD6wrygpqIQz+xetAmtbU1qdGFOrkum8FkBzkyIdzm13HNWBYA9A9rdNUVPB3izcr2sZYAzTcHQoLwl5xqkvrDRLSQC3crNcKtVbfaPvX8vNhu3ZM3vZT1N9YbJKBG2OE7U6kHX1iyCPpF0UVX10HmyU+r/GDJTOCyDBkBffI4kDb3CkPnJPNty1FA/3KlFfjaaNvnqavY1ndRuPLP5rzMHovAAR5Nz7K8LWvHLHIhlKyNyylIlSeaKU1t65sSn5f4kZ0GDJB9/WObzpGLy8a+ERThYfu4tgTFzduQoR/wvcB468+F4aJp+Pt0TSoVXSKfezgqfeyeMFsckpEpK48LawtisD6G3LmvIz7v+xY/lKcmKGvlWZot89GdYLojzZ8cfUJdpQiNGPxqQ6d5PC12xsYKMJiVwScWry/A3uf9tpybj+pGIUIhpQpZbOm3SXEtreU1ZwRNPPuP+977LUtxHfiw0B2zAkRiSqFIg1u7ofSnfYl8OJiQbdqq2L9sHdshIpNIKv9zPUiD5QDTd//TVGfQaxbLv3T9OHJoYFt0rrnCJ2VnmUOJV+xvy7kCPpAmx49L4pLXPnlq4SutLGg+BjNCh40HxS+tbS+azmzRcivhwBMgepaM6YowCqkexKOPknBFetKecZsyItMvg5CYzLS+Hwp5kf1TjOmfyw+VmeD6pccV+xd/DECVqirCS2gpZUtEoXX1x5Vjrzzm0bkiflFeBFIJj4qedV51tFZAk7ukfyqkyiMz1Jr4hRGj5M0cZ6y+dEugssrM169D5kBuGuZlTz8l9NgpOivJb8NFjelftr+BsQ0q0Psw6SX7JjZiC9r70+TKR0UEyj4pBVD6RFBKzqYOJxKWZfR/3o3I7dDcgyIgVODOg3dxKAzTrILGQzOFg25tUZwf/S4kzl5l6dOm4trYvwudcrlGBiduqtP0032MOW53h+DcMBGdvHl6VPjAjZPNnu8/8nITCNkh9Q6yJyJBr9F88fh3Q0wvr/4xGMht/rimFv/98s2rTMz8dL65GC2q91vDuaOEJh4JFOJNEoMVeeXbTqOCuC//DLleHiyds2dXDaJmnPgoWJkfzMYCIrTqMj0i+elODm6J7pxg24IQ1idTxiRKj3kDBrKGkA9AC5ur4D+hhCseWe6nRQLbCHGLpUifoyFe0xoHxeSe+1ID0+b2S6GwfMNCyRMxkD7rEPkvESk0r0IIexOMUtC0zZTcAkb8sZGOIe+/zMnNrQMQHe9dQEWZ3j3uEndfSej3QNIXAz61JvYo19EOUjcym+HQToc15QEePAdQkBy/QYOv599RtdmfAKcBEGU9pzCGO+RA5Zc7JSz4zBmSOHFz1MXc+LsHHlQKKNL5SNOg5rRk+W51zSAH8fn0EBU5tlogl+swAgufFUL751CrXABsOgA7DspKgh+BGuPdCdmlM2Frq9LvJn+YLJaUEdCFY6zFsp/CQpzLTXd3MHmFvt2CNcfZiV3SbPG4MAGj/GaIZ9r9O6oDqTozOYeTjB3EdfpwBoHCJbiK6WCPw2eTMrLnfX8t9WIOcUd17q9SmIMq8RwLMDWU/dpAH1napvrYNJr5MROTNBTjmZ6SDl0k6ivqKWwgWtdP56ZlLFxE/eGtKd2jSQ0h/7y7Myhc5GJBJRjZx7CAeB2RE0iKIqjQBkZgpK6c+auBETzNZVIYxIXmOSlkRqjq8vMeWBoFV/STEfHib75Q/bBjmPjwydikrItDmyeUKCsmaz2coTRbgWoo0Yp7iiBDAwl5TsWGaUxoZsYph73rCU4JfDcQ5GC2Nt8rqDgobVMLypeSaNMKCFajlZLp/ZzPwr0TAXkHYqKrQ3Vci4hw1n03lq/Fz/Sn7SeVJyLryx/3189112uoCsFJSoST4YwilEWpxD39Ls5PnLnxTxS/2BHZjtloDa1Z36dj2s//VdC+pW6fpP61R/Ts1WdOa/eRcuQMs54N8ULt3xbagplVszAy0YVvPsjta2JpJjHg9ZPgC5Es0X07TSaDOllJ/+SaBpJslaCub6YABAk28zCObFmiwgEJEYWIRtwqBb2rpwzDcoOmXS/cIfvGh2DT547Vq64nhXyB+Rd0XAdSM8kT0rf0iHmj/sj9I+S07m842+upk2+tN3XufufDb/avPa5AzINInnE2PAN4oQkf/CXTmTX9nLUjJH67zGdbLsf+rJultn9av6qlkgRqZS79WcJLvlrp/5r/KVgcjsasGDJpBY0NyLKn/b3Fwpgt6V42stcJfWrv7kUA6iOERsvTo8J3TLBPh1NKwTz6A/1jKajVfNQggaxLjaa6YvK3GuYKvDt0hh4CQKRcZRfkzBlBQ8cdnfAkZhC/EVt+TtBu5TQRbNIIyxl5+zhONlbtzB4u17zPo/LF+Mb+i3NPv12CR+sqJcv+YZG72MppAiHhMX7B5vsaQQyV9ND0dTB3skBmJ6YTs89APYlM9AjmU1v7halkcxq7zJl+K3IuPpQwZmcB0kKZaEjnjCMownhQCvBS8xZYT2G6uR12NxIcsGvj1H8FDsWiztkrcRhyxWX+NoeNA2bYlmmTY1HnZQjIDIz6bhLJk2N0xtV0Dj6j2Xn051c+XVU+s3G6i/GEXrMQ1sGiqcZNjTRVwEv46CPi1SqqSXWZXmnXSYn6FT1+XS8TnHumxq9cLp+JMs/wH0k2AcbAbLYC94ObgMfhy8HBwHninnNWwzdhVUZac8Uel4cXPxoUI5k2Ah91fsmaauPzVMBN6gaHlrm80YrLMBPRtNZNmcnHgPf7L7F80RSo8IlKqE8RGKrfioUmnD7RBNw5uQmkoe3g15JV6nQu8uPmhCWrR3tY80skOCLRYaTJ1YeKyS8Yto807inKjTp9QsHC0SFF8lTh3Qzgep4lgH9Pu2Pg4GjssGsg86Pu/Qsaxae0xC/mQXR7B2xw1e8uOOeJgtJc8u+/5oVO2C5jHX8TYXeFx2U/2wXS71/ITGyNL97vNK6t33J4wN4QIqF+dCtgfq5zdWf+FcFG+ufuM6JL48BUY96HlEQAABwJWPHV1j/Ati4A1wOIxPYxgzMNpLGIX6hT9+H3nkbJdALGEquO+I3yrnj4XrnxSSN2K+l0Hn9veTn8Zrb9S/cLs7X8d97/RvXJ7fQ/yeWEDJv98RBFrDSJbishDEsdiFvp/K6CjfbI4L7TTHTh7IUXIdrb/gi0+6swNYPsmDSDIHRyhRudCibZvzPO2r03Skg/VOtzri3JPxmI8iAvWSnZ5+V4LrTbv94PXfJAF9EU+wkzCle9nPJF6vOnEiznIVUQ1Xr3I1hKoe5EAwV6zD9KpfRmTGQCXpIBbdTn1ZkjFA7gxsqkpdeqeGKC7HF/LJFZdYivPLFYyW3c8xtvqBnPB8slrCHpdcq4hRnjk7ZDFbu3RV7vMK3IHjEAoDFxQXMBjn3TjGolUOhwaWMALkDnYI56pWzu0nqHE7uB+kdQ74XB3PpF78Kzk6uZfXjSQLHAHUNvzaBpYiXhkot2uubAi9A9WRgcHNcmRsPcXZKR2vn3yoQWmC5+mE7ohKDmPFKN2rQcY3/pYSwmugDoLP4zCssdjXfhEdASpNY8C6I7FvLzHgfF5DKBuxWjxdR/8VnAMMBLn6PG/z1l5W/OYXQ0CCdvCWKs8/wtVDk76PBr/cQvUb39Td8QHmqUJbOV9vCwRg+jMcWu1ophvAB03OgRQ4gxsdJi4TYgdeJr9ncgo7PnSh5eAIN9pmHce+pFQj/A6ugggU+Q4Hwq6xUci+krIs7tih77jMBUJUa5Q4wdE3w+MHgVCnI6H4wG7c9RwCBt6ey0qPJJTDx4gL8cHVebQfkY8CEml4uz/flKkQUHo8y+7DpyQNEPxkDkM5lAbG9+XCccfjVTSF3arQLPFQiL0d9M5wgTk9YnvpXLQzOmq9hwPNCtyL7HgdiBWs5g6d91dXNCle2pA2dG14xACLlPkrtABBOHNgt8xOY1Ppg6QsYdOsM+cdkjgRCa4N5EJt6czooJHy13JdCdEYpWiJD+6Nt+H0fSXAQ44xs+YhmgjWVb/quxfdbw10b0KAsYhtj7hT2L1AOyPfn/jxrMzWnDQdRnYMdIIKU1AJE8Gsv5tg4zjRZTtj3jtUJrHz8ZAnUKf4GksR/Rqj3Mky1+1DOD3Z17oR/TBtpDVRPumXTai7a/AbM87v9eqdSV1/tB30kxwEwrHV6g/d9CcX1kw8Mnly4jUI4LK8kgTkaRBDLVKDAWGsm6RwVpQ0sm7v7oUbIaQFZw9kFIK4wLnn0HquilFOXLIIVT2IT06FS9jfgF7hWb38E25aAlpi1pvxq5WDW5EokbpnSPcrkZTwTNDykwFLkHgsFwQzvqwZ6fV7Xmf65g7nAST1yq53Wkapu0UbNz7VXoOjZKDBZqratglmKfn/Zr6R/miXYDDEMWPSphk/I3jMfLzObrATcfamkhbN5Eczhcnd+nT8RAIU6MOkfjdlirYu9+QVISgZCYGJTEruigqd8w9hWih3O7fOIPMiFgn9iuyW7tkTp5xHE7GCxlQu8U5WyZwzPgDb6BFBaA3e8g2C70iZDMBr8vcL5MGcMRu7RLlbaVMu6zoSC2/ebTYUk9Lr7fEo4SarZnl7E6YludKXa4rplSiWPaHvr03sPpp8zISPlnGJ6/3muD9e2dPO1vZKDdF5p25h5XS0zzrlgeGJnIugkn7IaKYUm7ftOE3V0loAPtuvKxGUV5YB97iy0innG+h0YeUsUb2iYK11HsPS5PpyIsyQ91wMdT1Pq8GYKcy8i90c8AFbt8ZjCKJCFR30xsLXFdjVcP40ticygkVvIsGaZUCOzfwFr+KC52m7X4/x1Rg/dLRLsgCpFrl9Z85v3a4XUBUDIH5crzec350VOoBTQXTyrwnP4B1/xfVhFNHBPCYkGv3W6SLsMmITfavQ8SKPih+7kiRpDaF00yf6sCGok9jbLYt1MV4oYrh+Iqzc9oxLpXfoPXM8PdQheId11PDiSQ3WcF32fbKHGi92pUERU0K2xAabaZ4uzDNwbryQV6BUuQ+ldBRwXBTUThdu9xc0GMZJ5yZSaj3rGqp1VYsq35Vx3ySH2CxLW+jhNeTbaNq/kpFEN8BB5QwLdvAtGWzPIE5SyLmZo2AAOq1Eaa2DGdX9GqUI+IM0zK74Zg+xWyxubjuITzYaheZMFgaUWAwBVmP9RNuOEqiTi08Yg4iDolU2IaRypSbd5QvSGBpkgGo9zwHaDlfiM8LHjKaKc/EKtaWqojQffgxGt/ZyzhUJ3iwq7cYPTC5gf8FmqnUKR6mM0rDp2gV2TxPVIu1rBvJnU3SdB1ugHPuxWtOyTOdMCGhwMVB9Ic++on+3Cg1mFEg5XogqEPJe6l3qz9U9mTg2hiPmHBVOhMbv5eDAybICCgQL4o1PmbiCzsgsbJIYh6C1NSbJmGuDmniGpp2soKrnHBNPHXViInRLbBHIqrINakoJ72FkuZsbJ2kATWSQDzIbSC3OKPfw0s4EmkUstlwfCTLqaWcG+7QNSYxhwFE2Nknpb7T8OEheCsLN54Qo/4cbiz90bIG9XPu2rqoALDy/V7pdfFC6LL1WNUlvbTRb/0vQdjn+mbt4u4CDUaQDjSTyo38c6EfwtuyhStX4QfiJFCLYCDlvlcIMLgaFQ55yYt7z8XCkS9C7tEoeq2dZWWKUi98X6iyzfWU0pJQz1sflE3H0e4NB9OFjk14N4F25LAPoTOucZ8FigKGKq/pCVzpdKXF8jljodTsfuCUQ1564zarqCw/5opilzU6sNSgHHsw0FfkwIp7L4PHCJ9payViS1Drjip8ASRxKqUJOQJoL4XpdEA1Dci7IOHcccwvMS9jVjbLmeL/xoj8VWIjKbdG17ooeuo6lTLP1BC1ul1Gvu2B+JuYVqcBwAYN4LSN89XBNJsxVvMRlwXEataBxGhKR1HF9VXWZcwuDgaJs4NJ6lhVIPqfY6IZXGcpcnHVIhUCtjpXsS5c9S5HSzprGRYvzHrWOwtY1vUy0WO513KCy56qopOYR2fkMFkNZswTNaH8E2ItaQrzMLgc4xirW+Ob2eCzzBZbBoVw/wUsLSHi5+R52geTuBPDQ4WuxUf1cUykF5jPwmv+u78J335em7PyTMRPNGtv778+r8SLtJec0HMtEz2uEbOtxG0z1DS40DXCubvrOfsV1DCFvWF83wSVnbBw7QMjU3GTeK85vbkC5FU90W9TPFyww5dtH4y+9GuA9NouOO0uxulFdQZvZxLlWUDqMLTYldO3BPKagw3/8d4RA3yzphhtT7SRGvkUfwks4zWdf+119HDqqlg5wKfXYUBYY4wuvKzxdDLR5guJ0vJBWSR/VjUS/U+1jTiTwBMNe1pHUHje7lrjlUqPWnBYB5c80LOMyfn7f7tn+CcxOJ+hyuQwA9fBnwVBU4rTip7Yp46zVlcUes820qfGb9MXXX331xh1hfafufra739OS7ehO3iAnSN5zFZbiy9y993x3uSM+rloIS21+AvJu63r4hBiFEgA0aNYzk4OCDVufRqk5D9HgwRmcQ+/92TUpIZBS4YVfDGl1IY3eeIZ4JYUE7znmu5SgNdpSEuEihymc5gUo00Xqt2rU0NrS8Oagfnznste0tDBNuhio56eqmgsV8pWxdKliTyAV07pK4TOjwWtfa4dW3iMpI+fKF5CDZyoyLbXpizgSOAl2z2OtPRzwQmSEYJIUBDiAmznkEsasTTOzl2zSKwJ2xmLm8MhqlUApqJVlUuZadzappBchRcee9kjuKZQXljdFShPCiFQMYBwnXh6CAKTuem3XgYXSujS8rouU9AZq1Mux5ldqQ/MBzILZZ9jf0aKfi8ocC5VeBIyeDT9Oxz1TcqEBUMpQJUvhGWr6SvDSPMrslwAN6qiRAKThxeVA8kqoKZGmY9zpLSMpKSNZ1nK++iEV4r23Ht8l0Wt8+xv/t+7/4t03/OIXr8O3P3z08f3ryndPufNZ7bcnkZ/dWkgWiS364XAKwO6RYAP3hPNTMauqMugnsJmXNt2m2/eP4+MvefNmEx2/vHDaVLNF9tiRLuBVVAVvfxonAD1cPAOrU1MlZ20Zip+kD0VP+B3YLqztMzb358tVv5gWV0oA2m2+wU3Uuq98DZW9kKuny4Bi5BEO60Cvz8lhPjRNY4xNWOd3bacBSLd6wk3k1NgzjTBAIkQZ5ivcPMN9nK2LTb1ed2WKV0Lru+N4vH9dbzZ2Z79ht+sX62kxXVnAaexH+OxtP5U7WNB9L8TIGnQlNr+dLqhggCdgEil1XQ7juJy7bnnifFku718LdasunG5v4yXuLdE02wsNztiDTJUdrMYlWhadisP9OSeweD9aAjebTVzD+nD0x3gEqeeCt9kDGALhwG+/5SJEghWrQskS0vHweeF1UQcwke53YNbddR2OpHVoYT9mtIiKKdn0kZbbJSi4glFhl9F3Z4R25emZ8oxcJ+sXhElGM9cjpqzRjjcwCbohpVmYjfG6C5XYLEBGBfRlcVIGZumpSeBErOKVWf2tT6ZLYdX3/o4ABtfHXVU1zeZK00Cn2iuxc8U34ByRF0kShTj8o6831wNAwqKtTil3yLbudr0Zmwvr0kDK8CAKPL+Q8gBt6xeJowjbDt3OgAel8FUIbNu2dl2WACxlJBPtuYfM5usgDx5Zxnxtvt8sVmKw4TLl0HUsJa0I/aUcSeL8p+eEdET4NjIkbPzDBc2jow+5o4Kxxh3E4y3eJJtk8+o+57OVz+ZtF69Qjf3seSqOy1sAe/QzV4shTsAZH0QRnWfhlV06iGp/wAmYD4cZ8AM8gMNFQLyzvd/u/N6qWPXYTTqbWG4fBFEykHO1lbGcfNTijU4pryjLjNrl2IkXCqIfT74QM/GJctxHJNaki2EXqwkV3JZ3DGVPPFXEuxO/E3pAGZLmJ7cT1BJXCphTCehHRxdIoc+ZTe/dm1gNGD1AscWX8rXsHZj/1+V/zCusxYgDSG+gAtXZRL4Ak7ZznYzZ9tNAwDlZa00LOWfc6LNJcLtxQJVdJGx3eGmi5jz6oaC0gj4EmWKPAmNKgtwuzfBEbayXCkSaCMqoKwF5MPABHmu0wznqlIhljeTfp5SPU+K8VwtIBZ13kVRqReonCA6NNSeetaD6XoOm740XSByX8ThFf2GPYuNXRlFw35eIHN+1EfBjUeXywwKch50QuxaFix1UyubMXpHM22X2Z3OGVprxCKi9ZaNlACBaVKKLXXwe/ky/6sjEImKexd/Hzkhx27mltHCR7+W18vI57B3t1gq6n0HR1c1NV9c48vTZq3H7AtjihatxuxitCx34lMZlV7rQOdDh8kl/0f8QXUeawq5EPC18qOOgHiEsPELkC9Yyx6BUgtc+G0OA4gRB7IlpTo/zOTH/3vEcEe0yOEv0yvSEYNKPFC8cqWNpwedCuGe5zNKkj155bJypiWKs0fnsAdQ0iu2N2yYp1aNS0wSWdIj3q6raxRd6fLESHOu6yXv9pI4qyqlsyp1HHHL/BvH3i+U35botYfPJ4xG7y7efXg/8hUeXQ4u7DoV6sYgnUteUahXXm3VXe02pr/iLFzBpyAttgybHIJv8KScdzFAt1JV8+ULuSno2xhth/IErkvyaTRHo8HP+0b8YskWfu5z6UsJuWVLtHbeZXiefGsDagTWentwX9w+9656mcD0ZXGltembYCwY6Bm/Xu2GsSpwPCIl8DA0Fozf6bOH3kYQRhXxvjqzrl/+ZYQ7YUvweRi73PpSoyJwTvAhaTWcjXbrBPdI9AjRzlTMA7PrwcalKaj3qXSy0VCrVXs9bUL0AIJcDulGMQVbWKXaNhbm1BDmWlVhTQSkBFrXVVLrsPEh0VPtgawqPCiyjniZcT1+Gj8+Yzrw8oAqVllE7bdi5m90d3Oq0NcnMmxqfaZsqmmck2S79DZ7xejV3jXmEl/aMxaZdkMgtLYe7hMHt5qPE3UKA2IkPuLOPD/fWaNs8Cdlxs8RTjWEppukAr5YEE3xlT5yU9ABqR+FY972+0nugzjz68tpRPTE3YJK0kGmGRxL9+9I0kupfILpjhRrnF5s/azj8WwFnynG146mu48aDfTuvEcUTI/gkHNUnSISgiA2UdV5HV//NQQb83NQJekxTozjPM5b7v/xZ5velZibLM4kibq/jVNIEVPulMam1WNfiUwhp4URLgVFBC1NPK8azyvGfaOZtvi9H2WQ+ThYEkGZV5g1V3QTGTHx/hbvSBT8jfix/FDlmKecdf8YIpa3FVkS8EV0ZV2ufTr8+O/d7wWb2LW5vfZflZ2vq+a7YDCjDTwqg5zUUwCSZfydPl7Tc1zOwVLdY9kEDNXYCqwmcIvdFkafWcpb7tWTFLUpgEovQPvISp6z2iiI4if9IMCkL0weMDRVYpIthtCZuvyFQKsJFxYpYnDV4FtclOmqGJXqMF0XuSr+UoLKXcHXvj5WVAw2CbM+SJJ8rdpZzOOZcY2eoLOO8cM77BOFiZ01fRdl1q/Yh4vqtS6Za1wqUFoUywFmXVi+kRuRMveB5PggrviIXAnxd6CucB/I/i3qx8SCETRkHbkaCsVpRZdN+uSD1C4TkrWle8IGtWRVsKU75kD/OZ3TqQC1lNwsJpaWfejSjGFWxCn3pp9QDXk6cy4SXbx+HnEupmYFAZ92GJ7lSUONikOyFo3Rs5RisJBCiB1IyxGF2Hd80AMou6PCxG8U7NwTkBFAny65acp/ynNJQOGvpAG8Oeryivd7kjbPcMZgzpBVYMeT5IX4c9PChDwbTOE1tgd71UWAM63KXJ6z0aMUlC3WezJq09Ev/kRAkTOULhF0hsPD0XX91XLFqA50qw4Sco14H3JVgna/dg1zFJyuJjehrd+Ge9Fg48LKUsKHpCjf2f4dwPm8YC1oAY87dYYO7pmvOoHnbuRbnXYJ6eyaJsPJnVHu4HjKdD5JXB6nKIAWricN5AYMTcKi6rnyiw6nxXj0oqq2avQUvX6uSBq5GoslmK9oLgp5XHmDRj4mHsXHrA/DT4e9TDiY9YnxzUzxF4UlPd7vbFN9dKvXzffDu25+Pvr7w8PBa3oqbuyM5niluyKVyrfxbzqVz5WghbT/u/XVb/4KGxZSI9WJ6DKYn1lLUbhPvl8AYhQCMeGR4V+ODKJI7Df56GSJD71u/9AV09WQW0OetSGkcfo5y5MdjTFfxBiHW87zeNLE6rBhl9EKWV8y1OQuWaHIcTs0wlBcGHNgHVCoXeUvH8nTA8KZ/QWb+6i6xrGt1I8RETaXPLyhNXZMUAoXUdeD4/YtQRRi9vJhWp/zRD3eNaJFtekEl874FUFnb5/O2OtMK45rp6cJJ9sSvC+K9JpzG622Kdq9vyrKOpRxr7FHCZg4C9Ljzpeyq8kxboSkUzlVPZaKm7sSmflUViMWOPaqOdihHp+CmdEakEElC0WCKYzj5u/EnzZ9o0KohTqx63dYQ7L2xMuE+Pl291BodS/23wB6/Xi2tjpT68MvbrRTeohev4d3z+6/OvAdV9n527wss6Ik+cZLb1ZmtjWEDTmYZ8Sl40GAfbohFHULvyP/LgKXzlAAUz6UUgUX4ZFGEY2MUHha0KCQpDBBZVIoyg5sNxxiALXK8rwEIeI9cX0F6VLIQ6lRzYiSoCQkJ0UJ/wd0eaL9Td10JdsuZLhYq50IoWUfH7aK64144X5YnSz48gwo5oqK3eC1npCQfKWOmtdNxP00N0lrB5W4jt1sbeSHSSKo+vrnZdiVly2iOKgJ3evkM0xInahtvYgE3x5URtcvmdTvRs4JL2Q0DiXuocLMA05m/hCcYdPwK1jb/upLunBPO/pTmJxTxhsNrHi6RrXYCErKzFNRC2BFapSadsDoEWOpPbVTB0ZAc0qblzHdkURT0jFcg3+HUgkKGjsAmtXXEpWrusws6SIMenSIzlW9YY9xI1Ul0kxwmKVO281riJfKrJQs/urio1IKvyB/wjdVVZUhqZp2fktbqC1lfWddib6MQyifoqkg/VFGF6Mz7osZTSO9a99EIlRJOoiimBz1e+VrKytjxgm7KLJo3BUPHrS1yC0os4HYm5QWCc37CPBacO/tmzv0OsgSLkW28sMl1Fn4GdNMmaU1gUwK0FqIADngMYtuQtEnvaZ1gDLW4V+gS9hdgfLAjnJjz2eRATxgWbN3eIVnQyFv47BaJc8elFsZwOnQ1feIavuSHvfBZP7uu62qiw4DW6BUFx724Cte4MmcqUAjmedzsk8fZeqECE96pl0pFrT3yRI6KEKxFo7QGYzBjmf+r2y/spcGCnWU32dfGyzYkWlO6PHHC8JzhBPTWHzsL/iLs+5rBKdHLobLdi4Hx5rOAOduyj5Ds+nN+lq9nv8leZqf8jnFlVHa/RW4cdcDOfm2J0IaAyKvKMWu9Azrtt7+To0fUog1O/iDOFrYsl0uwnrLLXdfdZDf1fAaMuP5L+UQ+lWoOx1oPw/rCILVzT+M4fSJ3qokPbZnJkYHgc5QdgPLgjCwpNI+VG2s/o8lfzdyiU9KtFAqJNnNcxzD60saaG2duFpacuLEea12py7Dz9QKFzH8/XCB7oJoYqVQDIIQ3uHc057FEt/5tMu68kveSNGIV5DV/yQtSUKitSol1JNP/55w9z7f/jgLAM8akFF1VkYCLNJzaypZBLDZfyk7PDGXOST9j+RQdS2tFUAwc3ILbL7+a62ql1IM30gd65dUDm1NP0+V1JK821Q2vtYQQP6EZpIdlolKsp7aMAGdwv053JdiBgfoL1FaoHU5wh1eAgH2ixsIxSilfT70ZhlavqKa7fbF6IZy1Xd515Qv+vGC/KdKpphekviKpt3SWA8AkGZw5zDYEPAX2qLVPQV3XWpfMZ2K/Ij0xWZtd7BZTvD4TKtXW/j6WWlFMzZa4VXlYPDvUx81n1bLDLT3He7jxaVwey/LEgp7iXMvlkkOLT0+q9RWrvE2wmRnAc5OwiY4egYwd6y7um6NNjEpj6Nz0tBx51fcF7qAsomK9IYwhSgS3QTMUVpZl4t3K77juqJOeL83Frp6Gf5sZZAlJvNLo4rwv5igUdYyUWlWJFsyrKp5zxdU41cAvirO272kngmNOIEVpsQyj912GGQUGHHo2CRuZhyVj6RMBY4RTUZGeUtXkQsrgWu3N4QK6hSpVOYyNl1bkTFdVotc4ci4rIdbUY+ilTilS8PWtF0XUIiz78SiHQam6ui1uUSj2N6HLazHzeXEEt7tdfMt5tayWp1c3s3dzezvugffVKF/IVo7B1Vi23nu8a5twt9tVHIUhprSuyurKhobddQJQMayQoNZUn8UFmDlnNJt27jvLftmZti3Lyi7IllK1ys3Om14Nw7jxLiC6C6XsZKfdfjvgzWLRrbyUGEQ9essX71b+8UHVMdh/oWiaqtIg04vrfsapIYgajxmsl8n65Wv1nB6XxaQ1qlOjl5VHGdOrsnR01tFuXlg9mekFz7T7z56yUlELSaSdzzLjMHWC4hEA9KQLsFI3+sBk1myafs5DMduqcsxqXK2XZcn5qi6XdnnGt23Go3OD2ta44uL/eLMyWGxN3COSCZ5+IfEWGpaZohfPyjOWZJY53VZBgZxnntFapEbfrK/NwO1yuYdWe1a+O6X0AfSb2D2wmm9vC+J8ixZmSlV7n+loJeqoE4HlDuJDo3SyZJ1dJmDeuXbe3U6bzTwvFweHrECj1c4fmHSk9hBd3XWLZJvc3GgybacLOz9ctFv33SX+sai2WLzYirV3fXDtPJ97QFO+FZ1SSYGrFzmqzmWYnPht7FoXgAuPK2dfWUkzRY6j6aWSq2TCFu7TlWoMmHSlzDLsR12OSVIS1ZhfcrvY9kMe6Gu35NemjyWTwSGfFAjkhdfbFquaXLVzxJnQkyAVOo3QgbliWxBXq7B0XCzQLJvPFwm0iBpJ2QnnyhGjkVtjCsxHXbbAmolWzJ7Xfce2vwCKuo9+y/Pdzc3qwg3m8IRX2WmxFQ9hj1m6TdliFIzVoxnpF8YzqWlbcPTtMlsuVy1clvJkBbdBEZyhzDn0cybWYXrepBrtGycMMR+2F0bh41Y1xtBA0JWfd2pbKG1ik7HWoKhbxBAD30mlucjizhhv1vcZtU9PB/wZ8bd0ENM0JeHj3TUbAlKuVVfMQceoCt9/pK1JKTi2bYL6+rgtftyC/ZLtYrsAQiwueGeb3FG/rau5LbibF751uyLH7Ar2ijw3oq4/TT7J+zivxQFjxJjKI6SUcVSJS0YCSB47E+9O1hjrS3PY7WjZCzTNS4/Dm57/+HTbhNC9Wt2Wt/ShaejPdl/dnm6vfH1Cb/U3dN6/sJ6rpZBJr3Z1p+GN4MhM3d2KGX/0gPp23jd3Ct8dDvi1te+DiL9+/8Xh5nDm3Q16uhfD5sJiqJYjE5ZqUBT5D2VpwPh/mZIerpNRrfHNzbqePH7FgvzuVJc3j+WbF3IdvcNyejRWyypQmPM/kW4rWG/zDyQX2UBrHJKauYULNScD3myquf+h+1Pt9puyeswOT2DqncceViyeulbyg4kI59f7p8+yaQxjkQT06YcRvA4QjWQPqj+Ib1e3hzy+sZGpCno07ecZfsjnGK00RJK630YeSKtIPoxepoQhR9zS4PrIMCAk8wNzHg1+hQcGsRMwag9QO1m8FOKndnbWOS6ihFdX01haeie94zu57IlcfYlP53LVTIYZn3Fm4hmEIW8gob73M61q66NuFXG8Enl5YUfIMY8txFUVDE8AXoFMuQOUHSLzdQLg9caot2YU8hy89gVYEUEhTQS/EUack5tW17a+QtoaHo1RqCN4kJz4iM08n/MIpnhquyuYDFJHYUq82PFR+QXZ1LP1OzCt9fwglVrYOX/gO9a80ImI+bBP04Gv1x6WKEbDNmhzbW2umm2rNG0JuK3Uq8Uzg/sBnyjmOlQFMk/vGG0PiTqodleut3mqaoH1cLoFikJDrAAWYFwtmSt7+40BJ05GbjoFILKd5VtCFpFlu8h66t86zScXR3exgfshE7ErRKRZf6VT/im4MdjcbFdMssQVHFA0hWGCv4VMs4XC8XR6seVHK5W6jWU99ZNidjo9WJpM8gfDdKzd7oYajVvd+kG3e1BHFrhZo1EIIK4kWyBeeOhd4IcquGnxvmuTUXByGMKfenr2+sGoazPq1SIIgNCaD4+PLy6aC+ru6yIi4fPRBPEZxjCvfox13O4cTlydtfsfE6rfPyM+bieGNT7jRdb5VuVnEf8f/I9inNbHnzCJ0Y3myDAC4Gy65K2H1apGVVyKREck61A0unYoBajRuN2t1/08N7rAEe+jRx/vBFCYoLUWeDV5ARwWpK2IjBVzWXHFK47ehH6FRKeEnjjYOekYpkkFklI/tp7RuugWuVt10hghuKWM8Y6vN6lBIeBBuHn0xjMzyqxFI3pF17IUZ0rBhjZiPwLn6bDrhIx0ZgqfEgogJcOcoy4Oamr98gUvpeTGHBI/Xs18Np4X0FUthNMH7wtacnL1a5aSIqMpbxT3yt1WJhnTcZxK755CETU9gyUrdrQDWb6T9EVFM87SsdNhvdut6gc4GcMwgQ7cevl9LfhqUn3fYMZARoE4i5Qy9yjOJIVigbyzrbJxWJEha/e429ZwvugCpAgarg6LxNXzrHt2IrqflRrN+IwJ2EhDZO3YertdV9U6OlyAnEvGZBVNaRuZoHtqJ7OFosNO6S5rqbUU0avAzaNIuoo4e2uJtlBDKUEpzYwqXeFl2aXA5XFUGRwa00nGZ468pS6EbZnIM+lzxsPuN0gIHHdE6+yFBOuTQh5DdPKYe0LSIS5g57VGBY3P6IAAvIZ7+/XcPlEqyGnrsyoyY5I9IO0VXSDJ2AtD+nChqjpv60O7wu9XpYfLsIDFZqvaF6yqlihsyIzJXqoQh8Nu6Jvat69pkZNNcWQaSqx14H0vhIqqEsMKrmc+DBRkFwBIY/oLgyLvPIYq4ZElM+w6juk83n9CnmWhImlUSaPjCY61R1WyWQJwtu1ijiPxwxqtN9u1ndq21kQyeQVqPSnXmA1WOFyUDBKXLTwalFBnYd89dlIlQTUnZdaBqVGXrt0ndwTj06l4C4Xnr3MwT3p6TG/eoft375X681Pwwbs/j6cndruHu9f522dI7o7o+PDws8cfv/xy/SBeCRRKw/3RCOfswRQuOQ/+SBbWHSzwmKH1b2ajMb5xqtJ33kTvf/HqtjyUS/nqVXs4fPX10nXuw1tb2vJK1jsGe5te+LDbbocrW++d1OR2domcPWEidWha2PG+xKaWF7kHlvfDAdYBL2I1w2139/cPXxyK4sPbcWAbeyFbVePfcf455192fLsa7xS6dhxeH+7uNhfusKouBLXM0gsZ+PWoXXcAQP4PEAy5IUJgX19SGwBOo4mUKsahthbDpPaEDamEDP0OZth4RYU4LJnGfmFdJWKVQtYZ5aG7ytK5WAEQaSmKnFEUK8UKr4ZEW/GccSpjGkovkSWgzMHsX6ypIC9X87DNvZ8ajMJYV5VSMlsYKwb9hd1HvxpGS9tKdbLHeZrZRQX9xA6grIheWIrhtA0XQE4sCFyfxZ7LKGKY9oJwopETyzKac6XKmaKFkVOqolxL4lzwgtLG9UlfKa5ZZNAkNml0D/tQljORsKqiI4gK4RV68PEhUtW5A9Nwu2dN/jwCx/oRB0prNre27DnDXggA/qyqROl3w9jSUtAwvKznnaVi6Ik7uLWpmqYdsowcD3BLHfqWfQKH+fvs/Ki41ox4CLS3ODVZkjFkLdN5MtSwlKLPPipD39f9we5A4frGMaVG5CJhHBEaguUNPQ21TCNpHC2jvRDMH5scrq/LcLrd37TZGtMfSqygrQhBNpyx1FrxKCsyJLC7Y78e5qNC/e4xVysssOGSL+JoY+ghpqtt3wXS119aqlikzJHpA+Hirec8dJJVGMlr81MScGt6AGVpmIdYcJO2TVtb6j8Gbn1Wy69/JgvsAjR06MxRmXKG4MrcGuCk2Cs5Vw8gpgQXjFI/FJ/9YoxyehTTIPtzRyc9sl4qcy594jHrYTkmAG9K8st4MBJqBZM+6crUlEXhFl3PrOM6OVPDC2uMVaKHPmYsxTRaN5qP6We2ggOMHSKiNrQqBZVMdJ5mMFM6IieX6IxvIQ7c+LOaWZSyCvyJZ5OsP5o4LaJhDLzrtJJyZyLnrJmar1MtIrkcVnxZLV2f+KsDMS8IUvWxmqUzJlsHcwYYOlXP4WOOy+FsZ95e4XOOfIxuA1aLtuuG/sh2O87LqMaqhwv45K5dLKp19cwat2BG1EQLqYAWIuw9W8R6r2VGasmEACc1qd8M8eaLm5sDvNjORVEUX329Ol1ZrdKMllcE9d4H83R+JeY1MAG3vTGww6WyaC1kt+HqeHs7d3WtoEL19pvydKEseejbd1sRjwMHxchmNV73dXGXVFfTfVVt2qkFTcCfYAA3t8PyhcHuK9A4DhtdVexKxTx7hgbvUO2LnawR+R1ZaRtvjFlWqq+AAHF1aKcLrZWEew9tjPTsa0QRVhjpH8yCQHuCmZpTpssOV2qdrlUqadJW2gx8mT1NVXefgNrc0FnJOJddrLU3h91utZoBoilnMe8P2zhnXVn6scbPDDWmTnKcKQXY41NyXHqxyfHM3zA5ke0gIOAnMGJHfb4036OQgWHPtqco0lFC2eMo+C9rBkjLqvIqa72BYIvGSokKwq9AY82r9pSqH6+UJLOiIZB2jOGAgtJ2Ei9BJ1hGTf+JmnAUtDuFAZGmm1/HZzRBYI09gab0zh5+pRM+/vgpNaQknsEGNoddnVBmOmmagnNqxrK0SK9Qk1IqSxwDUTPJoEX6xO44unGXASjM0xMYTsulGPiInRTAOJq2Xa05IYG1ezFgh+qBMLQCsEg6eK5DAMJxr+CipDhuyIqCZ1IY8aMyZq8N+6oOl2ImDYO1LieRk6oyxwIIJvxz/Qzyx5qDaHNzSY9yeQbI+bwuUUYL74rUWtflqwnMux6OfX2hR3X0KuT4WNFLsgANj/3ywPHCwdxDoTXO5RiKqRnPzR1V/zw2CqQvm9qm/TdExrA5hVclC15AQjFUYNHFdfOIE9FWldZKOABSqrAu5HOj0iGZlz3jUbDBQnXM2LAB7NEcm3zHLbSTxpCiT4cqmaKxDko27zxgbNGDbbFdrha9JCzE/OYSXT38RKQaccUWjAjFYeiFyvZT5NTRxa07AHUZZD7LGSw9WvAyjqq9S+3S1USFUAHW8BWuPFpzGGbEPNCg10GhENNo38rbqZ0JSiHZ7aXcVtdp3vmLBPNkPvSW5vOmu1IGvImab1hz0vEbyu9HIkREXbTUtH24q2GQyFx4YzruDx3Oy/zRSoiwK+crpceDd3N56NqYRfyAQ7dYQRcZZOByL73csgujtWjerb3xQTB98vBhUG3UpNt5NpTMQOHaU/pClTe3I8Ma+8qt1slYr+DrqPYE1RrOkjyGG32u8Cl+zQXHjyFdFCkmBJSLgM+0WGdQgpsb41WNvLBoGrQadxdGTOhF2HSURyDLGJyjMBdNb6jesOywyY79xURF61xGp0Vsd3VtYNu/YKpNZvdsxUL41VBm+QK3iVg9TSFdLJkDUYOBleS09BDaEnRdZ22NBofzOhmSxRAQQiJFlbQBbbhxKAY4QwPTGjkkpBcvuRWZbuFuZa2fHkYL27IkTEpKCenhnBplrigqrG1dS5//juzqgpIGZExgBPBbzK27rqpsD8DaMV/21ZletBZZADDtfyGljoJO6Sxti7kahRIWVc5QeIQPi6V1b8sULzupGuo570RLgu/XrYB8pAWi351Ib8+6suyhbjRRilIe5Aaj0JUO5KCvStSQCxd9hS2GA5W/Vn2LjVbMSDCbixbYtpDeGa1VH/UWE9gfWRMvYsik03V1bYymMEnyprlUWeJtXEt8Z+Qatq7vhKCh1meJ2kw9qKMjrnhyfbT7OOQRZ9YoSEmizVtN2iBMqD/TngZp9kZEIB36MjI/I/ai+22qV3UmOqO8gILF3vYYV/nO6uCx0nMYRoRJ9VYe0NaoKPKhFSfGaOYEi81CUHwoSw6mRgglg6rtqkaxE5qNAyAwfQaiGd1gPVC2EYLWI5/bYIBj3pmq9mlKRBZt95bkbF2WUgrqIpZZaStjxUWdGnKeIaxCkVhtXVlnxN+ImtmVW7qszbcsYdzEqrORmNmW+Gwe8EXL4dC+H8kQKDXn4DSbr5+gRdlGlQ8tsa2Eixf4K4cn0ugkiKyU9PDaT0bFkNKdmCU7xSVhwrz8RTQWV+qDOvmA4bnfv/9G/F79rbt9DEApagqxbtuhjtVi6HSjX0L9nBDXH0MwNlxB0YAy4XZoOp53YXJXxkOFatX1AuK8aLW/zhojAUUCJQ6WGUs5RZDG0e+Q8qcM0l9OknyIeCSKLfgnqg/y3eVO+N13lLdAWvm92dwx6HCFllhaVsyVL1LK4aguJKindl+94P0fFqJVZxHe7fBnv6/x6zM/XuPHuxVfaT6PEh0M+odf1G9ozvSvvxFfvzNrocp2KM0ARMSL9hZJtgR6Rmi6pJtLsZiDQh3Tagh8SmSVQQX2676d5clXQRqE/ZBMVRqr3lTylGuk4F6lSQtdj7N82smjJplSdJj7HpAQAMKMLsrlzAV/84s2P9pCYNMhyFQUVjPgOjHr285oxGoCdjEO8l+2/pmILgk5KHUrVvNm2IARBX4jhwe4WXlsxxa5yp7tn9jEs+MJt9lurJhJ3HCVPl6Q4YcpM44HSFGDPnwwfXtus9gwAM1SaxY45n3u59tdNZGEzlQ9aR/KeREcV0cu3qatbXVWA0HzPfMQNR0+BLdmV4+8SBsNFv7UvL5nGPuH1Ly1PFzYLCveI6CqR3LOqDExkSSlFHNab3ReZuQRBolY4NSwflAA+qpSQepnVPn1OClKKZONLm10GfmjSoZYYZHj0PfnGGtdEUBp3XuCZLtUiCpr17JdrXqKdgrVaW8nsPAXu71kzDfm0nJvqlDTRJaAoYhvRuMJ4LJ15YMBKV09xL47KClaSE9mhMQqeOo7OztSfhTmfOO/FYOhddrJR11vQgIy3DpGXTa1LQgHHG4XWAuBcUbAwtVh8LnK4vhCW8wKlUG1vBJnXn/Fq6wwfcqTs00v6JbtYXPoLwk4XaHinNQknMLp9Kquh3RpzgySb04emBsnlt+GLYAV3Lvr45YwjlEhXF0LdRsW/S0AdzGFgWI+jDw9/ZMTcq7i13olguj1TSOvNB69vjQYX1KKzPc5KILktzmaSExa5qk3+Wzrzc2Skhde8LJKPPW9scP+TozhXlwlQ9IK6904tm21AFBVcSWNF73DpnUruMf4lEmKxvdwk+UTHSxmLD1jjo+EQPtW+BhcwOIJQFxPg8f5cijUTFRs67xoEyXYa1RoaQxxLZbz1jayr+vCzXnUa6nvASnlAuYy9oYrAKRYFV1kovl55WW5XY3zeG0mzGamL8ywblU1J2c/XlEsRZdJs5+Nc1uROKw+Ef4OzYvFMqzrrgPX6oD2y+UderJYbMvtcGYrS3ivxFnxBM56E0hOJYVkoLmrSWOMl1ojoE4WTdv2i3Aezteb0V4ZWUEeIU8MPg+CQoYQE+edmNRXNdKJtTMdd+2cissm6mPtnOotcwVwTggmGWOCu0XbaXRPyzgIOLmE5yoJYhYemPxZxSzmIRtKHJ3GS30XvG04wxO3LQA/QQNBFfSg74cxs4JuvH9zwclrl0OxgpfbeBtPcDIjjUGL32XBSPlMUELn13S0qI8yChaa8WjzMloEdD0b04STyJBwZx8G9qNCpIRsb899tTp8fMF6ynvn92Q1Ho7H22hFb+jNl1+92p55JZlPeV1wHK9h7KdUSowBlVW0jz037edz3Il4xHiOXRGPr9b5bGDFC2iGVa7FWRtktLa+kmI34eS/YVPoRlawzbg/Al9PY7rKLKb9QAdC1nAvmheMqN7Oz/HKO7GXDMr+kcbaAj+7Lmy2Pc3lxMLcrqG1A3I8ot6vHy8Q33tdA3IEgqPu9uw4RizITh4uvLfBd8a3W5zHL7eJUSudqY1yhlcqneZkCskJJqQSXwA8y6zDIQI/rQxP2vvtw7b4PsM7vJ0CV76TOJ7Ac2UBODGIxDgOesx7IDnIEk690zjTapXNAIwiqnC3ix6R3Gt+vnfRnGqoyeDmZGVzRPT0nh3ALvsepjiwcCJX5qhKpnroFZEw72Rv48jFuUUCiXBmanrUXxZkKKHk9DD+dKRnIsrN18cBPZOTa74sbbGxYjTGXbQyZptMKqzsS6RpK7fkvryWN3IhnYavzHVtdybRv1jQn2U2ZusWqqVY3W+S1CutnSSnfmh9GX8kLU17rT00GZPgLpN7+i8ChCW5WETuvxwCYetsOduOHJqkcmSRbE64i72pxzpLI1aJWIuC0sdE5Nl6B8vtcazDtZB6nsQcdnKzZyaHTM25uTAdDS3mZAuqaRMZSPtomGeEXUxxgAVO0PKvr8XdiLt9RgwEcMgmjPbYay0j1IGQrXxYtu7DilGGO5gaORJIeSu2xL64FjdiIZxSXk3COCkYaH+Z4pqDJpUlzHk7ZnASqAM31qYljxuOZi+4HEqeVNx6pJQdXWXOfHmrm80oimNEyKfhUQ37ARYIT8NoAz89c5bLy4Mk1nsny21xAu5xjSIbOP2t27H2EuPs663Fzksxk3uzjRS1EUWsx20OWxkVJ+7UfPSAz5tkpnbCUwPnawXYN5KgDtriQ378eS1De3zGawWzLAZqzMw2bVvNofsQqj/A6Nw078lbuXT4W4ZGBGpkMm2Pi7IS93xd0/wQe/nIa0jf4XKM7+gbP3IOn+C3UyKGxEk/yG+pWS47x2GldA2kVICmuB9jmF7XOCRq9/lqJoC8LwtwM9mQDIbg8QZOtNppTBeL03JTeqhdNAkX60/iDT8kao97v680bUI+R63yAYKDNSc5uTM558ysS5bFNZd6e36q6MZLVyiAN+yIrUHrE3rYsnYeZK+HLd3HRIrrcT/NAkTnxNpEL3+/Ol65dCY2EsPET5d/IJkgkQD3f4zIJQYJfVQqi0AZ4SrQFnmPm72cDmq0t+X1eEyB6chaAbm8TLWbtEs6eu2I6DONkmLJ6rrLcPbAdmdQjg1y3yQTXfPk0PXfykFKpulaZtHCcHWrvjPVp+Pxwuh+7bFReqpI0u/FSqeJLNT9IOS71mA5L3vTnZCuJJ9qPSXa6XoUfxRu0iAprC/iMvbf0QQJCqoACRf1lsKGTs9xOKTRcwx5XxAI2iZX+PL2L6yiNSEqD6UwJDcnb3CX3iZyENi41uDmh0tFi7xFrnRu9kVjGt5b3nH/lkDe7AOSub6p5NtPsJsHx7bRh50dZBHZdEYuAW5C7fud5/wqYVFau+X4hechESKv9/K6B9Va+O6/XZwWB55QeCFwtNJSTBK1my/dzO7+cvH5viAqcmvN/z2lOVYEm9/mHIdQsMhW9YW3G+ZGVwPMbUDVjb6jymJS6bP/7uLGeARKTOlyKAlK4UK7DaGLz1/yfiqGef3iIPOtvKSQFMFlGWcRe1aInCNKfxMB/I1PDgzCWhqScE8NS8VHsMsnzQxx43QfLZt2riuwXVTr/pynqiYN8dBO02qqWocNEBKErWwxP9q1y+MSqlN7bpOgZ8mBys9aZnGXsOpkKXRZUlOD3AJoiieUSHpIx77p7K5ohNbgt1hb3MS2llV7nqyphU/i+eEAirccbdH26/f7rns3vntmxKVq1BPxk1vwPNjP6bNNgzfZ88Dyk2ykAXQ5oSFj0UMSorB0FjPc6++r1cqpVS1qpFuIG5GU603lWGfv9epSONvth4nN/paUrKQJZFaOfEekDcjOmbMlrj8thBvqPTiljNWMQpxCfy8V0QAQZzTvwg/qF3mKMYaSx1jh1ayQ1npyatAT26OUnSEBOyFKH3rGcolQ8xYmBJ25Opl15WXm1fscxJDgYOU75pVZv2BPbBabhsHQOoCdcLI5C5XG4pYFA5YGODaPV/i+QNVj0bqp1p3bVWcUEIXKgIrRQczlAdd0lJblSi9WEXkvkFIQohAk/Qkk5DSJxFXcjX/8SyJ2qizs41whlnIQpNMtOAwV69gPO3I2KjR6CEK1d5fW0GoHMkaQ6JtURP3Q5EwZ0awqa1xTTBLZCNiRaZHmLqNWFWO1NlS37rAQgfPUi35EjE0hOtQOsfdXN06b3mB4FXlmkZolJupCPpUNBg/aEHG3lpnBcyhXa59UNmHlDPyk1o4JJz7XRAoB4gb6qmdMOsclHuWKkje6hooXIZB49+8cA3WPg6vXZC4Y/HhJZACNCNNKyfY3JowLZQLeNJ8JMOmyzFRFYfyRurrYncH0E9Q2re68lR096JExLvoJ8P26M3K59BMXPREyITn51hKi1shuUPtmuPe9mxQ63Lbe1R5sOShevxnKU3W6UEiK9099U0m8pusLFFOX5U0a5kaZYtbgoNrdZTDEAxVLsdUjwl2sFjDg1SHIaLNu1hfQ1DauxakB1q7LzKnaXNDgLmAVXB06YSFjJxmIEOI9gaZ795FKvPIpBcreJTvJ4j7mJ3Qev1Q1YREwSCkO8W7YQVA6f7WkE+YBL3gs0Utf68AqgFiuZ4WEnbIoc+GxxB08qO1hlhKTR8xBk2rdmpADn9oiOrsrkqzOgKbYUkIql1yZ1i2XZXTMTVIVq7VYXa51GYbUmEKpGEaYiKSz2lX9PovG3lNCm3HYGU4McxtzRvRJTYTOOqkFIESWW1sIN2OPt3xenDAkrLZXwIoJrqmhchY2KES2yDkvDWyr2nCecq90DSTgsyB8+K2gBZUv8IW0r4rOKlAQ8VSLZ0b8KMl1Pppj0zRofBjToZ6mshwWiwPEp6e9PGq9BtxmATuNdrcWU900XRu3LrUoYtiNcLHZiIa7YKzdqNQw75GdbJftdqccnFtmK7B5P1xs998vq3DLl8VNuFQeFii4SZOCTYvcpo+5jTFiqBG4mmCHuH9GQkDoeUlIJhyFbMcdvvs2Rd7lgmdGVzLLESWVpP4RiYKXot2hKqKLg0pYXTiiMeu3hlBcx4fuQEBB+gdgrk2DgGYJ+Cypi5VsOG4di0Zn22stQI3FBBeIcgF+Qqb75Xb9KbLquQ1wlzZ621GIx2CwHTDlr2+/Hr1u8UX9x/Wd+Iq0KAQYfHzPJwIvAQyXrgzFKlQVcv4R/5/oBGA5NItRj5ZWJFub9OuNxnmS5lsiGe7NKciqS6wfX9SeTIMirbieG7PoIOam8ToRfLHiaqzMUKrRuRB9rQM1MdeDTdyfuXQUhOn9P3jj1rJYpSgXV7is6rozk9bzDDPG3IQvum5t3CJqnbLWjFWIRUNhZp/yBBFGkYaNCwkFdqYlapqmQmhM6NO9Ya1I/zCgsHizKL/B8k+bqQCKWlUPIaGGPwromutFPTfNuILogzmmiZyFK6hWEPejbZreurFQL0j7L/q6/bq10wE70yrJ+s84+b7fZJC8wSJ9lBT1n55a3Bp0l3AAsyA5N7XsPej2dv7bgqJCTHODwkzLC19XKAJJh+fbsPiuIQRjUaU4KduMmpQx3WO3QhQjw7gZCn9YNotF20ZMKUr364YFfIeTfHGyjc2+sEZyEwLKJJZHNnSH3+sSUppTKhUwpmaw/IzFt3tqJLnVyDHCQ3fbh2JVK7jGyQ3fXuukl9Rc9l1TYWLqDuUpIn7enr7MFilZ4lnCucP4XD4rr8vX1s7HT6kVRF7yV420hBCwqtPScGgUQSGEDTQfc32JNZH3spoI2Ba9QRNLXdzsEBBD0V8HlMW1k0EQsslwCK9Dfb1fh2olICl0pTdY/BH7oJAUIJOiwNI+HV3tQ+RdiFj+3wLySVzqSxWVoUdsNKouyedpjyGPM3VZKMriJvOBwo+sKs6pZgy4jFqvCSXWWUUvIVXeUg1pI9McDycy83sP0NHRDdN1Ji7IVnnHC38IkE/ivF7aUkFuPgGEdXykcq01wUi6xPtM8impc95kr9hJSTf4D1TeAYlbb2P9Rc6gRaqKtrPz9XEwOJHRUtPyNpWPyYGQN11E3Nx8p6//lkQzE10Uso/Zm2l0cfBD7Lu9TkixKgeNrsOUWB9e87/EEmjwXCA4jtYe32+h26J3I5vZOncXuzmSMze59CNeLq/mr83/NOFDNaRvcPq9L0QP3jQ7MeFaTVU3Fi+VFCvVQUSp48FKGUrOb2Iz35bRTfgyPFX47txf1C/rV/WXxSy6uGq/DTxXbeVaw5+LPXUwBfLB9ygwdhwR/I8GSlLJG0N17/MOyHLd0AAIUQo1KjIyIiWC5kVS5tZKqaJH1Vm+xGEJJO4o4lhSVVj5p38Kpm42q2gTV59x+kcpVTl6vdSDhxxkpWBXPDTOJgS8TwyyUHCZMFZK11oqChSY1mm4cbylG0KpvUFg+FQ2tnu/rYuN1xqQ0ZYlemrJf0nIA4e3HjZoQHZGofdk84vE0RdzyTd06Qwh0A95UrbbQ4z++TS9M9D7999tmubNm/4zjh4zjRAVSEk6fHjz61iZJwHfp/kqZSXI46ps4IBmWO5bbzvhZzTgwftZ55cCYvPfbDcOkDqXQIF9RhCv/ZGbKsRjBXO2co3vImsJcTXxAuE5KfvPuapcRHrdWWdigI7qiPedBmihxB2bZxyKxIm2kxCFvtMzHllHgVbbGFCitwvetutN6SZHo1Q1EFIXimXhirK/UK9BvKk7wBNubVCF1JkZbxfFyoq+31iIh81Y+LBP44dS6FVzbl6tF3ruvNPg9sVNAaWUl4Pl8h1bZoSsNbB2vw6WA8TNmZ1AdsR/iWOgIBQqR55jIyiNjkkSY8kpR0XxFMWx9wNQfMGIGKMomkQyVf6eeInpZ8wes6vYE+2MF2ogmLmf1Yg4Sj5sVRnW51wL4eDsCBi7biPpI+xcb3ifXJ1jIfTyOTyi43KqzbaXqXti0/cUhXWClNYBY6up0uIzjr/nLQ32H+EIcJDkA8BSEiLdHp2GCajJ+D7WygYRl5ZACxdy+QZrOEoh9siIoviSQAgg0+KjUqVC4n29KcZTMuxxVYN71POfRzOWUgxgS+gwPP0Jj7dNKRgrmNFIeueWCqwqSsuSZ+WAh3gaEgz58HuZtkHJiGcbo194EZsIVBCiNbKolS6Js3if+79lMhLe7SLbUOjCah8piXKw9OqLnlWMQbiauZOZCGtV2riON9L7fmQR1F5ypx8afErMZkzfzGqcWduVWiu/9VkdL7puLiJOidNOtOq/xP0qav4PHnMT5w5jA6WwlH/BAkD9XYGDrJ9V61DCb0alIAQARcy4Z0zBJga7aOc2EPvAyX0BZVOhf94lCnKTGpBnPIXaL7vsReVsOThyVvgikmS7THVlHP2BZP0XrQAjV4CQDw1GjBYf2XtE4pms2+nVVJH3gyLEo6T4jONvI5284j66qjxq761YzmPY6HzifLUe69wdZkk80v+XVX+YXoyd8pwxyroGvVYVcIknA4CCENpwPqSULoay8R2QIK4hTVc7Sdaw/EHUwlqgQ0uD2qnjICNOrZ1FhHTWNjGExmOlLT3HDLAqECaoTpPWhcsgIk+oMSTCPI97X9P3Q/C7QXtrKOWENG5yuZ8T3ZU79hmv6+Uo+Ad4QxHr/YHMQ23PHvpg7gcjuwtofQsyz4tjtlWgBm+9Xt9dWOMFuvROdjs+Lp/Fs7tsSKXExdA4opCxyJ4bKqoYeMb4vFtrEL2Uhb+XGXVO4aaHi9MrQ56JW5lZJgVMd3HKp5X6FhqcAxzHEDkTfJfrbwhLHDrV9/JwjG3hb+aQItuUb1YQ334z9Wcm0elnSFdzrr9X4R0PSwawPU+3OczzFlwIkYs0RCC/YFs9Ep2N6dijxaptrHeYy3K9BlJd9vXYcbOlu1VrtvH3cyQhu4pYtN/YeLKND4o9KCr9dgw7wD+VnwLCSqtT537SP8RpShL5g3MiVpp9+POd9/zexd5CpO/uttvDYViuVp6eJ/MPl1/dvxvCYrr+smAJGPFB+Lp0xu8Ay221QXk2oXb+v2EIcfNn6p89/Vhr7LSN0baPnxyfEaBRGXUAxYCNNOBa2UwTTuKBF6XID2lrMpvml5EQqxHOPQpTPh2OhTmkr3BwWBsT0k+x20WX/MZQStFjhdzcGsajHGsIZtOD7OwsJ9XpcgHg9Kridc0ifrn1Fn2RUcPYadv363E96SsteLODyLIkFjevSEW83Ho3S3rU96wGt2gs2K18ArOtopVInhmgJRlHISopJ39TFcygLaQ7Ws5uKYehOzOgaqknZx0AfY4ZO9u2qxNaliQMMVNMTVWENG2nVsQjAkfvzTrE8qSqVqNQGDBxhW5NCn0xzpK8I18GfFcem6aADjx7pZe3hS8PS2+Aw+QjKY3XQztUFW8Vbqlb+f/jMa/abuUdF9ZuNlkpYWsoVOrqINuqvbAanqGrhRDFKyuxEkH3qFV/XJBJ6Jy9OIbllvXlWd1YD3J0HXh/qKXcjTwC2Ia292fTmWeieZ0a+kqXzlMoBCIrsDqzBiUHDlu6rDNgWZHetUrg3OX+73bycSzYLqT8mihQsAr/zk7TWaNmSsUKv/hGmjoekxjQsfIpSQl/vfuPmVRKY+AMuYgxRk9etYfjxmqCnoUCVUpqKZerCSHuwr3a0wfSXRHkIMQQLTYPBnBQCBfSz8RP7u7vj/WX795677xpmvn4VfX11xYga71vPpelJZwX/TG9Sb/nFeCH1Zf1fhNduC8eV2cewdN3b99dePM4fIsu5DSshidW0gq+/mPGZ9wLposh4ehwp+BAdhYIGHDwagoHhRAmIa5eFCBx0/SsXurq5sDnL937ekY9lzPP8Ec0EPuKeIMX1q9BYveqHSNka2EY8RN3Snw6vXI5rlY+6gstLosepjmhvZ29X+fN3tptvX2mxpNfCH7h4IayFa7FUkQQf8rx4+5o7j/JenUEoDLk8OOtn+voBo8obBfnnMUGK5UaSB+QoRrWq7WiFGlhZLQ3YYbG4PZFFmBa8wdOQ717m8iyjk7Sfi/lnGa9oQbu7TzfncTxiEPEpzXGpMvS7JXDal0c284iaFmS7x0Szr5F6AiCY2Z4mIIE1Cfo9GvJYj61Ef3kEIrjxlswMzIYYby9U82FUtl1orf59pk8JMPvM+R9D2B/aW+4nCJxf1i5OeHy3D5SFxto677PbAjPJohPTx0+04nlrCdRsazuuU5tRm/CEuzWV2Np0eD1wNU9xMlCCuqlpF4uIVC6n5WK9/FhIxcX7CD2NlaaUbr63bJGYbbeI2dn5lhyQjbnPlqWXN624J3tev32bdgYE9QM3fbwF+87R2xfHV49Az8QCLY/v1HCCXotq/lCV1nv/RWyoJyWkrURo1jtxla4P4iYUPRBj2dc0ZGqlbKhPASLofYPAETCAh4OQkf3tDijxv16eXXOWriRI4YPQZyoxh0IIQ0jFqZpuQgwiASlkFkiFsIGRgIo8+F6ZlnNPf+Navvq1TwP9wCibKDD24f7+cy92Nxe2G9W3oF0XahHAOlh7/ea5ThyTuy61krL1cQ707QMhdtkls7Bj+0OZ23dEwJxA+DuJLYbOO+iRlfW3m26bjWsnhmwT5Gq1sKUMHZg1CMdfPX1Ot0aOmKsutqTprCcOOtzZ+3Iqqr3ly29IAuhQzLAPgobVlPjU6BIAcz1vXRQybsZQzw0YAPe++KuWbLl8cx2id3LeEf2jAJIy7UCMUBV5lfZzvXnjXtarruy2x+4wAR72K0F92CPm2a+MDTOIGKTZT0mJtGuYlov9A7WVYNFP80tIb5zm7E/k6wQiR2+0MnSheU47HawCS/UbSGIm7u7Yby95T0bBt00p1d2uDc25tndcOZOmOOec0vp2sfv1KOqr+LPP5maOi9FPyjmGrOQRVHcYxzZOq3P1GlJl8b1D56plFQFvvhkN2K7HRNKIwYw2pGKI273dqLFGyGCMvrYz0GZi9ihBzJH77yCtRZ4jfrezgbOjJHLm9uErqfUhApWoR35VLowVNVMheREPC+9v9qb5XIPrtyu6W3V9t/3dBPwlRUoWHsFVuDZq413stl0y+XNhSVu0nkXPegk15pc0KsvNAfwTu/bT9r4C569+JrD7s2bn+2O47juOojfc8Mkk08wBp62r17VT7ySq91uvrCzQJ14EG8HS9ew/WzkEPnSXqvaXDcQFxhgtXj16u1D0u5hJd8CfBUfBH107x8n7IqDq9vb9YVbjBnLTpgN+idMxI1dLCeRphvYHVa4uApdsHSTwmod7i04J3uf7QhIX79Z7jXjAhb00fsdz47TY3E8VXZtZKgwjpCe3K02ZC+fU8yGrVsJ1wAE9yLHc7Kthl9RAZpXR4sKHsoiG/Wn9ux1SdJ6gDW83GPO8xNuw3bItxJWKwDzaq6QXWYJQQneadf31PU+jzI66FHWz36jpJOCeyQ0hp6kfQjhvEwUG9FkCWDq0yY1J4YgrxOL8Ei2rNfH0SRtZHdZkVmpe4kLdUTxInV1Mmw24LLrVkVRAzgcV1HBD/1u153Z7eBhO67HM6s1cilJBlTfgyph90SAzhmcAe340KAxkR381aq2chd6SHafBTpaJ22VTmLgS6iiKsBaJSsUNgte14HW25YC1gSNjOowU1TBNp+u6dfQm3k/qq4lLO0dy67FRNYN/3MlcD78TnAYx/0UD4Jc+oJGTCdxITAEG/WoithWxgyCMfiE4nGY8iqOtwiAc+0BPiCZEIY2Q/bsTYzZrtyUbLZ6tLxSBGqemSJH/yo17Fijc4s12JybU3nx9wBv2DtFsNYgX5dMYq1T4UsNk//1e2E6h5JS/MrvbcV7pSpIqxtxm0JZlBhruTR1YC0hlA61YTNApQxwPgy0U5mR7v2UvLhtmJZxOCJslpVasyTJmC+OUrAAU2D65+p7eca5LtfrOa6mqXhk758a3OSF9Ym+HgVxOmKvHZFq3U0BnyMPkOp5t1yN/yZmnpv4Xsl7lFxhAnjrlNjw/dRPhgBhwDCBc1epKbDLv9W4vuVc3+P6RRJCBYCFeEBpJrhBe/jyb40GiwMyXrZ0IWSHZ0bfJzHXsr+mCJWfgAAjGmkl1h7mjk1nknN32K7Xx760tq6qwxGX5dz3RaOX4+zPwAhm76sAg/OCEjz5dKGz4RNoLkv6b3y9cQCmU26fmRwySJs+vE1EAkv6Owfzzh3rKeSt4VkpxinJe7SfE6guQe188K1j6qH84flMDSay3NN21QoUYl1rvXLl6KvqsFulBY9VdbMGIsgGLISLKDMkAVEJeSmj8F2t9Fg41zMIUNWakyyYn4IlL/7YUhk4kUyfKOMTNqNoaYG3JRjGQjG1uKoAtMQYr0ov/RIHdAMz3HECmlrJzCAacYzzBeMq4Ty0CQyZ3Y1gj6nWw9ZBx0gUPfo+S1uoZyGTF6qSogjehbY7lMWqZGlXfmWK/ertASLnS87fvB2KOuWXldOWNFZvc/TtepmDaq4HWzJGPiU7W3/9UIeYrSA8+qT5t7ahZNQW2k7bijRC2DbRvWXY9X41YWM4kwUvGLUQ+IPNZiKtfYOWTcshY6UwgJBGzx2iRTDYv4iiLHzdN+uAtS3LHa1JWRx0qU1QYUYZJ7ZQ0ugdZrznwC9pZYd+VRYdHNRisaHZ9H/QOBFthsIq4Ms2kn1+acNFaQi8Gev0vZD0dQoIJ5bmysbW0iTprKLUX2cQROp93DxO6NrkdZASgiKWfddZTYrb/2bue9glhh3GymdyKXhCDCxicrOUO/4f7dOSBdQTqTVkYyexVTG6SuWpgCxBFLK+vBy6CSOisLMQn6ip+mxtsCUiAI97aoexEsKUh6q4su5pI/slNFTrCGorwFa1BkDaiDhjC6VCz/xqQlJap5ydPz8GEfs95wBcthn78dFFCi4/RFFN566IewKqrVoOcSpco4XCmItbUs+rPmoSRRzXeYZSlhWUek31UKOuBKAsKHhFUmO8HvbV313q6ppW6boy4FDzR+J3ixnB0vGP9seSvclep3dt8Ktd6Pb6ue54mZ3zKzInLbfZNxf1D1t/4FeK6e3stYakwK884fMpRdsFBUMl+9xVW4iVPHDQ8tGVMRKutJrHqgQFT7WQOC5RQyme88z4zTO9c/cVU55LRCYkWWa1FljDKvnO1zExf/FdcEfgRmlgl54ync8qOSQgYmAc+tl3aU/aiYmtTPCU0i4Q6w9qKsvkcypTSZVkJ7F3qZ0cLFs4fV9v+Glbuou/qbOPdgQfoNJ4v94u+31ZSsL/yHcZ2m3KPDvoVazfNFifc7Pe+2a3bjStG+k8p24Giqhde685cd1bWCdMvbc397W6yQ38tnbzRdS8WNvKXfP0omVf9Kk2uObeVU5by+bP/sSQPVbYhypIFczJNO+klzuBsiG7n7Mk+csPOSmL8n2EcjfPbNQ9DNJPDu3K3RoeTQ+/OMCTxyv5h6773R6fmwcbQBq+R5PT9u0TJAy/pPCSHWETsjYvA+V+Ppqpx/gD6pvXsSLxh/veJ379GxFxOZjMutQPtrqC5btreRTglyt8e4WnLvk3HbrHTHSEO/utXdCDdnoHQjHfEYqfrvZ6ijE2/6H93r8hwnBv/u9IggteqAUT4Rkf/urRiAf/X1nKvliQ+qSqjiYhZzKJkk5HxEr/YWhmd/GoumYF50LK0qB5F28NWrE8U+V+2fxYsgSfxDvBSF+oPS24xwF/1MxobRAJbsGSd2hKGU3ihbi2Eon7We4XvgMJ6LeiYmvlibfxs/hQvJ2NcAem322q+g4r+sekxK2VSLye5RFHl93w1x56LA2MwIRmaG4/CbCb7WP9Ko4vowMvEm9nXGlOH+F8m7XyXn25DsN2j2xm5ctbtTkOps/HiqKP9X94d/CI2J6TqthjqJpVNac4+SERie/rdzd9yxIPXsZheOo7zpZ8wosZHyR6Vr/Zi5N8Fsvm0P++vzdtSmYRVZQW+i3krzBcJOvEnguC6ijStONnYmMUGX5+MB99I3+3eDKP3HgXtbwnfrc4cnUhnagXDe/xXuY5HzePGeKZFsWiXtSHsoyu5JF6lCTkNJLxk2jFL8TfUzzn8qgCxIKsW40ndQ5z8U8VP5j+wmG1y2X0vniHDxL9iPzBbJ/D2s1hM11vmnAzLOugYJMf9l479OY/xKrsgMlxfYbAtlsnqOyJlSpAWSUkVn8PtKLDOSgVMcMESafT6VtDiweQLaY5IS3hZk82yFLA8YfDkdzZPa67FeFZPvsg+ZDDxmiUPLsGxxaCROS9q79WFPdd9v5tDkevUhqG6rluN3mVVkC+UUF8gNT01cFKdDG0teGx9gg4vmEFtCKJXP1jYpuokWv5RYhY9IJQMmCKubfpLb09TymCbPGrF3pjhkUS721gv4Og202Sft+AzurubSsS2TOzCvp3p3UffrP/+/4/93GtbYWz9hqkayBbPqwXF8clHnOnvChslWGcXPKHBeEa/HXUZIo4P5u6yN3ZXTsXmy+oZtOGacG0YKQciQNs5E6rNmRFSApaU6pjK8MxXEhAelgc723w8S+HvTwXYtFUq5fq4B0Gvw/+OcAyKb8qZQRmozmNNQyp+Ucc9SEpuQOJ9OWs5MySWaEVuZodQm5o7ViIdgQrd11B2dar0bvtXviy8eWFXciE6RenBldq9/J3acdhGK86BM4nE/JW9WVChKN2bgh0seUiTEp43SG4h9Zw5TR68NSAhw3akqvfNy70tCPj2snuJDNqrp9JK3CiMgfzsg4scg87coy2oqxK4yRjo2oys3+YaB6JIyu2kCWXLoR76LJPEndU4xyCYgbMvGsQ6/Pm19gNxdq/9D21qkxVr/bWMaAuZcx5JyQGxkvE/rWswu9RWDl+/ZxgFmgTpDzzx73e8ut7qrJCtOAW9za7uKlztomyhnxG10Vynjdbpn7tZI4uXnEqtvphaHLDMm2f+LnHs4KFE/c5oXis2edmVuCJcgCTQxkKfhhm7M3aZihN8yYFfRjY9zieO6pMMldzNB3qk7l9xszTP28x+G+WoPE3MgK14gm4g3leHRMp81HEQVVfrW7cXE6XodOmT/0z2sNJPp8Z10KIqh0fB2qt0qayIqSGQLpaLLp+9dTlKlmK07kSmcbs5LcdQtn+r/TB4E1780Fy8+ah9/RzpxSnJY+wKpZMLoca2SWmGZhV9mH8skN4N5gGjkM4VaquIPNl5Sl6bgtmkyQzCanVvoT4IHRPMwtcZGTCkdak3KeIl/sKi1oqyB3m6z2rpugd0BLNWobWKuLz/v9lMBkfGo1jZwjpHsdwnt4PR8/wy8vNklgrLctK45bSgoiJaEUQrYiY43oo4j5dWpo3a160W2hRSo2PgQTjk9/cddCUcXPUsdNJRYbl13Z+zpv1zG3nHTBhrkZ6YunwkLx99Dy+j1QXhSN0UBQ/n72YzY9XaIRLWO1A8/aU//JmPV2wzKAmLkZSzMZDVtkHFxyJ7dEMaWejlRaxnD89cK2ZdQJsNaZPqfzIg8JBH/WdXUSM1hWLSOe7x5oicHGZ4h5MUEbtrC7BjlrUkiH1EYQInEbnUjhr05oXbMTueUSkLCt4gS13iEti/h+RW5D0KgmZRpdI0P9qE/D5PkF+Qd/efhnEIXLYI4xY/fcAJCLij8iaAUXi4Lgm9WtR1YbkBZAU0XElhpZToOF0EJ9DNb1yWP8sgMRFazlCJcEQ6EH53RzljKulFJoR4cbYlAUDuuK+KHf4xP1dRMCBdb7yeMf7soxnIcJ6iUgDBTp4UfN3xfi/mv91tlaQemaaM5Hdh+ZZYUYw8dudTJJFCuXpNHPaUPjTtgn0RINpZc+HUFtA5k5wTiBX1pUijeUMy4FyRznI8Dl/ns3ryRWRzBx/mbE9U5yPcEoolwiKyHEDZfX6GJmShBkFRTiNJB6DyEaYVFbUWIm0ZCcICbT0HZD7ESETS6KT4gWwowzOUijuAcZr3y+0HjRLZBuHwbnxtjg0rGCfb3+/XMKFtbBEQSHe3mbZf0iTFmk7mRI4Ar5jtpj1osKjtZmOd3RQckiEJuEfRBjRE6fzPBBGj040jTG+XQ2gI+S0kgRB8prv20hJEVUNqq1NqQpYEzsTIeAXxYSTReQABx5ynlfNJzygysbcuesSCTOAunOLaixHmWDgXVihF8deHcONtNb7anCao7p0wUvuoCcyujg77dg2IvDW3t6/OyTZVFyYJ9orBfbY5GaXJxMXFDLOkliMBT+qx6EQnHmeHmPE2NfriUdB+CYBEGopfIf43zV9iwwpjpTOxNsCBKAdXFEUY3cNjCer/p4goTcLFo0r9hfLbYdCTEhpeptnBgqvA9hJujIKR2+SXUnCp8Pnwk+GisRKyLRC9iaxf9ZXeV47mtG9FEQ7/Od/WU3UWs8Dl4Lr43gzXsY34pfjy/jHceM0lfTi/fg65sVb6KHxvjEtdzEO4lnpLXP2uLrzcixXH9u1WG+fe2Z2M/5SzJLBUsp8Mv5xF/AFzKEONSon8N1bZPmB5g2FasZpQJ8iHBCFQbnVHKcceG9SwFgiPMfF55ECpyNhxKmCuILalN75gISjSYjejr9Bit7vwtv83tn2U+F9NBhOc10vFgwU/HiEeHs7gE0zX+mZVs2s3Jtumthysmjf88C9K6VjKgkXrOorWkp+RSJhZAsEznyL3Yonq9o2LV/179Ur8fYUUllEir31Wnq1R7FgSmvTMXrsXbxOlHV7a/P3vuhev3779kiOLxgphdCsIt716XR/3/cjWF2JUQvBWJLsQT5c8ZgfcWR58iggVy3HTWaRfsrl9+5hf6xvlsBcQ2svNhuljjepRPkG9qP88RYgXu23V/Z21As84dkj31hPNCNyaylIWuQJj9IBEHLk6EH0ZP6uOMuoMY0WiJHJTfq67vwFSltyJFBhSliW/2sAH4t5gQq9t3XjTL+HOyjwyqekwTg87zUNdPHmqEFLLKGW6Xi/b6I984uQIAE/1P4tJL/A4wD4GFCSWh+GZw2imXTvsEFjp+rD1TjCrtzMiwEYHzKvSDTAMHCXsYJv1ilswS8otmgzzL+HDt3iqfXSgvL4Qt3lHk/hW74t+rVq68QSQUIF6pr462PJL/OJW9XF7vtkO/3jv1X1T2GtIXS8Dwp88irhcyHmXSGN8YthWB0AbItyJVa3d4ftlQMf57n25l3p56ws3Vjjb6jhQo/RfVjJUyULPZNOe+/zO7lp9bsLaiCk5+T9cVwtIU1u1X5z51V6t731npl2GAElk/vMOG3jbdcH79aX9HJ5cuuzXEI9JW+9agw1aEvTp9A6ezYuNtAt13tosO+Eag8w1cG6x6W53X9rhbX6r3dyM9vhgS45owzdkGuZqu8hJWGol4I/sKH42fXdq/52mj69nOft7cfV2zfv3t1XrUp//L39eP3oJj86tSF//0MgfwFCEhARZu/evvs992//KfdfA/3UwCG8+0+9fAvwarP/9NvH/fb37IPNZrX5PSv9s0v+N3/9ePNnmz9zv+/NcMOGL9eKj/GvdRPWDZof+VEimEhvUpL10+q/h92x8vo3VlBSUFfl7yRP4qd3p9NNinaWvdNtV6+9523bxM9DikB3kVxs1vfe82FYLl819WH/9o2M33/XWDt8qOrv9cPrVISIzm52Ky+ejluYc3alq0Bx5E7kmOdrDZ+/eRO73L7VwU9kmKCiA9hQ1roalQ32AKzMPATo49tas8MvcuZ7z/bO9z78rED+UHxvvO38kfg4vndwDgI593qEfOrWRfThSB6O+IdXg9czCFV6/dE28c2x9RhLpuZ2DUK4vfUIlPBNmoFxsJzZjHcsGD7G6jK7fAYQ8Ta2ipjC42N/EChE7Mg2NNAfr9Wl+n/zS65KONb7SoiMIMer/fFmzuytghx/AQ/GvXP1e0on8Fnw77mpG4cAIQY54UTtV/3vuU4OrB2F62ll4vT3dMVtcVfwoTyWnyvf9ZMP75XAv5mOO27iThsQE8cSyiCwN9i9vZxgQYfEY2iwRkTMZ8cJrqESWRHiG7RAaH3zEnMkIhwoYH2LufHDbOKBvHrp+g+YVKWX0dRUuZup9xBVh3Jodbt3oCY9jgNzC4dA15vBaDkLUPIBTGH5WwRLT0/Ukgam20ybD6XrnXUle708rl7R7eKTfzbGn/goZsZ8ydjP5OLHTnfH4+nmYfwb/nK8KRT75Pf13/ro4+vNE0K9Ivuy/VLOUT1q7a+u/1TYn8omFd98zfgfgPGbIAPfizNAgco+fpxElL2uX3dsa1PAOkLi39KsCmc+u8UHemhBo1s6e0/uMueeIK1X+WrzwmKs8E3qxXCTD6LwrhTuI+G5jC1dPQyoFs3I9UQjz4LfHDbzctlYYczpZw6sPXC43E7jPnhy6xDOn93twKNtEyl5Ntl4pU/2E3uRP57aVdT+PEcFigRUd53/6DR2Tl1CmpJbB4uEsb5OM4+0aQBEpYj9ewkIyXE5ermgr9w+cNsSecFZX4+TR9nQEUpV0Ft/qIBSjQL1ao1W9fiCNeVzcW941GtWrL21qiSCUXoKNRxB5hMhc7WbUpDnGrHU+ZfNOMzeum29kDHp1YVfZ0oySp0bu37hrc2iyU0eoZclGQg+JuIKwyVNjD6bkfkPull6kyZ31QMr9P21UC1RGGGSdY4U8Xv1Zu7sSumOq4pzZONPO855LIY3qSJv+qYy3gSq+bttajDSHMnzu+Ct1z0gYPc2zmAFo/Dl9dExvXKFuzsfAvoVXiYzsVuHBEIkEk54sT0eF1eOjHCen+meZ5duqrjiqoMfoeza+jvvV4wmVKmxBssxpFJODWwyu28h7lZ0DFfWqS0s7yqaD2D5QlPpG+qhn9R0s84Vp0NMD/ktDl3hZNwklXc8jd7q3RcPD133+o+06/603R1Dlk3g0rF4uXN33vMWWelqz5RZUbYh3x5PfrS9WTOiShLcumltahR55pEbQZpFmTieOSFixJmHfyewHfzmot84q032WLXPVKtMxp1B1Zj+qHVqUC4TRaTL4eoZhgYkQdtLrHb9r2IIw7usNEsUyrOBmEFC2XeMgejyhym3gVIpADmDiM1A1GFtnK//9WWDhBN6HhEO2Y11o62+eB1bs0udFDvIVxNUqjZV7RWw2G5M+XuMUSpYB0nnapqASdO7Q44odC41YN4yjWRZuPs0QlipOyIGPeimYe/XvT8qYPPZit1u9j29udFDvXbxev9waNeuwuWaVROuqA/h0HfQFD2PkkRmvdh7kpRe94N27Evm5oG1cDL1iRN47Or7O8yFO/wjH/JdwtN9tKlr2pl7AIZG9L0vaorp//o0V6I0McHs7CBi7M5m5+V88f5vWZSllfmHKyUWrsI4CzFjSK090Jkbe8IkFXLlmv/089WrPJD1TmHCU/6+17qul+5qt1tSd+feHAa1hxqsUnrbEKjxn308dslvXg5rTV1I/tnHGyvBb93H+GqB76zyhdc+c3ZyYyY07/3/FP8+WgHdUEOzYQ1JNi44NMTuYJk0GlygwA+dsJuX4/fFMPABRV9NcBWu4A6qbNlrqjfbkU5BjwI/Q0GUApwJbyi8WCQku/HTKgdRtiQBJ+2quZigxViDEISY90px3OJ/84Om1JRSNMOxN8UiTML2IN2LfqJ1zjusl/MoaJRKnKiCRzHNUwmEyKdqnt+6iMf2bfTu+0cxzsRxl746vtRIev60Xb2Ly1XA9yKmyaCcDygTNt0/IKwLnuWOdGfCqlgdOqFVKnj//CioYa0tvh88g1MxgmGBcNKYKcgUQfhEIroadLvaq+thTTgai3DPcQfDDuySTHL9VdZbqxcmc0FHf2z7ZkSJX5VP88ixceTQvok9O4a29HV13nA7RDq2yFBXJpkO0q5gF1Qplp5qWZn9zMn77mJrFme34x/Wcc48fKfDDdzawLt5iaMiZp2h2SFnzW05d6LlA/iSUk1v7RMhO5UlOt0xfJ8CFCZs52z+Ott8lIj1ZeD7c6dxrnVglE54jPJ923W26SDqOiqlyP5Jq6yJex8/sFXIsQ3rXE0LfpeoCOCnUHrHJ9lsk1KJB2q3t6pyEIpwZ6fEXaUEHSzBOEl99Fh1TKlCVcQOcWG4q62/E/4/3xXCRxAbhjGphZDxvvUfL1nYIaO2c/2uD/b0Bg4pAKXj5hnfi7yPEK5BiTU7pVpgu9lQ4l+RJ27HloW+XDqEjSXsXzKp44vhb6/Q8UTiK6nnHSVDur6gdseHqh51jh6qKzPifiRn6ApKXY6edBkyh1MhyDHtao1izY/6ksMCSWWR21i3UQYh4rfU7wmMI7u2DeTaUicWaR48GxUwLIwDaLvVA/Mv/2tufJq4kzgMko0tYj9A77pejHNya6dQX3elshN4eZn/Sxfc0ZSAUr7VfTcOnFKntE02AfRsB33qefRlpHv1VwKMAvQCmAZwJ0A/gO0AQhnOA9IJoCnDK/9eb2y7d4Qm50gCnMnccFWOM/7N1DxCHMW8sZ7mSGnP72LGiRPNQ3SDrZSIP4fiFjiC72pT6XoMJ8QYcQSxXq8ckzA/5P5bXx+XkZUCH7L1YNBpnFFqXSojuL0GdYs4IDLYW2K4dJZTka6OzLF9e1fdCS5hHJlUiZ2V61+d004isjEIVYrJsqTaA0b+97MLtdC143qf5u8PJ8HUxMTLVy4Nnv64RjkXDuXHm/wQ85mW5xUAcE44ZDVw65+JW4Jaz5ouGe28xb318VkLn1XkPX6eIyjBrcmAn/1jb+pu/voT2x+bbb16nn8g/qvW/nCa8nX+PTEXDEqEb4mbYl+ol0Gp8Ct0Ci87EY1NYztaj+8D6bx4emY7/MDrZ7/q5/3ePZCA+a5xuXr9ZHwKqSyv60V34fSyMubVtcigrqYzVT91S7vvaiXq3aZWNt/7XTee5WUeLSMpizajG9HdqGZq8whby0//cVTVhIc11UxI0TO5p6FEoK6NQ74RopP0HCYKimM89ZOGraCXBh64xp9TWEenTBx8fvBahrF98/8obditiKtbL1Vpoo8940qOQUsxuIXTlCpDi0sRsMrZ9uI9hCkLxbakiOKHcjHAWyDBRyvZ0LYmQpuSn20m1tm91cPfQxW3fHwcyoEpTW3m/P0AnAi+mqvDsPbdWA+5dUtKDUyIG2tsYx1oGlXVqDGrxPk+01QRxwDgeTgOlGKa6LouXhwk9za2sQ4CliR37lwbbSfqIEqx+2DLH9eere4FzL/kIDI1tmtk20BPPvQGwFw4jcJ/vH2j44Uq0FAqctlScpsKDA6c7zkUwn3nicOZzvzYuSNJDE3PVVoNtvCBeWCath6ZuyYzDp7Wy5lP+zKmAM1aE+xhBmzU7ZgTzPZcXBlRc+ZptN7FvzpzL749XtcsJyHBEEo5ZPVaqQPoXGpge7S+9atkLyWnqVf7A+v4x2Oc4cw/yb74U/Ap+bkYvoZBeVKR8EbkxZqVFssL+djzOwU900+8gz7VCn7L77j4r2/VmMxwVQNa5zTgxN5ICtatLdX1wjvjTUzY1E2zMx1dg8yoR9pNkVuu58kHB6vhLIcDcXNGc+RZ7uDBQzA6BxE55JND4rmRuYm5Fk+fyO+qxC2rJKmxmif0OP41BnoOanIXoSJDeAEuul7h2sZfXu+fe3jwJPJ6ejjlZw8YCmbnGnMnHLw8sJqtgujmigdnB2eZw8Hc3KE9N3QsLHAizB1h3jkkkuOhJAKUBXZ5vAddfUuROCGQcXJJUg162fbcLgJ04rpehVodvn1n1SAfpy/qPsvtwgjIlVXrkzAV7OOVbK8vMuvDhT1FY8EeOhHt60UNb09iZWB2/fpICBp130HZdGVKK3nNO8keFzinzaUFcArbQ2xO341Hbn+4jYdBl6ZHXfdq3Ga51GmYM4K+iSnWixh/K7FZwOXiGTfWiIDUin28WiQUvrY+RFQL6Xu70Ehc52qDRkCEf4GDQCjIbjRAFnUDY0bEz4NcBI0tLJN798MDU9vbdUPnXniDVqwkLQT5gMPCtQXVNN3abXaV6ZRLljpEud8KwRSaFbJ3XKhvkqVdiN17iACt194jgxfoFcSERtgWj+kczoutrFFnLzefzlusR557ICiWVX8qzhyCcvikHfiEvUO/Wtg+W24+nda6QIXnLuZoXYGW+xSJX+CXWs/iK2k4Dk4Vy42dO5p+E+HEMJlPn13QMQ2tmtoP77BdaexDu5gQK+AYx+5VqpjZdaVvCl9svpTdCLrCpHEZFLQnL3n7hnwEv/hplZqqndiyW7fVkI7sPeXyUiB5K3uVsAFCAVcH52Sh+cEWFwuKBxydWupFMtMPW8RWT5rPK6Ldl+4X3RzdFchF/0e+ZKYx387R92y43OxVha/Lzu7RY9IRfY+MFHUkO2eXkK7c1yBT5lxUyzqfe85Nl8GQ2RWNjnxRybUVbUf+H0O8TI94lYdw1oy9+R5OnTUz9ta9D0zd94PgFgbSC3tr1Vm6LOtojGWejH7DfGV9PxnXXUIvopEPxDbYEH+QjASmSgM4b2mRrvlKtKn93OVCdjX+Z1gGJm/7IT5yV6lfs0vJRubauJx9WZciy7zy/pr5sopKyZDr1cL84f9yEZ0YRqL3YeulWyFTmylXxNt8GTL5GMWkykwdfp2GXFSjGXSe19nZuv28g2SaljHtM66iWk3iVe1ywuByulHLEvJ2u7KazfOhAgdL/+NiqaaWrS273CKYDZ436CpkWhADlH88GtkscZ7YbJtTHujhOID9KRur0cs+G149Kt3QR6ABI+DKFnS1evX2Qq4lz7NNOR1fX03q2A6PVuFudv2Ujy6x+ZmN8CuZ2tXu7gU1WBeoiDBSBL35oPMMXxhTsSDQCHzJGZ13wW+Bim/qn404bLQ1VaO3QLRxLMEGKQiVChOc2G8bVOAK0GFqxDLyiLMJv1ly2+TMdRKYCplyuIWK5hpPZBO2FFtMT1zz+4xSxdO5zHowt+5KCRodSYhGEsIvCNlMQjqTkOAAxiboH+Vldptr54xZIH3W9WtT2yvS0oc3EuxCpUh7GyUhPIIQ48v0Mwx/RNYMKGfibU4SAhnVp0kluhRxERHDpFMX6lK+JjMJoaBI5AZ6BnSrm8Zy2EmnakMXzAsUGgzfbtDFdTEAJ4P4nd6gYEvjaydXAVMEJMylk1cCEP9p8T/+xUYd2Tb39xvHS48eZZ8Fzs8j99DRyHtHwnHyGqA2AkaVSOhSKaZ2596zY7Gp3TP1Xp5VLi/XHxSePGGfJw8PiVNLp+MYaLa3DS2YJEVfyzYhxeHB89NBKxeL5VqD0+cPxFNsOmnb67AANyZTO1YKE18uDRSfbGhm5/4u6oNgjSDQlL9MKbFJQgqBHQm/FvMoeAV37FC5CVnPWAM5h6V/+P3Fo9Brry/7fBF6ENBZBdNEupe2YcH7pn29nTOAuQ3oB1+uquEw3N/+813nY0V+kLTn8eT0Fi2v9q9tKN99zPiPtt/iOBiCIqqCafh6opG9f/99/BP1PcD2d9mWLH2XMJ2ybNVoqgPgcH3sBerRYf/PJ87HEfkR8mH/1XaB8cD4zyaoPO1fWy7CCC82GBuypJ+6/HXsr8l7WmNamnsY75NV8u7D7V92bjZf2eSvl5zb50ZztVt0fL+5hFAe78DpYuqnylk2v5a08CUAbz2RlJr9mgoEDdZPKmy6AuAvMQltKIWbjj7d/SQf9h8vBqz9AX4m56bd9UtFyGsvvrj+4YtduzmB9V/22Hr/b+sw4ejkquf/0NUZQjaoeuh9/wUAjKkJVpAPwTCMcft4x3y0RC5XzpEAHD+lx23zC+jqePTNY0RANo2/R3v01ur1tI1ueOeZWUqyNEtJ/3qz90kORFyiwBy2Sj40uDwUuSmT4xzvUr8fBQ6QoEbnf6QlGtrjp+AspvGS632bMFZQUPJ1m0t5AwjUBNz8ZPTD8eFt/z+h38Cpxl6ggSvtqPeUpVXrUpJRrrT1cgeA+XnXx1OrvTaShGPSe13YmTwS7pWZ1WOlvCqtRNimvhSFaUPGch9ujvtvsB8h3xDy3DcwCEbOQI/BFUzWWBpSBFv+9ma0WAxT/yqFheC8withY7S9eNC+FxfpLyQYWsdgaYTBNZRZES1S04zdaPzQ6zdqui48R4UsxIN9qSkgFbRWkTSmMaHz7sTzaPzWvCBDWUvf0/97qaKVwsw+7L0lK7LUFMIpwM4fABOyGSW0KHPWNCFjIozhsHBRBmS62lZD73eGnA0bH614wQDPM3OIltkKR/6tQdHV/mSNTTbZrUdLOrTt0lK7PzTgEjza7QY1tFcGqrYvOE+QMwFv7boh3QmZSqUbWza8rtd2yX70rRTnTbNKhad0vwJd0W13Bq+apqPdBa0U54LipUfHKVw/ExsSVwWTMbDElVWGP+HXbxQF0Rc/0obamFH2bemVoqowYxE6txxjrZe4l/2Fsm2Dhj8KEhkptcFSPqCyrXwqfxo8YUbxOcg9/CT7fa2MpewtTDIhCMEmaXRqohubltu4e+EH3qzstZLocw+/KcEXm4LSWim1yiP2lbVSstqfWnOQR0wtckl91mdMAKBu9ow7IVGjHx8Q6BntOysZo1mvl7tcam3smfvG7GdVzR81qqzNOpYZfqmjPd7xvvzJx30a6DQAoRRFOQaR3iN4bqGcBpWSXdjDQQCvP+FoUhHdjbOCurv8Sf1KkCDok2DhRmEMSJnShIeQ4iR8VZWPnLynGfDsbsS+cylFBjEtuOW4UWpsoAFDxkFI/chHx7g438tjrfuSlW3X2CsNLaHuFyUIhNtsFGsbvn/dzzNITYqJXFjqbykhEqV72YOYRXb/qnkWrzrgnU0oGpN4LP2yTxib98wea2ZRPirMS6wV1HxoclZUT7SfewMmg2t2OYTNTI1pU6JJbe8OWcELxryk8Q+eQJ5oRp6elH2Nwk5pcVGaJrp14VD6dalIs1hsgVMWv3AaWjckuhhREd7juDTlC6FmRx+AMEXFjJoxgYjt1SLlwvw11xvmjQAAoskRgsSTIw3xJcF5hGIO92z9N0pI0eqh6idNSQaDIrNq/Ft+iXVa1bUsShEvoMLVlMdaBOUUqRq2LNFpXdb8pvdJ83MIBcqIkvg9hr5HCgoT8/cIW4xLTPAexU7esGHGuhUpWaJHJwVtLz/TZtinsDAMUN9pRCxN90VjnCx6L9ekPIO2BjAvI+b4kJVkROd0HwmwaDvTOJtdOcUD4bpnmHCHOcKoSQCA26u88o2CtC40p67cpVwR2gn6iUpVDg6zXk1joLCsE3aPy1XTi2RP+SP2Y2rBe7kL9WOABbzl7jcwmaaay3fsElRFIyuTRHHtVGHKcd3TTOifLYSAkmHhXcClGaBELZWUOpCcC+4g4RG7S5ZFCBJkBQYYiLpLZ3gE9LhIYkTgBugktwQjkchvOTGbNqJy5mQpV7JwiIvkUOzCGQuZEi7DabVtXCcmakzvq2BAiGwqF9WUvlqVyHoT+Q7+U51QDnrX6Ly7S6sH+G0DOoIgdC3lyxKMOHbW9vt396PEzxzgKNcakv8oDgZZTmzGBzuwN4T5EI5XknbPBsDSYPa26fhQBxR8hKxCgQyL1ZTQwuu/Q/+M37dSBPaG/UnnGrzRev4stAxzMxDW9c7mMRtY6WUZLGXj4HztCek8rUleotxHL1Ma4BnmPNFG+/C4uQr+De40BQqOfrBU0+TckyD1suSQ7WlM0gc1fCalR9xNuxDZuVgIQJMDAcyqkg8C6xSh06KodnVjLDDh9kBX5YYdUJD9BXWXuaf6c/Ukd9Vm5lqkxN3u9OIlU+hoVK80+312s9IupHCEkfm8NosXKuwo9JIsLAMa+shticXCyqU/rHA39Q94OPxwwRMzRPqZe/fYxKTXhKyn+/tr2UZjdS0ySTWta2vWZmoSEVUBVBeL+Z3asHxShkiYVRIvAfG3D7b/BjfITgUOGsRHdaRU+t7DaJbUKbEI19mgt2dnr9zfluCLHyFXVzx9yoMH3LvH5SVHRxwcsLfHaMRgQK9Hs8nODrUalQocB02Tz0MQpFKEwwSDoKg363aiIvjsSXxByj4ZPqf1fUAHd7ewV8jL8JH9OnMdmNp59SRIDkvZQxSqrHCPs+ETU31AwKAz7wYj55bD6R8lJhxCQk+WjJMrJkr6UKm2MaCimR7RY807ijHvhW1NFxxaBVCZsQ+oldOT2jJ4K6d+791wo2GsRq5ixMyEXoYpf892+eKsCcZKmpZ5HLup6rk7jUNUiSfxkPxp0eV9xv57Euclw5g6iDCdZYxyt5vhxlULE7lg2VSZgcXFOXns0q1vzgvZP6Xh69eZHo8dc55Q+m0SOmKJe/XMT5L+At3poTehISN/yG8vGTBgkUgfTBiNoNSNBdupf1rzSuNa78ldXruaU4gyOpNTYqpEyDiB9l8AApAKgqvEnaxojVLAEiPyHrLYjDQ2A/oAjmyg3u34ujMxse/HNXKAP8tgay6Ufx5/mohySuY0VjdHsOHh1nW1Kv8GkaFkgm4QvRvtK8D1SvNKQ0V3v+BoTpUmEdsaEy4UQJEpUPMIRvLEW/8QsqrPHOjMORfWVhF2yGpzojOIqTBB0MEfmMisseybqpL48Ah1YtYXzAM/IUAtc9g5P2i9ndi7X5k1cCjbyUTiidnty0IvrQarOLWd5rQQrOPcKxp6nZCvHavBpTOMKrcS1zSaqkvDZbqJisep5W6XciiYrXGqrj9HYaFLPMa8aQgX8/VDK9lMlULhCRG0flw6EJjR273i9TYr5E8IvchYhK5/WEszTR6B5jhxJGUidEbrKF3yRGwkBdQWVXN2gmDqw4HYpCUNIslg9X+/SLff/Z2KkKNC7ET2AZo5kFcj39Z2Dytvc2wYyeOKYqiNri93kuZbd1RXhyFUXaHrcSWa3s6lGnOrPEyE42FXRu4ux0KtPnl1EE+Nu/COEIETm78Lyrkvm+lUcz5GjSNqNSsCs83pcTnIM5L9wFbrUtwWWyLQEHRrUJFLqqDOf6UnXRlaQMvQO8zJpRiUmEYJ/SVKt1UxmBmd7/ATh+7QkrHJ6SoSGNbDTDC6Wa4wcMXyDqTkRNPIoLaumvR+0svxCaumSpy7f1sDO3luHaxy03YiwVaNOdzh0ShgaHSSCHZ/LwIQWdiVjJSuO6ddh3oSc3iBPF0IX4JGJ9atB/Prhnc0pCr9T55ei9k1XZVo8kdlRTKAZtE7UQQjwBWUiK6YBNOkfanekKZ0cU4sG+inV1ccX8r73Y5gc0CICQSZJLl+A8kIInkDnAqMwM+Dk7UfCqZmOBHN5DR9+PfrI3E4rk74dHmDoTRAIcCESaMh9W0LZtHmlWoSMdDwdf1hBrotDz+IFjp5NK5EHannbVenkeKkZ3TRGvbri+dvSyKaMC5o5icrGUZbl0dzLq1rJ3Gdf5+U6d4gLu/K8fUWGDxpnau/u1aASLO1xWulUiJWo/Dtu5dmS5uqY+l0JIa8ql+0Bxe3px8EFsdDMU3bbueZx+paDkPFfWPiqgLDf0DRJywKcGbxeDhQHSrrxhvJALd3TgaLbhv5qJrJPZ8+swAeLeNwV9IPlmtfD4wJNGX5JDG926ak0Pld0ZVaV2AZzWjQBBJY1WqRM22ibkRomg+WAtCPnEjw/wxCAStND7+a4nVE7si86uIxk36IJtppLtqCvZp4uCJO+VMw3Z8nSjbknJyvuXfeIsPY2NU6fJ76P3lCPUOPheTLz/Pg2H0MWEg/Edp8G6nFXx5hAFvL03YzJgMDhIFoe0gYoRvJnk7GJcylUnU6+MM4iL4vWx+cL01Ll5izr7ZLR6k+TibdPJDKraY+KCjRHZ1XCEvfM+gNAMWTYrXWJjksu7zrYagumWdzN/k06Q1wq4dS6IboRG7REv5kKHnAW6T/Ac6jBJR8r0x9QCH5vRc0QMwZM0IgV29wjmTQfAZuDCA050bzTZCzL01UyFXM4iU1IOR7wia8ybXZDxoqxMtBiLfZPjUrP+NcP3fTs8nTwIx6R0qMWQh4V7mNLncA5gGUSmsTw/8+ziLJgY0RitoZGjHfvIc8IdHiJAsBgrPBs941df2zliOGMk63SIkYA6e4khDXAyFdx1hhxDYXewDFdwBjChfGZQQiIZxnWHiml93d6ixtmBFwfs9llczjAidbvwfgM+XiI65z+5WzKPG/UAvhxLJfswaC5VxHAShWpOiiJ5YigzNKz6OJ9z3Vbc/G8Eq+GQAfPxAQKfFP1PLPOV+ZNWAb9768/NrJZ+3ceuN9Xhk/ozeXIFOYQ74jGQ5EDvZVEIxR46Aw6rXU2MjkSNaF5q0cozUl93lkKvXoHiU/m87dvsYxpJV7AVMt8UywG5NbxHbqEVVjQGSO3tn4E1hR9aVzdc6oydMtZsyQ5U4AvUDG1RqlosYsug1OqEOyo7+f/sY6EjjUHI/ckbpuwjO3RvUNigxJlzyvswNdbLONPVTUKBiRqRkN7Gl88jFMsf9Yc4Q7nK5+4yFp4nrKAIuHkH19tfli1/INEebDxPZAyBY0REbca4iB309fLMcgt4al8DyAGOMvpnsq4e/96uJvmQAF52mhx343D8NEKiSvkzWocBpmCmO2577sXn4+sdNssrvuzj12RYF7v7+xDp4/H/x5JYRnyFVg3yDXB0hbEYtYZsXZ6+Tzj5B/5o7pS9ZNvOe/7F/6NRPn/qZ/19/5x76I6/O06aZMcPbYaWVpfbYeSYikvDYka3A6/8mcni/juOHYXJ82IJOHQNTshclkHHkjBwFUmnVgdH5ZNwSL5h2HMKaVNiSpZSnC6P47hmUacDZ+q5RDlQcBkMHfT/RXiu5ujv9ro7DBmyf/pi/n/PvPU1EjVzXtxvEHDMFHCN1+8WEPIZy/ZXPr4uEb8yen/14SNl8wfKHHXYf4Uq7WlQa2DbDZLRN3MJLGlMwoc7HLEtgAC0MV1cD6xx/taANUy7TEAbBTALYA2AzA2AAbBWAQADsGYF4ARgHQ4DI2XUYGqouhuhGqlwF46ZTQLSnpJWWpJNhtz0pJSOyVdtiDuQ3vi1wWAbYzWzKh1ZHL1MtL27hb7/dpHu4STkXRcxVP3Lpy3l/uHg5+bbbtMvrGeKXLkg5VbIAFcu/pAOQBqE8y+SHZuktgA/tLOHVjpIx5fBZAIRVP+7NVE4BGgIX9/brICUUua8bIEQ4/ycRKAuVURh/9+ftt7iQ7n1C6MwlQkUQ8VgvA2T2OSLFzfVLrUcxf7Zb/tZJ2X9w7f1xDNfnZAFw5+ubxd74DqMsaLXbhWWnfOsIAHV2WDvDzqADbW4Aias6nVhYSwmnoJMdbjEniACkaQJygUBoMVc2kf6YUg4sZXQHYWwlR5Lw8meZkE90XGSNOTV78ayElnKr9+QfYVzEaAOUC5trD53geTlnYOxMDcCjsyoPveCt3J0WgNyg2IQL1QT8nMQ4wd+JbyfQ3xbelY7T2eZlQBsaAtnAO6kIH7EFh1q/IhzzocXvAzONKBbbh/fgmcmsTNucmWTjWoTR4ktnG0zYSrGBtW0pGsBRMmVADg516EtoVKxajJ9MHBB6Wxu2PcUG28ACYGNo7oeDg+tYxqUSWB1+UTiJlU/xBa2lrRQl1pUiPZEIf+ww7qh7FClASWrOvxB+iP7yoKCHF6VuPJDn1+8n5bX+MlT9Nay4ET/EewW43xTqwCrCwFhYJ3zwFFG6GPe/WlzCGxZvx+nwffV9PF/xu2GOrFK+pg3kf/a/7zoWkjoG0ZkE1eenBTOHT2gx7JWsImF99ktotYmtHVRCqvmVZuZO+LTBd774tslnhGu2nPUsX2NJW0DRGqCiUmLQw7smGUvaBf8ABoXYInqH6wafl2Rqq+toHYsc6Q7v7MIVKR5zG82fK11uRVnPrmsmhxLVv5oR+Hqb7LVW8S1meps/6oa6EfeO1LfKPs06LDL2nUWQv9C8nJr7fO1HPvDA8QLpjYp7HOHtnN0fewE04vhqi0NRzA6+7Zk4m3NgWul/WtS28X/f9KIsJmoEbaIBxuL9lTN2DK9Xoded4n+SnKbH22JFuzywXxqWUkTEPKo7hDGjMOMsUU+KYVI8wStiz3j7whza7EhXtdAZZVYFhzj2+RmGNenqtundqMXQD7xi5jBMZvADG+AseJVszm86spGmNDrj48Q19zvjto68sTuJOJsEFh7PAb5IzVlImUY6AcXg68lrUdFg/FXwWLPrOKNRmRtaNZjZfUxqoyvz8MOaRX9ptNT7A2HkWJ4IPfG9+c83qdid+sEDbqtkp9iLg3qeNkmZTFMmfDBCe9u75dmCy0dxL1TCZxDM3+7wjqAfJY3TGkw5SzyZjtmQ4XnDjvAwLPaXulUTjZW2B9NLVqFhpvRjYZVr5Mc50qaVHfaDCIB3dJeh2nQ2/3eizhSJelPw/3eYgzu94z8sduSbYdJ3g1nM5Ir6glNYXfTxd+ATgBfODGCScEJBnTAPtOhUwL5TMOV73z9FUpX1YLVDZIETHguEC2oL5hCgqWEZAprcYkNLvaGQ9uYGLpzeiO6sQ/XcTkxu76fUY5cvmgp0M0UjA9dEyTxtWM72LUSFsS8boEAlZp6JZdp0T0nSor9TEWHukHojlY2QcHTpYtDAoNg0X8l40Y2UEO1LbUunBCnuMMnf4RRs3TG8dKns3jbTjJzSMjVIs+9iWQoTXu2hXKGPe05VksLWIJV3DqC93s66uqwPnEEHXBWUfac4gLL4Y3SaaKgxbMU3rqG2yYdmZnEXLUuidgnwymc2GC508st5jHPbRyC5CttU/SVtgrWuXVGMEauRd8SOLhVsjuBm8XV6UCgGBK2WJFLB4Wu5glt5+tKE5LQYfx5Qe370BYnbDgD2YlXMZyouQA+C58iywmcwKMs1xIugGQ+flxDu6KKOmvirHXCwnyoSntDKG8sJxvyzFi7Abmp6kMsWRWZJpHszHoJS6iMuF03ZChwxmAOhhMi9IpZjQtFvqqc8lPK3kU9wDiLvLSQZvAzaTCff47+VthjjMnix6rXEu2nT7SfDBZLkVzidc0O7k9qzJF+qcUV/GPn0tJoHVUbcbS1joDCOOPTwIb8ZJph0ucOeNr1LK1YzWgucaMOQ/FhdQQ/P0JgUq5SoCQ0sRI3HgJGx8U4v1eI5jnYbTm8GNErOXn2MxWW2qRHssBSADpQZrbubiuOMSCqJZXOLavZw1UWkA8ZoCcA2AB4Uep4BHwzve+EAdunErYec2Zyk156whEJyclcamJZaPZs9WeUrRXDXZMCLJdE9O9vWSfCuY/Q9iPKjUNzKGuMpIAyygrIXlKsQQy0bVl6ma2RjW59kyh244xrBG37GUcHfEdPYXAxTSXFhnREcgKkIhkq9ZNxUVF1SLTX1rGMUZbvGagr7qo4RNSkJDIJ8imhdu7PozqmsSiEv9dQ97p7ldl7zstTx+k8I+w4wQTXsU8n4DEHUV2t1iDT2KHbE+fSe7+JVwizd5/6Gea7AngsYNlusHKuQ+eQGDiyDi2IdMtiox8X60pysU7oOMckpckIgsE5+ibK5JKjheXVNOGSFM0gGEgBIgBRq0sH58YVP55KVDaoCk9FmXVT7r4bvblRVrB5vZMaQqQBsQh17oB5jSZ61WIZDozJEU4SAqgcxAnwurENt2jE7JAiCu84tek7agjiDRi21QGrSCWplQkgcT1LV3s1QoJzvijqZSeYs2sXQtGAI6gjlAob24LOSAQaCxc2N7gpvo25kg2Y78el9W9wxfUw82klvOuzEKAkchDd1JfRn0j9EohbcBw/vW81tKDVFCnULKkN9maeuK8mdAgeg+AJ4H7Kv1fcDLdRQvpvAAK5cQUW/g8i6H072HT/jgkvCCOlX1lS2qg4azyvPe5sKnLjJNuqGgI4UPOEAXtd1+2AyYEjGFk1SMQsz4K6/+IqY05lU+rwSwZwpu0hwT8Ed+Vo9kOQP5bnryUHERGpSF0NJmmDTS4YeYRjqbZUEzl4p84J892+dDtiyAQO5IAckcEp9mVKzilh7QYLdlONhleecp2TKpGUtVFjnNhuODdFZ/WI8Ath987LsyVqsdRP/J19SFCz69XTm/M6HbLMZkJkI2Cr+r5khRcanvUVdBG5uTgfzLZOmi9/uJqMlDcAdffunNyEeHs5LXmYWOXLoSz2v64VeXJ9O8xhW/ezl97kpbFDIdo2wRQNqL1aSkMspjs4xeFlWZM+fJkZmlwDC029CbWqTlHl9fPPkNmei0kHIQgxBoeIEm9oyTRDtFFHKD/9jCrQvTy3l2PSlpKBi5Jr8vwkK80Run9uyzIjuIVRvp0bHVqirzB2xPadwds6nSZLM8zthl9mkq2fXqn3HOHRLWxPBuP/h+7Pw8oGsxlW5m3+4gNHCnLzjblfybEO64p38+Z9V++d9iGbR7Hs/+/gdOCsuVaTAhwWsUPgBJB+RdloHFZJbwjAIsHntq459/6eAak3ivre6WFB7sEGRm1zIc+2TXGEIHX2w8ES6kFoB6APLJAdxH+fuYbE/fywpL/q6Wc+vBTiBwAJwBArXZ42hlun3HEw2Z41GIPJg34Sq2Zpl1Hy/maMTJLk6xLU0sHuzNKX0UkD2dKk/y0NtUjVhYuRJ39uoKs2dQLhFdj22H3Khi3c4ZFTFmdNhmLL2xCdAp+LQftB9RtOvJgZdbjGnYWf/hCkFQmfz704FX/ADTQiParU3N3PgyMKH52zk+6O/akre+J++VWvHk9mDW+cazPpvfe87MjyXf70t125ba/Qijnx1j672Rvi3IkAXzDPtcfpDXkoXTg6KzQJPpyfRxUWXAHj14cmgkoxZXXIIbDpHcskBDP50W6IAao6mfIqtXtPfbMZ/bSlap9ScA3yet4L3aa+XKh+kdL/ZFl09zx1Nh+pF1Ii3ECkkRWnf4qXFPffVxJxFLPPqpUf/sDJwY2da1PE52BK9xnKDBFKlOlOZEsW5BQGyHa+cGPJH2eHvwqgCFykHFqBnVanZYx2dAdwQrGWzq8oOaVwUQEIl1TYVuR9hODic6ghcBQR67YCeMq7UIcC0LqFPgXajdCWNdN4GnQ3vniKAO9mK7k6ysAFFIEFwFJ/GtuC/uiJPDJZWSaQa1bb74OpV0BXCY+Cd6155lIZh3d2/h7AnhSYP9APfSYb3C0OHxgsEfPKrlh3OuJyjl2XSy7BNkgf0XK6+dp38XDcOVgFcEOjGCaUDrtjwNJMCW8yfpQScsfV7l4+yekpmTYNIET47zpps9mP5XixDNkkep5Dl3goN7R81H+2A/RRXJr2xE+MUtA2wE5MbG4CfGuXUrT23cEcha+rb7gqiji732nXb38OnBYQc3nAYwUYIr5wyAzWylOKG6c9V66JURuWJlvbftQ3o8nS5nxxfp6KEO0eygSA2pDrWgevRsB74/O011qRCVooBqUTPfali8dV/Moo3A0poB14Vjo+wx7kSuAK0LsIHUdtCXcJrSdddtfuSEGaKBzM+Vt9YgpIMfd+7Xv/XrT7E0XR3cbx932+Mn3+UeTyi++L6Z6pbWB3DTUbFCD5crgGH5zWQB5spspuPoLt7Z7+HwBbyvaZjpxbCkybV9pohsOpet4ZE/CtiOBeiIP9tx7gv3R71YTSU5jqUUf3h1DglVwAPQEIUeL1spP8ZhZiiEfzTrLFWTZ0fyEI7wlq8/UyAgjQ7nbPL0/gDW+JETCPJtwkEjX8wj37l8tQeA+LLKSaX2g5Or8NhTnGa+HGVVi1cKebyCxuPrn8Ifut7s0Pp6nC/sBfCnC+A+bcWsVo7TJCASCg/g3ajjAGb2HRtYxQ+4eO2KaQHFknLKVZGjIovK6wL/QtWcGMnHII3GjzQkeylIz7u6y2X03mofn+vuZLz+bh20zBhNUUGPuYNdcvFxXds+OJ9+1f3z9aL+olEmPCsdFHcRsFKGsoZKF3WuVXh5lgW1MvdZVrbWwQYiuvAt68mHUffvJ71Q9qLqRdFH1rxlITiBHVhke+RjqyKcwVLTiv6XHvgD3+le4NRA98JjUf9P16ViRVJW5ZDV77IKbfQ5cuJ2E16JLVhDgxaNeP8+oWQ2LZj2JovIqlzORHEhnzfo3wQqd1w6Czg0xz3ShqbbkJfOm3zJWEs3qXd/6BeXUc5YS3Oo0sxZLaCog08HzaNxRRFF4RIwiTSqmECRgYa6GEyGS12+xl69jFxTjkS4ReSIlGDJVzSBpqWyO4si/LCefk4ZyhBhzcmUoCNBE7lFtVTnG3pXC/WgqX5Ki6U6EJM4hFP4cKA2fjfMNDcdimk4jEhEfUXz6JkU9XvO3w/lThPqo0T5BElURONoHqVTuq9NU3J0cLJZbBlgdOxw7NM7mk7LaDP96ZX/Ok8qI+8qMTCiTRwmlcsTXYu5Z/CXH4hzoW3wYJKvPU5Z4P/8gr+UcU+gA/7Uj7CLHh0ni3//VbdSvkVPP9bP4MWT/OB34BvA+5ISOAqcBr+aTunH0f9KDcI/Gj8fGom/rLf4nzN+VSD09Ck8HscqfQHs66POsoBZMBdgvgC7j5Q129U5cN7p9IT48LKkTBllCBBQhmARvEEQmQYaaCiBDjrooGPpeENH+vTRR1/vpBljAgAAAAAAAACgREREREREpM4jjUISQdrNwVtgIk5tz7Y147jAFk1OcspUmi/VEbfsK3FMvEXMcdNlb8lrtlNrhPYBJ59XuQstb101V+2tFm/JKrVqc9+8zyPJw+Fj8ZCYmId2yYJKx4izeGg99CXPNieTt9zzhq94bn9hyTyLaL6JIqIsVIGHNhJJm5qL9tsHL5rBwn+A/LKy/Pyy/Pz85f8hU9cH5ucbd/XrYXQ71CJno5UbEgopKAit0NDTY0TP6hnS16dP325lVU2rdJtc+972YftkeqOSp9O0aYkk5mg+3Ms/rjjRqNGafLVPHS8ohKPWorLQQz1l6plTpZ52uDtejWvRMGVKw5SGhsZuryurqicP1CZtduLCLuxTB8dpvjP1Pnyot49md7KXKnX2u+P1Q5j90GYtajGjZUZLy8xuRFlMlhRVOn702tra2mbNmpm/rd05S8qWfy7nWaoqq+YqapuZi/a97cP2yas/Z9+Wyx+yvLw8VZ5KladS8jssT6VSqfLyctXgtOxNE20fnfbnBLS4BQAAAAAAAAAAAGDBw9szdy2EyqrausaW4pY+sy6GY8RbZGRkZGRkVuahfOauhVBZVVvXuEXV06yqqlKPfIsmzb7DXtdCVW1dY0txS8aLGc/U+GPqMHUtTBhUqbausUWMLVmuvqVFPKu4U7EoFaXS2se25bJ72/33+YXzsLgMxjAMwzAMwzC7vffdT/9Hd1yYZS5mcI7jOI7jOG65ixuIEEIIIYQQQgghtOhCb3qyKf2jLL365UIIIYQQQgghhBBCyJKLDJ3YrI1H22Fnx44dO2tn2Nuzt/ZGmkaj0Wg0Gm1pD6dR+zstrdUaDIPBYDAYDAZjGTPY1cAbAAAAAAAAAAAAAIAFLmA4O3O221c/s5si19hUKIVzmVTSKXzaKXVMtbxpX206Zp4n8PvVq7kuLBaLtZtvnL+OxWSOLiX/9cwwRAWeenjt5B33+nUU/35MiWGq5U378HnCfFzxJowzcAy1CwAAAAAAAAAAAAAAACxcMEQIIYQQYsVwjrPOw2OQiIiIiGjpoqFKKaWUWnWpYcYYY4wxawazqFudwXE4HM5uGFUmY38/kefBS+LjKL4nLzwej7dbCpU978+vo/itn/qj+fsQ9dzk+1iXmwNsEormLiUYLcocH3fyY6qbco2FmWD4+7Q9f4SGaCocV1Ao3MIrJnk/TlQQ+/QiEolEIpFIJBKJT8T8gszFmXSsPqJU2tJJmYSN543iOOJMR8knKpe3PKl8dshSoDiOeMvH9Ioy7NwLBEEQBP0Oghaalj3zsWixv1EoSr8S/DgK/VujGz3nqIcvCIIgCLLIhQxFoVjFpRgYwzAMw7DFHq6PHo/egxAEQRAEQRBLXMRQVSqVSqVSrWqmUehsGlka2TSyaWRPo+2sZLPi5Db7cOOEXJVuf/sNOQwJo4XNfQErHB0Z65iF9r5kRyv8c1RSxtqwbT9KN4CJ8MsTgbC5iJyk4oEgo7h6gN49roKBABomjIa6gXkYtj8WkRk1giT3pqifZxwKM8+jSkaIoc6B4jhrbgmQRU4Cabe3kMcd5pIo3GkpbPZcUIVJz86mUfcGgekmUCAUgmgcBEFuTCgmjweHqVPJo868YpjoY+IoQx8IMDarEiigJ5Te9pbE1FshhYM+MFWY/0l5aUx89RgLH1cLntRueMRQuI2wc2ElRTswYbTZELugdHHDG6657hoNXdVvE5j7UhcN3ahIP7WK5DnvOgl2esMf8TJO6JW+iBwNeJAg7pb5kVEBmpKYiipcKC8inIvhgzGIrbvjnid/8xt4xCg+IRZDUJ8+QjVcgY2giI1d3oirIHmSWjdmhruFMyWGraKl6xO49RBmsITc+DlpHw3UKCPRtnuxjp5k94oWCLQE9beNO3gYk2M7Ksw1tO2peOCq1WI3dLHnBs91MXAbkhyqt3zDu+7djilYaO5MqDCbwtxKx8lNMMYRB/AuKa0rzOn2Gsm8Vj++Um07Hl4ypmaVti8WKjl42UCOw+SACdaZtL1LqcybcDBS265xpQhFszQjZz15KlPNph+tOIaTpJ04hEDQmZ3T3askjOYC/oLp2VrBLIhD6KLiAZFoWTiZi2GWx5lRhRqY0lVWVpynk51hkZra+coQ2nFwbYvJ/nTo9WEJlIwWx+o1ZjDeK+yiIBwNJSe+s7SEEGY7jbdk0wMzTSxZZho1X2itcJh4LwpXJOmBDYHU1h6soK6kiawaJZhYk+oQslk3grloNqHNz29cY/YdQKHb1OHa9NbYzqq4F9Mdvhp3ABaCBc1E7nLZPgEc/qnlb+S5xNNdVZcTDgI7SWMvF1TZSShYg6Qyq5Jc5V4xS2GEGQVLEGVZusdStGGdiqLWwQbYgs2ygDNgaB7gDz0TijdAR/WSggRJYb4CO0F0gZxfBvf5hxQbcweg0xa2yVqrKOawpDS3kwA+cUeyh5DqgAZlGcALzVMnMpxzDfBTUG+dlCTYSq3i6dIg3Ji/Lmuhi7LRhEsFSmbTYPosOCMerpeIFIFlYphApkZc1hhuarYYl80W04kwcX1L1R2wrkJVw2UJ2+nwsfnbHI1xZsvhWlVPyQ7DpUD/XlygV0Uyv9KRdTxBZAfeqftmYTx2iIHZHy7G2ISB/J4FylN53YQhTFOVjhVg6pd9LKV4s+Uwbgr0+eXslykGy9HPFFxlcv8OOKc9cHVVY+d5UXC/qfJHeWmzcxVShhUIgkqRB84rF5C9U39A20DRQBbrjxcWtPR2eLw1cRRgBjnPHN/wmgpfR34M5x4N3JHyZ2s0FolfKaWvBNU9C3V4QeNK8XPfuB4gfnPltEaVjqOY8Y/APTk+hisH8WHXvev+4/eSx7O0npBQVtLznqz/wfpEV+wXrrHSDLjQL5WGX39pN0YIplfAWH+/SX1S93fhYTMAQoR18qdVQbFQnIfeSzfrkScospWifyW9469YT3HA/8G1MiT4ZNgKuEeZNVAGa8F9XuvUjsGXnxT+ulzU4bNe3Xp8MSfAd32+YloqG9zop34/BFmwJFGIYKEFWhsmD9nVV+Z/9Qx3XYQbbpp3yx23RYpyV518990TLcaiZfWflpCRU1BSYUiSOk00cHzPNNPih9Y8vkAoEkukMrni3L1WpdZoARCCERTDCZK69O0yrE5vMJrMFusUMqnSpMs4PPqWKUs2FjYOLh4+ASERMcmFbvCETI5ceeQUlFTUZzjCePVDS0fPwChfgUImRcyKWVjZ2Dk4lXBx3wnfKlOu4j7RH1Wq1ahVp16DRk2atWjVpl2HTl2AS4EgMAQKgyOQKDQGi8MTiCQyhUqjM5gsNofL4wuEIrFEKpMrlCq1RqvTG4wms8VqszucnF1c3dw9EBTDCZJGZzBZbA6XxxcIRWKJVCZXKFVqjVanNwDKaDJbrDa7w+lye7wAIkwo40IqLUWuZC9fWUzMLKxs7BycXNy488SDVzzzwmve8JYP+JCPjj2PJ9PZfLFcrTfbIIziJM3yoqzqpt3tD8fT+XK93R/P1/vz/f39CwRD4Ug0Fk8kU+lMNpcvFEvlSrVWbzRb7U631x8MR+PJdDZfLFfrzXa3PxxP58v1dn98zer5en++gWAoHInG4olkKp3J5vKFYqlcqdbqDdBRBjtds/uD4Wg8mcLIAviy/Gv8ar3Z7vaH4+ksDP3vers/np5fXt/eP5I0y1VqjV6ha1HW6o1mq93p9vqD4Wg8mc7mi+Vqvdnu9odQHU/ny/V2fzxf7883xJRLbX3Mtc/tyg80RDdMy3Zcbo/X5+fy+AKhSCyRyuQKpUqt0QIgBCMohhMkRTOsTm8wmswWq83ucLrcHi/iOC5AQXQwCoMjkKDjfNoMFocnwI6jNHJNl2NzuDy+QCgSS6QyuQJ9nB21Bn6c2tFktgggx939n+TT5fZ4AUAQGAKFwRFIFBqDxeEJRBKZQi0Wjc5gstgcLo8vEIrEEqlMrlCq1BqtTm8wmswWq83ucHJ2cXVz95BQzoDBFFGO65rq05kyuUKpUqOU07inwmb/e93uch/PC1TOoS6kYkgbqpz/GgUvDSg6MpiExeZw+fhdzw/CKE7SLC/Kqm5aABEmlHEhlTa264dxmpd124/zup/3+/0BIAQjKIYTJEUzLMcLoiQrqqYbpmU7rucHYRQnaZYXZVU3bdcP4zQv67Yf53U/LwBCMIJiOEFSNMNyvCBKsqJqumFatuN6fhBGcZJmeVFWddN2/TBO87Ju+3E6X663+4NQxoXUdEOGNcqlg4MwihMUa9ycBvzMaD+AKGve0jQvwp+5fEBiUfPI6jHsyyG8IQUtaI2alVq169QtMces8OLhvnGSZjBJ/W+lqrppAUSYUMaFVNrYrh/GaV7WbT/O637e7/cHgBCMoBhOkBTNsBwviJKsqJpumJbtuJ4fhFGcpFlelFXdtF0/jNO8rNt+nNf9vAAIwQiK4QRJ0QzL8YIoyYqq6YZp2Y7r+UEYxUma5UVZ1U3b9cM4zcu67cfpfLne7g9CGRdS0w3Tsh3X84MwipM0y4uyqpu26wdQ4zQv67Yf53U/b6FYKleqtXqj2Wp3ur27dECUZAVV0w3Tsh3Xcz0/CKM4SbO8KKu6aQFEmFDGhVTa2K4fxmle1m0/zut+3u/3B4AQjKAYTpAUzbAcL4iSrKiabpiW7bieH4RRnKRZXpRV3bRdP4zTvKzbfpzX/bwACMEIiuEESdEMy/GCKMmKqumGadmO6/lBGMVJmuVFWdVN2/XDOM3Luu3H6Xy53u4PBMVwgqTRGUwWm8Pl8QVCkVgilckVSpVao9XpDYAymswWq83ucLrcHi8gsah5ZPXsdw4cvjax7OpwGpfb4/Xzdz0/CKM4SbO8KKu6aQFEmFDGhVTa2K4fxmle1m0/zut+3u/3B4AQjKAYTpAUzbAcL4iSrKiabpiW7bieH4RRnKRZXpRV3bRdP4zTvKzbfpzX/bwACMEIiuEESdEMy/GCKMmKqumGadmO6/lBGMVJmuVFWdVN2/XDOM3Luu3H6Xy53u4PQhkXUtMN07Id1/ODMIqTNMuLsqqbtusHUNj0qAUzl/97fz/O635eQGJR88jqWVPm+ITRaPq+abXavPjRbPHyZ6BnMNVPbMf1eHv1y+fv5v5TXpefC4QisUQqkyuUKrVGC4AQjKAYTpAUzbA6vaH//SazxWqzO5wut8fr8/MHAILAECgMHv0JEoXGYHF4ApFEplBpdAaTlS5nMvz3l1NC/AUvW4b7lSCZ8huRWCKVyRVKlVqj1ekNRpPZYrXZHU6X2+MFAEFgCBQGRyBRaAwWhycQSWQKlUZnMFlsDpfH7xgIRWKJVCZXKFVqjVanNxhNZovVZnc4Obu4url7ICiGEySNzmCy2Bwujy8QisQSqUyuUKrUGq1ObwCUsYenJ2is1EHeTXMCiDChCB6poETb/wXBuks6IJHK5AqlCh1dPX0DQyMujy8QisQSqUyuUKrUGi0AQjCCYjhBUjTD6vQGo8lssdrsDqfL7fH6/PwBgCAwBAqDI5AoNAaLwxOIJDKFSqMzmCw2h8vjC4QisUQqkyuUKrVGq9MbjCazxWqzO5wut8cLgBCMoBhOkBTNsBwviJKsqJpumJbtuJ4fhFGcpFlelFXdtF0/jNO8rNt+nM6X6+3+IJRxITXdMC3bcT0/CKM4SbO8KKu6abt+ADVO87Ju+3Fe9/MCEouaR1bP/lCRNy2k0mNGZpKVnZObL38KUcaFVNqUtqqbtuuHcZoXYsq5X5vtbn84Ooqr9Pu3wa27vHle+Mq80pAB/XzkxG5Oky+73qmtreKVfRwbXvLQUXBndlooe6r9y7kxTPgtdpdfZe1PsIWizc5mG3cBm2APJmsKDDbNB3O3sB4THKuJ5XWwgWLN00O4z651l7Cl3hZDUTjy9q719HCyapdmrDwZ4ZDNyhX54zpiyjNqTr2JrBE3UcN9SZHh/3CI/g38fzjdcWp1LvYOud62M7e+vJKX3590DNNHjFo0n4sxjRAVheLXhYkhvlnGc2Mpwk4nnRk5k8xIk0C+EyQI5teF3X/eEoqgroLV1aSzQcqkUP/VS5p6XeHoJUPnF2Xu9GhIxsyMZowZwXR6zALYDONFnYaZCVlmNxPYhZxsYG1NZhxl5EwGt1BZVgVbKNd4/iUb84zrTbYjiNuPpmfpzja9mDp0ejl1HDf8cqfePdYKVWDx3K9XTogE0c8gmFBg3BGuVNrYvF7CFBh3hCuVNvbr9zVtLvdzpgpnPvdSCAXGHeFKpc2TzbIhXOHuFQOhwLgjXKm0sXltwoQC445wpdLG5nUIEwqMO8KVShub1yVMKDDuCFcqbWxeH2FCgXFHpFK4lTm1sIO+m1j6i+eB0krYvqMUjk3a2rooZB0AImIjmFBg3BGuVNrYvDJhQoHxn85f38fvK2GFLG4YY4wJIYQQMjI3hBBCCCGUUkrpV+o/917//yBwY4sId3GilFIKAAAwmBMAAAAAYIwxxsZ0xhhjjDFG+bu7u7u7u7s7AAAAAAAASZIkSZKkJEmSJEkSmqaUUkoppZRSSimVUkoppZRSSimltNZa6ycd84xWdpJJzU4zh9+zmKLjikVrrfVmzmhMKDDu2LwuYUKBcUe4Umljl2ItAAAAAFN5ELhIDE5nozSZSnTWBxP6utTKn3cteRcF2giMO+/E31t1OWRFv+9YpNJmFvLKhAkFxh3hSqWNzasQfit/9WrAutk3o1yXelcIAMBBcUe4Umlj85YOAAAAAAB4dgBMKm2ifaa7+Mpsq+18oYSZHRPMymNXD0u+wxzx3JiRIAbbSblVrwEbsH9P1Ey5mMpYIIfpMQve69OCazH+QXrfhvIkuvZqVQilgMfvHgpYmm8GkJHLuiugT03SzpPaNNWTQex71zGUcYah34ekD3Mycd2PYUBilJoa01pATKCbGMeIQSLxUhQHJw2T9Tw9RuC/RQr7dk8W55jIZqWZNfP8d/cPmfCiQXSh61zR3rDx6mPGYDVHCzGYdY/7eJBK7Y06FsblGoY/CiadWXKZzkqlc6XORV55DHcuqk0543ZVtQ3J37tt/jk2AAAAsC7ArtUAAABgc0rPtjQ8VgMAAAAAAAAAHAATCow7wpVKG5tXIUwoMO4IVyptbF6VMKHAuCNcqbSxeQVhQoFxR7hSaWPzaoQJBcYd4Uqljc2rEyYUGHeEK5U2Nq+HMKHAuCNcqbSxeQ3ChALjjnCl0sbm9RImFBh3hCuVNjavSZhQYNwRrlTa2LwWYUKBcUe4Umlj89qECQXGHeFKpY3N6xAmFBh3fhM/Ifz5wxRwlYuTMcZYa6211q5rAgAAAAAAAAAAAAAAYIwxxhhjjDHGGGMHjQmVSmd6mVBg3BGuVNrYvCZhQoFxR7hSaWPjcxFv8a0g4Q18AwzLiWvLZXd75VIAf894zAucqqGDdmVPPFAFKhWR0t52IQ+lm7Q1pdV97FlN0fWWS0raD4dXtYZ9S0sjXHxUPnE3v2aEd+wKmgcttKVX7LvD15t38UDhenMS1k+/E6F7m18QQ5Uk4yIKZFVTwaxofkE8NCi2cFNHeFIVDbKwYujQZiu/b+uusIjrlYCCtcGCRQAzDtZeBWQ09AvXJFtVxrF3wyFS3lLDJ8ykGkfEpi3yV5meLFcICze9FclbefDZZg0A2RqDXAc2FuFJi7aLwXiIaEfHhALjjnCl0sbmlQkTCow7wpVKG5tXIUwoMO4IVyptbF6VMKHAuCNcqbSxeQVhQoFxR7hSaWPzaoQJBcYd4Uqljc2rEyYUGHeEK5U2Nq+HMKHAuCNcqbSxeQ3ChALjjnCl0sbm9RImFBh3hCuVNjavSZhQYNwRrlTa2LwWYUKBcUe4Umlj89qECQXGHeEm+3b/xq5ddgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABg447Pu9G7/JrPJ0Vyf/dhnrjfhzOddbIuOwAAAAAcwPOJ/7nK+81roBOs6SzzGfcsV3tkkjIaCz8KzrWCRWxDSFIH7Cp1YfO94zN0C3RIc2jH8kK+Pp1KMW9S29K1qcRhwq8l/R0abvvcsU0ncUiA1tYTtIPoSeV8l87QZbeYHrgUYdVnjaouHTSuB2crVdbJ2SquxqlaCkWGnyGal5/cZNKfis1KjXrWbCH06aDHpXG+cpV3zvmqVR3pw3XaZaIscItxRmiVjqCJa38UqukgxhOhtXQa2t6faGU+Q2Yq3SOZdZE4LckGmjhIMt6Wc2QOZ2WWk5lwB7446XaH5jMspmAO1sIcDnxx6KgDTnHDWuAWzh4BAAAADtLWiAkFJlypdKZCmFBg3BGuVNrYvCphQoFxR7hSaWPzCsKEAhOuVDpTI0woMO64ylv7xbrFAgAAAAAAAGA8ugMAAAAAAAAAAAAAAByU34EJQDGCpGiG5XghdRsjAMUIkqIZluOF1B2MAJQgKZpheSF1FyMAxXCCpGiG5XghdR+gGEFSNMNy/C5cBkyECQXGHeFKpY3NKxNhd/zvP9Q7zUR8b/r2OBEKvpV9+KaPWB3ek1SUNvbu+yZzfOc56ldX5deKn3HfHZtT3x4RkvgOhTPfMaZ7nrTSxg4bv5+iQgoyXGWt38h/47AE/p+TFUJJsYiSSIqBa5KfUXEEro9QNuWzYdCmUjmDoWl3LrKSKkpWdHpfbQE4rLYIAlZb0NgEWpdoDCY0aBL+QF6O/N4Q9rHnV5biUBT/uXlq4i0eX6g6b17+FnNVZmib1yJMKLC8C48uErKycqabzuf35oTEq49VWxignX2UfD4TobaVUAPnM96ONwO3xWm0/BzkeOa5xtp+QWCRQOQ42l3Q+aQxZX3zBTpWYs6Q6fkaDlDRpxycmGs09cYTy+k85gjszqI2nwrcrIP51IE6OP0u9DjkiKNVLlp9lYC5yuaEbWUCMtHpO/Vi8CZZf0/Uxl4qV09k3izJyAw7G9OIaGqSLhOIdAVLH7XTe0YEEwqMO8KVShubVydMKDDuCFeqTS8sQt3w31cYWhuld2KB3rDSMEbUW1T6YOiVNE74/ZZje7D3hgCZzvqQLx84sUG35XLtG8hhv2yuq7xo+XmtmHrB3UQ5r0OYUGB8oPMH7eTvbgkV1idVUubHnQjQ/Acy6+eN28J4/hncOUfKH73Un81AN/0C+PWTmbz7qQLhf7ja64Xf3yeXdlsVfVTRLHr/LjnHCEAxnCApmmG5+B4CUAwn9nK9xn9gJAhXKm1sXoHCVeFKteupL/Vq7U7VlnhoBsTHn+nl5YuG6ls2+4MvAMimGQCi/6T7xgBMqW6w1DMtOGIyAUAQEwpAJ/vWH6MyCzd3y8V8kdE/+PteCgkD/BsI6W2YW/lgSRPcufrugjlyMeLAPQ88OQOdbi+w0e4K5JVl+DKC23A0DHq2wdIpt4WbN34xwd3slZu+6dDm4DV5gjsKIsNScDdLrZaW7K37MZGC1dSLxge1qmXQOFNr03oiv5jcYplcvM4EIrvdsa9OWgWKGDduHKBTrTGHc4R8caPzj0Cr65NVq3ZB+V8pPIGvLzT9eSmfB+VM0/NP+f5/B/lf1lY/bHR8X5+gf+Hzv8DODxxZeWIJeKbVa6gjCBLwSqdwyjpiBTzT6lnRkaXIMfsR/xO3jdnru2P73eQZ1BinYBuc/wazNDiXBrNecz6jQyw2EhAi5Lbiug3mLu2y5MO+trXjtiRddUhP/yE4DwIABfvDf2+uTWxLkvBK//4J8/VOuZrpn5Ti8bSLf/779zqK1Umts7et+IW11tLoIWQ2u6YLeZAY22pxJIQQiZRSylQppVQ1e21AupDHOEMP0xAyGsrTdV3P67qu6/n6gJRSqmoBIYQozqDruq7nwfRcRkMSQoikGJBSSlUtIaWUqZRSyvIMQgghEgmn19GQpJRwSK2glFKZUkqpTCmlVKZUNWxjJFOllKEaOfPBXqcObS5D1Ckfca12jbMqJlbJKVzPm+n6MHn92agDPHxxXJD7Di1Grk6bxbfErI0qu2EjNrEZred5Xvlmvplv5ObdAPq/DhuxAwLKYDPfzDfzDfxI2wbQYSN2QEAZbOab+YY+yXIGsdWVKRux6RuSPgy982KyAWugA/FfMAyH2O/uyYZlIDd3A47hIMS0fFUOGhUq0PYEIJEKFVmqoIKKEaACMBVMTIUgUAHCUbHDAfI1h/9miR3/OXQHgq8mV5yUVAcFp9RBiRoI6KQOCi+pAJBKFQAR+oOR2HdYVgZc3fGCz50AuW8cdwS3fwTgz5i6EiJM/1wcSwhhKfqM6SvVAJcPFiLAA7dPsBssXmKOCMXTrU9aoZV+9FIVcfjzCfUaOZ9dMG8EBNmT+BTBKY0+0JukdNZ7iZuH6JykiKosVAJR/74GpKjIJn7XXdRTcVSoH/sTF+cYSvDJsuNArnISbOvJUmZ/uLpUcUZ0x1glGXXTXI0nR3qM2DTsDvVZO9sfneByxoHrjkanGqVLRhMN7rVlKhFADj9DEFNdcPd/ZxyxtQ82IPXvtb9GV/Evj4J/esy+us0+RrAkUhqBP39SUPwE5FN/Ej5+MPHpLgXfvsnHjW+Cb4Tj4JEiVlGr6q+LwvovRS91nCQJoIrPssr+atZ1FKSaA1QnYRWS8IbLFvnDobC1chio/pIW4pPHiI881s2HJm5cNPHaXQWPmmeLp96tUt0lngf1LKjnyt7yvkVPamZrWj0MnjpzSvhJ3LGPa//U4FO+U8FTlvxUFeU67jFb2mOiyJGSI8LjbrPsQ8FDQnag5MCZA9TYS/Ac+HLAshuCcQimobMhYbIHce+eAly0u0F2P/DdZ3cLMwj20woeBa1iqomdO0I7hK+vVXC9x6xVnPvkWnWtMF8LZi3MoLZ/RdrlBRdUtlrBjZqZzWqAVX8VW0UHq+Dj5VLuCnXFtbvCXZA6kGoixVkN4gnAr0gAKnfLDHlzXmodumwp4pAl/iWLltAPLlRw0TzRacF0EyumlXTnQR8XaebhPN88OgNfrTpXwdw56pyyObRxc6Zmp2S4Zk1RcMYUs5XxXab9kTnaXYhk1B8VGEU7jYKRHoYjvGaJHrPYYb5hwsZhwWHCUC0DBw8qwEFaPpKUTIqQAkl6spKkV1KoHkVNXDLPMnV/XJrrKJT3dyvAP7rHKTwFSJwPbMQmKKMB13I61qZuEAuurn3Xqy7FU4oolmN5TvnG8mC5tVPHeujteLejiB2RKuIgRo9VoJMVqG5RRkWaQ0v+Bs6OeWJI69/a35r6W8Jgt8+90E39TaGpVhWbaAqWNvY0FkQNNX7mHG2jFtSs6ZCqpzXWowlKvL7wf2GRiMTvyF7dpqhOAhCdAv/01DmSUxXMEU2x+Gd5Xg4qkhII7yeAFY7C7pPwdSOPouxcfCMuiDdXAb31wpcPD1NLKxDR+YPmyqrxEPQB//H990HhSYZkbjB6Yi29E6PobDbVE28Qsf0nANjLGlt5lksQXUhLiDsAUx0DYzgLZHXOWaHh/OVMhwA72XFJ8BK3kEQ4p+tyQJDDbbANgXTUZQC5gzABlOk2YDCMbMDEHvER5wFo3HOCjSMIEdPx/gQAAAA=) format("woff2"); - font-display: auto; -} - -/* liberation-serif-bold */ -@font-face { - font-family: "Liberation Serif"; - font-style: normal; - font-weight: 700; - font-stretch: 100%; - src: local("Liberation Serif Bold"), local("LiberationSerif-Bold"), url(data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAibAABMAAAAFpaAAAiZRAAIZmQAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGoESG4GVahySOAZgAIw2CIVYCY80ERAKkcFQj8AIATYCJAPRKBOoWAvRLAAEIAWXNQeB0GAMhklb4fq0E573f9w5t17tlbKwnloYvswXxuYYbV8mnAgIUM90B7MxTP4EilQ33Rg7BdX26rvUO9S8v74obHTeBhJe0lF39v///////////////9/HMhFVO0DiAyBpioo8YnnHI7azV9t8x/dbImowIqwPsZMq5Bjrg4Mmd1OnUdLL6vsYwHf6adC1wxCNGbZGRhjT3mTYSTgkAVNMqGIaZtTgOZkvqiTEUylkOCLLVZEFjjyj65Xxy5I3x9sRsxNmj6lSJcdKmjk9OT1rgpyTISORFUwvsKSXV91zSH1tXJQCF8KpKudVqUFuhKjILczgt/Tmpr69M0yGo31s4w6xtCysSPF7Ei7Ig+WcY86IpWUp7Wo3Jo81HoydCxmSO6IkQXFi6BNb44lqocurxNxjQ6oVGsNKyHPsP8aFYR50hvPKfFKSYUQ9eTHz4qGSPR6MHbKbx/l009/g1SnlztmUUjonLaJzq+VgTm6jT60IXmyEOhyOfHhDpK0RxZAoJkaVCJZjWAdbzHBrg3dWtHtEu8GzlQjfcAJlhAiNCvEf+kW4C25LRgUP+Ht3xs5+wangK5FvK7EPMnlGEBqDFhIqbj2h5aSIkLipPXyhGpFMdm+yF9qTghtIARNin4JksiLKtNw1lFlyp9sXXHCCLifTI0emdEaF9qiglYLCCBUpq78/aecmxCB0I2ztvTFiWsyQvFGj3mBYlzPGMXOvrszw9XpBH8k7HkkfTYP4CWXaPYmwyFxurEhPi/TuMCJnaJR0RHA0Q/D675mS6NE30jWfUb3H0DnRAH+alsPe6IlUzTqRbx9C6iUMJmKK1094+HD3ic+QRLb9SC6JmcWIGiGE62N0ETDY9JVYNByQGbprMvIHvvsd8WSE2IZLWU0b4ukPDKCcYKATTnDYpWPf2hVd/8Ru3pm8xkhkDIGSDL/eVVUnkvvQEE8OMVj0saTD9mldWuLqypUt8n2GcZ+tYixE5x949mNhLrc79mXR52IZI3XirNybO/mHkIJ7t/Zsv6C6dsc8lKROfXDi4voFHeYX5/m6sJRtzH8F9ZmVcp+K/mKeYa429DenDiyKC7u5HTMNvJNvnA30+7eI6HIIIRT66c6SzUc5pZQyknu/2aqqqqqqKiT3PJv+T8mnlBAL/xFWpLxfbFXnnHPOSOVnXvjEVlIxAX/csRLyD3bzk1NVZ7drd/8W7vxwr+L/sqfevcRWW25VmyPvASnGraunAprohigRcYhTTLEs2zCvbotb7Hq8yid+/Sd+zv6ce2deJsFSmiohFadiQMUlK7X9UnNlxWu+qsqb+Xeu/+4VFFFQMCAIkiWLAcQ4COqk9DMvOTNvNoTY5dNvtUWbfT/kauvfbxqAbYqzsBAFJCwiBVQEVBSVKMFCRAEVrKhZNV2k29zm0pUL1+Hqi3LdXwySbuU6mAURC6VAocgobmRXwIGCCBUVeOQRN88QqQvkfRw4XsGyXVgQWSIyWkBciAiiFmSOAgXKKFC6KKuUFio6iKztrpndu5c3jAY8gBHx4+lrSXv9d+d27kAJJFJm6UPUCEmhREhG4ahrK/e+ru50kt31n3taJbRWlAkLIQUb0ACSDA8hpukEVMDqk3btc2+MwZYeSv7sLW3FzhPhwUQRWlNNXVOUrtAYgfQIhZJdXWnzsPLxE2v/7Q6vDDVeKVgjVF1zf2JfUS0NGgPxT4ubv/t277gQKUoQitJUFwi6QCkGaG5FCUgOGBtIVA5WjO02YGMZLBmMitEttAEIKgpiUEZhJSqKWa++yb9+cunMGBSinZvmU+yjQ1N5VqcFNFYASeD39Ln5BR5SGxLU0iAWRCNIWZoEvDFEq/pF7NTrZW/7zwv/wT3fzsydO7OrAW2CQUh5GkhiCWaSJbL/3avlf+vp6c4zs7vvYrAHWX3FGUHKEpU9QiJctpeCMSA0CEP5fX93bA02QjzzFzUkJUJrcHWv/yYY8AhFgAPyKzeQbfXg//eTPS6Xz5gLxp+DBhHjmkFcGq8cLjb/z65itG+CZKXMKd3hCq4F0K9WjPTXOv2TZ1wn9IH/t2bi8zlheGEu80OzCc8eLU2AJjQhd/hr2ym5KgIJ5Nj3naqs83El/mlM9uHduLiFLLJSNVpqcv/vl/KdN1LgwhUJoiIgGnFPk7azrPvfnPn72qdf52LmzXszLyThywdUVa9UJdmWBa8+kaqsBtSvakJJ7h5AaQitIbRiVr2TmtCKmD/DP+SYbZOHl/6LnX/aj9mgkRqhUSqVULdelu/8i/j7pnOn0+v5ukwFVuiEh3+dn3mGJT0B2xYYUGBLlmx/5BDfM8eT7FYp9xfdQlEhtWm65Yqh247LVH9iLVpuD7t+d2tuiCZKs8wwndR/01m5vqbyfBXhU+gusJEN6UMWWIt1GIuz7E1l+XFwNcbzQ+x9MSiZWdFotwMhEUWEwNyUFjqgleveRsn45TRfb1eSa5V7qs9JR79UQncMCA3n9//3yyrvffcRfeAgBYgzQ1lEUrPGENIQhkyYbcKqlYGqx7AaXJnL1eYG03J2M2dPsDWva75vWlVkQAIFZEZGJJFSZMu2qqrL3TVj7c6BlyTZ8zlXT+qb97/Qtwe49H30yzhT1L3AdX3UdYzz9nfvf3WVkofIc0A6+L5/9gGQBuTMPB+BFJQXZ1JdFUB32adNqv47OHvVtqGixzJTJu2GARbWbecJceB72k8/Z2ZvgciWX1VVlIpwLrJAMrD9hAUOEUBz5W5yf5cNPjDpL4ECnEddWeUqZIUuuypR/sG/8YBha2sLWxD4BeTeeaX2Ab/VbM4CT4q+1U5EL+YXUYmE2WPqq/f0IttRXbmJ4tbxUpuipASzxW01z47JohbhHfmH6dTsMPvWOuEcamdvCO8wEFG0UwyLj8g/zIgp/qcZNkU7vcMUkx3+hykio5gSU0R2+B/m453ZJ1Ew9G72JfA0pLIq0IbtmsKas+Izmcq7u9ZPrcep/a0LZjVEV4yikxnkBByEGtNrjQD6pES0zUoUUpQAWGfJ8Y0ZN6BAnJGyzw/wX9uIz4yPqpSwW11jInVbgMVU76BWB8HPLGIiTwsJRQfd/1S981q6r7G9ppLK+dexZYAmVy3Au9B6vAQEkAK+9IyklBU5rLxJPCx8OGcVblK/M8DZc56tePV8A+w6TEeYdATJDb8JAqpkoqesWxNCy0mkEvRjymz7/q78l9BK9LYy4zCS4Cpkvce6gXOs9OQVdjFm/v/PpXVvFTTNfe9RjdphQoqyx57JsjQpvFBFtQQ0qRuEW20sQdX9AWkjSJsnhKCZHU+S5RBSAbI0SfKZ+dv1w/00r9cULj9jISdkhZ1wJZxwSPczzCV6ys5IAruGiHjsDzObUi+fK+Dk/k+n+t/ZMbDItuTLKYnOL+q1z5IhaVl+IRXYBZVUQJo6dyV6O9Hat+OWtUAAH4fPhmV77/9yU+TkliQi0tFcNpMt8KaEU1hVIEpKsEVWuLnasiVwrTx3KTy4gjBP9lmYf0/Jaenooq52m17ftRQkRBsKGzuiMLWoBEBIQBSPeRA40LhQOND+z0zLtH53F6cK6Fli1pJ7dxLnLCkP2ZRcGtnQ2EiKFGRV9aun+3dNDaZnpkk0BuDuEGswJPcJANe5AUk9LNaaSO8iWR/RyPF4jnvGZTIutSZVGioJFSlUkitzoXGpgizXU5oK/lcbVXWj5b8GITUdGyTZtGPijuf7lv3s333ELlIL+TVKIO0EYl1ij+LgIHj+arpjhcdpfRDruN5u3bQFVNSKd7gFskKY/2Sq2Q72zRfCACfiIF4IsWh3SQfyqjnRqSqp/bMcCrN/GYB1ojJ1DiEDTrOgA+hIq9Jd59aViybEurD/tbSkI/WO9jY5opgAM70cCDRA1z0zz7etGV2O0Bm7rN+/u7fVkm5ng51RSAybGQBuwMdZtQeoAUT+/1W1r30gZY9m5gfrhxiKTvaP5dZbVQ/3vocHvIsHkgBJUSAlS6QlK1geDTXJmgSA9CwI0f9Q8pw5kmf2HP2Q8oz8ozeEUKZqiybWW29X7vb9VktU7d/p8KYVNYVConwKq/I7ufKpVIRC4lBgEQ5p+N9ps2nZVRwKy0OBOs6rkjJyY+UYdzu3dlr2jzAsK9LPHGpIyTy9m3X9X8MEM02mO9VsTbZm5nBK2VLaqbbbBzR8Pn78oBhEMIiSIBMcJBrRhBSM8+ADjgLJQ6JZRadY5q1ts5ppiJoQTGYNiTMO04xTqlOrJTPPmC2pW0ymtHLa816PO76Z09ZyuJ2m7bv3///fnPW/51ap4AocJNNBtD3d0AHLdgd44V+Ap5ftSW73Cz390oTkeSndu/c5d9+6t6pUqpJAqkKmqDK2LNntogrGUMJ+95xb4FJB9xJMAk3EL2Fewn6p7ZdQCcZQAo8oybYQjjAhBbdfmsn2THa/4BfTx19P+v59PPz/Xv2k23PHSqlwoMJ+2ADYIR+/+57uk490/WxPK0rrStCsoP8kT5as1MJQqc1Oqax0ggJZaHj4upFm7U5PlkJJoanpS7pL5QcndHC3LrFeREA0OaQDkV+gYSCBWMQRQWuZpklY+t4aFSlzMBt8BGFf+NkNPpBRgX8votr3c9vjmEXLjW+VaFGicH7b9/XVJ4TqfVTNW5pLIom4IoEEbiCBI26S5BRJM597rOnD9wamgCUqaEhipenffqqn3UPm/P9YQOl4vjV+W62LMBRUFJQpATLuknYYm/U4MebqanGnjdAKYm7ftT+m3/OPta4LO6koQ0ZCiF6HMdf/18Tw1rJrnQvTlgsUVARS7L+fmLP+m4imbvbqXktVpAgKUgdm+ntT5O7/L9v+D/7p+9mvtEEFGWFu5OIGWmf//6Q681s+sghzxXNFHBERLVq0aC2O2SzGN9N985xGsYfjbk8oopkgO0GrL+p1S/uRbf3HY4T5q2xGCKhoc3pY6Bgbe0+zMgjwPGtDvoaXjKYLMhaG4TgMYyzF7//7m56bdAZtNw+mg2AlU4Xpx897UKBOwyqOSK6iyGLboWHufr8TAI/j4+sl9XXjA6e+Lr/3PXmJUqY+/pUeg6EsQB4CyY/DBKKmZz3INJwLULN47QDNkl6NZbPcWDFrDZmRzcgR8h0WOPz+69r/QrHD/rerdT1iFcR1MLAjJqHtjFl0Vy/CArHmnlyAMAD+ZGp9flAxbNejfrzKrXr+KD2rj/vrU4nqbj8Hp5bPgK3688IqKPeG6OEdKhga8PKnxA0rbfxKc25K1uuklzUP0P/e/QHlHTrmygDQKfOna2vK/raBQxQxZCATWchGDuK0iYg5Ioxo9KSRRw2d0uSj+ahaFzEI0z2wAhkoQgP6MIKxiAqc+mF4o4uAIgCwsHwSzBVaaSLv2Nqsb3cy56EI/gkhQowiXgRfCElDTqCIqMkv5GjvmOK42wn4EKcQp4vOEufTpQMXLxejX/Vxo6/Lu4kC4jaSJSmFNEtGkIvI5yOfipcCpPhSMihjlNOUH25kN41bh9tetxdUBFWWWg+pGmpbEAFGx+p/BvTrcptHQL+ix3G7X3Gnd4Ou33LKnq9wzSewf8x+Benjg2yBFkOhmH8bMYlLBP4EIYRoES4HpQUyjcnhgyJwFJZApjE5fA/Hkpl8qdpo5+KRzhUrgcXljxTnguHFWZFCZ3H5BUcRaByRQmdx+RGJp7KFcq3ZwY1k8qVqg81DdTcHwRrQARNwAB8IgjjIgBKogIaWAVnQBDCSybWfkfwGgRK5nEC51RWoWuswI3XsDJA8WbtBeVAZlM75xK3xOtLw0szjrO3QACfuVN/M5rqxvuqYSVoZJhap5PLQDqrMXKlmnVKzms5oIynJahbEtuM3Q7AELAALu6Gf2XGZd5FhZncmn9qchtAgTMJMdDmbaZV715QPQGyXTxpB27u9OBkrgylzg5TLbFnO1Vc/S2TkkzbetkGgNPWzBSV/A1sdv9CZQnLNm6KIYLMp2pXxyblYLOUaPzjzGbcLhGIhedpy1nV5xLHVyWtzJEQS9w/ibbxO3WMbGVgnyRjI9Jm+TA2SNezDenPK9CM1exgGcBo/HsfBUyOkCv866VmTN2JEhmZG8tQ548IFLVpY6NRcVTFSln9uXa8CGMkEpnoHgIXOZnz2YIqN6WKORcxudFabf1ONuKPwl6pUTMERX16A09/qDZyELmLvljUKwqYfh/zonj9nb/Y0ZpvtBUi2Kg0sXVMmuOEEAGWDUwE4G4ALAbgc4FqAmwHuBLgf4FGAtwC8C+BpgBcB3gvwYYBPAnwe4KsA3wb4IcDPQeSCKAK5DFIGiAGQGKBogKINij4oG0ExB2W72hPsspcrEi9+Tgl0wWXX3XRPrERPUWXJvxcDcjZddr9HPe1Fr8e7e2Mz+wVPxEkCKAR55ogthvCkKamZCkC1YMsxOQNoz9SfkfqE/zImBQHoZDP9a6nVj8cgf8fSw3BUJI68vLI49plRtjYEbLMGYBDvkvmOiRyH30ywSS9Xd1eiJS1jF7ikeA/job6KVVccOrfQztd6bfjh1x+G+pWpBPZ8yoMQszfMnyehY2woo5aAkppd3zfcaeloo2XAjMdh0E1V3vV92EqYLrun2YEPXpqLAYirxe0hn47TBF1R1ubgllA1LnEHY8NwRNKjVOUJjMUCxY1ZcdwX1qM0e7hTWa52LjxuiB4YSnsr5np714jDUZWDW528whAY49iIaS9r9PH3TL2ylul/2iVcAdjAq33bNOSknKRvC03jlmsaVhcKbcCo8xnqxvMh//2XAYW+LJYlX7Fyn1X76Y82PQaN4eARg78hwABCQZrRiUFMsjkWsY1jnOMWz/jEP2cSlIu5mn9zOw/yOMl5nozkpCC0VKQyNfmdpnSkL8MZz0wEXKRUYDAlmDoMPbqDH7PZOpZjP7vnwLjP0fGdAEaYYFLX1iOiRKV8LH5yw8p4YG6UwrK3L47b+ng+aII4iRmzwgRFVlYAxSds0ylWSpVgQiI+5gYneL4+rTPufCVQzLdNpRtzL3iuo7G74YOD9iiQiPdcOQQW2HzAHbl3MHjsD4nhm9hc+Me7VQN1v7g7vJPBCYRTCEbmNPiLKqbPPVr73PTuAmOBNRe1AVJX3uovnDZbpQ8MYl6N6hC5mewoZUj3qnDTCntuGRuPy/ylexYKuRh4jJgSs0VOBNHEkUQGeZRQRYOH4rmKsSCP8QLAnfPbUtzmW3rcYcJABNHnzdzcAtPMu4Y2F00suHi74iPGfZE7ikg15Drka0Fr6bUo96vLTe6pzdnTe3ZzN2/zW9pLLOTsLLNoWsCs/j/8+x7L2Gd3DsQ9R+ObgJxLSMiJyH+JycPEJzVpyUxeClOaj6nKj9SnJV0ZyEgmw42Iy5QJogV0daLpgrKapo6+0Ii4lKyCspqmjr4Pj03OzC+tbmzXpcf03OLKoKWrPwnLrmj0xrNFFXUtXf0Kj0pIyymqqGvp6sfI+NTswvLa5g7dkpn5pdUNbT1p3ZPfyGjQWekl1bA9f96MZHhJNWwPSou6G5f9GiRVIHm6LEHxuwlhxM/bVA0/wwc+aEqaemLRE4sO3s09p7EXe+G30I86+FGvJMJn5hZKWsmNEMOxiQjpTRIhi8DMJ/RHVUojZpYlliPLUqjjN+tcqj2vsbs2fB2TXPcNUigabBH/tkj9SH3Xni9hn1UbQpBpMD2oaVs7b5MocXUAy/Z8LY+B1cO4+G+YluOGcZK1/TD/h0vqxqw/KpYA9E2DjXSdCSaabq7FVlpvq92zI1qU2G3Xz4fjq2m753dtZJ4nYgffLqn7DIRIDybQmv84zLfi717JDH8g3/4xC8wC9PvURyZEW5IsqY92p21HR8IC83gXTBxozTAGgd92zp+BraMSwybaTFyT8Y3GNqt6WPHgNssq9T3DxJfRWPrUUmN3bSDRrJlHf5YIulBo7C35uuEWobYQf23/X9Mf8nx8z/k+wzsDbZg0gERzhRHe9cilrfqa4b/V3X92kBdlVTewrNt+nNf9kAwnlauY3RHuzLWndwpQS4Dj4azL7veop73ode+mj0H40vd+zf7e8iQiwexnG7KVqV0OoIUR66b53BbcqUZE7IIf8xo5/2hYRTd7tMreFLPkNgmMqK90P2GokbNX5inwkytJlnwR8HAr46s5yVOm0MAOgpOrEF9NIe0txrQS96mSKfGwUnxojKfpNcfIKWlKdV7V3zlsdf+ioNBA45Uzjv1YKUoLRe9lKDcuqLFk8ngl/INnoTi8NznLUL53sIlXg2fVd30STxY1fz9N8/o3HbzDhfJGlvWR/Fj41bl1m34SCZAE3Nq+NI2dmVIdUgEw14fns5BrK4Vu+4G2Cr70gHSzEnwx2nZtGFf8mQdrqQHK5+sY+WE17efoOflXbleygYGIVT6jJ4B1N7DMj1mVzklVmzqr+Lo+MG2VvFO5iJ1TlFfFSND0eYaUwVV4j50IaLvNyvicdRRd0WXUlVN5c2n1oBgulYKpZge5sVHRvB7bRqFJ5MIjgeapWvYNg1vFID2GJzD5s+7/vWK6zz4wADEAcbs+ygH0Fy902lmz+nSWmFn8OKfFmr4T59tdNam9Spg10JzW6CJqP5vTKhEgOKH1eXdzebutbuy5xVAmMePo3+oGLlfHYbBXiuIDk2Jl/R4qNeshnokHKeSmxKz2dikrWtb2uhXfcJ1Q/aq2QLHCP6xd3ux6lI5z4gzqooyd0jaPqwrZrsedXwZRfmBIOBKJVEAqI1FIjaWzJ9+D/dpFt+RWnMRJnVwZUlZUVlHB3RlAoEih4xRxta7QcP2kcVgneeFjMrkfkzn3MZn8j50sUCYUKv/0z6ZEAq2KOjhAZ4fngYXe+ckVzGyVp3OO+1DOHRre09mBsOXQ8EPOoREcSu6hbDmUHYeSeSgH917oVecUuFQe4bW5Epsb8oHw5bCamVx8AmZXQrwTc1dv017OIs45k6uJTcdojPt7IVfx6y9ePZwRqf0RdMQeOcfnY/HTP1Fva66sfHdhs/0t/q9k1Is6vy1Xv/M/5F/hZ5UvVfcfvh+K8u5pi0ps20S7sGxbtGrrcxXx4z4dOvHP6IvF6GlSyc9nbo5nRY41nTZv2xbdKtt0a2vDHRVu+k1v6vV9eGgMZsgjHo8jf/SM5yNv5AEOYeytckX1I15AzqZliVFZPGAhOaN3EiPjYXqgx8P1lLBNyTfMVXzjSpNkM7FfR6kSBLekF2F4bQnjtRiJUFNICnffMqln7Jc6gAQaZmSYQL+xGQJ6cgMewCjTU6MjBuKCOhV4kkQyNCIROAhmkf8329RWAM94vRTsLylDrQJGMPM6CcCDBTyUoVzN1TUYl9SGJGIeMabRI1WFIUhpTRVagPO4ehWuIXGNCEdj/0i4X7nfemVsljGx0gwzUQ+qAGRbldNnvqHsGgRxyJyfjohxvygXmP5gTt1RC7EqTUnWiMcl0zt618H3DpamZM7PZ0iogEgF8SKZKK1SOpAxzkSU86QCoJhVvCxlVEXD8DVwX8oN2h/x90kEhfKd11Sm4YJGaGVXbmGHl93sTLrAKlWkDRAsVqBzNlMASz8xyEABSsiGHCiAYiiFClb1vKlFG8FlNoXUuVLgm4O1Q7J/yhQmmfntuU/qFtBeTCXifLhPFJIXkU1MiEPGnxbsBJ9CxpEA8RqnnkuHMm20ovZJY45nTxQHraKtp/KgCrLb/ZzisLoWuJlnop9a7KNaGvgIBVs39vfVUhd6fGAV51IwT7IJvLwtpV29xgYLxCTDKXVmcRoohlKoYFVHUhY+JbPA73gTrqXVVPozqKx+EdtJJSkorYJynK5VRlJWUI6oQONCkRZTKVDBqo61ySrWOFlRxZYjyhcUQDGUQgWrGqXibakIKGeVqMjaAkKdxCaZjBEprUIOFFCxWMVGVb762erWmsnl6L4xn9eRAm7DzItVaKciqyt5FVIXZMZZnFxmbLZG4a6rdfdvYlp4ApoY5rSAZK4osHw6ag4GzSAQdiZjJXgLeu9m52xj5GwqHFB50mzYx2n4k8n4IZs6QYo9FG0OL4D+kIIkBFarnyOIs9XcFQAmgjiRWebdlBi5JPZkGpI1x22Ar6aQqDce0jEyjaHJbjxDSGgX9M+KPugYU1TOVazN3BCjWoAYd2fL2nlkNv16XbGi5vxZYjlKZR8065W3UAJvIpmUWNOFemHsbGFerlnUZxscbuLRm/ETTOrW1HXoDYkRda3EKUMNuUeuFOhaGSRsMdqvijiRb9Q3Op4buMOGTlDBTLrQpDJD1Yl5bItVCCR9QM547X0kwdmUfaaXillwf71YCNsOACA8c9/ZXJaRoSBO+9oGOUb2o2aPcdxskgIm5TaZ3WD9vNxSf1Ce5ukWTQCGbK2MWEzmh93iIGEB4qkhmgzzAADQUR2pt9xAdaJhLF/NmnY0SzZH2xPiNubYm66CXqP7IZYQoGPHFdsHwpUJshPpce+EocMuupolm5wWqEJ18v6cA8GMc0LdSj1Rf8cGiU0hFEIrM1NgRvMFCEtaA5tMszzG4WBZ347XbI4pWXIAnE9U6Iz2ptWy2rSM1+8TTJ5aN/KTUeiV6qU/4+/Dsvl84/Iz7A8szqcLl0LkZMW0JJGpYffMSmbL8nqtuv4i6g4g0OPQOCKpYuuGxA/m0s0/7jsBguQ8r3up+IbNG8fEWFEN0fDNDzs1vfDCTRJvZak+jXAOo8qlkSfmnwGIA5Btu+4Y0W8cGGSccqGHIPaC0QC/6y7le8FRVjOL9JGjdRTAM5ZwHs96M1i7t2p8kAkkKQ/Rk4nm62F1LM+MwsLci2jX9hrVxgo5aRLViHJ7/+/YI4owgCcXF9fP3dQk12rY43xgDGWDEtCtzAjKR2Y22LGp+pT9EnehErAbnlkA5jezNNWzaopCkVJPIycxnbfa5MOQ4ozEaEXNb3pSbfs48osTM+VcUXwgic2ETiiPTOnKPN6eFFeFcwfXFfZtJyGccDpQRtQRl3561Qlfmsvj3HDXOf1Qvhk0A/AXPQcAYNTMTByH8I37FnOJejSHODrhhftkkjvVyhjdg/ZNKCmZXkmGsdORcurGoLqwXWdTNLVTxcM6r1RSxy4/1bj1g/PasrX4SsiuFI4o+7d96b6ZK0ANDBEkkUUeRRAgQaOZ1LhJMxSo2dHAYLV19fBEEtnQyNjE1BxF9h06dYbwukc9evF2W/HP3qcgX/4CBQsVLlI8s0TJ0mXKlotll69UuWq16jVr1a4TT+TUbdCoSbMwipM0a9pOQVpu23n5K97+0nUrh3Wn+L8GL/tXcv2JfRsjHgvj4OGu9rHFKo95Fnxc+w1VOEvhw0RZ7kD0/VXbt/7T4SpnB4cCJZ3KBUJRVuCLC7893NjAAe+sh70SqcjYfFpu3zC42bZDEVDN02U/7pYAuMfc+7PrBnbrY/XPwK1P8b1tW9vf03udm/9FT1zrTqXYDi0R2u60PqWzIO7uKn/rFtvmA6PYShkz1D9cg6UeW4S6K0FvsCIW12942L669BYqCkotT2/XerKr//swgGNEbAH4j2ZPBoCZADCfll5GKdooI432ig6LbhLdITopOi+6KnpQ9Phl2qSXRW+K3hd9quHXwNs+ai3+ftfhUyD69YTHY/pVVF9uikJAdGdInwGQ/EscRnhD+/gxuywVhE/SJJF922Z+WEr0ufP4MQu50ar0HBGVDxO8UIrr70ILSpexvuDyGLIGnsplpYAqP1beTz/1qIe9Eihm27ZveHVMuNMUQ9yOQDV/sL+lqO77tFrf147f+VESFs3fup8Zrsq0zLXSTjypt37jpxuSUKTFJJVUafjyXT036H/X4LwU0KlLgV14AJ0QTHKxOaYD+p2UeZQglywEkMsapHJ5KeNVEb65gJ0fPbDFCyrH/JpH204NowLWIAqqEA88AFQ5tdB76EPF9fOMd4j1DDTROunkR1Oi3Ircg6n8GyI1BeSGW7XV1F1w052Be+Kei6qk7cogzJRNJ5d19x5db20xDaQz37SuBiH7980rHpmPlhj5W67KfmVZObqcUi65rW1GoI9xcFSBz6diwOROO/55Wge0/4rE/zPCPPy/y5oeWGwlP9UsJSlOfF+FAvcbW0QQh0XGYsCUpIrHX/F4Xk/MFkQFzA4RiyKlHAt0wFlKiWK5AdabqDoQi4Kzf4fRJwzLlDUhRJNAFiXU0YEqD02NAePf7zkGoWMQ81jGMa45mlQSMbO+WfhRI9TMwTQQb3cLtcXaUri8VhAgM6rCzUK3Ep+T0KbVDOmkM2I3indA1jpkI/HFl4pzZ6ibBW6tIJSZ5+o4zBcHiWUjjBlU2CY/EgU/alANVoPXEDVkTSFUnOjVfSOWTwg1kg6/mmIjcQJaqaFguBJVaoPxdT/DA0OeUPlXVxAx0+csYGEDoFYJiQIxq45UBzlWY61HzYaFVhvtpathIJe4keMaPEYcE/asSqQqEr1wFDqFXlr6jkQN9gJTxM/GsT5cTz9OzFkjJxIdSWRRRNXfb/d7KqochcpV+uGPDgPGzBAt3CflYMayB3/3Jfrq/BN2/g46f/mtP93YE47Ntlk206ZLmqRKiiRLokWw8BbOwloYE22iTKRZejSRfFqfNHkwvpVqbNjre9953E6H3WY1m4wGvU6rmVoFpUIuo1mkuP3548vSymrycH1LVEnAPC6HzWLQaVQKmTSiCgQcFjO0LVAIOAx6tX4gxLRHfCRu/IfKwR0d7O1s1lmc2WTQ67QalVIxOWQSsUgo4Nr4ckLSD1mDz9/OX/70h9/86hc/+8kPvp/v4Fvf+MqzJ48e3Lm5ujhznR/9bhL3yNepthBSYWAprvdGb0zvruIRkSw3N7/CQBTwZVTVLf2oobap9Rw7Z+M5vxBE+DV2oAIChqEkLPve1WRMFSRgDy4rgLW+fldpiaBoBgmDKcEVkUgYHDFCxR+l4geAagCg6b+UPwMa+SedsPuEZHUZ5esTYPTAXyvo8eUEoCoVAPp7O3mcKUyD4vg5gxqNnP+gCP+8HhZ9Ud3Y1e/ajLlhUGyKi/7gteyHMBLc8D87ZDlBIqOiY3LyL4884AWf+Q5t5i3bdejcpWuPWtau/qbs4tV/czGJ9M9TLlKqlGrlJuV5pahcKL8qryuNSqySoZ+hbehc1QLVUtUq1VrVepVOdaA67lBut3coBUYwwAfahfnCYmG50ClsEHYI+4TvCh+FPwt/F/4tXBUeC1bBLfiEgPBKiAt5oaHepz6krqtX6kP1ifpKfbvhesOLTVaD0sAe/8+f6J/xvJzX865EFb44/R8YoER+Wz9q02HcsqHRfSz7axb5DG+Cz4sq+8gVpvkrsXlYeeYxYgR+i6rT17vq9p19yczB2z/0eaz5yvE5fW8eFtcl8+EaJx8ciLWvd/Elv1Q2bpTu1OwbYTltOM22Ec++m5E/2Xn6GbclLMmi//+nOyw/f2JCfCZN8HBzsdC6Kv7D3vX383R3dXZ0sLeztbayNJsMep1WJZeJhAIHAZWIgflUHrQAF4T5Tatki8n/p20aJmTdtJL7vtj9xqF9O9ZmcsY/Zr9Z5E//38aLGyViuNAhguTLtlYumsxWNrHL2K4QFO9ghBoqiMEDBxh8d+nCtEkTfhs/yhHXf33q2LlcHe4/e13/0Wt7Tf8ekbL8WwyIXxYCUQHjvjSOy1MRhDxjipyDf7vR1KjToAlDCxaONjwCHUQkZBRUNHS6GJhY2Di4ePTw6TNgyIiAkDERE6ZtorSQf5k4IGZFAh8BQkSIkSBFRjByFIQQShjhRKAkEhVRqIkmBg1adMQSRzx6DCSQCABrPRKH4ok0mXLlyJPvjbfeKVKoWAk6mlJl3vugwkeffVLlq2+qF66rpJBK5uX5l1Uuk/3s/Zis97cO1NVH8QvYJ6VT/kj7yPY8ru7jcqjpCZMq3XWevOcdn+23D8ul9vKdo8n/XhQ6WhfrGrk41/Q1fk34sqarrV2XzJlfksiqY+2Ra86NO3nNXItYLd59CR5LkixFomeeA9gtwyvp5mGxk+lKqJM+Gf7L63k1cSuBFt8ZJ9Ufk59P0eOw/JMj5ePA6O9KSJKEkXPGG2RujPzLCmQVGFh8NnhCCvncpp9bVkdd1SYk1ONVLXdznzOPnlIERyfrfMFqMYsamIbuW63lgrF1mMEsAfvJ7PFReYqLRFwvwN2pCymBLjiSfZ/wGjqFTNSwjeYvS+GBtu/rB036BKR6xiWjqTbOBt/WgUB9er8H+/X7oALnukwAqYD/Uknby4KP0bb7fxtlP89J7hwB0Itqemr3/4TY36Ex4J3OCP+SkZ7Hhfk4sLVdALBDsK/Onv7+b8OWY5/dfXQYG246TPXpDfT+C1XDv9uyfJkoYdhPkP0JkXrme3YGG+04w9nfm37iaUpix0JBeiFEDXyNmad7PJ2MR5Io8HuDfq/babeaHMvsNv6p79SqlTJNkUSpWMinU0k8EQ+HjjUiCo/g4eDQnh1dv9NuNeq16u+a9osSt4oKIXTjFBWmo9oVUHsmw/dshbElSIFOFCMcjdJdTIlZilQn3WMtkDe1EsmaXMd9uMVu0c8wev/fF2HG33ysV/ZNZhY3B+H9fjGC0CqCoBoVusOoogxIjj+YOGWHr9M8z6gPcLBchyrL641fuIEqHcNXOT92h7vCO6ZuzDlW9P+ctJUdlS7Ro05SQxEE5tUfUxuH+Rk2oLdMwYAqHKZyf5mtQ35q06WZzxbsyeYSLqVvayqkz/7mCsq5r6h7ko7jkI5/8s+506fUMp3CoaKTDPeTJyLOJfz+hZMNfQT3H+IW5/9mplIS2IY+A/IGxJ/o4CCLGGPr3JKF2EknnW1l2/ppH13ebLrpygKxR5p47I3XKij+2pBvJ/yGabYcP0lo++O3sszTOZikp3V78i4G10TQrb7WIzDLPIwqAyoblweBDrrrM8nGbRqUPdYhAUR8y+TZk4Y8Wzi9ae18Pp1t42YtBvZU8lQ7KoZjwdWU5HpK2QJB+n6npNBfbvpf5NBt68L1s6ZeAKjApm2tFFGZoAZLIcdUjPzQidkf4c3PJ3e51t0G19HpsyxWFCoLtn8w2UPZApzbNDqpgSp7xjU5/DRkaq1llZ87W11LbRNNhx35CDqLr2gH9i2LMvXU9KlGlzj3ph0DYnbR5YrUlLoEytkhf2DjIp2wwS5u5bwF4rvXBkIzRNy2a6CpEPFfTC+t0CErlgjsCmgRkDTEU4N62dBx40wf/wMOZIbJT3mmk6eYPH5TX5MCfaR1o2KoaHD0BdhOpZCqYTW67ImCKfL8Qw3iTwv7twyPswr3dmSqDL2WD7zyRVywFh3/w10AtTysg8k0RV3qS43BiBFU6gILfmqLwKgOU9zzUga42tW6qtFglM+Us31+noQDYUa9p8c/ADQuo8HJGstHul2gGzSw1ASaW9pp9FlCaQp1VGVBCmJKk/MUn2yTPnsj5VqjFGBjAfrBVTF56igbhP2MvHBMrP/25LWuWAZgNJ/BOPV8QdB1uZQjOZzcoNDC8ZLn1fpWTVhK4s/FJ2K2b2MJT571Xw/MPbbOka8NetDia0PU72HDZwzWnulvPe4NbN/kR+I8wqAsSx64ECsBMPGeQKm6ZMSGLCtnVEyh21uccbY/XZ2mmfJ8n0s54lFLpoqBrGmZqWo5w0OYM33dStZLsiprsum1PJHztPctPu1rMlAD2zd5i1+xrPxkacbsTJ0vKq2sLo2yued8W8/f1Hcshk+uGUv9/tOn1J4JJteUWMFSL+n7zEycNSNtne0iL3QP4ES8w8iTW+TcKzcphst9amC/qHR36m4pYBWOtV38rpthdfDIgPVPfksH6BPs+1k4f26lqjk595wfkl6/I3FvB0EW+KmcELFvLeTE/puOrq3e9PHT3/2nW/1z3xp/AV/7IiCB8wob19FaX5yo5CunRc1EICRV5tdUtpc9YUmJT6fCtbxchnJ4xzVUamn/S/HFBnzyMEIlK02Mp6WJ2tcCPGbwUiCXcDDJGWi/k3q6196S7tkZL+kwgkSIBWw7j1+xvx+E4ncW7GqK0DwikoGHex+96YxRTGjND220Xjh0pQikdSejGFb84AKqXChOVUac7dMwHXtsfBG1QG4UNd+QyNoPjay4cOKT6qccNjakQswS+RRRwawSn8tnoQH3X+3JTHGJpQotFYZXzBxdJ/w2hcxOiwmFeRzoK8+kgbHQpOnWNSp9MpapH4m6Ksjbio4i7WD2Ur+bqiGapWETm1k8qOaATMWVqKkUP1CBIXdp1A5R+RU2SRQKan3kK86ME+6mpT6RCGnN/jiQwzbH7Reazp3rNKbjb91ikUm6rNwwNVximIhJly+30OIRdOzdd8Pkk64C1OKGC0fFShP9Jh9Ug8GkYEeBw3ESnZ5SMrv62Uom6DwwH91isiRp1+jxVsWRA0lWAvEFBfA5ssxURTxvHh9Fl86f8V/+S4b+AxhRD9S+onDZ2NpVsyKsDPJpc84e1BUTRBZCni2MKjGd7PnzPhUH3vwcoQNkKO2a6unJTptdaZiipmXruU6aQFUvlwmj0ENWf7NCQ1P+YgFvIORWbC8+e7vKhM+ePYPwYnJTKMXsVq35jGXa6NGhcTOMyroeB4RMshHVqJaJ/En9lV5wLfupr7KsLK/4cFAy/cqVd4db7P/TkZBITs6JQIkrSGKMwZogkSjHU76lXkKH6AUi1owQht1PSl2AsFGq2OeIrde9RQnaYQOn9VUTm5oTzgiNAk3sZMvDLjEJROPFKyJ2gE1zdq5qYrILWSLBwLaImZAfKUQddALGqG5BkwqRhI0mjUaiZAy7pTAV1pxb+M6rYh4JogXu5SgXsgkD3pm8zDIpHsfaI4iADiqs43nKxkKQo4wN27L7sG/Xzd6zmb9SjDhgjV0J3QTQn6fHpcvpOq8czxCnKT3Wdd2MIITYlj+eSN88BjRwGMg5LBIWecfev3bewgERzIhyRnCkoJm7viA/nX10CgbIb0VkpEgecZRDD0Mq9mIQGrX0GGchx1G2vOUrvL//1Nl0YMSxpQ1N+4dBHBpm9tfr+8tiJ2kGB6xpUjPUtQUL3ws5TKJzkV9T1aRmHnhaZQghoURXPwwKryfMeZTsu1Kyg8+3i39X/ORlWNOU5fqKKxprk4UmKRUCYwCEEEJ/eQ+lOEeisHpz5fdSYwvijIFyzinlQAjwPETqu68Wp0IRkHxdK9o0AZtlhcqMdo4TaYrTWtv6JGNuhPcASjmB+DiteBzQkRxsfGcQacmlwQa3FuWcFngAKUgGA6UQIVyhKXPItSak18KLhvX0BXV9I+O77apIaenok2SoaYESqw6zLfRN83J5rG2c8GMegLGbGZL5waBxkXXTeTHFz7q5i2QYc/5nBmvMqWs8n8Pv6659+12cUy7mYi7fL/0R0YXg+96h9+jxc4R5hN1ZMPTYoh8GgLkdY2oANIIeA7bg0QDTt7djj3Hoo7WbFNV76DivkdfxVP1IC898cz+bZlj56+FpZBd9Z7nYiq/iO8Uf4BekSVYVVlXXoUwJ0cWu/UFtPpxcGGxrDRMUeAMtlhTFt9DxpowRhvrbd+7arusHP4jpnuc53VOa7q/zJR78+WzbJgwpRXe/b9s4sYlnlmXtGsc1I+c4hGnEcvsXNGZdH4+cQWfM1cdzXh7ndeR5nvZ9tZ0Gk/gKTjKnHPkYaoShsT0E43DxslKItsgX52SPZfxbeIh/5Ojz5YbPX/xkuY+/c5I/eD2H6n8/m/+9e/Wn/xOdP7aw5m9NF2vxVMwBC1DV5bALtN4FxGCBj4ovoEq4tXBmbvsrXZddhvqXLIXhV3AGKsYx8v85dG8jllnAzYJ1TRA3uZcMTcMe1yZRoM+9KlvoHkd9G0b0kHo8+IyHfH4PxSE22Jfv7u+7xOjLX1ouMTbAg91xkccPJO7dT84F5u8/x/N+igHlPvMf/nDjHZ7Hemk5ix5DGGQ0WKE1CKbT33nkbJExx9h3wxL46Yaqvgc+cMYQKSJ9WcYYE6IBgMOUxiE6aqhx5knU4ONbGFJJSV5S16a2FTN15ScacdPDHRG3zlgHLGvC6bqqJIlXkMJ4Q/mX9Pmg9JqeXxshxb8gI4QUxTyTUT6WZTcKhdzub5RmNhXkewMDMROJ/SAscqI16Ka/HCe6OJzqpScSR92gaGE7gszXqD0sUTretDbf3mjbzGLYm1DRqhBD6oHrJiFbjgx9AhrWLij/q3fsz/8T3Omi+FyUaM3dQ0p+y1m6KfgmuKLEliWFWGomOP39Psq+euL8vb5UfppIJJO35QiZkSIW9zjcDNouDZ2wthPTETZtKsSJER/G6TaT74r/dzujNCX66JqhyyWq3tWriSA+hxgoEtVaIS0QfHY5PV8IVgaXb8BlDCpdwYOKA5bRAM5mUxDwygFAEirBu5WihJKOdvLVAHm32fPGUYatv5fwih5JTQug02tq6Ki6oOpOLVw1QoSR3+tT+53BGKVqNCUoVKgEYFYhtf1rByHFcoZQvEzFIpwRQN4N69PVF4uP+8KclozPgLvkUMBwhUf2Z2S/Nx+B0ZoG6kxSfxrrLWk6lh4zfob7xOLIcT4SDC0qaVyiiIG7QmlSgFKko987j3GmW0tnUYHWmTYGpM1kqpRxLZFfN5qhduaydc0V54iLzWh1xvn9EiwW5+Uftrh0kGXnIlzSCyiFhcW59CyQyziiuGYbm65eEWHD1Op66JEvUfnCU9AYY42P0GuY93D6zBgDMOb6ezXEgv+BjwU/FIXmmycKFHNemRda3DFQQlfQ2BDlNXaJllSgXZuv0+QvSWHPZSngcelqWawI8x8Xqj+WtegQq1mGfxB9kT3pl5DFioDuBG0pJhdk3s2k5egn6F5F+QBK3lKfv1bwpbhEsAzQ0lpkfWtGeQnAP+jp7mUYEZdYaM7oPkku1C00m7TESGoVqOjmveuc4CmfP7A3LdI4bkKEJsgPmCh/6GV2r3JQv6ftJ1WR4cguMKzhw1dzOLgBE6C0WKGKaTRwhdvVPM6ZUH9SAegd0ORblza+gQGboTZnjS5VOld1Jn9RaNV9KJMbKucxNJ9TuT5q0EtvrP6IizhrgETHKrGdb6UU8obiCSH20pHoHMkh3jFCV7QYnJLAaHhJbicnG35oKoWRoTd7gYZ+wIkw+yufKDwyV8UyPVWP8nfv1eQ24Wv3SOu2WWdPOfF9jcyJU6gX7hl6EshSfb9YERmWHQRF0tyyar8L+RYD0IIEznUvSNEqm1a+lAs4LGUZsReujHW2udcX5qcD8F97Brp51IDsaq9eNTekn8B6Vc1QLMI9BUtlSlfTU3IuYS5Rkcesu5o6vdJWSW9ckD9GOs1/bNNClBqmtXK5mqB7nCpD+Fn1rv7PzYWugR+ox8fj9tLfOywKhvXD/pbMQYfZUizMXTd1HlO0mKvURMBh7BmlYeG5ZBW6Ym/yuSMetGqAZxTrTt/KuESpEisFOyUGPaIUriVsMeFE6AkL9anR5qjXBVHUyUbNbUnrbZbY90vu3O7VHXPvX4eRmtED1q9FHDshMZCKhCJ0VLcl3N0i3r9FiOvA7R0R8ClZdV6EiQuAOWTi4tqJdDZd62gwm4S5+6Zxy6Lq6+COyeTmYguDfOuUkabRZ6Ek6uw8+mAJuPG3WEjQMyDbjs4jwSLEDwwANuDRmq65fChcJuRuJnSYS0D2Z8MOpgRQrvGmM6ZXXu3ep2eyqv4q43iWDKru4WVlZ8IV847pLlxivg+BG/tUNTLlF4NKbqD5jQL7a9rzBjDDOdGZ25DbFgrzU4WV/U4XWfprkviJigZGVvF2dh70aZHX+SajgJUfh5Wz8ik1Rmpzq7LJqjiH6tuxap0gtJP+2FKFehdL1CGcoO5ZcqK3DLBE8BR90sQoqDzYuMYX5jZcMR4SNkmsYaatWuoiJzoJu3gDfoJ39NACJiINF5jWuj/omYoOVgPDp4sjOrRRWOK6cRCW/bMWk5HVb0c77XrdQ6Ms65BbJpdLAaYpfpUmP4BRg3+pE+HulCBNiMUlRTKhA7khAbjQ28GTTn0RiyTCJkI085A0hQOGOLdtIBOOaW+qAkiLROkC9h4iWVVk40pHJDLC4lHIZzBNjJfkLhI4yNN6fH/uVb1hvLr5aoxXoNaVdxCKSvoajl0ogFYUvXdg49rCFxctZPSlje27QJmuAcAK8twm3tZNDc+oy2mUNry16HJe5EZ7cMcaC80Gd7BEaK+ZzyuTmL53AkCnPKfYvPxeqk6Kz7EuIyZMOkHfzozxE+LkoU7oLJ2WzkGMBaSlLylvu64DeslPsAZZ3APoZr71mc7QdGbfvXdyfOiZuCPCiNqNt3tzjvw15C0Z3PLFrQp5joMyXdaRgW5iLqxstbcH1zmY4Z6CcvKdlk3hvEd4sIZDiUuE5mn/lambtlZDL8EsuxluXrofDzzgiPhZjVcwxgqaO0/WfT2Xx90SL7COssYJMXm/0CGHPXQUvNGaijhf+WbCOqFxkmhoVeM+FSYm9OTknk2KK6JVe0sZ6kQkwv6CEx6qu55jpFGebaLzZbixY5zfYoCy5hMKH+PkROGsDdJDML+fYdN22q7VMc2Wbiz82zaFOww1dkVRU28Mh3Bka3ci3jiHws5VBCKyVzhCE1soNGdtSHSFHU8GPTYq9+ZBr0Fh7hLuAatmt2OyeV4J5nV61an5fKNF8vPJKYZpd5Tfee3PCEJnreEPo1LILg+4P2yA/lsE+Ye782Kf3r7/RGANt3EsbywfG40yYrUOL+98L3N3o26b302fi0i7xxMeHTCPuCuk6bVLKLDP21ywkmZ7Aq4wB9VogncUUeDuG9fDEjBBbKwUVp2IkMX9SPiD2MRYREBWJ0QrX6/m8eVFBzoHCXu+xuocnZuEYnVfN7OyEskis9wt3CDz2W2ajZNM0zJkxkuqguvisvXW6FV0YS2jhAvnzxQfRmkg5XF4ANaZUHC0DDsYTuHU9ICKqxADQhoHosnfZaAqMCbis4yLuMIjRIxvRCMNt/FHK5CAtSaLR6HYIGqxPZ3it2mKm4x7gB8pEOc3gNt6EJH9/T27ip63AYWm26nI9TTdmonus7jc5zpmsSMQoOjxkohKdB3i9+5E9Bwnjr0YWhMQ5aFl0+VCWQAyB+BSHSXoUNC4yFGTH1rn0r/JpaqcHsJ4Pa9obOad8kbr8h3uggJVv8y5GxxlLgFLSuEdVu2TIP3z9GQXfPUTSwz6Pc3drlxeavK/TufjBj3+gTwOVbml31s/vxjNinHp2Xx8YmjBZijEDD7rBAM6g7QovVY5HG9YGeayq2w6txQxuTG3NJ97Y62FppEqB9K7ES8H9I3lGaYjiKNOftbU7DJOE7ewWWKfWfDYeMGBKkFOxiqNsR/Maa2Oo5EtDfwEDwHkAqHY6HkBTAupUPmeyYcaXkPmGARBwpk7BTl7EupJgevEzf6uBZTp0C9wKJHf0cTOgmKXJvzx9AgQasmBThbiFE7vqBQVW1UouukH7kf02mKlR8m2t0rpastbr3n2V9+HKtmcD9C83DhXAYhnvqf0I5yQoPtT5JN4kkrN+zIUH9niuCAYNGnVWS4vgsSkbtS9trgYt33jrQOOeL1epn2AX82P1qCcuts4znPbp/rLij9VZnI1KNLg6oKEPqiVNJLuSSoyX+7fNsBUMs20SEBEGa54SYvSj7ixShWrDM7HM18KEOS5qeHLKO9pyF0fI9jTteZve6epOpb+jCxKphX4nwyvIhoChUonP083PVrnizRhcWpLiunDUpTslPXG0m8DzPuhG4s8mu/EwlGvDAhCSLgHEaJRWEj4nHYliLa6YeYXAeu5hFJ1LqjVg5C9FK22l7dtrGK7TPZsUCjY4g503K2i2w+OZ/mTcdkV9bKbn/X6Og73YE+i6vi3S00FcqvcQMj5KrKFlSRc1IoJ9JAsmEeZXrD9LWHr4t8gtd2TDV+ajS4m5rltMHr9CR+4c3dawTDUnuX9iE61RLmA7cIpGtEKz9jZfFyGZtxTtgaL1QSaj/MRiYpNXQMC6E7htAhsZYi8H0/PZkmZ1i6YCs4B1g9L7PSENpHu58dR829E5VnOyfTiabPrTw1I0avV8LlNLMWf1EpqIvDW6L0H5JFPKLCdFzkUAd62BYWV4GANfOLkP7OdUeSxdBcTlPpyCAQjkfhEz570PSWTMXvMyvHlAo6xKCeGj74tWHD9GZLzcQddQZf+7nNzUS3rlccRZGm4o12B/MIrqutUkXgAoFyPIaTKgVwqolJSyWIpR1cSESh1FrN0eQpW2NzPIjEuqxywLstQvejN3b/W8LmpKzZzGJS8s2n9QKWQFNUmc62TsJjGpWX49z4xsEtL9DUWj5a+Kq81lMk7U6SxPEkQ7w6F9Rc3IcYqQE2dMGT8oc6Fi+nRrB54jy5GRIQq685UIJdxBD3fPKKkKfuWsFCIArQ7saDgSvB6WH65UXpZExTpzJdyUNm5aWavewbrF4mbtJqr/6EdgD/h5SKx8mhIbTUUjs/KhvNk4q9a+NxjFXK+4OACA2yqmMuZaY2loHZKWwN4s6y4OZLybOpWjgzsluF1QJocjRbYz241EnEl0qIWPu/yRX08HwS4ePb0aH6B2WHdLXoxiC6PIf8eQtbkQpEnhbK21Aeplw+wXSe0QIt/sf3NnIHrUTO4vYMx1qfh/LabFRpeJuAHXCHrk9z7I3IFw5cuqtFD/6gVYOGoSWeuIiMNhGUKkhjxS/nepBAT4I8KCyMjczEkjVVQUM136gyxDsRzvg9g6qWegBs1sjdSCgYTdtqgbUNx26EQTp/2mIj3U84Rz3bGu7vmnpEhE80LVyhe+Gz07vhn3S925KwmxxmIPE/odnLg2Zea7Cq+A1Insaewm/amcX0IZ7CvXnu3E8k4d/zjC13H5ERtv+PaKrrXkVnFQ3IwAzY2Rn5Aw3Tmyt3JGaZXAyg34axqRRLZhjSMGkD9WsWRWDJtgIPoEAlZ6rToNh3VQQ2uW5XB+IJMkQtrYgBO87gDnMBeHEO10g5UNcR3wbWxL/VAFlonaEISpqb7q18AqClaLOegtE4nyY0e1Fn6ieyxC9pFYPFUyxOcDvLpenxb4ew9M7/Et9xoJarUVv80ShRBDnlQ5PRqErqdMZt152xj/o4Mb7EsMy3sfo5r1+sqaCtYD5awxfYvaLKPq9e/jvkORJDVhUezuiwSotXEjOziygMR0LcndwDQWILGRvbjGqnWhHnjjuV7PGrb7tOL4jc2Ua0PO6R4x80slPP1nIDs0TL2jom5jj01pA+FrtXRDPl2NVYiuACdEhFplWVRAVcB3k9ZZXQGbby6M79q1j6Oj9UAxPaFzfTldav0wiV4mhtXmPfK9PxZs3m5O9+fIMw/Cfpc6zyyIGDa0rlvsiA3mniXqxOGHs9kygulxrSEFGK8sfvqmeHu6IXRpfL4NVPr0IZ2y7h5ow+8r6wIoLX9G+8nbhwU8AeBgZwMrs2uYaMJSEieKh4sBdC8aFZKbDWzllbHdb7FKgf2+iOTF7RWU+0z9DBbzgzKvWiMg+IVmFAxyh9rikQqVSWINj20QsdmP2w7nlSVwgBMlQVEMn2ycjXoxpKxJv/7MANQnLI7wNLS+TEcOLnxSe4VC4SAMXjZnFCaWods/b9cqo0kWP2/X1bh2FI169/bsLklVQO9wFHxu+baHrTPwIRyga2O9ruzCEskBwkT0Ffzz9HcMpV6jPGHBil3EG005Ecs0AyrxYJNvjxK89HBKdn1WZdBhyPutDQLk3wz3rjRrZzgqoAL2vscw+5J75HWst+sIyaDoY/CLMQnYjbQGN/KTLgfxV7pVwBzQzdtSgNzVxaDkTwL67Q2YUl1/HkW/zEE6LoKFYqdY483CODMRrl098gM+VDb75MG/6UFgillRClhStGLkZXuKwxzJbvNHr56SC4rS3SHNsZ1LorE7HzXDlYtwRzDH/JOlAkM8AkrGesmovDbhzJY8QHsGVZxaZy2qv5XHV1ul9McJNGj0RQQ7KJWeFF5P/qVfbvfavNBs6Fj3OtvOp2gA5NKwNQJ/xFc+jGc8xcDslpWqAX6ucjaS1W+JfWeHLUFgjjSnAkqAhW0h/l/lvzAL2OUJBil2X55ikdWPqC4DpUq9GZHKeOlMMWcN/uZSrTrmQUrmLQ3mlG3dC+9W2hqM3Tddax+NHLoVRush/38tT4qQc+ggwnUtcqDPq5DgQpODk/TzrvgJgaq3C4bdFBJzhviH1k7uAS1/bi8JBYVv2MtKi0lc73izsr2qi2TNlAqrLdRYjt9HKw8UaXgKHNJyCJUghzomY7gt5jVVNgm1OQXD5NpEB/Ael6HfgDd5gtTCqCbnSrlmZEMfvaBOM3ADLoRX8oY8OtZNY+RRxRJaSs+5vVUqoeB4UQB+zaoEtKha1CFij2rE4jLgJLcjiY/tG98UZKDOMUoB4IFU8FVzU9zzDXWOTgMoSXxQDmL+drvz5Xfj6L3F/bV2qm/pBxnGd6x1FIGJaspfdiQtav0Rctq7t0QR/2r4x7zI9HD0BhtZRyPDfTksRZZ9x6EmBkz7OPpNCef3o/9vZ8MwoWTDDGIWZKLb+pdU3tNbyW9J7LsrCK/Y3zZBx67GN7AY0mYy2aKe1KER+4+j3RyVnX6PcAeLzHMa0umyWeP4BGlYrvHN4gDlup1mXwxAuW1QinCCWoUTYz4iazJolghdMJsRjuXdlYHKQwQfjwg6FiNctEDpuEynrNiqk6e6W1KhyU9roB+c58RkkpeBNkCzhhpU+MxwTW3UowhaopvrzOE/c5tdD8flN3JzZZuaz88uDefv7x2zfepqwK2L9zf/dKd8bsszV50+XfIK9ViMMOVLAmPC9Uq8aUPLADBnNOYMm64T0eHdq1uGL1YZ0vlQYolqkQVJrSoAHnIg88KmWDg+xTEioLYI2Aep5tKv7peigEc1kb6BVWio8qBMvVaA/yNTeRoip1AtdugqdrUqGLx7asNVjdJc5xWLo/TmVaxkxUQEFe5NhgQy135fEXkC1AovPAbeAEYdO/RCqS5Oj1ZOQ1ScuQfLzgeXYcilrw/aU5u7LybyGgg7oqJ7J8ILv1FckrhSboG6BT7wU3kR9ZFnNW2hwppoUXpZMI61wtebzAM9KTBeoHPF3KyEAdmZqr/erAIp+iEFOaJiWqOpwVz9qtiCcteOrp5NP26/p0K6wZAPjKsZkG9TYtUS+KR4MrzOnPjRMU8jperxSYjxaF2VGFUmyliOCdJIL/s6RlFdx7w42h+wJ+gXka9yGrClFGvSiiqAodMx4nwFrLePoLrn9ZonCqK1bWOLdUsm8RRFobeteveGj7fJJK+0kjQ+pZcp12EI0f0opQIptZibSfmmHmwTh94BMUeu6mK+u99ELBFf22a0zMRGOcXGe4wZzUAVzS3bRY9DqRKG20IOwyjkmXCxgXzKOewk3ETEjpFGnX35+lpbd3ZE14+5Yy+eTnwUjLrQj63GQp1nNCvP7rGkbnasoX/VmGvNRBZINRvccJ0JxaFmhiMXDTrF7OHZ38+e2D298f5mTmOmPbsr2b/avbQ7O+OM24IVkgJE1xPCchfd/sCRF+iKjL+HvliRHd8pNWjaUPOYC8jYbNM4lUQ0fvTYdBcBY02IaNPkeoVXYgMuWTmrdCWC9VTn3jLL9qMA9/8q+nO5L4J//SljmKhp/jqSo1k5VL1oL/yLuA5C6EPgNmxXgY21mHrlTHPyllllVKp/7nkGreGZWLgUQH/4lFPnVFoefnNC5ICtJceK//EhLWY0C2f7AkTnDyx60z2pKh7OUA87YFp9N4/IWfqpafm/spZbu9878yrD2sWK60VqjxrX500NAsbMKFQuzju0331HxWv2IOp1ZGpqU17lfBVNfAD3CMKc2jqhHicAOJ6HuPWaBHuNSrp+vtxjRISR6ovILNXQXRSDIIJ7GHaEVXwHz+o9T0sqyQNUscSVM0JSFfasmdfOvrYjwFmKFPxT9CwiIATAk6FXVq8UuhnaKpZ9ardi9jr6lWDAS7NeNE0zDV5X5puODkGegVFBi6ZqbZ/siK5AY5YqvEA0x4qQKEA5NBnbqselcrSbxeXUJpKktgpaS28R6VY4RPUdUnbhVOQhfMb7XeDlD5WuJfdtVi0JBvsd8FFr+Tjad64Kbp93OwjrH57iurZHhH3TH5n8VMGsPHdPNyumVD3Z8vah8CgIdI488pIvXHoyYzXqqVPLRrvcbqLzmLvg/cd9IlkQlI8509bXnB4GJ9DcO5ctI3H+ReDTEhEzLGrV2TBQLW7/4FPn962aB6bx2Q/T3OhOl+oFQQTOHg2w1hWzuQd+jV4HYFs4WacbEMAR7sKRPe96unHUR2sJut0d4trOEYxgFOcuuoQ2Z/JC9JPnMXvMc9OEpkdibUUZuD42MXUJkH4p280mGMGO+/JHnijpYfGLGSZGZmixAUbam4wUTw1q5CFLiAhb+ad0KwpLoM8qeAkaCrow5qExg3tJm2Md8lvgYI+hTYru1KnpuPCuK68Rbi84Co3ndiL4qcwutAV17Q+eNpLD6WzYiULZf9Sm7dyraJYLa6jbe9cEXXhJ206kI87rTOa19scdux0V8ZPNEpdVTs22LZ1myBVJ8BnRgrfsCigjaqPHNvw6ZvqTJ9TdJdKJxQWhFP16MIFRnBBKbEONqrOF6O1Us1DRd7FQHNZ8XDmuD6KTuUzgyizcQb6jsvI1TmfuoU+USCzFtB1of5ScZ50nKl1PQqqOB1ZyOJL2ERJ3PdaOBr5SaPut/9vuUjQmmTU4pOy7YAuy2tD4TqNg2G1OSftFRcaOQnAwh1CR/LTeAyBvsYKjdf6iv5qdk9bDjMORlQtseBdaJdAHnAt5T+0191hH8zA5JTa2/RoOHXYyNNluLsvYs02FnM9mVry+G+TZIiHJw6BF+2MMZuLMJPZ+glhYbLS3ACQl5TW1aR30/TXPiAkWEmvonW5D0p15VPldr15WFBPN0ym5GyUVC8NnBJkYVnjUr2aPW6cNLH1GNRyEnrd+VWHQKs2szQnvdAfNP6ro8nI1SjPSg2JhK8/Xv9k7xIMGmi3P5/RiU+jE9iDvcrilz/bmc44dfNCyWX7yFYgEd0O9DaUMC7I3b7mcMp1QsVIa3T8QaCd/04pnrgogMXWozYuC+JnFknTS+HEcuYYZ/eCFn9eVmmbjTvCT33wEqUmZ+zid3z4iRU6oxV8Mk7HT5hIhiXHC/E/tmQUSYPmg6lt6Gvgmn3nByg5ZwwK3wcfKMB81gtIOsz8RVFTn+0kqsU90kGEgOdZFsmHmLquuh+23csHH55XB3ua5F6+BVKvlZ55joOASgQwfgWQT9sPDFmK/K4KacikIzeIgCn8QOYAwNvAR7gJNuBA+ayDgsr7PA4V/Hn7aHq+Isxp1SrGcc/WLQ8AS5BlnwzPncvKqvN0XwsURujyv8vK1lEmhieJ4ctkk6jx8yFVUptZDYqKrsU9EYZdGc1Wryew2VvrT3TLv8S2L8/9RytmFis922KFyY99u4UDoPan993OWx6XJPqVZcfHgOrr4km5jP/KFcYzhRGAQ/j7sR3heixVWXmqzoDdm5VtZ428IaHv6rQf8ZRi1lwDo3tqTTmxZxkHEiRY1HclTZBXP8bgj/ygsn2+CKYVZ87eddEvQ3JJlJ2N2kdkk0/qZ7g9PlZPnSedXlcifVt0NJY77W3xQlNxNG7lOjW7H5pU1blqanK3MwAEQbuqjasniqDq+IkXCtA+/KLFpT5S8on45IRLZQgARtuUo2fdVrfVOcbNK2fi/jJjGXTuQmjZHvsuxBsqT0BGyUvqsOuVrWnpPpJOZMGAazBvEAhjjvEYWQ4EWwE6v+lsJpMHCCKRVmnlGnN5b5/QzXoyKzsWJmF4rt2defMau/LVNu5+lDXS7RvI5DjA1RdzLONX1t+PePUhhnluB9JHVpsY6VvukO3sXDOHE0Gd5MyF/MPV/ok51OWcUprltXxfmFP5dki9phk5UA7ysxfvDmyo/ZuQpnGRQ6r8ozC31xx7Q8oURUfzvGiI0Bv8Cu726X0wWb5fjmFvFqpqgbtWBFzNVxPD5fv9lqo832+T8Y5PXciP52eznGOFWXTlItmBMchsTGOq9qYQB2pCLQy6SKBoQYnTMt2KebId53eTVKxG0YgeCzvMxKWDvqRSBUNwEvpvXV78tBNYwlGPPusIgYSk7zr31+FigV2bjJxYClb5pvuZz06BEkthFKElZZ8hZp9KbaPaiCB/zrnCntbv8aTNkUH82cnJRoUmy/3iwsQ7AvMyryzovfiFomkUxQNM9Vwlwx4tiqGR5+gUovf0lbLEa+3/OJl6D9D3tThxr9MC8/KNuGH+9m9n32gP3x+XJrS5oJre+8NFcdPn4/S3ZGWxsARhPsP6P73g1tfnurgOW/QfH1tpp1TBbOPxvYWo3hvvy9qmN7SxDM2ncEMs0ypwjhPXup6yjQVvLHFBcJSRPrtsnIGRbroAyV6DpHoo5gH8digT2HiNUV2BQ5vi3mNhtvLhVJYT+jSpCsP5DfDpD69YVNF8ftu7FWY0ixhvHMdUoa9FxA7qp0yen7mUk6qqBIVwR7ouGMdZl5+Q3NX+M+dDhKw1p76QT/udFVK7tbeK3aG9kPvqmgVIR00V/IV658AH90fNYvxtW+Ev/PjMhpFQjp94wLiKHeN0fYhsJNPESy5RvK3Gt5Pb9uyLL8oHWt+Ip7H4Ddk5YZ6T/vqn9PyQB3cLBfuVeL9eyKHECnzjOA8o56n+/CP6h4V/fSew0UbJn+FQzd1tGcwxNydI1geFsD6fWvp/c+G4DQFiXJx6WV2lMP1A0jWPfO4lhaYJHnLFMlVEDKH4F8zh4zJFUABc/UPAdstzxkhJxMNENLRUxi9K0kF8XcGx2DDaah+HVNWQcJhLn1/jc/4F4kl4tvBroQGeo+dm6AmO96p1tIfSKdBctMx0MF8BntJ+7yfpq3GTz8+Oxh3FOjtETauztpJofHbWVpwSzdF7ctFqDXAxhjQyl3JsORzheTMK4IRt1O/XJvOsO2OtEKVWYq95XwaYXL+1gsIOdfq9iyUjg617fYCLZFT9wJz7LazYWQkLhOCHToodxSWRZDTV17pJ2ZjEJGY8OhNehIJpyJrinE9GcoxMo5BQOFm+pqA73CujkVniS3jBNix+khG4h15MROwix4LIPdjOydWUdOyHYarE161IMlW8DqQtr+vrLBTuB3L/+OyytzslDvtKMqQESTg29D1e5aAbtwIfj3lHVI6SYq1LVONYxEeOIL/pJUXXXmH3pVMZZWWHVyeEwq/6odvkIWY/4zj8fCJvVOkz+FRV3gxuQZWR1b4Glm2P/EQXnS8gfNe+oRM5PoYF8jOxC5Ou8UnrzCbQI9tWuSsKEJo0lxNnnORKgZAvF3/SlDcKWjupvUMlAznYwpJWq2YcpGBzOevqwQdHZab3kH4dePhc4OnMVJfbS3ZOpU1L81VO98tTJ/Vb2fd4hgBBlTHlqPWIxh618+rKBGja/dyyP7W2djRPIMseMXvx0D4DP8ly8wc4HsOWmP9RRx3zUlC/7O558McXCE2lyBN7OhWLTaN8zpXZ5D6ZyjfKO5Uy2g2vVdVb7NBBhyUqH3JeEJmSoxh/cQtUZ7hOu+mXTvUIFZKrwIbrMqxuoaxIUN/aKl1UN2JrOv+xFXRtThU6EB5LKV/2IOkM5pfmZAs8Mfd2LiH4anTf4ZdNXuSW99CPvhb/QR0Q3vtymYT3Y7QliIaTmjdN1ZHI76lYwvaeiVipLauVodoMg/OFeB/2VRRPskPeNWxnM3RaoDW61ksvdCZWbvGiuR/N/VrXjFpk8Ah36IHBaweQIvV7Xj3e4SQ7UG7HW2tdzKuDhWJsHp7NGNgDbbrRnKJKMZjgiBIMJlXqYeADPgC/PGwrC01517ArPDLbPLA48mapzn2vLYmRqStTU3D0HAhZkC+JGn7fW8zn4CkOA9FCb8lC+EuzkAuiRK5CGHDyThMFnKfTjIHjmcw6PQ7ohPTuvGQZUJ1bMLeuRM5uwAixb2jimNt0q4NIhQp7+dlWoqqMMIsKpP/L5L7gsyEjIKC2zqiVjvRSKnIdb0DAB6KtIoTVIXybChpgkbDRjBdIkda+vQ4UM5S/v7rvaVTptRTb+99sZepcD8fjTkSQk7gdnzAkKh85Ig7J8ujKoxOoMB1SJcgZNcuU7rpY77GpaqCgZI8ryYduolQquz3JzJF+wPVe6InpBxcUejoRM2cyaAVXYjemI46n7DODs5FKQZ1m2oySXRRnuhRfpYpQ1LFe4IhYjFToLkReHKhXfTQNrNgiticcXKdrEeHEfkFWECf6xz48h8aJ5St/z27MszbTDDmbijsS7/5EfOG5zx3o7uaZti4VrZo7teVNdNdtT83TTuG6cPftKYYv3AlN6xso3z6c5yRgg4Xw49SGo1h1j1bBL+HgLCMBvA7fW91gcu6ZyJ3EET4PnUR0h+1qIF/AF+2Sg4X+RGNbZAPQAjaHHQ8DORqV2pgfp/z9BzV0tgFYxaFLMzB7OsuY+CjGVOvVVmmeTyS/abwcJ2ywaw07xTgm2SdUQwWfjxfF90j2ERzzrPCxLBcoZ02Y3ew09fdsPdvOrs8+9MAQBXAApbT9gmSLRXI/lJfx1O6MOqfNXl/0t1Qc2GgYlzjbi1vDF4/BVxiuK3wkbyJ1MlJeIj+98RTp+eYXMr7OgBSdAO+39A458PM4mCvawI/7fuzhwnrZ7BYA1pbYpP0jB/9Nodj1ByncTJrT3tcmQWuGCAXvMVGmIJ0+cAt3KW5by+/6zlJCjjjxcn4qdI1hu4edsCh2H6cwPkhUOHkS60ccBuLi2rfmv/rrGZixdf41o/HZ/GeFa1d6WGurm1dac3rAVJ8rAg0yXb1zZrN2b/4tbedod72n7ERE1ItbCpfLu97+NObDYsxEWOM4u3jiyZ5QOPR78vkdb7B5eWDm6GSgwlvMI6ouNHsTKVO44dahjRfSPEJ69ESCl3svSHocZ2IfLvWzEeeZXl6wXCjmx5/xqI3Jw4z0UR1Fr7tVyKsAlaM0IR4+kbXBRO1Dc0ZikQOAwyAjN0R6EfDjIPvUiex+HZXGf3+vq8uYny6e6KzSTzYpAn3vgg5oHSmonLyweU/k68NYuU7y77dF4fFKr7/1PtR6Maqiu76154WbIk+4eVs7JS+XIhtBhdLZ51Z3++RJkx4smr4e6SBrDdzKS3ELtn3XUK4gscHh8TTUO/nZ+Fa7iYvopvuEPFBUeT+jWUBphyr1GfW/3wKczIlRqzWW6pcGtbBG8fq7DvomXZ/zQeZonpkfKb3JTuxuNztBfUGoc7qzSMuru+HSdyUsKeIInYkXlIvRH0jB1dIPGkj/V7vuabj7lvY+xdNTNgkRFzf/8wNR4pl73jRgWHhjqkXXLmPJCVpUQ04yj8JIRV6pMoPb3QWrZarlVNSGwtBsyMrq9N3yW32Ey38E7dO2yn1czxEkSa6pkkdMbS28cUOH+/CbHe0YOwP1RtNc2zLvmvrgBt3bO4+/ZgRYkodoE6VE3uyi4S1kjrvAwCwzBu3TxbJ6kMTs4WWffLa+DZaY8XKr164bWims0aY6ujbye2PXDPWxBbm5PukXHf+aFW6wThZIE+rzkhc+1uz3k8paMdeCzkBbmKV8yN/B+TXQ3fpXeDXRB6JDhiyvYZuToYeiyZ8K2Fxw2yQcz1PY7uMLaG6w4u4W/B/4huoPsbK/zBcXLLktwElJz2SfMY6nTk768LIsbbQxeHlcKPsC+2KyNILgzKnWk04CDpifYo2KnD2leeoDabDFhZVE4/hucftdS0wN0xjWFRnftMxRpJtzT9i/krWGB8HkOit1NVQWm3yrQsC1EOC6PM1QdPhHfghu87wAF3X8rrH/uRqMPQYadhqN8KYzDq8+bR6Hx4x/IwJOyBTkJaKJAPArqhmdiJY7piyjagb6jVDjwqqGmfqhU4gQkaXKSIWfqpDnj5JX4+N77T4PlcTHwiwlgbcy0rJjEy0wUNsED1zj5dK4vdY61WZ52U6ry/JsaOzDr4GLoMSoXlWHGoiys/QdvN1oDeE7advYjidNRhZexlDB+t3z9QbsgpdStVex1i5kcZf2tR5orFwPXfveJ6tkXpYnjX3oRaLQlfy4f1YuCrYwjERre7YDQN0ZUHdosPdGC9a0pKlRuE1KiG9cZXy/78FRdvs3SkZsE5otDKewX4oYe3wXhe8Zf4BxZN5WOtWTNmaDMALtkdia4Zcg1MbyZqWwE/LeI6xaA3hcvS7Mw77fcs/k5GM44dXhCVjsn4XRxPQp9a+HEDhtDgBYqvVGQI05/vnPf/bJWqbvrnzK2FYBlAyySXKV1ZiVwqfEiOYufxaAVF0Dw1tH6e/AfF/sie3rLgmWsIKz7ke8/1zpPeuMVG3IrPmzqRf0CpyRfcIX6WXUSV2eSaGrP4eJQ5tL1j0m8ikrADWaHRPQOI4LSiYI1NTecdnoCw5GNRGKRckTu5Qt64LP9jxe/DgOS+shNNDIsPnwzijGp/I8kpr3eFtDq7c92QHbe4rSp2I+idO/re7dqJAjBTqea+aXMK88NKzQTg88xYD3ZBu8rWLvpLxN1cYAHwnDFbxMwUe3nt39uPCFa7/4jQYFIIUpV60c+N8j1KA2dEOgV9xetfzzxmEUnj1EzK/4Sm8KqwZiRoc/92EULAPfHv/MFeduBx6tTsEX8cxVD9zz7NAwRNB99Srvd9Zqen81f2L1zy9wQRWwrfS4mGryXrBWfdQBfDjjsMfiE0EBgU002bvVrnYNYkJM/zg8kkDkaac+CoHMwM3L3ev1bV/iXS+6rds5l9Iz2Wt/f2kx4fjRMwOaXLOYjuSd3u+EB46EeeN9SeyUN6XZVTnwDLSRmPNacAK1QpOc81qHwGRK2Png5lsP6WSmrAXEZXvKVc6WXz1hwGwpjCahuvddkx7LovsyQgV4QJv+bb1SwPAVjhR1lpIAFCAjX3sS+Em793BK3v+GrgCoBfvhvuRH+vh+7l2PCV3jBPy2jwpTQLI9Pqqr3jyRf3gIwqXttWIOhWO7rC+eCb8psTdceOni/Duwlb1A+2Hv+1wD3T66bevtzuAO4YLAbW3O+DtF/6cqI6z63zjztSk1bUWP47Ar+qpJAPrZNqxC+sANkEqvABTdl9OX3oh8R1yfVQeTgzunrndBvXNoTgHw277sZWQDDv6bAlYcxDjhLM5jBFnUEwl4bddLxy9fKaQs+iD5zZdGXkaTBLhMgiZp1fx8mfBACvFVzgP4X/sXE/G+85PFBE6nd/0tJcib+34o/guQdgxj4Tv4k+NDC9GueeH79DO+MZj/sQ8ZDErqUDirJI4UCJWSMGhjwUHZtTQ89NTC2VLYdw1gWWpd2jvNcdzjWxA6dr+5XWTg14rXvV8zda6mE4hhQsl37jhopV4dTNUaGmkL4yumKYfniZ0Or7t7+Sz7Sitvs1N4X/ka/X7Xc98i5J4MY2klsfgdK1C089uaJFX1UUsJ21Qn4zwyfksN41jrSONf1teVMxBE/vsNxYrW8flyzbb2r3T6deTuRptI6mzp8EeENpM9YEBwh6AXNzvgvYkOcgkgRMhqtP0ayaxuTGGuTrrX3sabf2MKvH0wXjdtuavhFkHAXpufVqweXX7xNKSQ13BnYcmGzTdpAGLIsYTmVmOxruSBQe4NnlLNsHxIR50VgxpdOirp1Fabau6nl/H0aqB9MW7FzIxGP7I0aXSuJ840ug67VKE60yDL/9UkWdMUrCEbIrANB/vTfbClSfjA3mvCGgoYhFMks4IuabDqlPNMPGnmeKKztdqdxqLuLQq9K0s9As83DjEExnhZO1BfCqOWoZvRjeKPguYqpznMILezfC3AiXtCuqXbO5kNROkrLwi4HErvF4zIRXKDKEPtjTXSkyMYpIDFdEUTenF2Iz3hdnW+YhV1U89KDs+7Z8xWY9Ita6A+u8soXn5CwtuNI0C+CRFjc/4iP6L6Tf5iNZ4yg+kfTbEU3XVYG3b49e7xjyMpy+I8AlbfzxQWn9fRO3XJsnae+hJ5GuJn9gRowFBLXIrr+4ZyA00PLpMTiFrAvV4pmrMr+LCv55RHhNbA916u91npRagivf9hEtpdQF71jrae04JWVKrRuPIk00Y46xCIDtSi5Vu5FBKcN2tYoMAL7KbriF/+dVqxSp5Uw6GNh2nqugTylhsAyQ2N16Ffng9Sg38CBr7yzHIJaLsMyDoZGexGD0ocLpY7UrOd5ES/1YN9zHvUzk7RaMtGHgAn+cuNh7oWFs5ShmBFbdyn8OIRRbmX4fqEGdqLbw6LhoZC1kgTccAyVOBkiOJl4lRWLvQpIJOSjT+AMhHSK2SmvshfG1Cb7UWKD7938XFf2H+lY28jp/S9OtEJ+60y9I4F8fPjVP/OSVmrKi9KBxmOJdyL2ACdmw2eVn1DiQcqofz6rqqKg++uGgyxrmlU4IMOnc2JhIrLS+Z8t7ce+fYqmqE8qfweTGXD3td0qY5/uRyF78FYoh1aMkZoZy5VsysFwDL78E4xRBFBWtIxmEzVH30JDAW5doXFYGDlxos7X8sC3tZ0S9dPy2h8RvPXn9/W1jMNr1X+J+sxWsQPbru7WUtUTrB8FysmyyHX7F6mCZ2uTXMbQ6g3x9W625g7wGsOvXsV1F0d4KLTzaCDZwfwCsJtgHgVVbEN6jyUSqXMU7DAyyds4K0sTIOiGDbMPCtsKitguZHiVVUah9d7BeRRq9Qd2Jxlv8t4M3ZZpIu17KGOCNkormdZBWW4UppOZq0we9TOHBB9urw4e2QijfAGEuKIWH/e2S8Y9zltPms/EF1l6qQHItDdimLYgz5KbWW8PhW4GgS7r8SKYPx06EY7x/tZ3R30kBCcqfijh8agcK69EfEetZfFvLVrrm1/j8Zo53BEqashW/3dYHMnongDhkLqNdgOjTZIRfP1x/cnAEmvK0hRBc1DDVggXwVgZhyrVE3Ie0V1Fn9x9hjp/jjo9fvkWIX0w3T+WG1rIPlfzYDIdGkNy5QbFbzvV/vYToVvhNL2BMQUYl0P/bEbQbeiQp5Wi6NN1zqjlWmxujP5EwyBUGJP5ARUKBR8iuF+VSgSmCY+MOwn9aPgbHAqPLMDjr81BrBFPfmsjz5ksacenh2eXREHo7Qg/X5kPTjtxqQJG2s+g3DALH+M/pAKci1C2cu7Ep85iOShJ25OlT98Wn30s6qf5NxDdyVQfkBQ9wYP0N7m+6l1edIRisabvKXRaux4lbw+0P5pZO18kOYfqGsNOX8AT4BUX+J1jd8VqE+KRyXTE5rc70/T9mhnbGb7AeQ+/yHdMeTs3MHT+/n+/UMByMEqpoBci5Zog4VYFHxvFBNkXoJoh9RrYACMnMZnd7ilQexpvxjV3najWITs5EbnVHxg1Q+OedSWjSyO/l1ptYYg0elNU2WpL5CuFzYZE/bMyco/XjsrQMlirugkWnmDpdJB4qLGzOJztveYYec/nqV+V/ZDMCNb3qBD5GOJKoHSenhexUKJOvKycJTA77cmLDXfSslLiY93y6nvAWsnd9ffYbpAMmmAip9+yXZvtmTeHN/CV0xvsGQJQjkzr6oxdfqvZunCD31qNmljHrgObQ7e9aqw+FLSfzFqFdkLHs3zerxkSTgNdGPDkn21ZyKIm2FonM+Tn7jDcKMeOr5Zcl3BcsV+X6PD8hRLzdk3Ou4krDOXverQM5+OeVQb09BfL0fV0/rSlYbiq7dOadCq5/QEpXTywu6p4o96L/QsGaSYMm2WGxVNvaigyxOJuiNVbRDiTHCMM8nJkFKKg1m5oOqXk8v1bb5Cgtr0/g/5YNtYHRJPVDSERR92fn3Iri6JTE/SQOk4b4pZjkMw0fAbpG92TCis8E6uqoMKUlXZUFayW3iuxELpew0bkCV6udoAkKJJIGKAeQafxYmrs8/l44PYeNe2fOtZj0UdnEq+ovCdN4fsVnpwTRxmGBv70zM4j6cfr6KG80WtUiMTJ1C+70J2U2ncizBwIA2ZbOCgmn7M/gBKjOmVUb9eGF4o2q2iQ1zpVO3Io1e9pap3b6ygt/IxQiREulYsSMINrH31njpPxxX/6XwJvT4tIlQm013NdXW0Riha3EafTrnUXTuEH+fY7F/DTl8oTnrgqsoDeHv2QBk4bV1B+cmgtUL8D/7lYtRawx0BcTHcVxBP8kFN6nE+V/0J1RXI7w8fmMDZkjm90QJib7x1X3D7gd4dB3lMWa549EXCHan6/Zl3lN+gsfDPJZ3KBQaXAgEEMSIIr7R6pRAzbLGiPBOLjTv5mPv7h3pTavns+CF9SgnVNsuRn+zNbobjQXE320Dz1ps8siiC3FesrsOeel6M/oIpz+GvF5/oW87YvBy0JvPCa5wLe+7vuAK/TF8oSN3sLBQgQwWlkPCkrEoMYnQfXuLd+hWT2hle6VqLZZmGkSmBATkHPIPI97ZzaZBvNy8ue5Q/SgUlnaIkqx64Xe61/BtMi+QEYdkl4YsbT6NpNjzsFDl3Ow3LUFqlnVs224ssVgNYo2pQ1AAwwm2NirUQ6SKEfHmCLBabESt8eE0ZShCsrxCDzLkEHp+9tSjvmdyoYIAlYVQQCVW1IpvaGh5dCT0WKwHx5hqLVfXkCvYSZUeZEptqUDja5TVVzNSK4uuWwZX9QgkVKQqHLezhz8bQRxVD4VksUAlSbXTUp5SJUCWuIEe1wg2B16j2RMWjFSQAvM3lHfqnAb40qiOkAt5CkGDmNeNKZEJGXYCKqi8xRchK8qMKonyT0yInv78189ESBwn8D8MJRRvQPLyBGt2EZgJNndYysbRyaBrok25gC8/7ncAjcj/vIxpeA0310GVJH82RniY3PdMYGvEYYr5ABuMKJakvkH5/hwR8PALh4aX/Ed380bSEp1PgYU0X0keAaqBGggY9sib9Pm1pWh0e18YbhHi7EkeWoloSWEPMX9Kq4aYRnq5BiF1yeWWN11f38Op6cSB99XtvCX3p5TmXKk44GfEo5dU0oG5PbHe3tnvVcT60CmzheBoDQW7G44XiW4GKn7akBzQK+NlvP34OvPdzIwbrnqKeXZE+Xm4NdUPz6PDkM+PhDXFxZDLi2QfWkrq+55d2Jp9/AKeDo4PJ6Aad6mTO8EB4bn57MlaHs6jpLFCftJOmbqJldzIsB6qvBS1Hy/2VTE8eZFFkhRi10McDeHP//KnPwvJSyNCCis/XRK64vppKFV9nSf5cFoes4dS7soZVtFnT04ZV1niMf2pT0G7UDYB/NX8MxEEh6I3J4MCj/mH89TntP7We/q7hEAWg0ifDQ4+4Yvk86Pn6XDc0dpLvAvCsOINfHXOs0qJJAolqeks8Cmezdc/wgCu/qC8KRRjanzRPgpkrfXglm8RYTw5YMsc3Fe+m29PTHgkPqDIol/x+/nxoEBXltdOJmLqvErS3IVih8aRPvAJZJTUfK0IRceedEBOnuWAJMrRKNj1gG+QW6CJD3DDlEdbzzu8RpVIpGvwH6qU6xDVACrmINr0HZVPo5m5yoMACrEuJuhby3nSX18R4IX84N6peeYbgRasjdxbdoH/YGzyyg4fZfTxc84s0uhYBDahZGhCuXa4deJTDmu/l4G1TIAHOtRpQcEDrQH6IbSGhUBAuEJfVUMLS1LUHUY5wXwEiUr0haNHFZ/uiQ7FF30vArc9f1exdGHZ+iHPGM492GTxRR/HTdiPHYzECm5KvELIj9uxHEOEi875wxNCGYPqgT7kVcwdYmDZyyAvKbV2e55V9uuN9VLEBF2QswOBUPgwmlESQwrF6d4xFUn03jXXyfmoCsV7cp8pAYlSZjKLqwguHx/AZ/9MivTc9tC5VOkbo1o5ocHrS/skGoHdCrA+P4MDzn8VigyqDovko07SuIfk4lLBRNdUpW88vKbHMUV5iR7S4Seaz8yKneIV9G/T8Vw/FQSlvmFt+oEr+JIiofsZpeAGuD6GEA/8SViN6kg2qc54k6NFmy1B6dZc3I4dkJrC9kY4SVJQIlHOxgdxPxx7SXxtWzPjsyfW1uplpydwY18AAPA1t+vCn5gBBthEiTCfJLHZWlUvFqTK7RcTF833n0bdRWcGrQOeJl4pqmG85Q8xhdpADU8kf0kKVBiZgMaSpx/Vzbs6H3c2N8Wb3a1AY5oyptB8Y+GeM0SaPLHIuTPN0d0c2w9EgzqXH4CV4iiYGsgKkTybsniylk4/j8CxyfYZDLaBO92FXGJf+ejxgloGt5mtWIGIvkt8jjxN79VbTrA/ioYeEhleJbA4V2hJVyxffq/Jd6adyO2+ETAq9YpNhTF9okAXpFHXhmDtaXWD3lEcRpSo7+GkEVMh9grdudd12j5rgOiDZ5mpb+G1wBpVLikz5fZ4HNGpzBrT16fUQULN1HZCEXAFqU24g4cekXMGlDoE7gx/41ACzycU6KdcVZdN2lBZ0SKB77MU8pjVAQjKrAiqCITAfIzYrl88d9irvGowXwoOwFfSgGXbQQR58A3CG3DW0MIVz2+3t9vYa28p/r22vbtleu0e96m1/EXKGKPXiG+1QCCYOt8AAgHwgvLABPl7hpDHqhRJVLkB3CPLnVgEvPVPM2B11trYEd3QIiBC2Rm83Am4XKvweHV56uAPOWQE8ZG4HjNOjkWVnK4Fqe6uXsAGBM4QNOPI86B4IC6Q5tU25ZXVv27aKVkFwP9O0HY/VEoqEbDkvlOCFgDnwdINSsOMAXl/YkKiwIB8QcaBOvnA/1cKoLxs90h0C5wgEK2ANlOPUepL7Xpu10bYRH9ULIw0I3DbZJnUwSsGLCLutK6TOKsFElrv+WujGQoPFtU3b0WClsHijHdb6hMBLD4PWFsZg6XvrtErQkKgMY6IfPX2jz0FYvkpg9ko1yX2QIsOfHGegKYsG3xzmjbHEDDqF306IHnLS9ryePdR14ONoDEASeyZn+lJzBMMdQsg5/glChn64eAS1+ZLVb3eM+cRaZa+Up6WleOLTzU97jVrVc65dd8wGlKkPvFPgWsBnHTrnQ+9X57bm4lg6ZH0QexXbC0VJIxY9fBZ0aKcw6IIE1KSsb9+LyF71B/+5VI7JzIP0qmV+o6vwD9E7ur6TqR31ziOHs+c977V/sFR27DdGpXuJzqmNoBmK0yKI6rqj+v1o8dVe7VyGyHp0OMm1Nj1xjNvyDfOF1hTI+i7T9OAxrtkdMOqZY91/Pjh8yygo+GP5L6+ivX9KrQB6VfJveos9w9Anc61qQvx4nu7ZIR8DtQ4jFCRgBMKEk4OLnndjtUIfKv547sm5vB4mDHcaoQmweDM42Va6EGr/sVQL190FtJkA0Pn859bSQ8H2b0qJQ6H2Jmz71FsgpeZbHwWC53Lk/iQcofl+N7Jeid9S1HV9fq9xtayyX3fYFcxx6Lgm9qWOlAVJw4moKIZjQeL+e/c+bmyTbXoT5IKJD0q2O8s05dfZgYj+mxAncZuKko0oSaWVoP4YjGxgNTMfPzZyYiELOzKxuLqwObwiJjKoZGBLcGlEdEQ14eBaATA2emLx0NjxXSPji/dKLxfrbw+HBiXGZGVTC/xL6cE1+vszIYgnCBUEyoZdZ9Y/On/NBl5VqNpfbQQy3H9ciOlQywr9y7sOtp7dMr//aA94TbFcU/T4GNovplnc2d6s6fIR4Z0JxxA8I1T8fdnx0fRig/PaawZE+fvvlk6Zj9jxuecVT3+FkL5+DiE+/fkrOPckr3oQ4mSHnP3CmJww2PW333eYapXt5V5UPvkzOPn3L8Gk2odrBs5nK3Exv2Hg9h95K8GMYBZvxf49BvYbDubwkr8cwYig8W+jOwR9nX29nb39nf19nciDaVtv3vttxX3Jig3EO1s/u+ThQUWy0BhaVoYvvmXGcsZq3cnSfZdNMah9k5TVZhfjPHH48MrqeWrSqvDxCjPAlRSJMSPg4/T5ErhxsDzB0nNa9R5M/05/B/7x1oNW8qQjYpJ8gsbB4Ua29czFL5Wp0uqZcQDkN+8lRhDRfNCG/eTDh8k0zN7+secLNIyYuRkZM6Za1L38W+Wih5EoLuQePVBQ0jjcWpJRVaKfZ1aSr880pZYVZ0sqeeHxji9pnAVSSI8Z7iy+qXN3PSjFkx6GNDCwsaCOu50dfJzZcH0zK9tA3CusR9prIz+/rfv9R9I3w/bpWpoD9X8bOprfUYXd80ly4PizJGEJlAxDjt55MNIwKT6ZeL8q6t34wNYu7yCG91J8CFlStm7JMvzTFy9czzcFfLZtb08aSMInWuuKlRvPnmRUsoiOvZ+/GFP55iFRd36Q04dFzrneJbMVJx+eerdQUVU6q/IUuqYNZU/cX7xwpq/S9I7fMLGVTsY2bt+CK0+hE2s1f9jXIgvRCFhBXVNMFhIDz6Vq105c+43ZNtt3SPiyIuz3bbt3ydIankJbv4ziNYN3clf5/PKq6Un7rYmAuQkm3oXRn5Jol8AXJDwEWi8E05UanCvAYflCjLXA5DzY0hkGW2/eZVhzX7JjAwlO1l8vkjyoMDqOQMnJQEnV7Jjqlc7/c/7P7QxBvnTpOtzFNQ91Hu6MlO/sXM/9V9iXssoOP87zTwHgHfLISL6NHEquymwWqLOpCC/vJZbHTu/tF8TdwxfbPehgWnbq1+NLyUlXj5Rpl/mJU4ro4tbCauna3IFnrIMMgWGxU52xGArWwPC3jLDBgz/sNv56Gfj8WpbWiW53sx1HejSJ7fxT7Tle0gOvGccO0x/ba1448Z8ZrQCBcl7FeePtnJkeH4sCdWiydAXwX8EUDhgExNBNK683bpp7LYUCNGAYWsnWVutsLKGPSXPN4a++R0rk+a13etKlWZLX9XXVA/scO3UppdntMWZ/AtPQwmkI0Gr0X8docd++cuhRi1MTHWcdLhtf1F33ZL5appRIY5kKiei3v5x1kTrbpVrW/vd38YGQZ273ciZjfjk84uhStM4OgVxk7nbnOyZf8DyBfnJTfxbmM1icn8ZMILEAUvJp7bfAFLRwCgIEO+POJ1ghjeNwP8t4ZZl72r6HtZVlPyDQ/U+LaBv5k2NRsNhmEHP/qS5wBNiOeM7kp/EdPum90EOudcPa72GdY9lPrSNinieUemIDax8ljBwIupVSlS5ldBiXwnf6h7LB+5LDTsRIf1sxCrR97nw3X+FcNwXBK/E1kF0u+ClIwRQU6AFm36+uX2sA+oBpaME0BN8XDQe7govC83zEi2ZPJOQ4UB/u2gCoBAYg3g++zAx7dJlNB7I2HXLHQLwxbAHfm3M3FhiHHG1I+lwGBRbW6vPEJ09DgckWK/UC0xDnVCc1uf7br3ftBjbb/K4YlGLNdutdrAT2Ks9jcyPs11QGsx36BEPJFPwj1yYvF6pgyBZasC1APIXBPz8X+nAWUl065GFByFz4beQ2vOoFYmH3j8BnzE6emDGPi50xOHFyxoDAnT7CFLBTaGI+lSLlBYbnHRgtrOgnUiit5a2cv/Y+hQJHdVwHcRPk5LWJD3+eH9n2rm8FHXabF9NCV+nAoH0ckA0VRnK5aQ2JmoIEAomHykvDiJUpKNBIpy+q9nSZX3I0VqZ+6YIChwoi9Lr6S/N3tnl1D1dXyjOGmb73uvYgOQ6f8BnSfI+pyP4EuSC2SXLw6+H3k1e94SzfRSnQVFrL5qNV/HzX1/i9mazxrKmfeZ/daQ6l4cAKNCvkDRcE/cUpSsnWmBcA/UU2/yNItQIFVKFCdf/47nGrWQhwCRiAGL8w+vmXmv3fvyMHuu4yOgUBje2YwnJ0Y4EKqKPkV72z5S8VFMACLVBwT5a1dn4bFFh3nS87lFq+irGcjSm1PfdXBARgA1sh5q8cQONm5aBZE5O5TZMQ4BCQD1l3aYp3QoErQA90xqUypR8CtAN7IL+l2aXthABXgR5Ixo2FXQPQAqdQp5PrVqXvZtMrUOAtsAIl9s1+CoqzkKAgj6BxRVu4HXJElOMvEX19FQCyv81K2ah0n0u3yX1sZei3rkM15ayfv2muYTZyCX3FU8P04jx/tIOmWNy2ScpqhwLmOfRLaTmHqFv1wK8pthN69jBb/pDlYurU5dhlZRfPTzdy2zRh5uji7LIk0hHHg1FsK2xSaLk7wsVGSasYg+3TLlnQvLeVKg9xy0e96rduN2p+T9ESGuPj02gxxMB4onPz31+/sKcU7iyz0zflvGTBaU9LB4E1sprFMxAU9Pvirh179odIsP7Rjgh0dtho1NntHtR/fglX0rMf34pobZtwtsZ5TdggQeExAl7o3qLLZVNNLSK7uMeheQsEY//lq7xl8cBaW3gmlKT+LACjqjV0Q2RglLLk4THeOSaJ5n0uyZLEFp8rs3919vveq6tev5v1BZSnI/nMersk4Yw35d1jwdpih7AhEBZdvfNhg3nGuMjgTnwHpt1devps0ycxyuI5wi6jyEOyvvCU4tSHQTDKESUFrwdCujL8w60PJq/6NJj89pzsnTMWS6gZubf3BhEwAhPsMMEhjxgbVGVb3zKmrz2LkPnhKArYLnIOfAElqIxlwFMQanh691aecw8emZuXh8ggYOIy8vJic4ts0X+idFki53Zsjo4VnQdG3UFRwAHUBB4qkeB0ipbkccAPmkkamWVJP6Ok4F/rxnljkWwGHMFkIuAMNhLBYgqce9f+WCzED0PCDREJP3U01kyPX1n+yiKbv0B45+RCwuPq1J07nVAXabNnMjvF1igZKt3q2UdnYwocdQ4lP4bLJf7FBf4qislPsD4/AwOS3ZbZurDRzq3YrMmIkmsl7f9LCyAK42leQxFbMYrqflR+4i+OQLU+g61HdjtpSJeZkRinR//1CVl9nWLJSo9giNW2bPL18d5JUlLM2Kt3juOJROR0HaSnTIkbOnfyza/FIcSyMh2qy4+83gxGmaOk4GkZGFUuvlo4w0tyO0+yZB6oKj41xz2Q7k61PH1tvxlVJrrsCfosRYSqn4Wu8gwEiUk9ty4tLglHVgbdblgXenNKr70PK9qrwIYzIqPL4SPh52L6wahgVAn4VwkY1Zr1wWvb6dHDiQuOLzScTWudc/xjGFR8dEQKstm7y7d4S27ViYF++T67bygH1TWFawAuPjokjIau9+j2LdmcNw9q3FySl16K7HLPX+m/eyHkAgsZhvQNSzSlXetyijqdYp6Mlc0Bu4gcKG1Hg0psemTI35AvUFmQr+D7EBUWgookOx0+nnzfeh66dR6EwoJAZ5Ul90zumpRA78gwL/qtQk8v2zywXj/P/khH/olUQJtuz63wbJAIJNlSn+11mWW5Gtx6/N8HspOW9VNMfQTGo+taaAeuzRK0y2P9cwaXQnBIN3yHYHM+jpBCsfgO8y6/4OfeE4z2S10XkP1stQnpkXILuP0wzuZhkK02pj+qHNoTeh8HFa13E837R4faPJSy9CxtWqpWdlKue/uWgS2NjDhMNIOB56uaORba8dD0+tRkejQTE8fgDB3R0Mf2edE/St8cRcikJ6fmoJeSdqy9qkGEZzwh63NG45YtA+3uudmpUi1agbY0J82jbWyoj/PrObEkGoilYcmBTlhE5saadpNe5EA+hRtZGEaNT4qnBTmgkLkmFf2gfnR/7jqAzYGuE8Dz4ro/8U3vVKsboHOMe+ydxepwwZOHEX1aU9z91QZKqDUubMLx8PeeTDtnxk7BjMT6HcdCcZkP03jwLLQ0IbajqNzPkSselzJR/Q2Tn+Y/wUqNK5xgbd9FD+XP/tUA6f9H+tmYyaOG5cFkTwXC+IpiWbxCLpZKZSiJuhQllirkcolSgSksVGAUCqlYroyXFRfFy+UysRSYUvb0p6X19qal9fcolX19cRr4f1A/UFmQ67Z3NqnAKAyKBtJIH5OttazJ1m4mglFxqHbwTU2ZUYum7KWueKHBuFNGR8aG14/IHZnrnHy2d8eZ4QXTBnUHkeUERKQw1roYsjDFWxCkjBBzwvMJkrxO6SZeMLWeY+jngCgije66LT4Vhk504cEzC7dkOAhjOD07Dvlk4cOEXj9Z5ABvDzQhRhSCNKLGdTi8VgbiEoKDcfGBQRh0SDAmoXo/CBAQiE0I8kkIPEeuX0fbThxFwOaPHoMvHo47cWQOhjh28ih8cRG+8oYxNlS1/Liv9XrfJu2LGAtFUwokqiZr4ORO5a5qNS7aqjBB+2GFu9EXjTHz2ChkYnwUajm6Y9Tan/q2O3aM2FhOZFmGkSV5PDKpIuiecohm53diklXO7tW6hQkWeTuNbbVODBpKMyWbpFBybt1zZMED2FlpXwCxdKGOJVJAPIQErmS+DmBJaL8v8vtX044+ny47zsvtO6h5dMdv5fyZ8IYeZBxvG82OJpj2Ukwj+FtHcpVJ7DyG7Q1HjGm0DYZMQRaDIsEKAbZuXV6nO5Fu2S59LlZ6eFtKSmcXZcQ6yQJToRFdnSRyzexsKI6kyqVTMvOIKRaj0NcQn2JKzOrqXfqc/q477UfaqWHg/3MSyQV5RLlnFhEVFR8WlgzJi1vKhpDq21SSeJ/0VEUaXcUvion+phoq6SySgfXOIx1qL4f37UqIwxN0flDuUIKQuIYs92OQwrglKYRjciExWUE3lluLknINLPlOO003uWUYuazHvlMERrIpmRulKD+w9qsPJ21QlW0cApko4Cd30WyCWk02SCktuu6JBvJZm0ca33vKZUnvzb0vR19caeMcCqf+74qPQoChO9kYezbWAs6l+z6N1wk+k2WtOgxt53cq45vkrcboM+gWY2SnH+plPdvLfcKnq22ws7G9f3NXe19rY1fP/u5n6WGBaQWFgRlh4aEZyCjRTHfO2d62DhBXyhLNq9sKZGUFsQmZe91hju3PZ3YZvPRJbxdb3a8XkDwCIbx+zX9gWFXTQAk0BHl5d+uuPUYgEAhsBbKC+BTEZkoNLQN90P9m1bPrUxAAHjySU8WtaajBD3nVYpFAViCQFRiJjEdLpGgMGimXI9/kFUYDhO64OXeenBFNH/l3nJ9e3T127vg0D/k7/bWTr6zuC7x30aAo4zOt/3J+zTS4Dztjn6/8Quu/dGLGnGAFAoFB5rQndHtkTsCr9x3LGkiOFNdzBtepx5zNakl20B3GdCcnwUZfH85DpYD5/9zlMd8ZXZKnAQmR4QosjsGMItuJo1uObN8Rvxly45ezW/vOeEPNIHJ0dKxMjzdIKXDOkSnwSgSJPXu+ubWrzcsoTLPYpyQPKfIvM1cnBY14JTftjUvcVna+q6upkxCQzk0Ycm/XSV3QyEKTsVxGsHsB8uWMy+h2AMMFwBRhJM/18ohjGyUU0Eowjic50QAanAj8QsBqJl7v9q+sMrJS9xlrEhU/LWYi+Zsyptw7GXYTZSczwzXNnrksH15ZnRtj9c4OOmMdm8Vp//fsdjqGmSIA8PGzl/ZO4AiYQ7mg3W034uWXpMOdDyMik5Iin41F3P2jgD/FyynRhjiOkvmheFVZwXRWyb/IZ0FxvKDEnCpf/1iwdvW7mRBODnmpmWZSfkcd2DOUuljtG2BhudbIXpZ4A3VviQN6eZm3LGBCK6VIqCbPO4FHRBdYHJr3OY7HVpwjgK1GuSBjCGgD0HKsbLG18NYVjvghe6m1UmgxfCh/WI34sEfykfENYdtdXuSfZCQxvQ6lgBL/Ik5VgypfY0sIYnXKXfc2AyV/llGnM6dnjUMw6zqbQxee3Ze5j5pHt6fo/U2Tm4e91wj/pCHgfQnF1hTbI+Zbt7x7Z0L/ydyWFSMrCCCuhAQzX5CjO961+7zM6YHr3fsmTok/xybDlOiXurJGZlqBDAm2lm43ikR7oMAccAM6/bm5wbkda3493TLFmu3et4CfgrSP85voIMsSzH3xxK2VQFkl3kcmUV1JArt9zhKYVSj6zoPLacWy3svyPyUmtBD8XkjBXijwwLikFHUboVystHlyf5L1P2uTBctxaxOi+BwbKVv/22q1ObaXxbBkzLzw4Q2gDRAwOHsHlZkkpGbp08LNLs8zPumPr687LlrdkHB62dhdqAejp9IJZNg+g1OZNbwzyqUp3Vak+Ozlz8u3vYzMukMqc9CSWJk5O0lN2Pwhv17QcGO1VSyRds4xqwQlgqI/3k3t3pYUGhEP7pk+ZNMTER+SFDeyU4WMqdr1utNcelC5AWQiTcoNMBMQxEoFsqDlxf0HUUN+UXP6n7Gq/1vRBfIc40vXYTF93Wt+h8YIDDfzdUqlhkcHjyFGoM+APzy9a1YkbksJEr1D4BSDNK4lK1SVRLSYVReFC5SMWrGv4mau2eMgQ0pjKzVY/IAo8lUHFTP0NvEDT/vyY+XUC56CppPyYY7rg201RcPynm00CmV3vxsx9KbvgOtt95Hm5hAXbV7a0NFa2ezWU1nXZj+Bo6DmLG1Onyr1Gwb2QmynNgNha5Sv6iwZRrIMXSpNyj/Sqz6x41LSvbVh0Do01Q3kFyamMTflWqMhXo0ndQvlecyyzNyYOuGmuah9qqUqedMaBetyaVOLymuWbSej+XicJGE/BUVmbNjT2VuWzCiQrB7MQHgsG8yUnlzTx4SQxkxApzhq9CdKT9mcttx7f/GuGBR+lW0IxMvLevyNvVtlZUdrQ0NdW2UCVxmvOrDr/eK0Z6aF906Co+Ura+TV4Oa8lxAmPGSRf732cE25/TuUs5qUDPVGJEQFhrJSt8oamZ3/br+r+fXZz9mpevOIttO1lne6kjlDQ28vphGTkJfLk1CUQI09hgJO5E+iqdYfXYHLQM+rs0fwabkvzNjhPodWKLNrSpqf5N2dJJ7tElsX+RP1W6qESZHCnSB0TRx2g/3xD4bURUdmdLQJD3S89mskHcrw4Hi1WG6fqsV/PDylEr/F1Mt0Cr/5NSq9iKmbZ15SrvfV5Ie7EU0NlYbc4xrFr/W4pu10legbE6ySzIaGzZCdLiPyrN2Godt7NsZvdHL8aDl45kB7QbLFc4Rt9ri7X6jKrNjh2Rd1+fv0aKFc2lH0LZWq4s2pYVOyD1lU2Y93TTdf9GiJZv4XCdtgVmcZ4DuMW9BWoAJq++O/DxdtT/+DoqNdmnLNHEPvO7p7Z+ls4OFkYSVYrKPl3Ysvh5RKEo2BecSD+orwHHQUoiLHQwVGFbUPnNrCagaVVxRUk+4WMRX/xtvrX/KftQ72Pu3eVI3Me1o9fWvegm+teaNSuzSUtQ6Fl278/O3PBWsrnXrHFgZNaRt8VbVrhDI9h+AdG4twi+YcsWCmP3aikMYWKYpCV6dmR7Mi8vPl/hRj+MSZk27Bdnd267DDu0K8MXuELhe8BbDHVBy21k5YzAjOOnO8a7DXyuWeNYZoiaWbkcTlRGQUKivkMMHnLAK5c6azXi3thACIIfPTOTGFzrr8U5K9rzaQlJwCY0Zv4pn9E08NOQNVEA1oYRUEv49L0nkoO27q0sDgwFiA2Pw/f9amQ39eNkZjUukaNkeSzPhTyayRLM8hGI7wFUKSGR+r6V1GAC3c4ioV7YKOJGBgWEZqMoe/RRAR1bzU6o0SaMrpjki0P/DF26URtuxKdVCZyrI9SX6R2Ri7zVUPiRA1344155Ohhpn7t2YP1n+p9akIoZBLGzT5oKHQOwUh7mLeu2gSaHvOfQk96OEV2wdOiD04h6oCb9+b9tfdhbGuXuHaSq9gcEeZUZl12CYNU710OCrukDaZt/9x2gemmS0eNv7ildNkAuKHzDwOuWfiw9x9pnQ3kqWyhoOcTPB23d8NCjCtQG2WXgk0TLOkkRa6Q/tlWCJSeK2RnJwE80KWvmE8uUtAt5WqY73AhkMDFOs+DeBfkCyEMITl+Nkt6+dUFnNsd+ZvifluGXwUp4pX0SQFfBdZ8Ave+95//XxQEtskFwwm7InM98iQED45cHcjR33vMSOCvLLU3V2+zV4pqNCQ+GhcgNz1sYMK9W2fnXzg+EBVXvFwl2+jFwUZGU3FM2JzAjQJtSiNWXR7/OHToxFmoG+MUjWbrS5mzp6IDixQx9WFQ3K9cxAvyOaso1eXqzwFXhEeez0d6LGX59HY2lkGp7LComtLw0RgOdlkbZe6VjGUvAuy/UCl+V6qI0SRf12Pbx7uGd/l0irNVSdjQ2Gphqgda7mUsDSLlrX4rFa5hqlYzxZgvDEQ902HWIGlHeakJ9+mBxqYli7sHngeWrn/5IjvSx0Cc5uWoexAH649meDeSR3gk0EflJUzVWHIYaGnsbQv7x5hIDzRqUIOIdFPXlv9837gaquV9f4c60o6rJJoekilo/jiqvfn8vINE16c2vivS8j//zDRycg9RDSFpSEL2XXc/largWuHLl/t8w2mwteSN1XV1G/rJxV7QxTyEQKYExJivSk3TOwaTXCuBwLDAbgLKibBQNHb/1wJu3EsJ3lTDEOnEeaVd8HPc08ILaze9jUWvUvQkS0hzOQjkij+JIxPwPdwOrPQxKCFUlryi2ZoU06u0NJKLQ29ZepIzLylr9ZI7c0d7dSQ/W7UjChWJ6OkjKWdSh1Q3FykSRqPZtrTo78vEbST4nzWLMdsYfNTn/9nt3UJDylbIYWvOale1SuUcz4gNwPLt9ZEP9qlo4FEP+vfDQwhbnM+yooUlv1tDuh1YStECXy91cWWFX2ej9lha+mzxtVOPeKRSDjyr9Hnx/6i6LiVID0Ezn7YXwKCbXM5A+N31O+emuzoa2krd0iq3+tJtD3Ss0LO6pc0n59esKIaYX3CykxTuJ6IqYIvuUMQhblnU40gJSYqKSug0LzeMi9d/lS/qy7pSsfSTzS2b90qyXQuUh/xVDSACm4x6iKkZPX0ra6Kzvz+6s0v+caS/6ahAPsMF7pMNv+jUviWC8KvLNfWAwLOB2OC9vSYv7ZKmAYgcgcY9R+N4N0usUg9e/djshls9uhAXd/DbVd3bXE2gBH9pk/JwV6XbpxOZopsj1wUJOmB4unI9L7p3tmQswRfUxErNSm2lrplau9W1LBToHTccUwKMwKFjIBjuCm+1P/31TPDOIGhO30KtQ08PQhGHZ0K5e+TqJq2npn+DS4OlUmTDw1nYSvjHVKTI5hA0KiGbvuouc/vIW/ao5ps/G8vdWbdWUpZqvMRlqOWz+zIDd9CrV2jUfstzD+fUFkGindtlD6R5BCzIcFOu/mEsVjW/kL9opyycbO8lg9D/Bcm+FM2f+p5miHXh5NMzUPqfmZ01wmdUbls5LYc836t0IlCfl6CMNDWVc+Y3USxvzuzt4CsNgA5YyM5JdkyCUBC6FP0iTrYNSrUhWNj50+nRm8PhyXZ0dhhbnXw6TMCX7g1SWIc8ZLR4b/fGlOmFA5k/j5mF0BlPFvVZRZrWAoEAllZCdNvtf9nbQkgkMDR8v2jtGGuWK+7R49+zpgpg+UBcExFjn2RDX64vf/mVpXh0bfAHqiGWdAUBHh/8YB8TpV+5Ox/HOvSE9Jq49cNBYqGlsvi63n/D4jG462snO2tQGMUBAKysgCIafWD+t4dE5CV1ZXpkl+u5k/GBjbX9TamwgbHefxlyBE/zZkr9b0Py0KiuF7Hbq9V96c5ybJDyJ/v3lXsTrcb9EDMfpTWOBVsr1UhBTjYvO8WjB5nnUX8+T0d2yTp+3Njqx3q2sse4J+J7SmrHkfnJheLogArnBUo0mmOuqjS1OKfdylTkrWT3kDf5VfG34ss2lymYW2nIXjSyVmFXa9EQfAaXZRA482Ya8CJFOuCpiwBvVmef5ncfNfqB0ogef40qGef02PAyqAzxcEy299KoWPyc/dI1eT+bts5i/MHmi9EXwgJhJ2/GHfpwLxFF2TfeIH+f5s0Ui5bKCW0yqbqaiNbpbS8wFLry+yuHd39JsDEeG3LwFiXKMZp/vLhldXZIZc/qDLH7HZF1f7tvYaeKAamqwJWEIeEV+Z3MTCeqF7D/SOV8qz2NKefVFf4AnpfIoDYsXRh3ziOED9LiqpOK8PnUJuZVXtyddRrx57l65fKErv7JqlIF3WrUkyq5qqGzEPX/K6phcwsoLWvi4ECgWAgoWYTql7tfClwES7NYWVn1MKd7Vh+0Gbqw6vFDmG3VjjB/5PeVE1RKqN1MSbPrSe2RYLZIBAYAgLN4EPcylrkzJSO1LyrqcPJcAiFb7u1TGSBomtYYsOtwzb2b3NG+KKR2uatqR4TAFxIiK1zJ2tMm/8tNw6dTiVL8XHOuptDyTAIjQ8dLhdbIBlHGKKQS8UHkHTMW/RiDtZ8HX3qwwzx5ZgMREmVdt3RSBVFtWAldvl8RyxRSkL1XJjuVCeDqbUWOBusgbWIHZ17SVocN2dtnXcIoaRs87sqAkhDyVsdOgFgOiEQe1vutgaPJ1RcCJQ7DE2qdk89Vik8c50jLocnYs/7JJkk2Cs25qI53GFCOy35kLLC8WSTP36gVnSpm7zF9arcYsmkaRvRnc1B45GvgPZNLkdXA9/fxafhbwo/VKqVdhgcqXOFuuIhDmdCTOhIa6vwEBUo/ArjtTpkqwzr/mObMwaDN1Z0ATPxu/F/7HWarlRfylZ88Bo6tuOgZp0r2ZFgkuboMshALg/Dlb0luEkHIAbnpqWGzZmP8Qn61TboCaaSZM4UJ0oMxtNdwUAuG8YQMvxIFF+OB8kFy0DD0AZ97P3YlQ+rI92l0+/3+54ZmR8N+pm7scGk7OAi8UlLGt5ugAM/iZKCHckmSnteYXmaTKKCy6BnXcexpru8j61+yuvKa2/qdAbLwCiYMzANvXRAfSAUH8Z/4XNSUsboVpod4L25mnxelRYnI55pOMJ6ysoG1YMP2U/BQ/VDcA504qkTjRjRRSypT43tmKK1RJfVRpW9gjMJWai2Zof0jg4yot6b13fXYxcmJaPb43zz5fG3HwSyt854l3r7V2eNXucRlWWKw4mRZK4AFEXqZAjmJ8ZbFnGU9TVH0hMog7UUL7BE9l23c1V6PFRoynCyUlhNy+BDJYqscFo9fQ/+Vcy9wVjH/dJa6c9MRWZgDyxXb4ZCDy2CaZx3cGHxT9/04fwsb7vexg+7PgRlBQbV5xoInLfl3yhQnC53JW13yLyfMHYw+Aa9RVaQ2wXGPDaJ1jC9vkRx2fPTtQVLuTyXelSIJcv3b1yJXPGNyLVgvjlh/vbV90FFCuzYiTO/eBye8gqq1XZDuW9adHFoBtw+xDsbgUNlHZiV3Zm7Q5FZYv6tMRwIQopTK9Q4IIQRwzMoifm01imYbO0l9w8HuITEvxbC1d9Y2wUFGW37Acp2QBO0Lh+vCZt7bPyS4s5Az3/zQROo+oi+h19UbGHe5BZk9Ov/et6EIHQG7c5wc1TyrT3EJyC8UlRnT1urvP9x2NTLuUbJsapb9ZyEAyhUrTk3O3ue92CtRfXwIUBJdiI79u0RnKIwKCtn83CHqIw0PlrrlTKO8Pg2npg5XnPcvfGPuWpY0ZszdX94eit6xstJa/4I7ZASKNRHv0VZRW5c/BXtomBZzXC1JHumYnAhR+CIsuLILZqic3B5x1FUPZcO8mVGkrmJPkGdXTgg2LsILbVSI+6IniMtJIfPXK09eVFui6BN5vVwXUIqssvAE6n75erAaCpqVQ4HLrewEnFn7gi3r+AgP852dwgX15gCzrED3sKkejumQIkKqOgx+518b8+1K4EeO82yqh9ORNVgtzPuDjno6q3y7MbSfRYpyrl9np/2HtO7/EZulF0uyU5wqfRNvXH/+irXGH45hxGWYWYYnZdJFz/M7TbP6/OIi2raLv8IuvryaZswo1gI0t8D25r7rPjOTLGLxhucc8UJOY2dhI+KoTgUGcEDqwMdR41ziQ2MXGYWu9RBK6JzLkRUAcqaC2khaZW6srNyWfSGXPdRY8eyEwxeZGQfQ43Cs5Lo8hPOFTiNb4tdZlae3sjZugjTN0BUxcLW530EuFPZ91qwF3cGf5Je1zMr++hToSVnw8NTe4Qo+XKbuq+2sGB/3WBaTWiAf1aIQMcla4N3tbdjseEDQyq9IiTj2+h8TzUxM4tsoh9tpSyj1811j916uManyh+fjmBvCZv0JXMvv3TlvytDCYYmYwn5+1vCkfX7VHNeL3NZVa+LicBt5w8V1Kc+a/KQcJiMpZcFNktCS/d3xTDS+B5Da9+Q4dm6iefuIKA0TbG3d0Eddl7Axo36HoRrzP0AL7+JES85Q+AM139xrt0pcGFF4bnLlWnnU0MifxOAUddRBDBKMc1al/42FMwaXjOR+OwPV1u+EgIkRVECOWL2t4V4/ehxMsi2blKfihMH5xui1iVRQSQ78ETtu+SZrT8aA1Glwl5EMTG/aHAVtc1PqJZtjqum6Nnum0y9oNIFKaCk6Oy4kwBKlyV07oD0eU2bSKj+VL26GCcIH5gPDS700AbuTcnFgtkdgLL5JUCPogdbrrF6RfPhi6OxEk+oLLZIjtTDBQ8EM/rjftGkLf95QXLeWokyLQcTmtWml1NxocRilwLFmZYD+qZo4O3MFAWbuRFxp57+JfMoVZZO79XTO26Gx0X4O7uNLhul+G2RKAN5AFPd/ktNHpjRbiK3hta6dnf2jkxOta7r1XNxR9czO1p+kMQfXo9O7wy8luinu2f11qBcCbBR4hOVkiJW7TTjYztxb04KTtkyyBk7L0naYZHqCkyhHbSCOgU+r6nxx5WGolDx9p21p/820ULre207VzOPRaY5CP2EeofIJejT+WlVDL8L/UzjIMzZ4i4JvfVW8bUdT23abB0CWySzWBPkMQVLl/vLYVlTfMPMPtLmEGvsbIeJud0H2puLl6aqpSE3lwhqczcmB6GhuhYtWm3pGtWiiz12hd+ruZivsf93a47HuxEasXF1u/bEWkNpyTqD9njHmogNob5RaTa69diVTN41HhOzco+NLipNELP9zmP5v8wRoVtHIWb0/fcA3+oiCKlvoMhNAG/uyds+3UntS1JH2v6KAicoqT1PO3ZmrqtAfSpDZm9MPE+Z5BFOcv9COPH9dhDOgwtNeN9tmbafHB94mg4uDyZKeO81FcPxGiz+CP9uWtqVtJMgYM+VYYr+PTX0/vBVcDOf33E1Y2Jmpg6ggHm4xXl09J+GBFIBXPBRoIf/TIcJ7deZn94b+EKYBRfMLI1TKcok8cE5unC17NiUIAseg+IpT5uvsxemw37qD3CvAE5K+NMQujRFG5EbHC8pjZJHnJguVvpK+BEkDw2byY55ggIFWTQx4Md1XWYc2FpAdkvZI58L7RntoxpdGmFuHslCBNUlQ+tPPehhjWjdybE/47g4rZSW0DRQfa6xd3HC9PjmuoKUxY1N6QYvkEvO9j2/Ps5m9svd4iM1vrRbtt0DFkPAuMFc/YMJ7oH2MI1ZojAn0GgqcqBJt+kz9IEKfd4YJlCV72AsLgPqF6LAIDEy/mVvyIEAEsdPpl6a3eXIgO8TW5BSFTawx1AnDSh2qGKsrKuioqxrrDx2WAeCOj0GwRQ5tyy2wxm7Hc8dTj5qfbrUGHL4ZM+vP6nfxxycHqFlknUZ3Onu9shROT0K36v4EuacOjR8eXamxOz6Qu/v9/YkoW7E34rXo4LwQRIUdDrtDHRNWjDKPyYeMlwgfxzzDAa4msj/lk/keZ6s3txcBwqNs7IdTB/Bh+GCEMEwHGr/pMRBQBYUO+zX7dFpHAShTG+jpA11aR4JDhzugvCf57RlKjv5wtIdUfCGHCprOtGZrc9LDY1qTqjE2YyUTT9dEkvheaTrWxHmsgODzVqOKkUfp/9FlybswJIK2tpNNK0dQIW+rkpoOogO2BCezUeFhlJjsUdKEnno3qv+mmucZZ1rnTK9W7ctOVNOXKm1/PluW9TZK6Nd5UMfkumHk1zukeAZPvzzbOhj2fWrIw1/vabxUZZa4spMefI23e7kHXk2WdbGkkQh1/3LZ2tAGpLXBh6HMyM26POW+9dcr31hkPs9QMZcIrmAB4GQ8au5dUx61H+WFZZot0a3+WSgwSSf6e7ZzMwY39JSWraleezj7wnE8/cDa1eydvW3RmeXqa3MI0F5+eGNu4YkocU6IdPFlWkS+bcUDVkIs4H+JfW6AW6onStth+9u3NY+WJGR2F9e2ScbQn9RU8VVZrvy1ifODjlhMfFGhr4gEZtGvSzbNb1sihc4tWgNYTqrH/56ekhm47tRgXSt5HXG2LHCJ4Y52QD0zRUQE3tt9IzJmi/kkmqr0kNwf6qevMcEbOpJFl0sMx67WNH8Z0OOGTBV5vD7tH5h82KMPBqcco+7ZYaMwH/b3vpzYIaSQhv3cVoms0SnoHFePpxYK+JjI8mbWVF+OjPh585afVNGUbV+rJmfEahRH+wNjnNTbjKEsjXS2jR2bAU14duVSaOpvKUVdD57kZKoTqpwbH4lnH4LOuxUaFekSE6Rsn9eZbQVHdYIAdDzFVVS7mCADjHidsjttqRyiEJ3PDd3S9MUR8R5ZYvzSWLbZMFe+MF6wQoUq3bq/SmdESjhryiveoXrIEj9pj6PyZK0UeoQwldvIW6FMiYiA6LpP89JGYRmyQnP/JaeHUaOlyqJ7blxaCggooRvCwSne/enVWYEg2kXaDZXZcr+hN4E5X3xQ5ovTW7Xlj6QFnQtzBmGM1eoxp98Vm4dhzgXB/lOEHU+EWAasL/Z+djV6OVbuDM32lR6OqvYGhZTGdDq05pcn3AIFetFsjDMTB1CYCcoQGzqggvCfQtIXFM+Mu5YC7X43rYlg8ZxRUHhS9el95ARZOdw5iKy+7F19BXLfXmy8TygkOF0K6CivDSH59ZOtOPfg3PHiQc+esSHXKcSo4mEVBIphUBUA1ThRdU1eT6/2olI4R1bDEEpxSVDyHZEcPLH8jYd+iIWq8AnY6AxWhuykiyzOS2zIb/1MWGYlYSs6exJMxkhAm23Hykktbux86prijqKm2LRTnWO28408p+uI3m4quV/dpPfnEkgu5GFNtv9Fj1z7/f3FNKuuEloQvRx9yZejoBvQ95D3nTQKrjBv94/+KTFMjL8r2ZQJb+Rx4CgH4JqyZhtVItPqe+rlfaSq+9jiSm+KjGNzvw1gEfK/zghg98SoigOJwDNpVJmRFRZWdRnuyI85WIXKAxQGCxheJDT53mXaUY3Lc2WzTPnm/nn5lzKDDoAN7BX2Dcg2FU17fX5cb2RCJt0W3ZKfLqtjQoZ25tXX9NexWpGfFrBhhsOBGVeyvXP4ZvxzNlptrRuHxHv3EDh38K/A86qmTiYSNTikjV1kQdmhNff1MzjTlk7sbtgBuJ4eJ4gD2G0M3G0ZBTRtc+Eo1EYFNhdmLl7UohNnEG/l8CZkG2FRUy3qzZ5qzYR7k/dJzgayP1ZgLNxV2+Ch7PqXDg21vK092nLGMy1djXhKMweXF7e+8GzQfFO3qtgooSeZRuMxlLBkalCZUysGBqRarJs6QTd6tqX9nyMMywFNzEH1vhCOm1VdYweDs9Pu3nEuAqxrHJXfXBm9tjyJM7QBHV+TDdmsF/feFZLIiMMJ2acd1IJeLAoo/WfhdE1PWYh/n8CDv0X04H/TcCjvflLZFzVVvFKZcSH614qqhZAo38VgUAgW6nU1sYWtADgHWQykG1zQCWLJYfwFUV2Zny+cxY24pz5QTKGfLGAOxxg3dxLfv3n7FZpxdIkJwlBpbBKv0Amky/UvnMZdtsTbU5qKTMHVjFOdgizE7iQWTQc+psKFY2SxUpCC3SxUj14gGTP/3vLkDrk4nIy2jEGJYv2AnSFk+ik98q6nPpe0mGS07KZHXZxp+B7vE1a1DTW/RMCOX111U8fLDv3S4BFqQaeAOwmxMvzulKFDUjD5eVw1AZh4flsFHSlMc+JSCrINK/LRJxtas5E1vIa9Hgx8d2faLTz7GjJaPEcf1D4/fljreOtgY51H7fVf3TE19Y41itWlwVeqMv74u/MOH6s3/bx9pZaqUJdrNbd8UBkdcRUfcfRifJUW12t/fy8qRo6n08XuFw4gc9hKIdf1M8W4DEnMBzdeY9PjoiXx4jCGjFKNofHmPjDnmMXS3VAQtP9+/fs0Kp77s4JdhOaUJO9nnYcZ4rGHp0cTSty6Zu8b4yiH0BA/idN7T+Az7rYexGffQBttevDBYpBTtc/nFtWEFTUqHlgyET9PRiAaMLoIpNFwEbzPsEWEzkCWg7PVdu4g2y+Nbpi3GRiuEuS1jnr7Yh/RJTO0qugQrTgD7jOWbWG482sYKiY+WwFNi4JARpTIdZTfhNpveDLnduor6sHJCvG8AtteQ7Aru5cNhG/tZsKVqUKlBGJfFhUqtHYsg1gS+jdwonepU5iBUTGpiE9NhMxHjJOkDgiBmgJU1mS0AiNOGi7LvPAEDd7IKkybwVEvNRpohcIJRzA7KSbWzg/FDjP7qN4kWYH8b83xzYla78GrLdcamkEeX/JK8ped1FIlfDUIcFRaZmR2NVlQOh7xrkt8OxMJOgs18h4UGCQzDhoXcAx8+g7GJtWeUOW/Zg7fQBrNuPfizBHgMlMjND/RKmbs/JtzmTLkTE9y630J0eCN1Ho0Nq7TVoD3pj5Spt+p6WWS61X/7CWyLwiGJJgVmfTSuNGgE77Bb/9dCGFiZHfZ35aIZhbZ/bf9ZH7COmByFMzsKgEvlLZ8ygSDPWQEf//HCGrZphAna4c49GSUWujBYtMFn2TeLzzObKugsYjwTl6EtBIrwQchISE+DCLm84G7oH0YEZWdVvA3reoSsAW56WWS7d8nZRR9TODdYPt/2qweRAH52OvzdliKRMVgfIUy9mUO8e8bIS5sfJ0/wioOV2WowFL6DbXUiWSESAv3sP9RlYMCDSp9/JGwX8rf+KUTTHlRVtjQWhi8vWIMaYpBtzmgAzWvgOZ75RlMVuWMI/acri2+Gj6PzqdF0CjvXF3v2+7RXxP9STRBhNY9IlwOw9qtS8yMjpi3dKlYi/Xw+TQv7CmE4AP0xT3aLL/Piayak7PdAAs6wYh5js9OXle+nI+J9MXdYbt8F7mFVfO882IgTuwsC5tZa0Qc5wpkTA/g1guHn53X+HMdzknMENJXqEKjJQ9B/DZH6FT+zsDMlA2Tsx22GQTrvZezSKc2z9FgtcB/n2gfc/BkpPg8JzxbIWlObXIKCww3qodpleh71skb4i+zzYqdQMCOd/5fsjb3VDjtAX1I4MeumVxX/0Yxe8+61HwyPih6kdpUQ2HXGZayrVrgb4Ae8R3xZMNE7apgAKwA8kLy/cnC/HC2hTFUl/hpCkTZsf+BYE8gW2gUdQV5hljDSCauwd1DX1S64U8jZbPj9ExwRLoYhh3ixtKZvO2fshbA1szAwu3M7G4HIxtqFHKlcYsb+1EMKX9o7sBNHrjgDBH3LIS7Iq+Uvesceo4zT2zrxh7gKxSX4F7+hLqEjcIAdb3dSRsDf3UKY+wNwG7IM2Lhjvd9zGWTnu057ogJTzwzNd89WjQ0rg8NSi74wg+asuIlSadLvFQ3r1roRRuupXmVImEKDDxuCEgpXHU5MiDESDLddFY/2vM9IOUzZ5LKBJ9ZdDjTKswfcuIPPk8JHkzYxlZElcZ0BCs8dASOPHEmqP4qC3DVtrkXufe/e2RNLGqF3/vAXz22d6z2H4hhQwXzy3N7yFfPit/WRu3ZVKXG91rJDOKTFN58lwcJOSFg9B8gt3AfwHMIGe8iG83XFKcVtnEIFvEOIb88POTg92v5iPdu5v6xgjfuVQng7K5AMXz6WGDp/85afo4OZlIFJKJ3iSSmoFdEz7W2N9mROmrGu1srxnaOlCKKWbT8YaFXfhEOhtTTphIKgoKXbouvZb8tJW5nkyfWxdAfvQ3l3zH/7PqpAHmOTrSu6hreGlDWAZ0PRWRJPf1FtdklsszlDEJlOXK8/dNait7RwYbx+oEfFvjuL4e8nPXe+Tbj/TzfcrYHr4bzjO8/Uu5w3KX/rZRbAlBjcQlY2W1ssixKPNBkunh2eE0Xy16K4JEXBO9xKdzyXeixe4Tg21DiIwOFpXISdEO4npdQ3lgeSbJHIUfZ3KjIOhYQvArC0F4535+oyDHOMDQAcYiLEEiV1ywzy/yey/ISd3vTQMRtI8nkgmPLJ3kEV0WEYThvtgoSOQy4tfQRKfOhdVTp4/enmybZbdeXFkS74BAbFv0mMAiZ4JpnjO+JKfVMOHvPNe+tpSinIbqCvs7u4I3/rup66xCu2FdgEMy5Pq5yxeR3o9OnHU6/nyjc8lz4WWHjwgT03AJsz3W9vPIVNE2ETKZ4CguLzVyzb8q80rsb1IfGD6MhF+z5XOMHaISdtkLZm7NscGtUUEmXDWs+jjLt5kCfD76OtIWt1dlf6kZYBVAG8EjLVkb11LfD/hHXqRsZHatEZ7FjJSxE84FfGBanOa2pj2wu6nNDlDHUm4V2Vx/f+yk8CS/onfPytW95/LX58+n3epVvbsr+CdnhfJNyMrcVS/yG253d1ScfB2+KSNjEyo4O3gTKiNj45vcilPtPY23X5BX5lZuQsr/FU3XNmKhFeb3OygBFdxeuKnzbLVRayVh5sGK21pttHW4qbA9OAFl9Bb9xzoOWURgRj2f5/GxykYu9LziPcbq3wfuWdV/ezXGwF7Y8MVtIdeQ5IdN7B/v4Jsga/f/GhbNqx26GH3HjH7UkSwtVtNQi9zXoYP/KgJdlA4dZpKGwVyAUKoMOXB6GW9HgKhiK22z3e60Q6rhaQzAtr29Mjb+5fbMyuau6Ty4JS3Qq/9GFACM51b6dwT6xKIaytc94mfG9i0br15dYpKQahRTFQeYVgoUXaWaSPN2gV+PJiwUzH+HDkxRT/9FH4L6GL5YD6rtv9rHXClNv8T2MRkQYKu6IoKEUl+OKC9MGKdsKU67tvDqj8/d7cJnDclr7q2QSPiqdWFNR0c35K52QU9/KIpbFRqum+gtMZwojmqUnOaxwJIe7eWLg886lcl1MUjz4aDe4idtx8fbcbf4zCIBTqeIVgr9KNHYLLDM2pq5nAkKtom2tTNhRPtHFKQmtCahB7K9Pck1G9cf4GQKEBF8b2Y8K8HuOnnT5m1a/pGKs9dgp04jgPoVL5C7EZp7TiuA6q9VuvSkSsdhXFOFgPdB0gmFvqW7Wwksr946Ei2NleCTnctNMZH5cEGdjbI4YBlN2riws9MnoOj4LcbXW9fqWKxwJ9XtsAhzEwbfyEnhZPJl3jMEZETkG9MigKqlborE/OItR856ShQIpwQ5ts8+uFoVIUR5N6dyYpWYyEy4oOvV5pcJCEvBA6JUyq+FVoIOonJ56kHORkhy+x2Tb1U4E9jffHL80q2sh0Cn08oF/GdLky24K/WhYUj6O7S31quEvNiPAPO6xhnRj9dbRJjlrsIenSwUC0se/siBOpCXU1wa7H3zPFN7E+PKNT2o5S49lTnVJ3dN4DJUzsIAhpee3Qa/it+9d1Xz7hNb/czz8PkN0blHlu+nJAUezqTGGT4WIvxt3mbfcj5uddJlz326QOTRZtGFnk0RrFdCbV0yZrRNkkrK8TsdjbHXG0rererSn92Ym1OSRzmLWY/QqFeuP6i5quLJ6qrOjPin3lUQDGF+GngnrkrgZwgumlx/yC9T5cLnUxlxvmWI0+S9s1uXt5i9HG3jGCyz4QtklP6lkRmVF3mnZ+4nLiqyb7gwuSxmJlytPWjwNNOFGs5mdZRdunml8+wn06EHun9++QfVKm1fsayOiUqmEpvhoeX78minQDUG9ElegLIteqAeLmhYerjZTyB26l1/l7aIR4o7Br/w4+b0qpn1/umaia8agF8aQwO8cf04pats1559KUdybMSDbcsaJk/+PzcJt/kKufb1uOXeQG96Zgovyyrz6D8U6tRr9uSkX7pZefY3gX/29GZDt2gh0X+U6t/y6/rH0GV/VdCGH/zNXIJmZqlq43A6Q9tqb2ax4Oi5ZrOxp4n5pXVFwJqa6jKr7Oa0xHZBGvzCjNml/21yav5hn0OgG8tTPxL2EhOX4p56fz1UA/HFdMDrku1K8Yh7gTGD/Xerk1cLAAn5l0GGrJsLrxKRVXD6JWNwuLf2Jx7Xx8kPU8d0rxxBgleQlgYk/M9+uk+/oLnb7KLNNvruNlVGxMgz9eNHc/lVvas6ekcWt29edWbeOrqoHDaXwvBOiIkXJgYFh4fDQgr0gWbQWI8KTQ5ds/ykTnujBpZ6gdp2cFD143iKKrIhGiUgSv4lEs2R1LlDbxALfl3ugv1+g1lXu/Ytwujv1XbEr1eYi7XQ5h3Ls2f1Lp/0ztkz9svG8/fq0K8T8JmHdRbCiz5JDBrwv7npfsCpT4t/KTlsuregv+o66NxffKavWOG9aqcLZCuwCoCN2Seurf+2fsRZ+wQq4WnlHVpehmuHLz88UNKevTjxq/hW39YpbQf+o9fmx4aOR4sUcdjT/TcTfTYmotprzPBSDWP5pECCvVpBm6PXVYH+mDsnYr+8xEdnwAUfBKnw6BH8wo/1QdhWdZjvEd9ItEjEYJZGNFInfV32HfOsUocHGbiY3XqK/NkUs3dd84aARNyqwBI5L0Gcvm/wHItGmveD7BSQVeGsXJccl7S8qLLNQ7M0Q7iLVMLwkPkmORymj60dB1t5v87waZHYffOUQa7ZqrMOoYy21A+oy5D321IxAGvWDRc8Ispct+6lVE594LJBNiuzTZQEgLdGJ4PknyeZNGh9gItT8jVEsfu7IbwcF3vccMr6/xKABydz4qyMOTWlZL3VdEoN3r5luN2et1yZJPehctrfQIf+0P8vO3SfVNzgtRXahxfEYg6OM2KZdT3R9RUOL99ltb2oCLjwdPOmk6ORbVeG9t0u2e2UNZWweA9xeF61Nl0gV27j+3ycbuSAeaUPMAXbf9/E9U+a+ZNuNgIA82N9O9Fslxz7CF5WUjH3KnfIJX5knMTxS3MOVonLSvYk+46GRbh1A1lvlCnJBMiZ98XHK8KLqbNk+IOv4rZcFMWlcRAsbin6gTo2Rkhxz3UNufVnMcqpHZsBfvNIxX6ukdpcgB65zlnsv5+tuNndmnfpSmhFQJEZFzvq+h5kEzxm7x6EbtbmqEQ1FJCwYaLt0OR6lNOd41gHfvz8U+i3j+PQsleWxRdrnO8BDb8E0pX5JdVsbiXF1qcaJQA/kIKTIpeOcdu8ioIzvRA15LpnK4nqI3MNkqZXFsqV2Xmp2QM7+rUhQJn+ojj9LLlt9wkea675+qrKn4KHBrgUdyCg0NZ2WR8VoZmvzIr3RLpcuWOKQ1UPKI1TctFqZW0RH4lRVcCoR2szRt4wTcge9MzWy3WCW3tzTSnp8dT46BAUOl4uQkceJFaB1v6p61sndthZfrq+orQ9K0LuRfRd5MBPeO+48/fvYl7sUEnVgxqN9PTs+qrivkJGYiTCH3ksoYec23QzEdkNumVzZIX1YTrjTleftJcpAHy8duKs9zi33v6j72uD/PK1vF+FhlO1bXWlVd4pHnP+sETQx/D7B0ORClqIyJtkH8LNScmp2NltiCz7dQBk/7/vfQZWCKnoPlfOaHyPrBhRlWULIdjtdDeXFBraotft8I/QDFguoT0qyP+H/9/zHQauyL9crI67HsbZAlYMRalfmjxM5AUEMhppUhHB0i7cuc/al8Ho/l+HZANIUwTUM3th4Qt7aUQTIigsNo0Qzb3KQQxFUi2SrFIswgQdY87bZtiLvjEmgdkc2A7LvVOjl96OPr2wfXGXUJ8ghYC+/eJOPK179vlGH0uXYgokYiKjzxJ9U/2TNxKtAtNyry0cUpzh0ahFOWpuliR8DXtA7oSaXz7YN/Z1NuVCAKqmlYlSPII9vRMaaTKYKg8DlKZkCTpdWuQ7BZllKQDmCrrGaI1ptzyDUzxEjDCX+O/xTSgZ+MPPkJ8vutN3VON3/5hRS8J6TmpKH0ITM+nTh798b1zqZR6d0DcoYwuKAvKNU616bMWxIVlaAkk920ZlkGexw+zMdrY3POcZcoqYCBt/98ZxJJGE2IuOAv37c16y5KVS7+0ed/i4MY3lu8+idYivt7KcLbLDrNRfVtGxYThCHaG3unSwWtgblxJtQR75NrC6bEh3DMpDNVpl3CCwPI8jpwa9VyFv99ey/I5UKVAKSClKvmDEbu/bVV3/cPP/3T/vRPgQLlW3Xa9VzyzgsGfElNJA5Bc8B4wKQPHB+/jWqPxfGG1MN4oK/kXFJnQdB7ydOaw/7TTNVDCvsGnchT8UQc1jWURE7pD/qm3hvlh+Oo9MUgr2jpMwhneTUaULInNj+CAZvwICBOY6aoHi/V23WOLtgO3etqqHFOlpEizJMmfUic4KOc2yD5N+EXOhrz0KuF3e4VG6fKmh8TIoGqVe0za5BF5KG465tMk5zVWUs1lgEUIuiWPRxcTnH45/ekOWilk7LlxYRGl+YkGkt6rrO3sq4oPjKzp7OEgz/oyhjpSaYePNrhl1arexP2YLvAbeQ29lmdmdX6rRPW1BF2+dt9g4OxbyunsWeHj8AMThvsMciq/khSngfSn0/X3Oiz+Bqesurl9pod/LgoaOhsog25jKusYsZpWkAwoQgTronCRTJTqtIBphTVwGsgKJpLE5QDlsNM9pSURuL1dB9lyXDGEwniGgC78asXh/b3gjNqD2e0SqdGuW3jMPi4088Lx5Eer8X3nVnGXdXLnzfxd18l5VA9rYfbZEV1tNjyJy2pN1Jq0+lgUMQvyf+GVDgK1AJ4Tafv7dVSjQJSxPp5/dDgWkwHbo2Qy6oLwLyIWee+fd3hkHy4YUw/536lsv4pmr5hyu6V7baRXvdgnUz4j446t6kVlJsT7PVFab8/WmTaadtTVxx6a8D3/E143sbbbkeJE9hhcldkZ7R23p5Wc6pRelgVh/hAD339rw43PIF7VlqKWUf4kUFB9YBs9c5wtwrr6YO5sQN6fJbWK1J9aCRJ8MtmjPoqfqLbV4apAYcsDIBhmSHxiOK8jCNNq/YhLeoC8IpRmbvCEIh2nr3zhMo3ebuERtJmkQreVicnTTR2Yxx7DuQdcxbHI+HkVqaS+CpkCNrHyr8QO+x9IHgjP+LHtdXrGscT3ra++DtBVSlQq1WAnXo71cHzy97DcLpLvKDkFtN2JQr7LxrwC92ZJWRsK4EUW0yFulr0gFbpXjbEJeP81KgDa00aJuAsiJLpd2bZ6PLgySd2PkA21V18Ub0yIVg+nPJ0aLiUzv/YZajUugKuA8MazAIpDprKuKdXh0eEuM4uhlUx2HHxyD4IrN+lJgHpbgE47Bs8i0JD4qOhEwQBefdIMPmk1Pedfw2EGDqamhDXKr8QtLG+e9RsZlZLs1HzD18Oj+johDQBfU7s9Cj8qliIr+vsaJbq+2Ax3lYiLSgh17bv8oaIu52Hq5JEErT1DTknDapswsNzJYZdCiT5p4NP7hy+dp+GdGn6MIQ0a2yYuvrVcL9r3w2OBsdbnzRbH2kjmJR83I5mWlKmhRQt7Y7uEpSmr47WKC95FMC6b64yAYBTlMMSJk4+d05IZXSmVg07VpTeJV1zZpZvuyLVr0XT4FfSB9nLP/RIx5cZwT7oMHozpQeLAPL/L+iQBECsjS9L/Pp6xRgSiENU6t3gGrfwjiPXR5YXr4WctUCUEErO/w/8gzLiql9zzb/J45E3yVlOVcnakkM8bm8VLG0MHBrS6JkHqnMtz3YfvS6xeulhFEBTxnYTeKCv4R0CqnglF3C0q/ewR+DZ3Ru0pBUzeHKgR2cAVcbGP2h1iHg4B/g9Ogb1lKrMVh7eaNpckJLz21SxCoOBca9z6uErRIWiFPMzMoTs8M9W8jHBlfSLMooX/EfxUleDMdSLHHsRYXGPeuVJ6/GBP48V4z8IsmwmIp044E752ZFsm2HwdtkHzkuM1HqCe0h6h1cDWQFy8b6fv9x2KJ5h602E1n5zOhDTKToXXAM8Md3j3wx2dRmdaEK8/KUVcqeCUFox6jFGCTOY9j8INY77nTFO943LWXhVl1AfzTPsFY2On1jArUOU9Vpp7LBZuuzcNuiyCGIyIimNamzWeg6nSQ1VHfUl/ncR8HzMugH9MAobSYllKSRpKOrcuyESjTnXkVYsZpjXxTTejWOkeikIMj95wL5eakKQS5V0J3HdqJWlSGhw9QOuNmXDZFPL/gnSG6YzZ/TJzBEQsom8aD8/dcOACUC8L2/J6LrR8oAfgcWOlvHpAKMlRAwDAN/ddb/eIjjL/2OH+KzPjkNYGznnBuWnm+yllcWRMc6fW4k5Rml19ROKGzIyArHbTxzkpXu/cOii+scnc1Tyg9XGgPxn5E9tkjm7aNFdg60cxCpIBmM+h27NLk5gvqG47xj4juDzM5lc6ncml8okpkBdbAHwq02ePB/6TF6mqDfXZGIfOLOhou4iNKPy0IJ8fE4IJ0ml0H8uxfMyVryrAnShKjs718e43lpUMiq1vH7sHAhPQbG86oXHC1KZizxAKKuFK58iKktpbqlHr+vGCn4FqlHDRMLufj/Wj2izJy/I7mXX85KRtYwiGMMs9pDh5XPkX53PLRbcfG9cNX3iOLQbfICUo/wW7ITJSZJ5lF5vXEJh8acwyCfHB9Xprh/Gm0hz/97oZKX3wwhgaOOs0m98algvexQyu8M6FqEyI9QUleXgymjjDwVcE1NlmR5obNroJyVHiPLLbOqGXzr+aRNlfsieCMPRLUs2G8g6XTUa3XTRnjG99CD3GC+uAzk9w7KLwviHtQeDu4kWEbNnFlAE5OZrnEBE2zLqrw0cAyzZAxHDgujZXKbvQaRRIMyA0tTAkXRkC2V12SzpSyn1vGyJi6oQ+tJ7O5eqLtTw2OePEbe6srmxmeu0pkFejdxmsq4YWtzNBs83PfR3+3KKqo46yco4EJEJrte0VEdYCIytEgiggGdZPjpu+zqZKpjUzKsTvElQg3gYtwuU+y4zz/ZzscKvr7EdWvsQX+Hd7S6BC6nvFLDX8DT4CC0bJS6x8yALpHiIvBHlpc4P8hbT2dh60T3zf+qIH8LMLXqvIt4I5UksbWVpkL2rUWbKrTlt8V5p/I+kuXNeJfxseMdfRL9J1HoIAcGIE6ywy7hyK2FMa3AnnQgi/pT18VXdgwrUO6Stqu06JzhNC2PXk890seNML5JW6iX8b5qpHw12tnjj/27dsAORh9Ba0A8/Tu+uOcuNTXWBTDhjgeU8riVXplarpKUCOoTZIMzTIynQmvJo7TbWq/vTS5pJg2K0K5JNfFtCOW9WLeN/0yfTAdlWblU6z6k1s2Y6vIVNJCCb3a7+u2cEGpKAOUxSYUhZ+MT2TF+TFd4n3VpLqwEtf0q1yCHB/nRbZDu5WgK9p2tpVQ8TWNOCIcbYiychLmbGkUDqrzyMraf0akC9bDVlV+OzcdBnABWoShx7zcJRoOjNQ7JBoEIajsJCKOFO6B9EgIoHnEElO8TuPCidHB7igXvBfPBZlf31ZVvnVHnm1B0FGuMp3ilbUQaPgr3fN2ffO2QA8wb9uX1xid2gabaMhRQIGK/FPOdR7pbUFl7VAADbRDyySKYL+84RHysV+jgWRVwsusbsxLVh1fldGGiwnz6yHORk6UwgV5iZbOqyidcHLB8YLLRl3zVVLlcqBu9x7AZ9vJsjq5gKDFEQMbjDhbLfZv2/La0lrjC76xefNt0HsNW17cGCyjqNAE7iMz103fXRf8uNtI1rpcivKAIZbfCFilkAm6TQ7pMt+KAhtMNikcXWaj3GHwpUb7BYuj000wEZjF171EhniSwbGEuWjP6kYfDly0uKMyMczFXzp4yr3GQCa+OyT5cQWN2x83TbqX1OWlqsJcHvgjkWtXcFshw0OtEC6n1WZouNVK4TeV5smKC1f5JtBoHENWYuZyGPuhPgrg/DhD2drFT/4/kQbW4QTS76veiPg4P3+1KhZx9ReJdPvqcYQu2tcvPi4KcfQ8bPi38YT1btROe/BZ7EFVaZcgzeLvLgJh7bsG64FYyTD4fAN4B3jG+W0LOdRA/jvXj7377WZ7/8Jd3bnfZNLtq6Pazz/dqTztfvQibE0JpsFSiZJvn1wqnNW4WvRhhFkGl9DZ5ctC9xmcuazMh9CWOX5USFTIHL8lsjRBcGMrl7fh6uoxgUCH2jpX7yPduAztibhN/C/6eCXX4OevP14Vc+uOKdJjKWaTtN5nDrVVJxgTrL7Cn9zKvSkoSxA8yzF2+o+TSy1kV9PFAGg3RlFDzKEnEj39fs+ygpXlGUUwZo+vi/3osyUIbBad/itTug16Nb8vv+/quX7Em6cdsJnsBhws2H15JKu5cXfRwSxhgd5FYM/LixNlFR3c3djMinRfHgxrwGXvnVvw9E0/gvnka35JCiEQxdypAMkqDted7oGqzcdIWRIxBEfTOfpczsL93eXso3Iwe2WFNc/spD1vrgSSsoFOagzXoXhwy6+YfZgTQmLRSWHQvhOCAK2Ka+43bTc9Llyzg2Zu7u1CzFs22JeRfUD7M9Cfl//iJ3gPYJfkNubucAO4TmCM+hFp+z3ROyO2gdcm17juEm6B7OCtSm/V7oIAdd8xQ1ivM7nuOm20tIRMjygcjasWnA26FHMtSFF6Q5s3EtbqDr4L1Coag9eme79/326YwPetTSUZJ/xcl82tCQjDEALgada1Qz1ujM/+vNkA4VmzTLGy1BVe5BIGtuo1c3ZP9wlBJJrojr7YC6uJYyrFrqVwl6I/3xRAE1j4lIkIlvD5xgWf4xQny48HolVXXTAelnxryzM29o8dPVFIGMX5fpCwZUVcvsxfFX0c4wK8AXyB658ciQp2OU9y+GTfTqbYEbj17y2/2U7Fkl49Cihnrnfxixc6dbpv6UoThASChwJ8ZQedDsEK2K22vODWf4Xd4hvBrq72ycPSk+nKznw4pZ5qiGl4pn6GoiE7P1krNFmRu+q02q5o9+d9xqy5gWJ5I+sEQ+PF5ppidF6oTENh2lpTQCo9anWpK6bWz+5aJh8vK49Hab7roT1nxkklSHSpGg/hXgUqyGGJqKTHt+blu6Qe8DY27/CQ2jocfOLO58s3IACgKcWdCmJexDyrQ1IBKABFfX/FOZeDmuER+NpJqJOsMUDN9YmP+viKHpdDDHYuVnLI3E4pTvEVHSK+QCHgQTyMCCW+Ppq+1wuAaNvqoR08VuPMlDHEp093VN7sXJMNDVAFML0e/vRST0XXX1qLy4Gs87VkIfJIyWZ7KNZ3EulJ/5hR4Oro7idNQUMVLA3JmeCUn7/4Qxz1v/kVJEAxZ3iW9FMHIDm9Npdnx1ZL8irEfg+PSWGuD2JAROP1iy37MtlhtCQ7WPj26ASqAqE/bB5vrlztrsee9ctVVbVIgpGVZHMxqSWNT0n7MGp3TK2TRkpqYdW7O2bMhnFSrKwkO41zoHb0VMth0avSWt7fuO5q0OeLgkdQM1wpCxpg/menczgHNLZQa2aZQ+kpqZaeLo/PfKjkZ5w0BMqgqb6+OJymTCr/7r8v+lsSw/KSEgGN0b7ZT1NqGWtaPT3+OG58m3qbZelpt8bEkyWPvSRQCPaoclVpv1W8JUc24EpFYNbRWS7bEAp/DUHV0FJ+K5IjVVTczAKFCEurVlXG54iyK56Rfy2Q6fQXGlOQmSCU5dCfsN4U2RePlasdulmaYn7VWSWLnt5Ma90uSU5t894pTzW0sRDjp/fZyl5HAXxwbPOIT1a/1I3s03kpcut2kKFOhTpOrEQYI/oqzvrQDusOVhw9e016TilV+KDkpDFYpvl/dIcpCofDvHcqVDD6YW+Lr4Ya10SNVr1dVQ+DTZku+IfkIEp+33bmM6uOsTBePdb+oQyBJCxNRw3DCrB16AVQfjYtGPSvnobglfp//+XOevyJCm4k+2frV89X3czWqZPsLp3sr6iY7C8lETcj3JFgwjLunBQKC6GaekdzTJH1NTFJscS8qdhY9rMheA0iJKchjDSpUJbpQrArEuus656hUR8pR8hKsuNuJj8EsBnL23z63525EmQNSaOdHiwtL5QM/dJGev+mtiW880t/5uruRG5TdJZhOpFXIeYqO2XHkQMzBvTXLDRYUwvq1cti66y1Q2ouB6oDgwFDcPBqzbfn8uKcgoVBdhrFsosURXHpTOKyC6tQJLG/tnpGxpKfMyY4uTyoaN3YOWXk0bG2MJ9pts0ifkLrdYfr/2rRzDLS9GottHVdIMd9VDpCGrVoi0zTsyB4cofmC5Ic+xaI4r2mGFUIMq/SgX6i1UBMVUflY9nPU9LOMdfoVWbYERHRtyRDNTUJrg6oopdjk4wambtpqn065GnmtbNptztVnMfVt840ltqx7Y1H7IzMx/JEUUfZ9euw7KsLQ4Th2cg/ALA6eV9l8DSgiaIdtWmka8m8ZDMPRNCgNuDsA2i4OCEx+aocU+jOsu7Nyze/XLSjil/8bB9Q+PzgdTrCCU3X7wKgru74jrfxCLW4dPNH7WKkSV895UA/t3Zu0gl/zI69gX/Ucqx2DbSMDDSzyfmNpnczvN6TvMG12vW02bH3mq+OvoIMECj8LPjmtyiV5s+MLSNb5x8Z/b4R2v56MjzRqEU5pTHtJoPKuHxTPzV9bXRUs+bgrp7Jpp0X+EIegq01IF/nGXrMVjvKAyJTGFh9nuhT8CBmF2GCKH/tQSHDAFIi/qwqqe3kbj3HiQmoKhUij2y79qd06Syydz2jdxJSSBdl42/9V/w0zWo8WTSy4NP5RHunIGA/17gSY/ZOS++jdWY4u5kNeaY7b/ZE4gocgeKySzSuIp1t117VUtM8Dta8yMhFbZS5+J/mKqYsMDcRDIm5CLq2Mwg/heqrv6lmcGx482gTRem/I35Ve6KSN3fM5spq8ZLDHeSyTngQdVKGw391cGWjuoG5ma8bNt50s5j6mqI2Uv5QmojarnkNegVd6Mya4eI6NPdBtLehWtsKQs0YIg0wRR966cbcweylwrWDzZZUAyUTTGtbBoHBvABpu9p/dbxubu1TczHOei+wfiWvAnLPNseIBv25/h4nFSe5+E/iTjyC4oO5AoUglJmP5tKtYkd/t8jGMRz0VlK2fOdRZnF9nosl3XrEj87Bm8yRkJjCQb/l6cMNdLZDy0rGBO44L1XUvy9J2cCaUb9PxvmYRCYNHoEcTB+Xj04mmvELWFckXilTgz9mTFFJHTJI6o7dHQtZByctL7vt8tztii7c26/42+X0vQOk9KVie+Nt4hb11Zrq6XFrruxonfkO3Fz6PGj4Gk9uzz1Fqyw6VTaM/ptb76butrvcH1xvarDn7Ofx2p5e1gUO1tKCyxMJqpPlf2oKvyGnrUKOgwSSKmNElR2tLInmUTY4C7vro0KCC2vyJwef2SIgXa4qGybCAZ6b3cfeiVaJGtU82Bx+RIrjkCOSAz6pu4ktPieSaRXikNl9DBBsrXT78UWEKczy0sTHF0zKpt86SirGvrt7+1mX2DKqjF0kgBRzloJdfixpNrAABR2ZJkBFGIR483JLV2kBZDBkeCmDmiokEbiJyW5cW8rRLFvGv4hJkxzm22CKUzuLzrGS11pLDpcLRmOgYuqqB4oEFkzx2RV0N9ZiP2EGrbUx3yKZZbdzpS4nMPyX3i/V5xddIKzesTGudiem3u7qjxOFKhJakBtN6w5KV06rJC5ZnckofOQ0FqypcysxdAHGfnrV3GuW/d/xtqotdXtu7z6Gm2i05o6UA2/m3n9dXZrlryq8Ee6ESJ19jrqRKHYOqSm7eOGz5GKqMFGaXi3xM5UFxdlRi/zqkAX0FDJLjxUmmZ8P2nUK2/AJQcEWVOpIjT1OZMHvcYj637hOqYWEsvO5N0qH7b/jnMrqEyEuWwcPDjGk+PkxZnqKqjrLmfRoJpjx/llqD62okGfMjI9fm4befCTiDC4IZoBoyi0aHVdLLtEAG9A2856K6BtVjc13FiT6N6LbNzqpnTHZCdV36KWWgjg1Brirh1JOIbVT8JVkSkWTGWWUSBqlECop5EpzPGWUVPjRAWRCArTlyd9L1HfcrepJOxIktDJ52kMpJxNDN4hGEJBIjUlcjL8G9I9mKcJL3SB6KaOyDPqutdPrF4Gs0gC7jt0dZbDFSQpsP9z1qjMzsZJWK9dpZGyNL0ux9BoSeg7J+hlpmFoXHKOVstUsTvjYLRLwaxgNO2t2rh2nqhv2bp9WZKsMXKtctH39ui593DLKzKmJE8EANmxset3ERj9qLPh54ITpui5SU1WlYSYqlWlpnu3ATJAhriqGgCW4PJ9+Qh4VqZ8DkKgOwfBAOuseT2uHxd56fbaeoE1vjW+t3oglvvCiQi6yurCqFVi5pvvsLGhXw4eaGQWKfA5+7q5C+KZQvm9BHXT4EJeTWQOxNrquQaqEaWqGfp6yRFqlhqkQTbA0a1cr1LnXzj7rtnvgXEZx2AR3PerslVhFq5XpdMFsLYcp7zqBsi7jZUF3pdpYCTva2yf0zQTJtC2Sa6gbXjLaA98zMXFAeREyGkGGmiX8vgpmbDLJz2iOi5n1/SzxwYSxOdgj7WGvqbK0T00cJeOMoG67CfndJI2Rx0rTujRdSaVwgw0uH/jYKhEow9TrmQAyyKpqv6ZG1iUDimuo5zYzMyVg5YaZmT71LSGGszDj+cZYxvERHEtXw0H3qFhLYx/0PwAC1SHc3Vw7S3GrrEvm+ngFwKJ8v88NMTPNQsRBCHMMdHGSxSeIJfEGmTDpZzZzE0QDB/KHG5sg31SdJJQkGDBmZtFi3xNokP7DF7DCznULSYrNicvw/FjmxF4YHULcjnRBQEkNwuXlrs5bCHjkpnBuUOEuC6uzUJjE6Q4Qt8vnyd1cuxXQHqjtitVd2yzDmB9wIO0WZg3I/d4Uq9bmDz8oHOvMz1HIHWA7xwJjyo3JPe7B3kzv9CBRkJhtoDFvDUZlUzyQobRwfCo/QtsaG3S8oeHftyzOVx8ZCrWfPxBX2mWFTWjtD/H0jVExPRXOZig794C4Bd7+QoUuSObkgRSCqsLV4DUHBes9fbMjhdQElL09BEvfoQ5xxIitb9S9tBOqaELcQU5OMh6rhFhfiQYL+eOVhyMun1/PcWoVbZ1d1hVoanongDRNg6YtDqHUwiFQeA/ZOUIAC3NzPABSWuUozihXEEKRUQCfoTHs2OpsYoRaAdpkM1WPNn7QduXDbPJ5IATiNr54wZUFy2MYZZURgf5xyUI3PQoCdrBzgS/CtKI9eMlZjtz30lDkCP7KEtL3d+Jfug4QONz9aEKm/RRkk7OMoqde8PTNjqJDgq1tofZwu/vwh8KotSOm9+z5CSZuXjl3FGioA5z+Lw16K896J6dBzPYElmkddHyWjXU8/DR74zYSh+6lCZVSypB29hA8hZM1F41DNx8hPQBa3JM4Oc45FPN9QadApxme7JNFgXa2YIGjdqG3ebJ5slQFi/OKXXNpwN1BlgCCgyBERqVErqEgmyO9+YS8WH+rdssOmdo8NJQJsgt0KDHZY3I2IqheHhLkxdWH8mjlEAsARaHeJdQTdxD+Z6vFrjddbyoDi2JxZkssrA645UAuQi+g2XjtBrZk9cZwcCtlSwzhqRBU5bqQuCon0bHNRaJg8+ID3FWuDmAWlhnWOoEHySzMWJvhqOfoKj81fjutlkdPpk7Ex6nyJIrMbP9mtYsWvehWTkBRseBStiMuKY1Up0/IENibtLrYmo0cTcv1I5Ie+IGYQXGJYmqckwMYgsVFkV7ugGfjWY/gdtub9y6ytjYgxcxDV8iWWvOXkYph8BPMioyCBl9vCSL6XG0eWPLxp5vTdl0Kn9GT2ZxZkV8fGBitpEE0T2wc+tgfmKOi6aIG/EUvdrJjK7ws0pApGDWIAkddQc9tqSqKm4oakz5QFCx3j/IGZ3Gb8dB0imal53+QpiIVPnwY6fpoplOAWbzPBg61hkqjIUucoN2eEeREDieFfYn9GpUI7vYRP15+3/bQYqPHq+0jglR7cF7+mZFiDz0cvBYIR1PYyREeXpkOO0u+FaEbeD5RAzIxPTVsvcXQcli6v1gAaHUDuWaH+roUYO+spVjryCHCYwzUEwcGjvomrknbwXbC2EUsYHPiI9gEBQKFIVLpMqXAz1js7J+iD0kelFngLz32ikIJD1Cz8IqZHCNho33duXf3LIFWDPNIo8KEBKP4mmYLocWbPCiGQ/XhZ6j83LLhUHsomtTO38+kYO0cUIuRCXelTjDoPiuLrNP5aARID9K7EWYdXcuXi0l1UIQLchVJEdPh7VTGeFasdkpy16xmmuFBNKgs0NYRBEdTiAoVO3wVZW/uyRLK7f5F8y+ln6IV23nSAC9WDBujCYLHeUlFjooQoU9IX/jQhqHV2/av4/CemAUS2thHBujg8HAjWxauqaMy2GmjvAVFwqgoOkwqh4wQHOSFOgkCKA48GQgOBlN8JP636/yYXyyUW1nRYHoAOCuwNqAoBJrqHT2BACNtdd7ZoSdrQNDfOAKHKZQGEdOQUCjchSIXydjBVsZRA2hbEal8vE+lIfKiU9vNrWzOkBRLsQ6LZvCNfEWiwDh6KxqJdFf4eBm0Cqiza4I2XbFVwuMFPm7uXfJFK9gJkJYIGN29TuZhX2qHIXmVWPdWVyTCPW4XF+rimhw9lZHnTPeKUwgpZTB4ryTc+S1Tw//8aDMkxMK0XDAyYuU8GR169frLXXk78Gu6TsCNV1y2talF/k1GjZJj8GEwyGDJEEgZyPJMR0IcILfQC67IZb6ecDG/3XOnimyepCj1VFalMAMEXH/vMpg9CAw3cg1jvVosDGT+dbIrAVrsz3ZCx+doB3wqrS4fxFhJH7pKEf9BgOZhkNOp8rtuZGh8gLOdL83PIKLR9HCwPQy0He4hFnrRkP9shdhbYkFtfOye3jIXMkUe70HXwsw2ACF2ArS/vCPZgQx3SLBGQp0vwx6sFFgDxRa0fUmoUExlZ7Fd8bkLPv582rpyhogOumlL51NobIoub3RN5giC5p0c5AJSp4SI5mondZNfoPlQ1Hjnl7mFzgheRxtP1K554+iTH18UoIhczm7v0A6EOvKLIlJdmn++I4dz2KxYOMjeNy50jy/TTgsEnj+Pxm4NumuAe2VlnC55SIv/TpWzvL3zHayRcdVXJkpMK+gQnVU8F+KSVumbc2XNGa+K0H0xhV58v3AYeMGu9nceZBfpYpttcH7s9XjweiZPJWoKKC9zI1y1sbOOccjRdDsv4YnC65v5HdJwWnl3DQjnvddJYK90iXO1bxE65/rGCUYjwrhcSUwkn1ri4ACCowkRSeHu1ArIFe5VgucCWVj5jlnbRHt7A0ZDonXuy5lLBih+W6DAM2lzwwycftz5eib9S6x3z+GDPB4HfZZxJWFLA1RkcQAI1N7uZNUXmDrEOTvQrsWBLYueRi2tgwsspoBW9xRl5khRIR6qd/YEY/gUmjyqi5H6c305Egh0OvUtdChVZu93kZttF/U0OPzJjzVtKWaRuDllEkKQ+1MBXRRu1iOQroamKagKaObqGH1khslR8maFjW2UoA3+n2ftrXi4IEZQAmd4Tf0qWngf8jserNCimnMYhBBnEAjT3Fphx0w80jRuCRDrLfTb5dIeWTjBKCQ+20uRzMfsSUv1Kf96BeTHl8mPMegM/K9lqEBNkfdW7N9vYbiIJKdB/ncEfPLTds089QTT+KsSsTLMq2yw6/RcXfLF9sgcQjJyjcr4wxa+uyfm+un7O4e8v1cZFxk2PZq0+v/prOjT7BLj7YKXHzi0hjWeyosNM+gMEdfRDOMdoViMqxTgiF0oi4+BMvS4bYn02vbXYvpnuj75Gx0KHgVURf45MW3CgH2OrEDwTflZCDw3a1Dhcl/hUrv5M4YeIBC4SdZMCfrhjj/7/gTDBXmy9TKu3QRcQGggJHKjcG2TRq7DlUN6if9U712iZ6+M0u0eCH9tSipyfVL36GKxjc+sIvw0ZM8WvvEHFXJNcg4hsqPvwvHOx6eHysK8ECuVxl9PWA2agf98H9M18sAVd/4R9rH6xHOSX/y+weGly0L83UleROgq//nnudyQ8Cm+S0jj/8A5//3POsVB5omvxsdWIrzCygZPd80da0lujyTkeK9Bqj4Y79uCtcZBKwuNf37oGUpm6XPlNVOllfm/aS8ojhFfGNLgTgsorDZ+98qKkz9GZhrVmhxc79kLoNvtfjuCV+v17igLiDswcmqNq9gHtw9PfE5PwKhOHFfZVVwWEl8a6ZoOL6lSd97re3B3OLErvqQsBRLlqM2RpuxNPWQJ2I45wBgtK9vAo8oDjJItVu5Zu3LlWrUkMa775qN968IVAUveEH7fFNwtfWFK9sfc+n2Lzyo+8Z5xV32ZoMs75KsDGfIYbVVvbUxw2jI3CwEZRwJ28z6lZ/DkyL7DtuMIIQ/3Oeu9Zecl9MWT/y0M01VHO03nKCE87cTCLs/O3IgofZw6Jl6VrpZC7t4v3mibDhf8E0TCbUsyi1OLc7OKUNUOQp0wEwZbd24T0y8yBiuUdv1qEjY8/pcaE+Ml/hjFIbj6EImExwpyUZFJlYqSlTBPiczrC9skDKGY6cWSRs9gmceZLWV8iRt5LyL7GdeQT5Q/WelTeb77HxPJnACu8rBl8wRyinrcJ6MgIEbtg6s9duwP5h6QIyCqZWRcZC62OS87xqBN12jEMc8ooauw3+u/dbep37nV2HT0V47cHxSZQw7ers/b/sitKNw0wjQuQiGJCk3zTHZKxK5WGC1mDFYAO7wLN1XKt0p1HGx+C4Prg4amlLAr2ezMCnZieIjD1QBs1WcaXxcUEB2forEb+3Z515aVI0Pb1nQEM9pimg1p/lGxAiHtM66KezXEgfXtPI64vDHk9yOtX9avFC4gjS7RLpSvj4ILzgvU8PXBuvYyY4ZACF+5Xs1RR773Innab0fqI4xSmGaMAtSLc9gXK7zambG20uMo0bFrzkWMh54uMMsoKOfDjb12jbsMsYhOuxg+gG+u6yRG5OjMsMM8qxe3icWQfabZMxEQDpGTDHlkln8jrxTG4CghXUooJ+n8dELa8BGs+Rf7qarZ9EfrXsmiRFo8Fb/lSjm0s69l0FrgNb0xJto9fUcvfRBHjQyNhBCVMyeJPvqjf3estMSh4xsKltahOqMWJEYOHJE9v17/u7X1T9co7LRIPgOWdT5CB2/w7Rp36dsQu+xieACeuW4XsVpuufmjnpFe8wHm7aATN6eamPbSSWJ2IVoN62nbyL9xkKOEdikhApZAM+Z9Z9flOz+aW0fq3Nsh8a63Al1rZN7hecmTUyt0G6Lch08rIZwuDg/iTVStNsVR0BI5KKdoKNgU7MdEQLsiCker8YwqKoe24GDtUi3TYb77fWNh1229K0WoWR4qe0kBlKjhEPxhGk419NN1351hEI4nMmvuVTyEcxO7/nOcBihJTvzCCf3BmM/ST5YuoKuh299jDY8KZVAgzT636CY91q2EZRR07dN9URRHBu2SQTgdnDBIoIT61FID8bPxi4Dcar2a5BAD4dgUAl2D+vkW3udhGbGQKROVxqKDzKGgKINuNYmMk4UBbbqsClm4M/9VXpw9tPW/i50Vlw9/n77262KtfZeIx2o7OQBrsHUX+HUTUOLcCeCKxHSeMl2M1ECSM2Xls1WzNZ/Ck1OjwXyYSiuMWaVeCQRkLgvdGlNTB3zwvLP24yHcKFnvwoW9kUK5zHVnWqxQFgxS28mDYp7clgbQPnPl7zlUXlm7oWGl/FUThBOQw/gvmPXHAOFs4ERAujX2fpNZjzcvZ56CKSGcAm6kPCDJhYrWh4iDGWrNdz6uJ9JWDGlohvoCfbuhDXaiSFt8D/878xq6hnhMA+Xs5qRAj50qS9Lrki5kQvzIfjr7031Tgx70VPOZM0vOx0M5ppzLNm8y9hzdczTd+cVOTh/HAJs6t+8MA0/wq7PnK1hWvRxmbe3pJX4hU7hYQ3q+frOe4H3Fcbh6WV72Icbm38WfAn2LvNI/J7tlMb1v8RCE7793ctALUpVhYUEP3fv1juxFQcE6edXm9Xw/RS5+kZHSnezJcXcQk9qLYeqE8a4HJgwhYQoREuS6fcfeAKZBf5KEC0tcaEBFaJyESfnstCC41nKrxpfrW1RfsYz0/JK9pkiHolYVtA4N9K9pTtxHYvwgsA38yM6W3vEXfJjOhOo2bWSgRCQ3mQh0F7XJ6nKFsF4qVOHIYxmolKXlKjOUc5gzWgUUwcMzO0KULp7IXBfvZwRBrgvSU+kS0pEZLoKrgGjnMGeUyqx8KYVqYPEcoQpqrxCWW9cmE7m77zSpdiqMbNVygdMLsmhNiS0JFUSZxbU2QbAwISQsqTGpymv0jV2Pa8uFFalr8kaq2sQBuGtnVJki0sojnJBZMYMYTOAZ1P5b2ulEoVicT3cLF4vxQoPpsCfPQyKR3AwCuJh/530V+SaZZ93WfcSfTgaTbfKPizxGGh6KHMpu0IEUHMWsDJKMrtvB1t+f5dZOQviA0Um3cAPJ7scmuAyK+UY7RVwQhz/qV6FIi7jqISAh5ehibzre0LW1v2q0s61meBCDg4SMNfe0AIhbFxISaN7o0hKMbYmUT9WVFXaM9Dctr+f9WyDoj7QhB5AvXGghPLmGfpjBuTEZ55nJx3weCyoKWbou7TnpaatXJdmdu/Yx6eGfG+a3if8YxUVBIUwSd5dSR0KQ3EOzopTklN4N4BIbRpSsDOT/uJx3Oo+ksiJwRE7i9/9smYsv42AtHiqjOhJoGAKbiPTo4miSOJVPT+dTo6MLSQzzYi9bWyuca/nvsXf9ZpI7KhqaMmtVomRyOtpYb6fLka/QoAdDzcNAoCOLHzjsFRdBFR7p0otGajQmYjVehXtepL0PPqNLOuJCDQt879G51zUuJG0QnmI8j96sPxZutGTQszov4pO/w8oHgiUQ5e+udnb2Qt7PTsFGF5HLejqrKjobiiaXWDuDJAHJBSwJmm8RSZdFcP0DwjnMhMhsTLCfV15Ilyf+3z7Dgd7GhrqORtMIkLcyKzsmD6nPjSEJEiXFfVXtoyMdhpW0QvtMN1gZG6EflxefKD9f9KPK4NH+YI8SFI16hn7CIWnWJam7aG0warP0vIc8uDbzJ2kqevNiwLbDVTNVG7zc/60OTtXR1fJjM4yLbIgEd4yDN5eP1MWYdhiXn2K5FjgVhfm5Cdta3Ph+YU55Ie490xS8NZeSqLbCBQSCmrblOd4dgyJBmZ7AQeGIUq4DZfhsBHdsAv2d7U4rzhL8yieooetp6aJllIaxQmT5laOWoe8Jwgoq1UkWOROCcV6+ev02QRNTn4ZZkRGocz9Gs1w8j9f7oZbVSw32ja5DbqbX0vXe4nWRyJ09czuPham1DP27Yk1wyTDEVHf0lwtAxRkp9v03E59xBOVVQh8/S+Qz5i+zYA/k5IIaOsqAEiKRM4UKP7/dT2m2xNeIa0nMv4PGf8owP4xsQ3WypVMwHFvWquueyl2ScUckAhw63qPN3ixBS1xZW7iKqVBp0hHxx5Y+pDoLYYqFoV2iZhJRLUU3xGkuOLLhnq1Vqu4EdjFcjnw5jUMRhT4QNafBNpCvQuX4yu5bEatZulqgVDmqQX2poG+0+fTcvvjUAwdoDAjvMhDjedi/KJ12RPJ6oESYhQcnoiT2mwODURCUdjmbiPYFN9bON87uPzpoxgtm98WjtZMR7KbVTTNb3EiWrlYaJTzK/kP5BwEyq3ST372u5Tg8Fqef6ZUtiEuyM2z8Jusr3v3u5RgWJlExZq4wJuX/nQgLdtrxYPfVvIEJ/oHA3D5jHywlLU5eZBtkn2C44lj2poF/9UXjmPaK9OgF013Hf4+c/+3P+6mHz5vM0IlE2zhHs2CR5X+B3PA28EEurdv3nXtTJxHXnCNih8YkfiMVlmnu3MWO2qTN+N/EfmbJYTwTO1cN/1FMaRzjAUfCnGg/48npsno5moqKR54qxIKO6QmZKhfXKSOXK8rj/h0grjxqaYp/JBLCU1J6OV+RH8dXMmawUxF6fHbOsZPL+s+oCtrG+08mawdRSPXSM+Rxx+QCjNDRVOpe3b1MJMmStd67smPqDNImM2M1pzJ3XZ06WSbE0hQjGlcuFMQdiKsOSuFKxUlSCXF15x9Iy0/LoxWBvpvvN9mPUxAsS65t2w4Wf9dxvCGnwJB/05ClzU8yknzXqycgZ7dbFhIUOJP9Zvu/ifPzynQr7urV5Be36+8UbT+51pbmtlOlR5ox3RQ6o+CjgASm7IhAV51+MoCKMA+vnIBRztOMTH8WjLxU1i6+FyUF01DlWdOsIS75rdQ3kF9KAJqH34V3SX1wdEUiwEOkpvqVmKmyn3T5A8JTv2I6YQHiaeeYqRNJHS+eBi+FtTV6qubkJjEqppsyKZv0aMSGFyyW0Gkipt9DdJew0OBW0xr1Q/QS+4OaE9yNBW+yTOy42ybxRgmRbCWxdkvKpCWn6kKf9p0qPUIen13LNJYMCS/W8qxWVGelfkTMd7hlW6tD2ck8Sy57dqGe0/Du4radKj2SBB8xctvHAnEZcyqmufTw6ZgbcBJtZyYcQBEw8KegdnyGfHPObauYQ5tEh04r7jxV6eUiZszSnF+iOI5VitTxVLFDaLwI12inNxaP+wxPnDjety2VR3NsBRWgggVPPHMfuCdsXB+2WPXyvXjKgf9sj/WAPafbdVzjg6x1JB1vl/q9oV9qDTI+XKi9LSLNkLKpTpGQ+2CEFFfkwMlgzewrboNg6LnR//j0IydMJczCF1QSKGfMgj3PwAsNgecTuubrOI93EyiUatlus3okK2MkZN9/01+lkbnBsrVU7/SQsPuIjeMu2+KSuIkwtILAUaEjIy7EGSmxaB9MNg9dW55AoaZW7a7KyelOLgP2MuyDCWhKUMSDTXS6zw1b/ePLwTEJ1UiuhSBybyo+F3V0SNvFynpDQ2V7E0iXJLGibBtk/Jcgc8sOCnLMlqk9hN5BbnlwXag73ZtmDcvLV2fGqBvczRFPwLBBci489xTb2CPB44kDIofmRQXDiosK0uPw0uigpFfcMfLEeF73Dg+g0vP7YDw8x3KHp00qdx3ZR4szopscGD3bmaJ7wnEt/P5B6RO4xkePGXDcp1QQpWAP+6RggzXuvzrKvLLd4x3c7Iff+Sel5/PReb845gV6g17Ss98RgQt+E1lkkohIEpPI3pxfxEXDZSIQ6fPmYDb8JkMfaocy/cLoJbmSes/0kF3JPWiYyktxrofkSuo5pwhUHJpxqTikwPe9stQ1pWQpY6RB/tGSYPX3JCgJzBQHmxjzySl4YioJLyETRXbJ/yUZFaqJDShUiNASKCOEo+3OIoSkNjdWXnV1EauX9MzJMv2eoig4P5Li1kZCCjfaS7p9rpEvPL9uJTIcHxgNOpSj+o5Jo4OmYOSeU72kAMolms+vNiJSeBaMIURIt5WL96hFp9WS4WTncPbqgEo9fArC7hSUou0px9dNF1VXx39z9z4yFdVq7zSv8K1VxLSAtakGeB7pkCYIeIXT5z7dRXL9pARvHJoQKieTThm6ZF1aD1k4QdsVxtLlgtb6TVsUdGqblwQpJLb92u867HGPfIDc8ydAsrH0D3zqboO3jcKCsEPhi5t6W9sqRwd7axdOgyGzWhYmB5Czp4YQT73ugTYYxW8wMuDj2czpsPbx3qWgU/cJZNLFU7Yoy7rBwTW2Wy9uife3epJtWsJLlticltoEJR0oyA5Mkdkel9oGpcT9Tw9g0DGxbL4ktqPf8yiUehMxQF76988N1AKXHypkFFKuFmlzUkusXGWEcAw48AtzQOwC2PFmkdzxpUXV1XmxMeCsHbLsyK4pILbN5Zk7y62NhLiq3xUXLkNfBiljgkXFwXIaBisLLMsgff/1J6pM3eRBMPY6m0u+3VAUFLJ0XaZvkO9sHenpl82z7qSHX3yCAve7H5vcHOm1SJ9DXDxRUhFTWZhnhwfF76qhm6/FWG/09YkJjpcqpTKJMl7OiSZbb8QA19JrRKYqED4bXF2oeRsSS7S8EHCf5EUSgwI6ayRBPKEw2IZ8ifyGn1KZ6hFALCltLIXUkZ52ZWtViYvqI7x0VMQSmJo+yPCN1lWWrlu0l2FguBAPFXJLuO+JV4grTgIrTgAPEYkMxwWPeKoW+zjq5C5nowdarAxEc2mkgedoGJXZvxPGSmx0IXYxbhrOW3Zu/LgMl3DG7OEHC050d4q8NFrA4QfSGeF+MtgqnSS7M87bfk7+0M0nDfHNXWKviVLpklNDU2N88Vts9Bu11GXnWcQc7lLzij5/3JrbO+0sdu4AWdsZuzHpW40mjhitoWxjvPGibPlAtqwJ+ma2bamxPIpM6P2W5OkAmfBJhBiw7dcK4X139zfI5QXSDOvk/t02tL9UdERqxSUBHDujNNIRCRBCHcXM/Bbqqh0YluhsYWPvcJlbwqCU4CDkQpqZ+Qunx/Z24j6FGSTMxBJu8rfIM57ceSCaRM8vHTMajHPsLKOEumlZeW6KdDhUPDX56sGD3tk+f0uo6MiDJh7F/2BfHwRh/zOrt8VAiitW9imWP6WIOi/x4hKzso1vKL8o60ML9IV2UDbw108XDq3RaNxJ8P1uOCn8auy1/0zJhIWEhcR5JDD5n5ScYQszFQXL+hMhwWDYx89LnvFVrUBYhVuya4V3gCAADtBDRtasHCkw2AJ3CJkPVnuoFRzjiENaIi0n6yAQDAbXIQx5X7Wx0bjQxYKGEYjgEPyFMHJBqInP/1l9Cqy2F3rH1xNamnsXNtp1Aco7FzXXZrY1FlcsXL1l8Jl8E/LVV6oN2NTv4JLC8ZXtjrvsru7r3sK8EA20/DwJBP5wjBAGcwhpPN/c3EL01MFnaDsGjHE1BlcGgySNMlLNk2O8S30xwAA5C5guTXdDwGBAEBAGg/VikPVEXAi8wsnOfhEMR9zF5oiVQYaWkkYXJyEt+qGWy5EzNFim1b5BuT5RipaboY9UF2K9gUCI+dhyVrgU/EcJ4V+gHJPLlEBFNFd71qQ3wY3vzeIGq4XJCys6sXioCI9Jluwf4aOk2smRM6zWP9OGsN1tDwsGw2BgrjCIuXlAGq2BdWE7KpOEcrU/m+dDIXhPsuzRUrpwDoM+MfQrWJxWo3ma4UaXlhJDkFjJYe8m4GCL7O2cYsIQNAiEToch2w4SNdMtHGc5vqi2T0K44ynH4FfgptpgDHaHUCbGo1p8dysGArGCRDwnxXc78oc4tziEJRliwVpzAIGI8s7tKOAogCkNMauuUja5e3KXfHIPw/IArbDs1IhA29A9Tx8G1Zb90tDtIWvYl/jGTx7sYUbs+QXL4tzhwWCpAR+IeOnWaddpVfW2rD6tMfbcEDK55fr9BhvuS2ZMcKIL+PMqyZMSy8QBtKwMT6f8zm3oqPvxVqcNhUxwo8fSsQA1O93NKJPbr8TTTZmrRMtU+RqwOhlJIRVPw57kCG4osY1zv1wyYQgQ72LozbvGekzfzFuizK4DGR3fufXq3Xob3sNaYYMSJ7rT4pgJAFWVcYq2Zfn+LyujnFmZ6CiEMpB+SBY6odglakx/+mN28ToroTezeus0vlHdTz30C5S3QxzpQ37qgyNbPiM0QBZDrufktqBbP8Nbd8qf+9ApfZyDnNmFugQA74eWo/UJZgUHAUra+bw+JO3K3TGan+/R3F9W10XhIMUNyXi+OEFaEzUauj0UDfvy8REb29Aa4uMfnTK0y8pk/tbPMZ+X58of2xvJiK1Wrb4mTxzeUBXj0IzQ7S7g0jdOeLYo3F/ECwm6xm0LKooI8c/q7fPPCwkPLo5IdZn9AYUf6Kp1/bWiPlbr7PMQiOn1X+xbz+0IF1saRnT2tueGN4O/qfwzEFOgNleqrc8+VKY9a+sv03EmOZv/XQqjxRaDKIBYWdyGF4Y1Lkxu8trhnNU54mPiwkje/jp2GVxziLaKJqUeig9G4OkodD+veu6irLTW3DpyL/A/Nwz7eRLd43OfHwO0RFHmyrOBkxVKjGMjsX8V2a65Y2RyJCFV7tFgSqr+eRG2mvgQZX72h8GnoqG6jswssP55lEPN37DEWA6FDU8h+68mTM50pV7BmBJwPwwqmxqKWzbfungv8VhLKodPhyyG2eSNBMHwQ3rNSFtEZqH6P5ivE59P82f7+z3R5ip1zyWFfrUOiPxjnNwbF+BCLUQhuBM/k+QpeQ253WZvSXgFAtwH56JTGzNLy+pyxt7QvGlREa40GsWVEBHlTbBYRTri/f3t8EiMHd4/wAEv0cqXlbbWlrdXn78TSzjSwZdIQtD3J4/aInCbdVvuxqnKqvbnTvP9rhjs85oJZWvEX0Nz4UkULp3Iaw/2C/aDBe/28L+zOTbYN1g1lxn0hRC+YfWGyoa71+pj7tRV1t6auXzMa9zPz23b0jmzMV9f712eTYxW49BzoS3Ggk6/kJf1tIigwf9zw6cEPGaGVx4BCSeFuZ0KgOSFLv7NMQmva8uQwr1kLGGDKmquFRm1lLm1uC0rE6x3NMK+ChaNS+FSAGQiTifeGBDooLywODQsMcKp1mfTE/sZw8DX5CSZJiEZXQHTNf8eGRtJEqV51JmQqr8q0JwvGR+Qm7AdLQWF6v7qtmwVuR95y9Cmdi1HhAnURB9/D9i2iQbRHZwpOXDHnnIlnQp9qxUYsdZF3h4b4n3CbjAegksn5Nbkteq9TQTSkTbW7YnVmUUF1dkDb7kBlNAg7xQ+z4cQGBqQbPGU6J7g6eGSQCS7oDy83OKp7t3GeTilH1Ztwfxq+v/rJej//3IWA7R/4S1bBIic3vZzyyU1l3JMaI3msd5/JYLacQbDypgbVnJcGM5KeSOp+eBRt/HEjaaa2uCvlvE/PYsz/FvAc5G7M7ArHZR+p8tcQRZq5F2W4VMlMfBvyQjdwjADkFp9wxIdsISEskxZR/6983hQFcilaREy5VBw7p0AY4mCmg3hTW+FgTclQSVgVJHhmUTprBoIj4r0FcRNw2ZGd5tIVA4nOLphBFOyAipH2FMQ4CzgyZNVZFxb4gayb2U1sezbQcffyt4uLECBbmA7dGFkx8QtU+lb6UucQ5xnLpyhgd9Y3lPjrHRLmHTMJ9pVTpxOwDTkW0rX1Id31mCMpDo2O8eqHiaUoRLrX+Ofz8KKFmcYZV/f2FQLXk8GSfPt28j8Nxfu9cGPrVmULh72SC74xp3kK1650EaSuyBdOKyeYROE0uK2xY+vPhEPP6ZLtm+7PoY/YFlUmFGVI/XIS32cvVcNBb4DTGihFAKMGOvvW146xKIaFt9W3m3ht+Shv7h581tQjolhdFkmGdJ9nwWhWCdG+FARks35TbJKu+soByIU4+jijXaDfOfwICr7FCknYzS/J7LFFoMN8ug5NyqtqHGleBant/3vYJuVpzghfRK5aC0NH9Upvazz1w1E6U4dUqoffPF36ZWqHMzkcrU5mI7U8kbgo8p5/Fl1fG6nClj8K/j5YUn44pudi5PAoqU51tAp0NHr8KZiTM2B8p3BpdTTf+3Wsvuz7r6pkT9YEuIZ+CcJ9vNyzsahACsAZgaKstri/tLyPTZuhzHXQRYR7/srKVZzdr9Je4CJ6aNuUzzihF7Z2uBSwv9gBEvfrlOj81kK+NmzugqSkqmJIlpnSgtjdI5IW02pYG0nlm0fBaF4ZLfNTuqgJfFxcpDamd1suiyrwBJtJ1jaXmNBM48NNrj8LGxGBK+Y1nBHWterBQs+7rEMRoy3ZNonpOdNGGtEmTgkGlPFpN7R2c+EF6GzCmGPBNmOkeugz1jUwPQysv0VJbeYRW8LASIeNgcK6HIyGiiji4MNPf52Owa/Tp4Pi880Wokjeahucp107xXS6eHykERaZp/Jw6H8X1tOTFEc5nHmMZ0X9++i3Hc/7tAVzNsULPI7mDHvPnSgoXfozJbYbrfztX/mg8Jogg2Rf8XZR5dJk3PE49vEnreNWF5ib/8oOY0ZIvfxi0wXOepfDfestXPRwNPrQusShtP9YUlMmt+hwKKIrLg7NnPcpeiix+UBvkcDkrcWf6cZClYemBsrrqvLn9/PSntDuOy+lzx0cX5cSLB+LBbruyEkdEXgtYgKEe6VDuNrEeLK2NHz0vNqj2zmINe8Z2YF/hVkKczMLSROWjplwVazmE8BMFAISyeSYx5moyDx6KYdQYEglGF6WiAqVUkwqZJVibXmIPMhm/t/u0QHnIKnanbJtUUudbUQPArM6LFWOIP9a3VbZNYhfn8dcDpoV3cYusc+DVsz7ldyWTpeL0CwNn61QGPR6SkoAn/o4pSckF7xL/lL6vAI7vwAbi+N6JJaNBQ8oS74lPCKYM7v46n9MS3S4SS3OHok+EpUgdxybQgqAaQqijdNnej3O/VlOy3Nhy1lALg8GuFwcUlqEsMTIjFPT2FH6pJVpg1pjQfN//NNJ2upU08a92cuWO53I41V0KDfUFNNwr/cupvMoCaRLbuRm5xj1QGob7uHdwPA+6CR9yGAWgA9dRg7i63FHl9AvLOgQlAnRX8WA7gMOJd3zAF4+of2EU8CDOUTaqlT0KG9e/Zunjm+qqQAecUbWwENlKiXNY3p61MzZLCYf6Gx6Gtih6Ut4+V1A8uXbA1zKnAKznKKcrYY7BhryCpc2rdl7N/OyZc0aanFsasXA6p8fL0zymdKJHlzIsEwKv6PcodiZ28V4orFbLBT/8BYX/vg6GD/4EhX+8jQzMCDtMQH82fTcvciK5AjSK4tAnZIIVzLVxYtwBW/jTf+Dd46lezLo4HnaVXTkBZofYrk1tuOuLrNc2yHpc+fTR20HZZY61yG6225pzCwFk5aGEjmptn2JAq//q6f5/y/w2g/N9tW3stgyQZ9GooWPvxsGLtdPbb8fX+L2bJNXf9+/Awt+hzfarTOP0W6Rqhs2ZmubEyQw/CredHTJSUOEUvYZX4jy0uUxyxoX2iHnN9udnp7aWsaLc5WcYkdfOlZRHOS6aZONqqhK5nkO9VD43HF8By8mnQbF8nJ6s/rLM1EHmKj8varxvLJIo4AupCewmcnCAF03jAcW+M7l9UROch6oMMuidXSLUdhS0w3XGATYm6OdHR0ayD7CgIaZXXDvTJ87xuWbaCD03vRWGfVSoFvY4BsuE7Wi3dkDWlIky+zEfOxfmUz3FaZqRPX9fe1Hl7+6fprHDq8bNMfRjy0jtKs2l0u43py5n1DpiH1sdvfs0xPCzu6LXZzfP4wEdDaeONGaWWv/ememrH1+6aWdNHvjHbE9yZhIk2Mi+eHPyZmV6g8M0bCsGF7jkGLaHaxFRVhsSMLE+y6atIXapWD3flI6XXxvRFXY6aRswZTuN6R10COdjxA4PoN+rSenOstaE//e+l2uhvQLMQ12p55Nhs3R7F9n5taHB3wDVtllmTcCwhFCaBQG3X4J1L4qfsfj2yTbT8UMBlha/TQSbxbNxqzOmzdzN2uG4Pm/LrJpoSB3Ve3Te6+PZC/pzmwll+zqi5nYPuce5aqs4vfE9Dd2aNNrlteV1W/jALx6+rsjU+oWVFbV7E4I6qr+way5ZQ+M0t/GgEzAuzmvbv8oKn5anPZx2FAutbssfms1YceHQU/e3+i1MBmmUkHVpRLkBrIaws7vi0PJhZz2OKlNcbIYDM+EGWam7J/caHEWekwA+RC9d5Qkcgv1Zjqv4Aq9Phe8xt9fjMWX/o1e8zGnVun+qkzFk/7gveal/Efjfbt7fNv2uH4NGqdBI7Y9mQ5gPrEIWcG+86gnENfaB66Wyk96IOFnknuG4dSnic5A4ZN655Bl3FHExXIe9j/zmAkBRLRePV502mIatbKyF9mNzcsOxf+pw/J1JFeguPO1CGAefTx9V9vB8kDPck4gsuZ71ozML4tMhOFJW5MLGvNsdVfHviHcj1IUDxmxdCLJxrOSfUoC/xA7AfAow35pmwAYLFrwKF7F3lg0eAA9lKRDLC4gUGsjw0u2jFN7GqBX9sX0oMVURzEqw9SKEEyGqQVAYK6oNP2sbhV3eZ8zDgt+Dsv4hot3AXW0OS5LHKZd7P0ivsDnNjI3QPzd+imyKehOw9l3R1QAEwlqtWSXxLl2djfogAR1Lzi5sB9jgV+4G4RIm8MugfgsvLsZlkxQBLnuvMpJf5qs/uIseTDgstqgvk1uUkCNRfuOrRCZI0ru7/MCcAS7krDXw1M4e6OnymKrqhrAre8UQ1rMzNzTrFNqURxeEEBt0lFOg60wAM0aNuhFXfWDFrSSMirbgGTj0lAjwDa90fTnw3CClLJ3iArMweNbgoEPUBFG7C4hWEWWQL3qj4v1SxhgNN2aMkHjcfLkVI00dLG/WgoSNUlCKZwyKZUIl414Iok3Y5c3TbAHe/bP8+6PQ/YJcuQ6zk3TO0G5EKsrzArxZ69V6QqtonmB4yI5KnyTKHCNLcLQN8NQUcoH7nobeAGiGVxmSrUI0gH3kitYKIzQoWIc0skzwwuXwW8Xe2G6MwvZTkgpsjWQt7NFZttIHo8irjlwqe2zfHCc9Lk8jAjUjjPa+hv52u0h92Qj+WbKh5jESI1KwIHAN0EEF+MFgpblSqUjv3wQyveaxtWHPLcRozERPB4283bbizJRHK+qvAAmJBuAojzzPBkYwtUXkOs/i7fvMiJHpXWIP6Uo0UuTdI3LKFl0nsyzb/nTJVy89mRItRQUaHM2VYnfEZW8Ugat9NFyod3dlEKlU7K1BcK04XSU8nXLqVvpjtVXBzinw6kL2DUlKfKoruix5d3U5UrRUKEltWpdD2pFAiZCROeZfB54YpA6b2PK0pHUXpASp/DBX46XwkQDKgsEgh5Er0SqtK0cspWVh4bHxwJrpN2SmYla3PPGeUOXDkt0YFpjhIs6oWRTVPpxGVNQwU+G19qzlx+iY54+0tcMir+pe7TWtKlSlIPcZWGzS9q3KJuiSCZMYdAp7jNqcj4sVJzybkeRb6S2kknpk9Fp7FL5KUbl5bJD9/4JoWKYgWxbusS1EW3losT9a3i0e2SpHh5uYjVN4uGN2lJqmhyV4I4dVIg3pOaKtq7N1HBIuvEPrZ5SN/CrVsWF7cs3EW1+RCLWkh/96VF0R2nxsf53CdTC29oD3nWce0VpZgzaP0Z++xzxy1u3oo4K/fjcneNhWpiYUvfQXmfoBDQWGz+hJR18/xML9pgv3tnqSScXZTMLd7zZjf/yj43uPKg+wnS/HRRU+vjZPLK4rr2wiOLtqZphLbabn375V7FnTsVlWmzoOJSvdkDQja7xA+dd4dLrbZab7/cJ0Mds6Hg0/nMa/efvQKIWpqHqq7rr9+DfT/XQIIdKBetTwooxf5fvDlJo2KphFdVzN+BSJ9wNcLen6td0aLNZiMlv6wjsR4bPlSNSHXcfm/XdpuvA2z9vMadZWdsUVmpdJgot7qNTa+2D/+x73rB1YcjowqvHY0UaB1w7RHRsYirLylLFi1C1kV73olm6mqqlTmkMyQevWnc4vT+eNGBLAQ6ByPfnCwNTgCABIIsQSpNeFDCiiT4JL7C/lreTXba+Af60LirIf27bS3Y2YlzqWT9erAzaFVjoH9ocPDB/Wc7/QEhEzTHJ46O1x1wTfL4tqHjiQb4Hf4E8setEISmnm7i3hYdMRCYykqjh61X3qDgUbDpTwxy3KE4/BMpLjjwbcC6e3wLSSJ7Y1APkLqpxONH5q8tLtKydfNuxq2aleEFi8cM5+ejAK9n2AfZmovNxLhjs9Pzi0li0zL811ajynD+7GL28XlVYvbGT62nz8c2nTkb1yoQpgpbms6ed3yEJBgqFegSQsW+idxCMo1GVqs6x9I27tJIAAHeTEuywLkrkhMayY+iq4vJjH3XqNGRfG4IHr6msTm6N994g0a1QVsIjmG2xRiDTXT/pyYfghuw74JcES6spU9z3iRV+cy+/PzpHeriyT1qLNl7yIFVWsISlBcwWCVlTEZpabyzziUbgWCyv6WtHFOrmZBQXcnYlnpSa3vyzh282g35CGrZlJA+1W3Cmt3Lqq7kspiNqSkthbVHQhPwuQ3QwjB+UWhvon1k0cECVlIVAVOelNe9javRXhzshtCfcC8Z68vJHxlJp8eLKB7fGR5p6CQcIT9/y0R+ZEEgPwWm0Cn3HMwoqgjNsYSLrK1o7Pn9H1lqvDisCpXe0iRldOS4FTkVtuczRR2NqXTGicym1kNVK1DH/IvYsg2KyiY0Jqif3OOacFin5yRVmtekxXR1oVaTSzf3p0f1+SeV5SX73iZrpHqrEyWDpzM27+3nFQdEVhYX52z7++/9LYh/8rf45LBsNQWIqg9IKclMDuw+4NarLmgazovq9Ut8NEnQ0aaf+frloAYScHoELVjW4FWjCtwGNOKc9l7jJVZA/LqJFbbX2I8cYzHkBlb8e/RPqABd48mfXLjGwXcdNoUXiAav1E+IyDa2akGxsOiRLFS2SsANSFaLomURdqeC/mBKFVI8+pq7QexriUKCB+RRfa4GV8jEAXSOlp75qdoQY7cKEwrET6ejT38Ccp4fe+PaQzysJnddQQZusb3nKEzW7gs2GJ70eCcnlW+J3aYrcjT06d5cD15ZnpldV7EUcAat6ilUj7ZPsVwulWeCf/OCxBOdSfFaR5+gz6HdW9fdL1yVJQ7qAwv41AEg1RRtqc62CTnR0E+kJ6h9Q2UWP9aJQ0koW0z7wJCQStkozmwSr+iVo4nUTSmAAa6effopFcW0xbRfGUIQ4LaO8z0HjLNScSBPDPF1+lpeNRcnXF1HFA25ideROGi7qf/kshu404z3JHH0UNAy+tlv84MVXWANLtGJH9FaJx9qeQ1DuUelWMVbhYaUqHBU+36i39aDYx2iZPso8UvCFfVC+4IRoL9wEToQ3Lfu3OOWXZer8OV4RaFBJSurNJY36yA7II+S2pCbL5BSMYLytGoHivxV6B7k5oA7HAqmQMBkAja4NA0MYQC7AGxCvqYB8RcR52fZjV6BffTXbRs1nOPBmAq3HYRxgttORhnIyl7jHU6IwotbLfV/2HLhxcsJLgc91TFeO4vhq/Pdu1qj8dPuowFYdEggBhPEdgODEjAm5qub2OzLlz1b9fplsmBMfFAQOj54TWlimWBc3VR9dDfrBdryzcEkbDQ/9/LtWnd1pKGv9JO99iVtewo7PCk1wmYLOy1w0sqgzBDZOIwfaviZWhMvR9avvDZnFs+5OexSzxXjuEKMjiXc/6Pnmk9js7PDxG4lSzfYl7cpb7f48YqmzVDTRX8Lvf2iYb4g+8yqM6VWNbDhNW8lnJOxbmF6D/XOjs8OsKapAT3mxg+2IH+XKG92K/QVJqdIOg/N7j/yFe7VH0r/nyOoPP737sjuxfD/X+0lFtqKnWkXIKUiwNCg+mbPXqwUHoDeBFjmGik3q2mygMCGkqF+QnDBGfxxWwWQByPO90+vXL5s55qeYwqJTiaSa0IRgsJPF5hRS+4sqSYjQQugjRzTVkoSuxb3dBk1LSFt5+H03qFQjoEohzuhPHZJdmYZVil1TLoJiAiGPkyF+K8FWjYAVnqxl9vnqQDicRPA5Zyosr7yg7U7bRCWgJgXwrpu527Z9GkqvLJ+m6h8NDhsJUvisu3L7Jeih+427i2/wYID7NoE+DaK+Ko54w+WozKTc6YC28KmMDFQZINJXcqDB4HCwGTh7Iv73LRDivTRHalQ+vTI/ikv+xpqEfU51JPUV+74MuabKMtTjHPcUcA8T6+HlmXZWckpQk8vqsDwWK87y2lKri74kLO4om8btdfluCgkNRScZJmatRQr0PhGoxegt7rPi1OCU1nEgCOHBOtIIwPn/+tOOT067NfygmubNGNxCdHjG7dol8fFa0Z/2MNECbKPNjpsNGtjy86929wjwuGJOk/oPYYAE+wbxgmQpcTaWJmaHTV6OyEDM9Mlev47SHlWjg/eUzungMqQuIuFrBvtKukaNyXsdiO3kSnRZFJmGmmcTWjV5DSy2yjd4kng7KGTlp+AeUzy1DHC5Ul7SxPeYrsTs5jbl4v+u2wUMl8zCR0XmGJLMcKxO9nBZD6aLr09ZN3GrpKuw1s5ymAfvxCFD1sR6s8JVzDmLfasI13u+DAWRWptMkAe7nAPRr3ToYgTfdfGxglyT8ey2FhmRyqF4tZB/PO7no9zvaex9u1HVsDX6GAd+a5r10GBgP4EgWRvfOBABxZOn5Iyx1tiEwKogUba9TkFeYkJEikrsgOvgPzRuVPxTSlFXvaNdKLIG5m1Y9Gdy6HJb8OGVvVValM3jzxM/tWBLuhYtqpemywlkfdYpYKyeT4rVIKWoinmVinCth15Qgidpok7skTTvqxYmhwP1COioMSkFWdKxUMz35ffA+heGlAmJJmkpzMMid73uEgqRWN8kdBmnBNLW82AFuN+Dis8oMrpOLmWBWtGMFN3ZJ6JDglzvCarYsCZzY52hYJQZTZy7m8FA8GctJ70fyKVOLYY13mj5t50dv+IxRZ0fNZnxVUxoM04nNgpdvMDbjqtVdZ4QOd8WpuVBrzU2TS81h029BIKyWnIPtMn7XWEqepo0CfO1JztXsBX6vOrWhpc1Gr2s7vDbc91R4KqgY5k/Xy90oEq6HD8uqtB5m/2CtD8tJZLExKK8744dY8MyliBeF3q4gopk9Xhtl9JSW8gWESlW4FB7pfwY5shXyOpBm2m06ELzlpo/SyiugZJPnZMfu/RAGx8xpIKTYPjfx8md0T5wQToMlMq3ToS6QFRHWTKshM336zX29rgR+4gc57bsfxDDTesQuK2aKUh0RmfoEY6vU0qWbzEYPDzC1lwh+eALFkcVpoYSwmO12sXkB7Pn0xqaRl7waRFi8d1SVunbi6NVQCkLFkSlxIYGAufcYYWOzoOJZaIvdNgwiCammXSXtS8tFTio/9EdkV4cUCsI05Txo3b6OgjS3Wi45FMJNbyLliuYdxRsFBCv6aPXIO9f3aQBB01JNADhpraQZzNO8IsFiDCvkliypEw1D0hx9ZiimhYWfPXp9xMy0lu9PLnArlz60MwXFJsy1IXRNh2uQMLaw2juHnyssovLoLuLP684YsrgUGrhUXiD+0pMGg9B1UpaFXkgBA7DvhIuxHYm6rE6jrwsbyQ+krp0rBHaPrjH3FB5gWi9MTYzKF6B3Cu8VKIiIfuOSSi4V9qi/c8cUyLLToCN47DN7YGZwID41KWLPmGCXTPZic7on3jBcPxj2uvOtLIHLxkEJ9URutIpvqN1wAxi306Fpr+r+t4FB/0bqxTHw/8A4ck0n6kQSroa4qPtzNPr/zY4aVvzJEyexp1qUw3CUM3QEpGfnZirDyIWqZuHbqXr0w80S7A6uqMS3Gnd+XhxyDJxw73keVuz2DXRAK6dGgzfevBQ/kM+5zxUpp8kDQQZAMdgi9ol3S0ktitd/ayVkznJXWQu/CWRL57yf+byMKXAs+pyvvwdCBrKhjI6Z/d6pkKRzsYk1XFQM79DAkL9/FkxgfunypPFO6XFIGE0jLodClufzqLwv1ueUJ81IMJ/6DWZchP9ebNWHJBhxPpRJ1aiM1gR+//Ob6yjJu4V8Hips6/9Owu5Rbe5A4MrqV3KXtLJah5qXRTMBzsCn/rofjKelDzDKx5iORfIkbNyaDN2eZbOOOTUMZFfQ5dAT8Re3NpVrouSR0lLepw8fp817l14132+GkswLRRa2IJGis61KSZ0XrEJYHQ869TrVzKbGHrSlTc+xGfuuW02l1seNBNqnrzdszOjkjI3JrxBO8uZHWE8XLZ0ekhCje1wzW/zWnDZ9VXhAx0bySCx69Cm68urtCl/nuFaOnhzdQHUy1ZfYMfu1X7T+kMEXWEk2lWHRBaniVlrl8MxMtYgx1uey6NlcZnlEVbqYa+FPxcjxa6WSzrZwPdkaC6jto90232Ey5qraU5wlRSH1+aB+W4N7AU77qW5UZ99hVkDgyb+17r7mwaDm0mEHw7qDehczdvejitVY4SwfrdhMzfjKE7flV1uNCNc926c29uezu2GEslKtJ8QU7PVzAcozgqIXi50NEOzmyuOvSuyULCovvYIyfJmQ5Mz1qWcwnPq66rpRyCcdBiXDXDiaVdxCE7iKyiT1dUGX64jwJMJ5mklwndSwOYo9Pfl5/MlIpXnElMAr1SlwCTFxdL229rbmMomk5LCMmSb55XhK1i65KiJeis0C2nVLJkmLZXJN33OHqD/ho5v3lEm9pXCRtaFaKZdy6XL4rMGm+RTrx5BYqaUvTxj865e2o0S6JITCgoyhlZl5QZQI1NKOLMUxRDyFKSNnlV/TLkgL3xgfwOEAL6swMYcUeIPTD8C+Vyx0KRs7Cww6nok9k62I1CSe1gxsYuM0/ZGYZQ3eJ5Ju9fNRd4CW2zRVjtjOjEToBiFYhRHTg2WjJqbzqqAkII+3cusPmufIxyQIu8pHTtediNNtRkAEnEnL4PAOmn5mN90t9DKPD0FPHdPQQ8hidPENiO6bOxIAgsQBCzfMBlbJ4pVBAfi2cJlpKshCOXn5eMYoBfs3xpI8gB6aAP6AlyujQgwN8/JEQgsIr2BEIBd8hrS2jO5S6ll3Gfb5KhFdBUcDP4xKjGvO3mqfI9l8N8B/bR2+3PmCiwY3liW6f80srMCiaLppci+o0252ENwDKnZnaGC4RbbV8Gn/Ur4gxuQvAp/DgELQ7Bz7dpqxRYhGbeOvf1/DhagdRdHiEZg6WksUtJCOWN06P8o99fZIHMVi62stg5fpQy7E4j9J06ZTpA8yCPQTTr9AGbDXBTtepjH2KYpaeq19znFZMrpEkZHbyJ8BvhTFtPBMd8C+Bm27g0WYI84BRpc3+iM5ppWF1ze3X74vPn74Yd6MEWSdAijwQiyzZRfUMXmvfyHPkFFTVGnjSMVhNGj/HwOGiywnPdXY3O0TcVYjw9ErsFyvK9HMqvlsaS+u76+v6WozdCZYz/KQC9373MBBeBs7MyzZIjNYY8gX/eFtB4nGUqezcSQQ8SgJw7lzDC4VgCf8A1uGXi3Ft73oiQti36F9wQzK0M0M+pX3s24iFXbt5WA04uU3u5q9ss8iXA0J3QZnusJ1PuDBLx53Om5TQEc+Jw5+8ao52As1DsYdpq4mfTjWajG7iyDJdkCwMzbJgan2SSurLOFVBk4rVuzSJd4hmmgRWBKijBfFdIMEzRzdyZCfwkcQzm26DknBzs9JUsWZds8OMSAoyAJczB/ImapaI/wNVzl3WEGEVHa/ZbTieE8uUxIZaNMUn+uS714fmiyaqiDX4pyWt9ynIEqzKjmO2arNIIntOkj4ga7qj14NLTdPJ2t1jFMO+Oy9BRFGenkl5Sw+CFMufCyTQBXr+0qeWL0ACs+gGxsUdkKpOLG+7GwHpTUoAblX4IXopElaA3gusanebFN5oz26wXaZTPBTyG0XMe8SzNhg+FxbLjbCbrnzaS8mQGG9CdWC8Cd9gAIIQdvkQQR0RRPQgBZz1YuVWNk1xiYKPBwE4yEjEkrDKeaGbEjFh10bGj804GmnWxZgI5BuykolwDu4JPeKMQlT59EoUAwarGAKNGARifRD5gWTaieJSB0jLU2eBVSyhk3sbc6CZRxb6YDQ/KRUF0eDuvw+139HSsh89LVxhEIhsChSQms5Ik8kiiUBQD3mtluI5UNRRwCUZlllWpEsfVL29IoVi39N0yipxNZadNRfHRK4VA+4a7xeo7NkjYKGa1dZsPmeLGBMfv8Xw610i200Fvx3EwQTXIVnwVT6K/oYzRATj2ALwcLdcgiCQQTwQMEnEi2elMaqaXPP9KZgDsV/Sw44gcxeGhxJvH76qWVFGJZeBfqsk7FMp45FB5Aq9RGuYowLGyDr5DaK1woUTqGLKTCVjJhL23cSfzqZ2oTQExTbGp2GWoz/HWezVXN6K/ssfpFSQeHINEfS06aTwMmqyVhEyEq+RYQ6gvW85gQlKGCsVUtmnif0NSJfAbt7HN1SeAxuPVyhh5D+Blyhi+gAMLvCXhpf/HgwYdcndm5cNAc1q6uOqIJZdXUiUMdjVW4CyAduqq2X2uQ/qJ+qTixNbSVBXKPGzKESSGSynp4/ZrQY9eQyY5h3QZUPWbWB8U6oH88GS5Kn8H24wXQ/JcOEJDUPfyluI4F5jYlsXkBRfDpTudnnYc5h+IawdiumAYqkYtyQBd6JCm4jLq5XUtBAtmJZOH/TSkTClqiyVSGKAidpOKB+N2Bm82M0rs1/zj/tcE55NBBTIc8A3lUaz8g8kolueJu6UsM0Rl8Rpga+J2Ag9ort4wOePuUbFLiaY/7TjyOnGzVoD/KGblLRAvscNfYW1Mgm3XK+7BKO1EXH0kmbdMgui8MkLfXDPmLQ/k3SBx+AbU1G0jRMlkxQxQU3dzXl5ArhG1mcG1ioVfQvxH5prSi3tJWAFukkSRFAl7SKWGX6V8UNFY+loHYqC7bfSRINLK7Q1p9qFAE9Y6dG7jCyQOzCBcnkfLfZElBx+MGMpQrh4UFlxa6FJiOjIej0o6SlAS7rc7oigLn0YUNjXjK5dqeE5JZ0VpxVcWWHiKxbNsE0tq3sha4SZtKj72qyYbTDcf0FxHRdclfryAKtWU3E/q5z1GMU08QwSjeT6Aczeus+WuJnxU5Mg1FPSNHgFa64p4+IPmqwNy8+owB+Nsu9w+Mtnt/HS1UzhxF4R1EFKCPSTwmghStDCc0GDorhfLaML9nYzPAR3NjJRrucw82J2KH3UKkBywiQbVVXBW9RJcCz1UxFNSYFARzqSwRfLrFPXlcE0lTcpCtMezfYySHkJtiXNUvy7ioP52Ojsl/RgpbLyBJ0lFqsinFekeP7dRMmHi+P18YaQLMx5dSadXe/gVYFN4OFCO6x8HnHgD90zCegiqgbMTXkdxSQnLWxgHJpIpAzaxDR28RJiekN1M1JorfsX333d9tdn30+WuMwAbNv4SONGH+YZug0g9NOH8m6nUVkEarVOsAD9DbWKVyyS5OtATSrKbSyfs51vAd30oMjEmwPQgcEEBSCKNDBgcFMBVZe7J2K/YpGOq50W4o0CtwQHuUaj67QUeEu95hqjo0S5cVYhkagTwiaJa9bH/zIGPEkX4rqMPmWaRY73Pra+RpcfJfZmtu2cI0FzcBnz4RX5eLfjrA9Gz2YTXiyWv4KwiHA2JWtKYGWbKpIEzqexp14Gydr/gcI8M3FURzncZu434/qSogXvDia1eoRJ8HwSLnp7in74M9JLQgNnJ0xO/P9XXOj63Ay0zDL1qzJzlc1U5T88ucX/tXbDCl9UkMyF8FqyN6ZxL1gbGLOFMzPqsJ/stBIWXmsGyRBgyqnegp4xj5QHJ0hdTTw4w1Veq9gjyPiRPttIPivU8e/00e0FyBLjvq0/m4PJwCiKg7h0DOjYREr18Y64ksSt6ir3REh8BKK+LnJAsX+prOpScAlX3KjAfO7hJl1wa6HS0Et8EsA9wAKb+zL0oOWVeXkydMlQa6HBi31WZYlzjIV0imsdmbqgDdfk4w4PPYLCiWViE9LkkcqDLGNWDRqiVtBXuSiuaAlkaWfRRHk+8gc9F0+bvIYCBz0fjLAPmYbyPB56/YpD2bjjDFg8zbIM5dmCTsnhAgxP2X/nVh0UO4Ju0xQB5i25TTHJ3W4fwzdU/ibwIaAk/PyVBAKMpMsVcPcFOTRWMBSU+zhhNyBcK4r9Krs6rkBzBTllTfuHKIywdF0kc6SNuCWkXSr52K1K46OxTR4ZSssGkKHZ/2RwZtzlibfOlKuH7sXyKKcUAfFT4LAVJvjp5rp/GZHr9wfs1vuWMcflllc3ncFMUv1fEtZozZ+OE3uWsgi8Dmnv6lNXgQdQnC/GzFNlwahhRUCG0BJd1/Zjx9IuzlkbxUtc52us2AXwNQNQn7XFwhxt3KdHgSlcFdogyGcEFmgxtoEbkFv8qZTcmMnARDDEW7rhkGv6nI8lXKJWC1kijS5KiwZNWENuemq7O2zo+YxdJZSFT2sYSvOOevp1YeqY58nY/pcE8xyhHHQfLuMZtvoyP+Nwh6VMNDkiHIjPah6XjkaMyBPcMntIhnGlmDtvUraYdt6EmGTO9loz86gVxUMHArpoDu/jg4To79NlMlPnXvbleTmp6/eHnEe/oazEVkx/Oi6G7TsEUrTPICA0QxyJw0b0JFanpjA/13CSRXBzhNKB4p65SdeC+7zkD7s7xwi/lSJfOCpmSxXpiWQYGwYTka8UdV3N1esModwimMqwb3St4S5kl8XEOPsnO8Ad7RA48NcLs8CEL40rzeC/bf5xhbxYutmQk8IqCH3EuVMUMV0KJrk3splHUTn4u0gh5KMrkoIgK4j2uLXKIo9HmO0Te8OYkReNqwqftUVl8koKJ3lTYVSGl60600RgFUtIBs3psRDEpHwNPilBOgmX+H7e1HrG1rLdRlixk2SOwdHnoUPMwuLIxaJnIwJRUskIjZNrLKDO+CeAAoPASzNIMg+JeoSKf5lU8cWV1m+Hsga/kopXm2NOszx4Zybiu4nGjKxkc86AM+GXM1cWHuW+AeUGQgTfiI5o+tj+gskHBTvx1KhvE1LNtLZk6q0VZSVMbWe0sJotp6bTNUjpT/o57VipHfhsKJDex/FlsUxdZ3axeVq+l37Zo6stiOZcYU+V5vJmK90K0RjoJLGli5AsJrI/IW31fYmfiua0lhWe1OBrPame1s5g2xvVBFXm0dVyrSbq/FSDCNantaDAs0gvDQ02YjNIIYKKZUQMtawFxZ0nsT0mPVS3FMYxAms0iq53FZDEtnbZZW4d1GKgBLpJsvJV8iueuazs8D97x/QcPXu4e3KqHB4NvQ3j4N/c5vH4FPKQYgE2qciCupXYwHHBcrsjHTn3VEE1XkEBXy8/k+TxmwPKHzayhq4rF8BJ34CG81h559uaonsQ5SwkZTgVBY6Y1mqndDCdDNRXw9zt6ev4BxVQIfGA3YbGZTTYNkmYObDpWmrkoS9GF8UUUU3/efTzZ9FZljBA+IJvdoimz8YMNOd8t0d8qvZ5bKka39K1ag9tBNQUjlYLjmFeb5hC/QULnS9hyA+PdXoMWXmjygdP6VHrju2eWls1RdL7odDIh16GGgEJjCWVpdg6dM3Sv/blQbqFNsXotmqVZmqVt6sl14kehSvPrWX7en/pNG5p+2pD9QJq2IQdp+obc71QpX4DPaWctyEIWspCFLGSghuyZovvg/ia8z1GVgxGnw85BtaJzX1ZZ+aUE/8qBMJvVA+w8bCYaw9uLolSzx/1NYOTAd4qKEuDHm6IwSlHopShVz+8cmgTtG1xtH7TpXtG+Rnc47GE38ZWdzS6bRpWdw8c2nXN2LidUae4OHbFlP9A+ZDCWxBP+qWlLbILHObo3jUcOPwtXahDnadRIVAh+TWtGPzlq0CqhBaijUNjqsOg4dRurGEhTM6xgQl8Z5WQ2MbDYilat5tmXq4GRcP7eZ5lqyLvhirD9ka2a0LdVNjhb0SDYKocGW9ExslUuJlOl/vg6tjXD+/Tv800vuBe/TPZbm+EBaZqy8UMm57uNMN499Ld8jbz38+sul77lag3VU0uWoauvizYRME6S46I0GjBOcsbadMaPrx+Xkl8dfZ6/NiECeWhmMa1PdQ3fPTcjJ9anrZ+zNt2rOx8XSksl/NLRfY4a+G6KPukFLprNZsbCdDAWroJx0n7wBJqPTOkOWF/SVHtiBRYE4LR4Imp9enicZhOah7E23WM+2qV+hp2CUY97PRjFD6Zdg0R284fXaqSi58hkumAP/G1a1Tr/3m1pzLiPbHi9DRqPzB0/Nve8+RpY/selLzTSpThUR1Bw4Iv4kIgLn63xBP8qRCw1LqKpDO10s8IW0bE5fwZGfXvrU77iS3T1fs5ypwmF7lcaoePzN2Z+0fp6+73rv+PFW6gt4uxtVT5SzRG5BtQaVRY+wQVtirvxMflVcR08nh8ZNRKSa0cV9NI1GnBmaDYzqg52oVW+cKcOz9z4YLK48jlslnai4Rwbd4bzLVWE41di6rCLzE37RSnRtsAwRethA8fbrHvHkLbfNizvPJQdD1ljd2L0iD93gvIrS5n7nQy+Z5KwutD9lcs4H6i2fCk9Uezp82XER9WJbBMgpm8YtVkfbj6AvRleyNrOfdejp2Ww8LPrYUPnvtMRuX3/41Hw0nPgsxQREU4X2bn7ggo84sUP++3y/mKHv+U4IheUFNGkjTOHykfenLZsdkufP76Ds9AHq91Xrb03IXM7fJXxyJ9AXA73RvmfIMSlIvvdXH4tN0y9Ud7+BNgb3glSEwCAAwFVoKAGnaDLqrCq/cmKnYLzzP9llxXLK+lpXM7zOHGJAILn+f0ZkBU8Ke6C130NTep5SQmDYVbDH6w7+VsjTLtrpEFACqAqpdbiwb4fZaXcaeXgWy5RYUOaqFJor0SoYXF+knrIj4sGwmon67mHp3JTNmQNL+SQoCnUxrX2g5wjnzBDq3xp6shoYrUT3az4RptHQp4ToKOlqgpIFZUa3WnUg4sCv3rnAq77NV9thGWCujg2yxfvTkij8wU/OT5flc1egk99s/4cDKmm8SKz/5zqJlKV8u9DZhIS9iXHyyUpJPQvuEWGX72fpZS6XHkKuzOmrCNb5ZT3VjT4Nr2MPkNlUr84L80W5BHTQnMwTurFkI6kWG1HofwXasKd2V88h40n0XJsOmBC/S/wnTJVyXTxHCwvTkvXiJ6lMkoJQ/0wm/a5r61yCr4VjaomvVhRCy1V/Sw5LESDMT+PkRq8xYVfZe9u36mIKduvM9hR0X0jFgjLFbpcYLZO682PrDvYUdF1xbPQ2BrSt1aOmyr7y1Is5tPbLin8M6XGKMr3frZ9UVB3hQqe4FR+88xH/fnp9gfYvL7fmhPUYpid0TGy7fDtZxLwB341X8PtSa6pssePfM/FchbzAbJDxrYCrjSAGiXrv3xwSiGXHn3dwSBAifpEnEA6vYbywyGIqYJm+L7P398RM6httgGw9uAPhj/hZyA4O9FXCKC0ohYA3U1Ymo5c39/+L/zAwUPc2iuefNsLQDvK7oKPTNBykQ5/eGe+S1KbpF5Jq+Ef0DQB4WDPI1gCrQrgCUPO7tnP5xby8u3vWx04EE8rrwDoenL8++LdT619uqPwlSwijOYIQJwx/UwdGGcX0NYu7xAIIgKLUOAsi0D628ckjAHyd1N1IIggABfM3uzUEUEE7QCCnTi+LI7EdfeXOvQT0TBoAVaa81N1IIggBpoARAlcn9rSqJOIkEd4QvAfshGG/mLrvFBz8kMdCBPx2REDYHkdfRvAYJ8M0ifs/OGAdSFiZycPdQ+e4qr8Sx365dEwqD+GmhpHdSDkQfij6apP+bUm8P7ct11GLmcpj4TCuYJewm6CXn3VckZbwoy+6O/OUD8bP1HizKh9+4rGJpLGeUjVjYeciBVLNxy72rYLJ+X8pEhY9zhnsnZBL2EnQa9SZ0tchCP8PAsp2mBLR3GpriDkuZzJEsRYiJGk3hq3kqVCzuS+dyjn8nPah8tKM5DNcLfUZlwyntuoNnfCVWb9pSToNbIT20x2sqWMqWVxN/hbg6QP2YnaU5u0R2Mh2KTMyj1zebYRQCAgvND//ErSAmZ+lWhPxeAjfjBvtGML65vsgB+STtYpMRaEnZQVpc6XuKg5gRrgKTvRdpFSOUshEtadG4ro1wkYt9/qIX0sGEf9SqWulLhofoLwKEZ/uqsibvOSEIry2SDoL0xSVnp+/SKG38MRdsJofmzuIgA0DHPb6PjFznqW1H1KiFzqs+SFIcqND6vDgotYnqCXsJOg1ywVg9Pojewy8x9clWhDW7RLaX7XAs4B5O9Xd5uPcSc4k7dzEXLYzR8p3QXkeGQS+0Xv1BXaj10SzO6IlQ8mdZcJJ2aHiusUM+69G+A+JF2l2zFHTioROkgCAnxldmK3plqcaFhLQ2XYNKlOrJiVn4YT5Iwb+dUQadf3CTfiBXMbS9hbY+FX85oNAw3qXk0SvpHsKhe5vN3k9eanH1QDnpXsNM+fm0aXERwMI7pKjuWsbifu5BNa8qF20k7Uj9DuHCl+06gfKRpC7XMNp0VxtNg/1+qau5DCC2aayzlpXnUKLLwAjR2hZx6ZndkKElSCzJJ126Xk18nCC9DJ2cU4vUnuBbvX2XHi0tNg4QVQu8XwsbB7yojMh901BWIDTfSw2TiznTBK/Yz8ah5tjBcZLzOtjWzK3bc7bZddGs0SWnYdsxOoVXHabmyLN3eEpnfoF/ki51ayFf3H40cNqKNkTUiNzs7OVBPtxR3AwBPYMjsI+RrMO0IAfyzFU71q8gOg2eGJVN59EeZMTzoFV+Epp3zAobtesM5g8Boa2S0lXP2Pd8tak32S/mU7eodF6oryaG0GAJSsrK+7vVMtenoPNkoSuBOojdpgc1EqWAkkaNdLog62Un2sVoAxu9NqooE2lIAZO9WySKlGZR7sNuf8Hd9C++KtriRNiKLoIJiLEKvFdT/Sb5wd+ac19qTTI39eI6COtxrMLxhPbEH4D6m9nDAibIEVTr1XJ2EnUovHTEW+w2q/mqazJwFPJtULjOkeIUcaIF//47Zyiq0ey62t9W0cJvljQeawMimX5hvb0uI0JZT8QLW7O9BZCR5xjTRPOkgaRwuI0kFJ71QxSvSbN7CEOftp4VMqnjotl7CGnQQrmHI43gqQD4C9Uiu39h4Yje7lyCAGU6cNa94ztxCkNo9LAXe3ZUl0MMSx+tm2pWPxpANnR4thNZnrdu5Z9tTqohbGdtLY4NpAf0/JsRuXmISNFg/qbB5vQWl2T16gyE7t5EBNrLhConaXml5V22XWcn7mUYGeWE3hBachSGyvO0Fd7SCRSKoxCUUFaekxJx2wcC8YZP0wveN6WZYo8y4mQOTOzJxJI1YEy3f1IWmEemAZYjtZrToSzTUr1TKJGVIMK/w1XGEGnD5Bq2AhfIp6aze/UQ2x/Hc6xczaZfJwZf/7EXpGqPmJQNMsNTiRGHW0GaZ3iUqfSfRm3LETBICCmG0kUgJ6DM35X5W6E3ISFSN0RfPxmdOt4V2UefZoz7oLlvt7qRIATOgEsNdYPJFo6e7TEwGaDt4hdMBdPMcycYg7eCdUQbIm03VCXBpK0ROa06oCvYb1Dp1HXKsqSDanXDkhLo2k8VhQJCXuylxbmjM4o917gS3I9cR6jND1NNT29yjKKWDF3WHA7r9t1iJySSXbZu5ed99UQbLZxWmSbYkXwHfuH/orcdfQle0S/VSk83AX7XL/8FqxNHh7LBIfch69uJfLbuWlOZe2yR5DkNzCztIt7QuY7aw11M0M03LKuYbm7OPaeail1guIsi4h/ghbodZmdqhIPQhnZu0Ikm1JDFXDpVzKXUPXSatRXzbHb/WQtr5OqO2DHdLo0knEmT7BOnEmjq5kgd4GKV4XOT+9tBRKLXEmJHDyXuSpw98hDWeQrY3EU8vEp9brMKbe7cpeF/CJFwrJqnLpNVJhcNeGa79fsmKKlwlTFNx1v64bWXjO5vhc/dS8yaXLmgexQ4JkYSfBzNQr8aEnkwRewP05kyUMSNZMZQSeXL3D06mxOS/w/pbGMzV7Y4+lQpBspY0aqsSloZRZoQSR29KTI/jGVnONt51My2629UxBJ9oWku1p5B0++HQG+NtHFdmR9yNEii+Pc7RnsNjW8YpewHm1Z0/euxU35sI8V7qJlkVkCeA7rIiX55wVdU8f/nqeO2S6mN9kqVbh92hpG9IrXlHqOX2HxVHKXDp7M9F2ttrvyFaMPKedQ7uuQSgm8JZRR3ZcjY/4MTlirgt+z+63sa3jFSU3oqH/PmllPPsZ5Pw2l/NneQ8per4KxY7ZglWyS3uR4+2YcnC5JC8Wjp6W+O2ktn6g/ElrRd9XsfRi0qXPh1zSaWSjqeW0Jd7RDs7rt8E/8QJbDaeD2LV9Z6zl7vhAZO7TykgLBVAvvs4RFicvLyVDSDzIVsM4sF3fFgQURM9vXl1hH+tttqLiIPKvWtopmQGqBT1S9Jbuxhlj+1LQux72MKbTuW2XBM3vsXgZ4XXPloa9p/2bFL2YjDMGApHszFZUHFC+CP+z7SuTUGDQN3jD2ufL3n3rAbei4iDyty/NrDB6Qi4VTqJcirfcioqDyI+XlrQ+epdJQLBWE/gK66XtS7GS70wgkWCKRDIpkhWnSDhNkXCQwo74WCx60GUHJ3HAuwxSMLRBCwqFQQsCyO4iAnNLlgSGdkcmccD5Bi2IzFg8BogzBcJiJh5vu+JJHHC+QQoGITwAgwwmYDABgxQW7XGU85PjaCLW+VQKvjvvdL+hJCl0MUhhuK3bLcqL9SuVjk+BS5HqcITjUjSnXlfAscxY6AkcJLFqHEQ0/52fQK6P2Psys9cmOeXwPnqzSJC7tBK5M4KNSSTZzoUOhCLF53xNktZMTWqjlHIfnRovJGwtandENPC2uNduq4vyYv1Md8Cn5C5FY3bBkaTMDRa3u2Wtt8swNguYdHejW2+TH3lE6fmow0wJB7D6TohgfJ01cg0/5qYuhzDeYOj2jreZGRy2F9Q+eCzb+VdH1hOOMqitK5UtPN4xlTIV/Keozh07oyuZdYAY72R4h02+qzm9Ow6XxmqvYaodPe1LPyoRo7iQdyVlUSRLqar/JlWktZ254bP76uCB2lkl+w5fvdkM9+OUyLU2JPHVueEaF/Y2nIhib1u3yeMPBcBuY/femozGfva9DS0a08M7rgE3lU+5Y4n2BwtyNuIjpzQx7KkCqyndmDmCXIxCt4ID8CX1EuGGLd/tJguQrzvZhZXYPc3IxbjpVE+AOOLGxA5ujIUFl1trBffTXk09AD+4S0O8Dt+w95qMRZyiNG6MwJQ68lU2UfPprzsvH0HwyulGHO+QJPtMmWZhNWieE2+2kRtQD070/Y7tlP5JdYXRnquYCUdWkc6WY0cYuH5UbcCxJbaFAm8aRw9r+oa8MUHK/qjJjTkFEMbVzkVz93rDzqvduOUjHrAbUn9bwkSrs8Z5Ptdl78d7RXaK2R4xzxb9dYVWuA/5zL8Vui8VgkZdPggpe/hDt6ewwkrE+K/gdiCIdDvIBC8yhnor2yU67+xGs5byKTwMX7XDM1D09QkpYXmTOYuXWW1GXDjqWQVlOABVdj/RsKcwQF+1c59YAJq7dxuwti+6Fos6cI7Bnuj6eoCVdaxl5UDSO8FLvsA2D/zh9L8vQcl6R1FblKep9hDf/P+/xWFgSmUOgrue/YmTV4j8r6I8c67A9Ke+FejMR/GiwFPn/TEYfOxDr+K9mrELz279f9DlehmPwrhYgfhWjuf12T76sJF+/8duDvMfV/l6Jvnuu+45hX20ApXN/qU5Zdzk2y3fXl/tDEYROGijMkSMA8Gt/LA5Kb/glpfs+XVZ40kTHkl/IvPSabQf+u8JGxu8SFAKD83/THpq/BYDP/PMTTABK0qERNjz9m4rbm83m5e379rT7YqDU3a/uYSR315f7V68RqO6vERLxz6d8Gqh+n4ekrc/flbExYlr0Y3SPewXNvRKXEebCLlzyVC8MxN85IA5+nDFakaggr28+bChXdu+22Yf3v/6g8enTt2mgBc22lX3zrZh5l3DHSRAJDOGtHa29Zjh3qnwiWC75eyNhSB+uRJnwpSE6ELn8KIL+9MXfQzWPxKIPl0D604Ky+PYkQN/UlehK1YRRSwC4dnmX9gEXvaCH/r2RJIQEez/C/1QH9tBEyjV26LqQuhdneOfs2gCMgEvgHww/kUiHVZ9GSEyO4v893Nz6Bjq1/2wCDsF2XwWiD4gZzJFm51aMmXnsEZUCNX2SX7JqX5Y8QfnyNYDoqng6qpVuEYhh73crMYuKKLtSXatvKuIodsVn+WrbUkZf4GP2OUTkMznJe6jiHHme7B0rJsf+55RB8JU4BpqkeyiTBq9Zo9J9+zASLPxSJaxSII933F6fisuQP7s9PyBvak3Q8p8g+veABDpKK//OWJMhRENBBeDH5eInIMxZRSAmMA+mopbqQYxRiES13MBRDOOP/UkomUJPBkmlchVLDb4q3gNfQT0MiLgysDoCG4zHYkx3C0U6/ANnbdhIFAKJMaCdxh/sLAR9F3BDGnLnXWfiLD/Xu158nSxLxmN2nlzskzf94EghDpC9Kckk184dY7YnzszmAERqSU1JCAuEL51xwqQBEySb4iCB1kPE7Ui0AmMwxISyBmHCqw1Tht9fMcSCQI6247+DF+xelmHB9AV0jL1VEMPhPBOGg0qW9iQUkaCIPFnkR7s54TwBg2M3AoFeNZdbYAp+F0JczjUdkuT2Ps5iYdxbrR/AISXEuCmoChYIz8YYOA9a/lSJENZVWJAPICSEi5Wk+CC/yTOobbr0s8YPWKXlEeDYWOAjqO1UgmYRRVV0zxXfeGjTAE5Y1GIghE/UqL05wEhJoOSrAf7aFvobGzVnXNrPHb62swapTIUmIwELeokAvFbNCwBewIoKkX+Byg4j39GIBXCNoJxYK/2Zp9FYZBQjwowVjhsp0n9k+i2TqCiNkGBLXQ8ssAGAOBWbplhQKMTg6fRZFyi4oDIjZU9xprpvwAxCUSddwQimHsakaIHa8EBn3u5KeX+CkXX2Tr7fRwcOEk867a4WC1RwV+4ePQamYBo01Ygm6oyKxAM0FWxGHJSV+qUS2zZOqDxo69O1k4dkYgGLfx/dZamr29369Azhx7cEMvjZOrjxFeDQygNaVNT8xdkpn/hrJu6eNIlwffmv7w9a9rkUUbT43gxBSZBKs3lpydn+rEgJH6LH/Z+Rr/WwWEIX9Y4sVv0J8+xQIbaEPtEgOCEiLobyE8kqZ/xsIJ9/MaCaB+RxDp8BqRgjGOcwVAzsVv4MPsZek3BPFRwBDtfS5kga1/FQGGhU1FVARnwdOh2WvR9UcgDDVXyblZAoTRBktmHOZY6zWrx1/1Z/OmTT+eEv+sfmopg97AC1+GLL+j4n6DGfPCfsZ/9w/foouZQm6WDMxKFY6+eP2//A2/Rg6urRdjuGHYBKOj9EDEJ7MlVrxZMSV0LxfHq3wxLXykpitBQzXm2SB0FURFecZYbhlDlE3HkRwGW36nRM+epC2cGxkc+jOdFHjkuV7XWb0fzEeSRPbrBvOz29uZG5T77Nj8SW6Ap/6Z933JddHg11UQJ/4SJPtLJiYJc+ZeK2Yk4fa37Rxf0Hnri3E5P+9hrH3gR75d66NLeJ/HHQbxPUIrafbxVhgMjDIgiBcQG83EvHGJAm0l7r2T5tfdKfgDIH2qPVKtF0VBdmMWWQYExnUZFUZrh0XcGaCX/px36Z4597jgEurWCoegAxCcoAy0+ArZb9+DmcSuRPD3nXdYX+y3mW+kODyESTZhmaQ4HqSabvSs6M4nsv1u+WZQWjwVnfhIbKJslbosw9uMz9tBHBD772Ejv+ZDn8ZkaXaodlk88ztkRpX88o59fQN++gM4WEL4pjaE0eCt+oXg8q6bgecsEQ+9mI/8f/AcHkrVSiS9da5Ihi4GDK/ml9dDCh8IgUJKAQpTCoaY4oz0m8t4YdSQIJZdHtNzk31TcgrIrDnPikMehk/HXLB4oN+NwKg5r4xAq/q58n+VplkMoV+JwEjXVLMpBvHPSkW65dI5vHg88rZEjxjcn2Q5j1VErGWzhIEec4zbfjhfI3zMWXqHgNoFiX2VStK/OEwBQhKWJWrEqnhhzgbpIFlOCibefbHasZ9D01OSRMwneB7MmJVNipfbsQ+Zu4ndMLxKYDRRbs5xursPdd5zV+C8LEmiBPq3LujzR9y6x9QkTUBpPkKqzgbNK4+VtRvh1hbcD8Jx0gd+4J0GbcKdMoYVt4RRntEFHxoDInk+CjkJBQ8IhsKMEXBIhmOPLGT2f0QV5QZLAgjSZOGWAK7Pz6e4QOjtclx2oQMsjn/gtizq+tvzfKv/D+ao7N7Ha9nUfLY8eI6Y3ro7CFX6XruKNTJTjzkSmIsDgCFO0fFalF/cX+JFPFO9g5gYpcWJ8yqSCJAt2wjctCgeBAp5COvJCKdW1CWsaCGpABuFY0ZqgT4hoQGuAgjBWdCYy4YmdJ8gwutGi4ihFEj3ITZVfajLN6D9oDrCqqNI4rBlydt/JJZkWcNNL2xKk0yzEvrOcJH/CKZZSOZW5oaI/isi4I24MeyLKvyxLcOZ4TC+yO2JRv/cfoFIIevQJ6dgpYbs0A2EOcMahk4UjzRH2sceSqFTIl/oIUIN4ucqMOjNkx/vHhvq6Whr2lM/hKp3g83b9vc/uDlVIoYNEiVEpxGc1MvR+9KjKsumRmUCBI3tbN1JE0GxWq51d5mAj1pXiKPxcA559BQnum1QATMRYSwKppJd8ViIRVUP711R5dNEDWfDQqXNz7oYAixu+8L8PSha+VTpGl5I4FEcRv9XGTv9XSuSb+8gENkGrZGnm8CfClIHDoSHoxxwJcPn/NGTFhQmDdzzrLW14yW5e/rBfbTzWg67NQGxHFzIKynLn1ie8JoITWPMBQi2h7lToSoJIY05Yf1LSsaG+LlkGj4XmcUp6rCGKCGoxCXuCfjCqIW/12fE2E/7XRl6CYWMv1vx/oUihRgOOWW8lVI8yCHNmxMzgMld1TGGEK1XlUDME3t5GMrBjGvzXHY5rDCF6QDkncdqYOolK36leRACNkklpTel0scytrYVhti524cuJhlzNRjGSS/cRfjFiYyACRC9xF4n0xHdlKBP4fBftl8ZuaVCOBL+0rd4R55gBShwSd2qfKucKy9cFxLUUQI3+ZqUNdTl54DYuOnaWYIBveeWZpx65cGYY5ev7wb5JbRz8/LxJzlCQ3SrHokU24id4hUL4PcLqL4/oEeU9PC4t6vuDnP79kD8myTnhmRVMZIqtJ6HEUaToxkMnTo2GSLDGq4EZMqDBmK2pRqOQ8Fhofjuuw5TE6LJUZCJyKMRJnWQSgoHzlSM9WHTGAFWSxgnzGeipUhWIoj0GG1VuhUAvTBUbqtUS9sY8mVG/h38cs/Dd0iG/fPgo9ZBTEAvQg3u9LjpG5dEXFc6Eccwg8vQEmq4pwDhjNQohkn+Qg/yYtFLNUL0vARmLhjgsFVpIfik4T1aGDY8joQ2UDm4bDRvgCAy0NRlUBaKoJcyezFb6hUCW4i8VStyqWpEjvKdo7IxLCWdqPFJnUtNSkggm1E8Tu0Aw7g2kp+XYXLHGqRegOYmgkWvsa/dCALp1EXs8wdbkEhSYIOi5W/v2eKWuuTCNu7T0CytXP8gsu02DTt7rXQUNwb5J7jqxgCVLW5jhN1pIp/pGqZHlQCMDxEoiFnFQgAovsuggY8iNe4NR/NTpaezyuLJexoNj0sW9tvV5fGr4SWRgoAv1HXMmzCm+hY/AfUJx0YunKdb8FmBqRklSNHZP8giPxJCacGEhoTMxAcIeMb9MS+lbO2BmkLLgS5ymH3VH0iBsU41JmxeAiBOFFdlzZ3clOTMLEwlBjlsIPZ/11e5pDhE+8BCTmAOxlgm4ZSzrCVNRzEQvQQA3EL0ILkiAlwDrMGjI2JED+yy7NIqbhD2piMP2N0qOjpd9TzFyKGK7Cwl6HPaDe426oBoO6VL6AjJcOIjZCDP8jgI0X+Zow6gZtJCMsC/0VaLE3VNTRPQ5+UaplnihIpfkheewEoYdBPoqvrzeX7SnJYH3w5f8E/AI6GKo0MmZ+YEcGJ3bRgD4hiOEA3b50am67agKMSYQOKsAlTbHbmL1cQBrQBtTJA0eWRiPSRccUZIkrZATAezk3bEd4YDcu40E8KZvRoxDJrYIBsGEVMB+/JTCmoNCrvb1/VpeaN9a8xENPvFnM6WAFcUea0FgNw94tjXJAW9AsgUMLPErr5boo52nO7raQis7i4CDhgfjo19v72Qxkv94ew0W9HWv4tJ43hwUXV3VuXOuzoSU6EJqQnUQAfQ4OAYMt/61dtG/Ai89j0fbyzM+Jb+1JRiPj16Gd+O+3k/ez8wohMmsi9J1B0Kbc0SGB0j72xGvZ16Io6XJbjrwCl/OvQhmfmTFXZ9Ee7KU03ssBMsDymZcHQHagikOjgHTW/96wIVXXnoej7adOd54xscM8tcGvrx1rmS3JKzKfFrhrs7wuaoChtx3mAxkO8D87/Da+cALTzx0aW9X8Hkspd4oa7rCP7tZLyjcVKIqK3KZ6WxPkYJExAdIQb34SCqUSi4CUjvWV7EmIoScbn1paEXdk64UmVDJWEKPoRPdKC2cyFYHSCkn3nfobQ078rJCqHkiruf3DGmcqDAsTl5S1YhaRXPERZdlAbf420XjFpRSGcsL8tPs9sm13saXIIRS/eRpcAvicIqGKe2Xy/W6SZu7rwsgNReZ3RyYrheKTV+btOXmSNuQtw6w3NwZxFqUws1Le/NvLBzuE4L41X0IiZ4Gvh6qusz2tOCHGpUq3ZOnXkrsI1jkoTa+z0nQ6c1/3+Eb/qqfd7HADaf/FvjIy7jy2dPXMLtxi1Yvi6aQa5Mj7yRvZp9m37gBCNGqRgL62z6beto968gnGDzrnnevfOuuVj/qE0lV8G1icZbkgUggSByQpv610vllpoTq3+0KbZzWwH3xnQ9pVSPx3ch8F1UHWq3bI07X4Iq88rQ+uq6uOrM1S7fcdGyst7+zYlRJJhCSfqygs7TTPEuTPSWYtt9Ecg9o7irp3Leu0STllgbWHV6M35EDHffU7CqGFC5lQYDnfOsbSmhBcrsLqqA2frwckxI5iOFH9H+HVz+c+FPiYSZQlVfXGqGjhpOaJ4jD1g4LWYlYBVVSjAL1opPQKTdUohC8gIOY46XHBtqR77MQAPaJgw/u/5isY1yDxq1zsbcbBRTa2wvTSQXHtDB/HcXz0PbzngET1ml54APmrL4ToZ91vuYjj+7aP54s/Wr6Hz52a39z722Turb01G5Hel2WC6r/XreThbveXK6Xew70rNQ0uJgWe6pwKa34EaYymjwCJKt0ZwM3y0Aog1QZxMqwUAZyCcYtTuOgsd94ueGFhu81KGUgIQlA77v5yQ4TykUihUrAZNGiCK1jMfz9EdT7gX7o22kLLybAM48PHpyDdiQ1OjEEuMtcqN7DXLkDmuoKIUGIrT2Hl0mVtgqb4UX4YKMdvnnxl+3LmynxSUDlNcaNIkXLFfaTvo8TmFBzLWdJUc1PWajUVJw4K+emLOSZ6AymKmhlEMg4NDRNPAYdGkV6CjkCokYGmiH69CFYtmXYZSTnmbHGD7Jl8MXnCUxUMHPIR6mnvagPzyxr2G8UwDEkPBaDhobEY9rt7PZjZTDAHmgTcbDYW42E8VE3tk3hd/0c8NUGwlAq4sjQymhPql2gw4Ge7O5IoFtYHgGcwQSH1jCtoYdb/5pceNW/BM/j0bYzxxft0WzmxRrwbb/Ycct9GBx/0tVF4ZxrTJwkaCrMy31L7UWswIiDY8D01r/uc+GVl57Ho21njjeeFkqcjL5Vx61vgHTZZEJgoEzSJBnifkueXnty38gQQ0vJVXL0rrxH3sv2I++Ouqaa70m0zKHZEzUuqM8UUfEM9vzSPN2eBEXXxOMtczK/VNFfp5e+Uk2R5xQ2Bk1ruZEIwMAAJEhoVoueFqho9jQFQ+rAp5ZujBdP6Mkuetiwy9i5WkwqVJpqgEdC4OkdPNMwiKIiqpTGoQ0PxN3AphqAPQAZ7HXXvDkjak3NQEBKNUl0quK+RIKZbbPtKEGhwQCBVvk+ojSU3TgzBzNmVqlhUstxnBkzUo7jzNw53QoOtlvsn+xzHjaRxZRDzxDj7EDypAFbFZw4jpKyC38XDG1X8jtLPrEbGHSEsJ1qeYTwGmPv2j8UN8CoqmG5166/3K7ayXKubWq/b3UP1VTS5Z1RYhjAJOkS9uC0lI4EbnafMUhRwO0hp0On/J6iQtKiANKxoYd9F/3Kayp0366ZiCKCPItt4FEDtKIOlSZyWiqJ6rdPd6iMDaH91Otu3blj3hL0vstf1CiUh7n+5XAclcA8D7Daka9QSSFIY5aSqfS0z6+ny11iaUcB2nXwFpYchzKaj6ikcSaL2m2ateAlyFMTs2IwKBUi0+CaAJMBTRazeMJFeifnir09zTAqXGxLyvAgA8nt5w7xH7KyMLpE2drt8764djeFgt9ineBrJWovWmk80edi5KswowN27dNgg+2G7E7/0W1wF369UdR6fXnfucn65AWFMkVJEu+JK59xzInE3NFk1Ht8THBd0mhfxNBHya5e3m5XsQfyXFC5wY/i9Tz/zRuICgDp0EppooBL4EVaiPRI5grTD4SEB9Q6onQ7qGCfOH8soDaj9xFGzg0McTh6/lPZ+NgpgmyJtj1+8QNxS4hpYLva/dDc80wIiDOlwglEyTCehjgDFyCZLWMwWwitNccyzY6tFgl3Fhg/+x0vKV5CXEKptF7Gj+g1gsOE6ITDJvYCZtmBZxOCB//94qUhqQSpJ52GY8Kw0EWWGomAh86/9sVHlbmr+aOPsNowMjCCKaiH/mINK4yGzuNPItfOKS6ZTh5LMdDTrs1AWi1EwWICO2o4J2EEHHlZcaBMdA6xdxiQOcYOlOVFe4UXbO6NPkHRs2g7yJG12HbJ59uXy+tdlUlpyTmiRY+nw5janlb/X5Je2pfFy+Jj/33/he8Z0jpBKi4fBhiXTwSw02Is6e9wre9v8bekBFQgQLN5hDcErQiqCTrd9v8MOuHQKURpPLYygYM8SLosNcYAVaoFNCcGetqaUTVbSwiWRsW7Pn1kPthJIhGc93cbhxL3U2lajSUH9c7dRf+uLeLkD/1NdtE4bnL/k8LnQGhEXxCyAsPfS9y6yItPPdX5KXgYvDe+P74Y/26Y8hgkqvpe4GznZG/wRdBp95OXIPkuEMS7qSiS30WcRNyMl16ueOHhbx5+DCO62+LGjAl6mkg+HfUOsnWYMngsBg0N8gmgUUghBEUfMSyHZi2CL3WcCF2pCg50nnwdJ3Wj5kTESKRB9Iw25IQ7fjaqE516gnU8t0NPY6VmJYEymlSZbM3eNX7zO+xyf/4xDQvEBOg6ikBd82E9rhVTB5LQVJlGxQOcMjKIJuIN2Ed3axhGshRDOKpD3xr1UHa5o+La7EyIrZRATmEEp3Onr+rPUIuKQ5t+RmYtsoN49wfAmtSkgJYSt4Cp4IuPks+63ztz5eTzBVhjgvD6HwjgX6A7IkMs74xmn86wu27nK1wLo9mr/f+sTLjk69D5RqCkzvOyjXGZdh7ZDLRrqxNxVWaLa1roxmdC3S+cCXGyk8L9ysTI41SlJ3LXNS9eG+OpA/GzBnWtAdnsq6zYpUljmEP4Jc5iin8l/Qo410aAAOQzA+4S3nTWsVLj1D/m0ClEaTy2MoGDPEi6LDXGAFWqBTQnBnramlE1W0sIlkbFuz59ZD7YSSIRnPd3G4cS91NpWo0lB/U/wnYy2Y2w96/peW8Xd8C/GsFJGitBsdHRUY24XGdHVJ2zV3Lu40gEJlcg1wuf6wXcSwESUfyYSDCMw51TFh3qBVDhsj5Oxx48PHQ7wzbDl6zh20lyu2kMm6b8FCwcLb+ZvUMzaZw6V2iZSkwdXQB44G77dgFs+YwAr/8a6uv6rZ/6CV2J7MuetGJJiOfBzd+RJ29OKpPbVkUEkMXS9ZoX6g9TThkJizX44l2P/Km2zInui+kzk8gQ/6saEN2o6vZSWfKxiPMMBVX7wZNGOfliDS1nrZxl/B5pgIaS9bRVGG+2V/czbM9/EEB2+QIDvfmjcvpYtarvdqa3qImTKJ1Hc/BmbQd8eO9FUv1ToEQlh2TO2LAZL6ME6lwzKIiPxLDyr/4zVIW3y14oHx1AgsLUR241JD2M6HTrMQusvZjhkJ/N0xRYSP9he7+iBdJtv4fH6ygNDlfeswh/PUKOKW0IXLo/l2gHHG6z5/z/xndPTjaTf8ilV0GdXzIPE05grCMFKibujPufgg1QXKYiaqw0gxylvTv/RFD8e7XPLh38n53nduxWNetndV9/sooire1b4LQG+u5eucyX/5TRrviS2W7zHuKJ/t59noGacihATZOj0H51BsihOpnyfOr3/4xF529+LrQqQPuxFZ1PVOg2qe5GoTzlnRGOuLaAwFWwmbiF7ZcAat9P/6F4ftdL/6bMsKuQ78D4pclMIJSMCW+TsKJgof5E4hwpB1wgnRul92EalSEerQQmeWGVgeXu/xH7R/cZjPK3QL90VxFV23eTi5qnjQ8wjLnJTqeeM86+x7m9NB+aRBUFh6LgaJt9ksEqM0gaDSXGqlLfo/ujB0O/Kf/fQ9GvTNbyTmiH3EQclXXmcXT6s4kJCQC5eE7BDPM8rR00RuZVo1upNPFvCucXkVYTirvNpQBqv7NqQqKyyBfQKX9lWoxLZhlazNzyggQe+IOQmIR92sHyeFTWrjyPTJdglngezqatpLMqJcuojNyL5qlh4a7O92rwtai0zO6FYDcAZSteffORfWv38uM/z4WaNjDhvNTqLv3yjQv2m7FfUskZuLY6PlJ9w5oKJHQ2Sr7HS0aUvGObKSN5ROYuxVinwDUgEsVov+s0yzhn0gYxMdvQtakLbZ+UCejGOItfw3N8C4JYlmD/6Knx4PDGzvNOfzV+FBR+Ja62uBnTD+p9hcQdrk+VCkIxrrtUVDqt0rk4weFzQIOKZvNx5hlolvJr000qtqm8oZgs4G9cq9kc+jtj+xS45E7xWf8dYxm0UF4rU9PzGxaEVeIdL8KILpOYGwBXevqW8Q691aK2IZztv+53zxbtWLkOzNUx93WKYVJVTyhvVa+m+aw8s1jAoa+a6sTgfOvaMzpZdGQtG1Kxi5d1v2leitHBhh5AYJKCTToXBQA9WM8gR74NrRrFJzbFd3hfovQd7i1uUTEahaPj7CqGN29ASfs3+HPz/fXGokmoDAxAtFmNRMXS9waqyGgOM6w0CMXV/E2fqtM+oVxvDS54R2Go2mRCSil+re6yUqg8dx0K6KTzKpWdiTrFbZucsfqSJf78jG+P/Hkwfn18muH4SArWZGGw2cIn5R/M71LK1b49a/QZ889PVXARdJ4U7z3kjoOESuA2hMVpQ5SJQsOnTAIocQp8+IUAM2eNn5vQ1Aad+sbapJI4ziNYe9hthlLqJhycOpBLtNxpFS5O+Lw7hmwOZV9Z87cPFc+emoVKv0FVxHdhC52wLh99xnw1rMLk3QyBKjcwLntr0QsLkLRm2V9uCsc1VJc+AKsZMWXlF2fi8sy98g8XCvKVH9vk7ozEMWbPMsmK1rfqdjRotsv5MABSJSCG8Lp0w3lwfZusm2j3gIpFs8AXFeYY8V2TcPOcRUE4CBp9I6EEQJZR3boLkxjHgsRv0O/QIeQQKPqsXxg2tFBeOydIz4tn4QtiHAsN+u0E5j6BkicwmhG58dwkW2/YQKR8PknGksSlJGKYc5NDuMOtYTiio11lYuSnJDIOxfi3GcOk6HWWpkQZrHB3bTYDd/YEo89j5cBexS2X5tG44niCDIFVugmQmWB3l1HjGKFn9BnzTy9O4PX0okuoBA6PsH02RWixICjes4yMcHHTV8tgEEqrlCADDDA+kdwWz/FYyN6gg+27VcOTLPPkgCxeTNoQkg+C9DOcKa0kLg9kSYyjuDkQtZbHOT2icLdFgLFNfpF+WqXqoQBp8hwCJsj4nXh7La2yDxaH+alvTCgUrT/Ud0/XJqC8VsaRx2KJ6ZDIJtBDVt/jnJhwLqahN1hxZGBk8+JP5e/n2CToafgsxBY4euLs7o7aHvr3XWb4v2P8mw/enT+nL6Q79j+zYBse92yh6gQnZQxdFMHW943xzO9mVZJ1dDzgWShKrNrpLakOCJF3Y/SA4dC7eW0xnwUFf4fv+sZK0WfMb5+u4SLWF5bZ3PO0PmufydAXfNlfWJxAOfFkwEmcZn7pz2fp+MYUspqOR6zOnPYINxmBJAnUDdUItALCEQOLZePFBCX1D16/pk6p0b+Bb1t5kD6mtrv4vLbVzsTZrlncz81uqmsZbtskUbkbEtZGdMkk7ertCE9/XuHPKpzr8Y9a5GW/N/Wo4IRp/70jkdFBrzEjCxdzDmh3Ws/ZmgNg8ZzPLuPkVE0+m9BQRuGV7CT2AuDdTrb3f+l/fK2jldhHtur3+BO/1HuQSjQbVG7Vy1WV7+nSjHF2ILfcTfUI1iA4O6CWaXaxoXM86kauvvOMnr88cuHM8UwzsY1YOdi78dAzFS9Pd0bznDhEU1SgpEzXc1XDEW5wWk/vErcLbfcudcHGasC8WNS3/rAEtwZRh2NgTnfBPI8gukXLqlJMTd6PVMXkNe19lGZicn4vcUwbyINgqaxlDuWGO4b/ibh2mpp3fVazg8dtMypbOuOS6JPOODo6ibAsvlwGNOLPnrWv9U7eecenDocLskySiCJBwPP29vR6rdVKMZ+etvV6J6dpPTh4Qi9RC6Wp4qQWogOKCoJkmnei65Bf4ZObu5N4Zlk0Da5WXSWkWJJMOP6HSbF4Asumhildd+y+Xa98WYTD3Jier0hoY82vXQahB2MsEHNvs8iqPN5w8m0yMGMLgoPAs2DSmngbdpVMYalQ/sZPEny2c5E8P14edKGx5mhI8CdZOpMwbIw0CRYBDgENBXG2mwxnYEkTFHQ2AVFTxQfFfoLZ9EmVWjbZDZVrOYt8oFPJicIn1gUgSmZrPPjS4iCin22QAbzHuZ6hLKlzGkzuYqJL4y6bmulqOk6uJs/3l/tHk7vUj6fd5Nn+anIxiU8g4OGnOyMRppVnJwnnVXlg1lXW2DV7RqhNGnh7UCpQnEs9pWRVBvuhTSVV9HIL4ymU6iRdEsLE2FAPmYY3rDK9Fee6fXzvEkJdO3VcOLlGmWZxTKtXprmUunRAehiPwEpr5WR8fBULYI1+B27od4drH4zhaSq48p/GL+OP4uSLl6uzLsHpxnCn3V9trr5VPiz/dPni47c/XpcDxwb8z4kssG/45O3jGVJvybI/O1n55Fk/zuIo8IRIEMIsj9M/KWXyZ89eu1pAQSUPz1lN7CNOE2jwI81esafsEbtiF0qwrBA9LTmN1yr7/P/JJ3/Dw0yh4SrKFBUqKUUOhJkoZJIyk8wOXTgATZWXmhkuoL8gWrUlYz1RoublZjtv+VgHtI70r8AMxMMm0LHjUZaMdfxayTvQ1mWwI4Fs+jhTIdzHJUbVTvb3f/H4Z2UcbzqLG1s1hANAYa57R/znrzIgHJAxZWMKg70N2HiFMP2LCEjQdrP6Xr6bqe5fNTdKr6JbzN5z2xWedFArJmY6lSBQvN091eRK74pzvN/ECRMRSoQQUZLjAYkwFf6aV3XpigcWU6qEVW7qwNC+z7zYPVEiNAQfMFhqxkcVrypeVui9Cu0jYxc1pBAPMFUZzE5Ccuu747lMYbCfGC2tefBKfFPixFeAf14Iz33T+aCf9bjkBQmkYO7XTs3Bqe+iJ9Spm73/0TKF7Ia8JvOKe//MTl6wy4w5U3WYeMrvay3avEuYyV2b69ScdGw8aYNSzNKIEVKhHxBTm/SEdNtRokSQC8cdEg0VPjwm+TDmMLq1qZbISYY9tuV9zj7ZlKSaSH89qS/KAPqYzlCUOTLU0YXiREgzdbfBK/4lgOp6l8a8QV3VZS2nzDnmCKIjY4U3A8vXAcm9CAsAN2IjCJ7AxErhFZzX6gQPb/Fa6F3lxwunsayGuPZfmYqqIsae3z19N6cXR3CKYUFKWomWUw58pcYc1NeX9RgiYrBkcZCoXOqH6CgEMS/lmboVaNNmHREG5gj/xeMPD1AJAuBGCQPk0EWWMWTEVlZF5l3qeLPdakS1IWxR4bm6CmmHrz8tRBZn7YHKxIulLcmucPb4GASWL+GIKg4E4GrbSBZTJEU+VGpCeCew+SGNn54oQtqyb72oT9+oom0T6K7jg9TXV2ENF9/Sn945kMC9WZvB0DsPX9LUd1vweAtM7SuQmK8wG3FFFumzxQMmD7dfX+5et5dsEJuoEMcm9lXcl7Er4iaNjYtvNtYmVtF0GX7XR8r7ve/JtPJO6HU7WC1w3Dnp/Swkg33zXJeySVMTZ6jS5GYAtgKC/mSuymN0FT2Kns8fRjm6MyGptkP9pKCUz0NSxiC3QmJm5mC4cuyhYGNEFSDVYjZ8o92co7EhaFY0dZKm0QNlBqV2D/QCdDvUY3gOgxJ6ekl9+FnMIvk48HByp42H2nQbYXGmF68uRIwbPMmKG0R9doN5Ob4WTz3J2S7/3MKUOyT6XotNFHOPPzgrlaPVtT7Qg+/wT+bVPtiuBtH/h3GxgxiWN92fKE1HHd9++3jNkDHCwkonhrY42Ft0UBY+0KSvhuqZhHS9IgfdG8uAOVCrD/Ft4zlwAtl+uEpjaPN3wXWmNe8iu0hrr8f6+BjN0IkotrisQeuRhpUZjcDtVxqGu1nNQ6lOWlhkkY5mUxC2LOkPZJkLCCHlISo0C44YQ8gk+rnCnhNVa0AxOicZi+I16Ovzse7WmhxtWHiwXJ9g4QnrSZEvlkLBe8CZmli4pDeb1b1ySiodgVrkllfwmfSJDxVNZStadGFiRHbAgTYPdKv2pDJ5lFg8i9qBZKIGuqZFShKGYyLJn0hnSuEQHAQ/tgJhPVkIpcYtb5FWTR0VCSyfbw4yFGCfGx0iopp+wVCBmtLhMgRGAL9X/1S/VPytHheAwq18GQzmlZzBarEM287KrRatl2A+xVfmg7THzk5R1TTepYFW/ESlwQ3k6Q1771VNWXEnHpuiszKrQev5csT3zP9RhtHtcnP/HMBA44WYNSo3lneo0V0jVLnOx4A5IF2ZokmTpqzASRGfaYhXMnFCiyc6u7CrDDIm0uEbRl4S8wlIKFFXcicyT3jr7cCPgJHKwmhOIKJHnUGs6WymOLAQsyF3RJui5UyJAzlRm+UkKpvdEd4a5R7UrOiJkosWOtv+KMvR0Od5TudmSjYra27NcaHrPYXBatkbnXTkylo9ix3tqWiMc2MkYZqhtkh5lERn1FnNQT4LEUHMITYyRmwSVJlIPsFYRdThvaHDpJYv+a+ZU1IyREut3YBn1JS0NSQV6RlLLQbPP9wTYWXBkQeNELgsucSzTktgy9Ium8bNIAN5OsFMyuRMmlp93+dQOI0tfSQz8g+bKT++kmaNgbKSsmFoOji+3hTgij9LksImvIryM7E9ERManmqTWqzADMi+tL45qtSLE6GUwEgwAd6B69PESGN5IKasjGMbupp+9Ib8fPV9FTnNNe5OWJWjb2+9AOEaxhX3RmRC89d/l2s4enBFx7mV5Lk1ot0V2Ab4ynaeSSVPrPy5snO7G0f/0px24kQXdwL3tumU/Y22v+LDhPkuTKVgCKS1IygtojHVJ/RkUuSgtthplrwWRmyjgqJB4xSH1poxnaHtMkmC+djvmWtvYILtcSDyZMIG9EsMxj9i8yu347P8bVydSm7SAw4gb3nOzTFq5/FFPI2ZF7oj8I1+YoXgIYAE9U2JJhEHTSfPMTULiJa6KGoo+Emn6eVxcMe5gkSNQa5AmSOv7AFenxDYDnz9v/23sSwIs0uEV2lZNijgm6FG9xW9XVdpnu6pddQccRFiK0KstgfgN740KoCRbRertLMhj8UJXvJAbxHcQQgWrWR5qzSmwgD6qkOTMq8cJmXpKjPBiT3tcr9zAiblDBTqNymidxQIST/GEO1dqIFz3MUCwOHAjH01KfOQnHSlFyeO3XqqsyncWH/MwKW5KCjZSCf9FGLGDZOqcbs/Ods5TnIca4gqo6t96RYpSMz4REHwlCDp5E+DZ7wJNoE4OVI6iHWlQMY4mfOg7VHUJD3CilBsgMtkB2eyJFxPMljRbwQQpTFoyg2QsuBdksQY+PmCrusFlMTr1wAdYFlDWxnDeXPEOtOB5yVmNMvObjD1WpILAIyyxy6WDN1j/CiuDlTRx15w1B8U7vvkVi1Z64nHvEE28WzhkVU9iaUoVgHCTqGHE37FEaIjNHUE5WxCGSzHKpi0XpLV3Q0Cn3M6WhyIsp3n/ncrhsAOYDVsxMJQAmGmWD69YnhRe5hyrEDhPPv+mdmxL5vzbiapAauWgqG4Xpb4ApobiUP81jVdHtGtMy4xcaFiYFPxvjQ0T061FH0NmkanifIFrwo07ZSIhUowx7twhm48miBVUHtCpG7kuXRyVLGd1Y4QT4gaUhLPcftj8eOpxaRN6KWMko0fRlhTv+GHrFABXscgWh8vnJgVXvBZuWeRcWf5PFmzml23RVPlWpfQ6dSAC8NgmjgOLiS1WUE3x2ck50AJimQ8qjGUAyYTY2ho2t5MZVI3PXNyGi4eCFvgPSJP0TwxuRLKF+XnRYhButLzgfeK4NAEV1IFjcT+YutOjHQCOauEZkNfoQsdEn2mD+hUmRWNg3fEK85KKLVEouinjUE2aZ7LEPiyUgQPRfopaAqm7USBnHPFTc0yFl1V9hlPrNso3AOYlQJ+uSrQpaaxwn6mOMayCoiqP8WrSuK83whgDqUi2uc4Lmgw7eypHZonWQHY2KEJ7/GbopA2UacZo7K16IHXrPa5276fJLw0gxWd0Xypiz70qHScNdWtuVmFrTuhfIvqdjqlpK0Ryrk1ohRcSl3xQP6EJytg40oCWhpUVhJAUFTtA7QKTdg9hCFB9ylBReLki/X44syJihBoXuBUyBMZQn4IWlih+HoT5SslwPT5tdnTurX9VZrj9bJxynRhoNk44nfMoeoX9R5jgoaG9ZGwqUZu5ih48nR5rJZniXqkdc0lk4iEDOgsZ4Ef9ZOEcfHEcs4ijRiHKTCMZVNN71I4ZPgVnr5Z92MW0wQylDKNNEQ+K0N+EKUKUXpgqOZLjJNf+tjTgJXnA4KQoN4CDcrvuC0SnQHlErr5Gp5T0iQZLbnXlpxmiK3aVChxxlQZvUTGJMkQga4I+gjqhDpKGXRFrTRFWsmidK2VWpuldXL46JrPG1M6OQOmV9kbrS+x/Y/2FGkpCqfOuUn4oja1Sges3GNYRQIrRgQqQX9IibbHHQdNGkwxbYJm0ubBatOyDNJjLhG0JtuTadhlIvN/1XiJZr3wmQU7CLPLu7QDwIe+JIuxMj35pPbclAWZGZDag9EajB8VTkTnSvVGkze/IPWrlmFut0Y2mIYsxmAQ7p8wS2EZYE9tkAUxjPMTcQzFX4DkU6KOkY2WS/w4kwAJPmcMzxKD7WbBcICxkBo79GYOZnaonkrq85RpC1hwngVdaTHd1PbbACHNAyJJ7mxWtZ+FswFIHZI4K21nOn7ApV7+gMzMcktCiqKVrGxQYCmK3oFxBjSuYBdryCiMZhJQMHBILLAOTy8kacydwPwekUUhxe/heDAdgjxQ6RoUExuQ2y7k3brXlP3ogX4dqoLt0FvGuNga4xx2NnnxgY4hepxGL3pU7ERx3wQbvLzVneF+7/QRd/ZC8lgM93C7ivIDsMrwqZ0lnA1p5scoRn1F+7qGgvh4gHruvTwFza4zPldIRSM3Y149m774i+5C8riJXjyixXFWGifJbvEU9uJIJzupuq/ws0f01LErBtVeH4DuDM6NhAat+2VaKrv/e1iXTsehYFdrY2ibM+vJvB/7EzChFio6GYUYW8S8b08oLmYnmMqGFn6ovvU98A3/bHP7xfqq6EKZ0kn77Bn//j3BlSzCT80fWJ973B8ekB98fdbSSuF+Vs9ilGwPJOb7G55WB7c2bpvb7uwX/gf+a7+PJ7xbnt4/pdsjZAYMmM4qwlylAcSHgfXCtvJPQjemnd6ZzwdrgrkIfuoypt/cUvfDHy6srNNOiqYJHCGj7VOgsxld1hOUZG0m4GK+LGdYDNIE8KCVZBmGFU01jAmZ0nBiR6TpfMKrn7t8Y+q9zv3jC145gyfu3D9Pp91qdf+9C8JwPpj/1OXZhb4KkM/g8YbkFgdkBtkeYHdD2wOWZSCALOWLgbGS260hfmWls4u3gXC2tEPz2HzJ9zlf2dCI6BTue+s6Qe0tm+DTLbnH9eoZDWIAmcJCmIqM5oagTqVSMhaeM6Zprw+R7s322ipiQ3pL7fzyr6wvrYlOX9gXXd1D12y150zuxghx7RFJOl/07YmpdrwPOlYXCScaYh7aujIzIrpt6H5a+SEtBCmVL1RikI6oWn+cqbCtaeUZ64RHDTsyWvm4y+1t+g3KKvxsMbQlx4fNkyaZrfO75w7Rl3tH0N9h1RdCP7LabiX46uvGz1x8KlTboVGzq5erXxnYRuRw+KGf+6ZV1ad98aDLx18oyTd9Qz7Jn19bQKnv+EHfs7GKHEDjwgV5uzeaDgn4cOEL/nbvHdd8hrAsRt6CFwkSzpv9ED/Z9bVuCBq68Iw8wE9pmaeZNl18lkOmdYQh9sGGOKtzgJZ20Zct2hrKsql7uwYqtwP4cGHD3+EDTDF23uyNHTne6YaaJZjmxJownqiJpvWN5OpH3zZtbqSMn5qgrfckaxx684Z3bgCmeLpBotnv4bjyBlZQw63dEBGoMbg+IN050e9oqy8frHR007R7gGpxHtmZNm0e4C0/tbOVtuv7+kZbScPf6utOHYtMn5e3eK7nnZN6TeedgbHbkX+98ThXZnLau76ssK2ShMegKk8HgJ5MEg+mwTjmoSex8IpvXN4li27TlzV2tdZCGjWZDnRmCAJ8MElTGEhTTr3d3nReyTJkHIbRfjz7cveWxPWmn0CbdhcV7hFS5/o6sD4oaHtJfkBKnWf4J0DAGGGdLLWpM1RLzJyPj6Sp7e/KctFFhL2qB19hj24+b56a5FCjXguBF45O14V/UTrjNN0+QobUEObsiGiNWspVcZs2A0opDPwsVBOzWC+dAdVyTXUjdG8So282pltU1QIHu075MM8D1HqcALmlT+Rq9uKkMRiO3CyZoo7mnMMRhnQCMp+5S8Ksin1dAP/5hdUPUTQcGOd2ZQDs8iCJ9+qUQIQ1h3p9nNqGm2nAM65SzeNpaUBTJIUQoJvoe4vDU3SOOQ98CzNhRi2wFTZlac5tY98TZqqTKk0XCJUSO9tIXuGEGJi9R+Ugoe3fR07XPnvrnC3PUlwGejEv1venvFrPKR+s3eWsvVgVxcXVWsxmw6QvLpR2uPKh6kosGAka2eGS+WqVuGc9futsjd7M2splolSYlpa0LKqbDT2ur6Cgy+TAZtNyd+wInAzzB+RJwqeDSsn8Z4NsuQik0K947lM6pxnEXHqoH7WMkTO/rQGF7M6r75lg0wLbWVASDFtczOT2d9/ev/ZXnZmm90M7A9vgx7N3Vzf2psGpzdmSOWOp2IyegI+zP0H2sfP6PmF8kqoej5jxIH7eo4Iiet117b6Zjcr5Pf6lD15IlEH4sDVG5ydwRsjuIoaXkf1EVxLfwMnFfY+KxE+WVjPUabuT0v06fn3Dixs0ATbe3LBQAEYO2CbaJR6ML6vqFqmvmlEFwIqmTghbueEAywc0Y6GOxZ4Ewslujvhsg6pvewzduK11smIs2YKvwRi+sDAAeuWankCVlh9H+cjcNFXeoIsyL9XtQbiC26PEJ+lG20c59Ijb1BV4KqkL4FaMH4OzQQPIdQbBYiwIO41ynR8IlgFepr5tu3MLGrb2aJtakBxKL7IqXkR/cSOMBVVoGSfOC13MqquVqn11o9Cbz7pttj1geeJUbH4ZXx7RdcJDk2WAHGjSe8Pv53w4bsuoaeYmIfdce8VHz83YjEtWbg+0KVsUI3O8CrfhK0ttaJ6O9vxI7WcN4pZ51vz36Je3SuNq9KbZUxBgeH6Mfq/rM20KKh/HWvt1EuGJIwe/z/CsLo1SyezDH3AEGClTQt3mhOX/phhmo8Z52wJPNzjrEtXnueqQIQermTW3qT2v5ifSAgyluMUdjt3L69IN+F0YR9DN7+nbnu2X7h+SOQdyEbYyw4ZcJzdow9xSkxWCn8GlCDK0dMgHCUKQT8KSdMlmNHIAn+OOY2FXJgkqLWHYlFbMnDTcEXYWk0BUxxCqMETV2taGvKU2BWXvYBlOJI/AUtq6HisizrStcqQ6j8kI3ljM0wwdBaDef9E9Q9vVds9uy3zDnPtMjfo9VYqyhVYkup+mIJIxz1V6RO1aPO1S8UhZe8QYOvBNQg+glH4qfyQq6cvj6YmoIiwOqMqpf6STZ1JTkE3uUWI4i6xWxrsZxyX0Ggk1zUqNCKRSuOecSU0voZQ02rLKtoF1uKiiVZ+m0EQzSG82S5S5AGcNTJlZdVPbGXZ1MxA0obQqcty5YJY44aGmVHNCj5a5vve8qmkyA6mzmYD1BEYQ1jypnBvwNiR8/qmTPsK/MCJBS3nlj2+uF63O02gx74vC5BdjnNKJdbASk7M8U6XLfnmmiOcXvUFgQz0UctNjE8glxjIrTGdJGEAJDNv1/GXWN216EUSh4mYJfFvR95bTpU+4YBeNM4+VTPp6GNI0UWPTQhq1vVo6i3p2YD0T87oGuSni0An/HS4DzQ5GDDLs5ZcNCxM4SsgN75efLI0o7aBUOn2VJwvEZVAVR7Jck8SkQCw6QuFSbi+rNRqMKJ5Zi7L/JomxbHc0zA4FmrpHHnDBxxonwb5EL9D1iv59LOJoQPWQr/yDuFUd6sCVjubmlTxeUn16Rhv/XKH3l8yi0xkawlYgH6i5txZlXGWZjflsRheZWRBuQtUwjbHpSzOqW+WxjlJeGUjKIoqxwS4S6fMDXTzMP2CyMbhKPX5WYxtimb0j1MeMKopQssoIeWV2ZUqzRDAz+vzq6iY0mGA3puCgsG5k2tn+us2TMGbRiQFJ75rRqca3273sGVoEayTXoexd3Q4NPq59jc3UfIE3q4WRyPjAvJUynQTcDLUq0mLPpKQ8PBKyYa2Do1taUnHl7PO0aK04gpMgZANazsEKexRsHwhyKfZ4c1KUugQMLbdPggaOIUunZWUW3nF//FtZtU8oqUTjIsVCstWRIBN5cKyF+gCjmSSLXhHQP24QThhbK1JT4ROMzeGtLSmas/GxQolKMEt/0kZZGEFVXEwKX4Ac/cKz/QGbee2+R+YVEW+Z8k/6mXeG7rl/TYFQWz1fRwA3T8jD80cAM93I8kCZMnv9SAF1bhk54FqPDUW/JJYPelh6W6sauwbJ2iyRMJAtwug0VI96VsVqYy37WmeWKk+qpbDcEmx9rXiNmZFOB1JDx82erudELcpBWeAWStNbiZy3RMSUqKuV1IlRXI2gzQTpQ1yqKllQEGIISLvtiGj1M+pdfehcdt5b319frK87g1L23bltxm+mNT0s0cJ3HSouAqX2l0Hh1yNeIDLlycyf1DW4Ty1rxyUJeyAzzuaAyNSaG5FpiIpIeGVSXO7/NrczZ0Qr2pqC5LN1ag6oy/PqgboGylcH/tBQsb+bY5KyoUT2zRzAPOguD5EiqsdHZ18jyXp3vehntE09z19EyNAJqyHTDprUFg4GeN+JZtYpy+2fzrO8HeT91RN0Ex1bebFk9p0Xz8B9Ay9RU5bFA+Tmqrx4Vj4rg83FxQwe+tAEyQM2zGBwohdbVyZQtf85LlNHTF1V15Scz+mIDtcV83WqVuwT9kNGDUxjzw7GJz4bps15ct9A0IdNxlGs9+XtYwpvvvJoa81vlzpRO8FD0wOj2uNqp1cZp+KrNb+WLRspTR5GdH16OqALMMOs0WV5eaQ1ev5AkbluT2gzkdqXaP+S/n4uoy6lGnZ6bAJdzFkqMpp3R3Ijiukc8JM0Y6rGm5XyY8SkAKAELRs4V35YB1jrDIaPw0yq4paOJyW1jq+lioAOPcpYHPNE28yqeaEpdQ1zIhcPnNR8OmAPaYKQy2HRns8kj7lLGoMj1SGb5akLXqVOgnRPv6NJRwkvnnAYw7bMQm+0+spPT36dxoFvtbTHonW1KCqYCsfXGzpER5t1hSMi2w4ynGJKDOr8SWvehzujT9l8Y+bg6CPeCqoB7oNe6sRnckmt1tMSGc8EYKiUeHcFjtGgtVqv+SMHphyOTMBBiBsfJPK7kdoSLzuS9lGHzuTLKpffpLYMwEdfyy5/G20IPY5szIaAhpeQd9Pr666UBpjsYEPGFKTQQd1uCAypPIowkliJIx2P6hlZarG0+T0qDbyjQDw1kEirpRJ4wOIfc44Hge9m9wDXaVMfDlA+i/ANfe3UvZRZF+gTZza0AR3Jct6ymu0Zw7CvaZvvaeHaMg4nXaFJZEP92B8T2ah1i6Q2Zwa6WpmZS59vlmOVMq+uJ0MSzrxA8/UjVOt6Ou3cwi2I46zYWhnuapt5tpwBiB4qM7fc3bq7y01AJ9ZxylEaST1LdUMivRfQ/LW+Dk4vo0gv6noYNDrFbz4Lm3XxyPEBu1x00zTuWepeR0M37MlGia6qlP1XGpv8q8iZIsRfXnCStCOd5VVl3teZVO0ptaqOaD+1IuGILRJOxUo7MxhuEY20GkYrt81rpaz78tU8fegGQLuXZssyIinFiQbOEVFVkRnJa5zCdZQysa9YcEXvNjBsifI6IMqrAT+W7TCVYwOqqh0Bu14FyQEQRkEIc9T28hnwMhU/4uNEyQf3RaLzAyTpWOXeQraBtGmsl9LWPehRkIhuNng5WcoPgPsS0VjDA+BNkHLy6O2dFc2kLvx5gumMihMAwtP5QtZblsxKGqaknTZj4TYpYluMMDsoZUbWWuYEifBOEEmEJXEy4aHRehGCHEZL0QLX8Q0FA0ppdeEEiS4TJJNrIrpzUBTNI+XdCbp5EEIBXbUvdab1w4xFRhPBE5JAOVJ74mWF6y7cE5tERnxPvJiCNqWUpE3HrZTrDDo5YWUeONRWCiOEka5YcQiZkn4ULzEFeaoscT0Fvo4Y3btFZpayntqVmXPcZJjyZZUgxu0mAXF8XDnTy7mZg9XDEhGtc2hxV7I0hefK0pSuPyDNgUyF2Ib6A1OUfKYvCOpJZTZN3YQgQZbPq4hafYAU3A4zlNNKXA8ngHzDmqYprhLCDq1owVObDmKF1OlM3yBHbjxr/HSxcFQBu0hkuRc+DrgGcDRw5WtLyOkMd+I8K/xaIQ4JbFxHKyNAdhr/qoiaXJhJ674bWF/vOdgjH9OAMolBQvj2NKHY6T3QatOlTYvIpAu3lhqyx0NmBSAZXyg+tI3T9blca72sV5MQywJdgAbT4dEmh8cVmqaokPKRJo4ZwjaKkKROJxi+U8aUokvJfCeNLdiHrLU8LfHVz+0wARC2QWGVNI/VAXdmJLQn7D37cDf5Im7bMFjEhA1GgNtRksAGBlDBPyhjEgbecerP5jEdoyZKirGK28i7oZvlxs4nCz1NZxd6JC9XvS30YP8X3zos/VlOP7TZiqR7aEt1/3hgpFzoT1KCZHW7CqtZoKFh/AgzitZiPacNOmb0S7MeMCrJbJ/SDDVAxf4jJXasGyznQyuFq9mvUkxC77iw2vIAIlOqXQ4CElocIE3pOeJlpbxRF2AVVCsjI0DhdBaBB0wwAKLnIItqVRCxDRzpUNmLDVFZy3qWwdzEBhy1G0ZT9yD8REnEpGZLpAkzVeGi5KcuY6YhrkaIWLqJf382TOQhwkkzPDrTXGRiT17RktqCFXvAGJZ0/JEc/3lEnAhfz3wdkynqwVgYU9tCUlpepCIli1F3aWA8K5ftsigLeUpLE2aCwHZP/lJuWw3MK/iTJxRx77AMzIvn1LkOUsQWtaY5vSfXZRBCY1IGjiS2ckainT9rh1YnuvkAkzIcmhKqc2FV9vF1GRfxnkZ3QrhVToNLygR89wjUV32zwy3JvU+C/CZMEZkKjSnG/w2gEiEKu4lWmOyKjuSGQrE1zJLMzo3KoESV8mB7D7W8Xb5l0VLU+azLGnmqhLVsYpfoYQylW4FUfir1ZSVRhfpqvzukzhlAx/orioam0FrqSu6b98PdYAx5AFYm9svCZGF3Wd7CbeuiiOKKCsb8ZT9O89GZIZ3O23bI0cFqcH/TQ+9bXxswpXpR8eTRzfwpS9yPnUf9YHlVVmerxdr3Vh0/s5uBjt650RTcUjQ+4cFZSoGqpVzwyA0zQLjfOhNNA3u+GE1+LvNvGtKOKx9ECdb18QFtGtRBiMgGNNJ2BrYzKjCLJukMILdsIfiYJ5wXHq5Rk6g8rciCiRU57U72WOLJ52FYgKVyBTOopCEuTUyMQZw9eGv6lakrvGzHXqRUebWKrWQNDh1RevPFgVsM73tsxoCEpvKlbo0WRQEnVhK3AdkMRVu3B2pAYGu1VYihqCV3QLeIqtjfDIOCQc0wkHJlpEZEm0FgrfWdBpE5GbY8TQ7P2kP5kGgiPw31SXR1NYQA3qUspEVe3FRJKLBEtGLs+PKoBfUaEG69gaEXMJ4tYUHVLkFkBsX1HE4PUnk7jekmOKLixZPmmoZDQ87uHdAr8H0YbeZ7NrBzgrDv+xcHpqb86Eibaclf8l+ISY9uX6nAEk3bc3EOc8GbirgXzydPviVQebdJN99/dnt1O99zelOOvkNifNqazBQOnnOJPeDrpCjsa5g1PePnOIq+rD+pDNKk7ZEpWKENppjBLszD7RibySrH17djWKDipm9XZA0i7pge5fISHO3oQWviLIzGbhxhbhooJptNtu6iyFRyRCeL7YxCGlxgc9mm8SGcxROaLx/IM5ZOtupRK8Nw+025v81fwDevaRzZ4zUsc5vffr2eDkx7Bm+Tty8/fqQ8uLwk2pbUHYju6pReS0j2AKBOZeYIpa+Vt/yt+u5/Fg6Dt244T67StKuqRYLeIrc/eRred8PMLo5sFsZJ0emma44cj7RMeFVUe5JGkKZLAM9SV5Cep5+ussCvwQBVje4v47nZluOeScuY+wjcxZHVlYS9KY+Czo4TJ9CnnBSbjKrUSa10Twxe8jiwZ7KCOUlE/PrxV25oNg54u6QTOvFnWLWgeaG3OYGfuyFYmFwjqLQ7FXtRJ01JMHweq8qWHfqaSjOrRgDjyNK0m7VFVezptC6Fd8EZUj5CRAtGsikL0H6lm3aemjC6bWtG9Hy+mVar4ci2bnIl0ICOCu7uH8IaXDyCuaqZfvNheCqEReamOvsCB+/KTa9yUi65+ypD9A3cFh/xHn5XUJkn1Nk6d0SMdYcWY2n2lZlXLhPqkQ/f3QocI/hv4C44EH6Wm226b21ZV1nxBW69ah39bdwBBAxe16XXsWFcBaxNPDVxxETdwOtQpxA2u/vaMmCFw5hmJ1d8UiBfDFbIBkGSWh5D/m3sgQUoUlSu5LuEqrjxduD6VanhcUntQvtF5pUl9h29UxNyEhxdJm1Zrd2ExBALS/NKC5eDnqxQeGr9LvCrgd0JzJdaSK2nidTKOPY1K4VLU86LK4E8HOSNrErZVnK0rCwySN70zhufS0s3eGWj7Mza6yUQoJQlSpG4s7Dnf1l5qdogHFEyE5OzqN44Jj34Gokixzbt0GtHCN5Z+ShYueo2G2gQtKeWPPSDh3IN8KeSzzUozST32RjE3A8BCN9e/EkU0YpAsHa7FsFKPbIAY5n6BwL4H56S9/0Y1XYl2b2ivWJGCxIcpvotEy0RJoA9pPj0/GVA5CIREsIeB5aroKPyeGJNw2ZtgeCAiARTO0TGnk163wKjA6G37G1tilBJABPxWx4WfpoJAFc1ZEXkg1FM9EJCstynbuav0fDs+4/nmI75OflGIHKAXXa8mxdML0UhFM2r3Nds/SP7/yXeqq3tiE/AJzImmwgNEdwF72OJQRXaDkhVhksAFQz9uCBAcswStM3THaSOJkODNtXfE3mX/H0fwH0jtfkeLsOTwAgCYwU57z++wT1lTCQqhAk3udArElzDx6nvJ8PDDc9oh0kUjn8sH0UouaWHDTm4C4ZYw6I65AHtYAIWDpC4UqS/jMWp2M0x+cRr73sY+zmhzfhjJ1448cSp5070zvwmxcfOeP2tE09dGPhcSmAj/tKBR717aYOEFfcbHC3FIXAf/M9A530xfXNfGCclCJkYS2l2mlGtkdzGeDq2iWKPEOcV1cEE4GQq+y9VNfWKGIYjkgzT/QiDdc52nZaAppYnuc2EzXHchKG1y5xSl8Oo9H4bt0AHNBMGEyac6UXVreO+4yHZTupv4OC1QZ60io4j26R6FKCupHi9pFM0FPry1R97lN3y9ge5F/UrioIfXS6VyFEGvE5QPU9ipQoRx0SNEUZZfYG7byzlGlNiCBOYqjBSSvkHE3V+fqSdJACwkoxAKsNKUp9Q/FI3OkFy3Hk7vvcs9K2FMWjmeIHc4LwVCIBKRewaeX0CVSAyJrUBITiLC7eoDhlS41IFlBHWJJJTegdkXPnNlKC+SUExYNoAu0vxPhMp1H7vs4JIPYf41iDIbA4mkcxswsKExTqDeeCozDSAK2vjJ0CWAB5jxqKAfcbJMU8IyQCuL9ZcWElR0qsM9o5EWkrPyK/C5QjgEVF1pZGvJI4p4nTIBvR6AUY3hrbC6B9baEMgKchaVA5OD9H72HOIYHMnTe2C2TeKFepS7+087Abqb/w9/gZEDSX4bziW61PfUYh9tcjjDYMZl5qMBfwakiBx67NSTK3MDoAnGfrz3AkCLkFqc7UmI9AQaQbWsVqOtAauFLRYx0UhjWKv2dSJ9p4mJJDQhUbvfndYek6F70LNkauY+75KZ8HywTfWCT90b9p9pTwMSSf+nSLTMS+1A8SOz1x0CyQLjQYERcI4syC6+bUl4rUWaKXCmpA+8mivDv4f+853ZnI/61JI59b+FwkWWCv4ao48sEVGM3j6fvPYvl/Y/fHWLQUEx4XyoKKpEhk5qZNrdvabCxEMU5/AuW/f0o6UbPiOhv0SoNQromqAqFCo64DdbfbGIAR+0zd3NxGXrxmYzwLW+a5tobg7DT6jvGu72SzWysACeWOrzintxQ2dKkGtADS8s548+Jjf59fc5P/cRy87TLCPf6b28YQNQdAePAwYPOzP0RNLZVMFShq0eYRY4g0amEzZRto/4TqNbrWwRWjSfZvnd5f3EDu752HAD1RASIjExTuRRgAIMMmluTOJvAzVATXSZuZd/Yko2aW7c4mtsPppQrttBwI1kwWM7I3i7/e9NhRYHUWUwxLYpdO7S2sYdfKNNk8/NGJ55hUDkhM1JKPOXTYJTF/jKiGphYayDCVljKUDlKRT+RqO2NW1MdwX3X/hMRqvLrzdrPuuh4bTYCwddA3qbgj784cn2af0ARF2N1nek+3er7JtKLtPl3Vq1L1LP1fKy1Lkeq4h4uzomt5kWd4RLAyuc6+J8/5n4un8vGKfjZRl6f2jn9UvNeawWosafWEHce0626CWUC28EiB+7hUjcVUB27Q52AcfzmlaJgpT6TKmQMUhDeGuTvedSle+NEQQPxxBFj0Izzo9243HCysq1rMNdZM6y+XO2vxi1OHSgxx7X1S1Ic/roC96ZsMGplC0kdR5o6tCq6GywWYrxDdM8jthv9PZZwv4/12347ArmVHeioMnSj8dO8kjMA6Ghk6dXwfXiiqPfR755k3Wa6JLt5DVh1pfPmnvafQjvKp3Kea89uSxg9ZHNmHdpc+xZ86PWNTrQrW9Xd/T08/oHKprbh7+2QZ2KBHF79z7BH33QqrpV/83os1oZuzXeU7kwP8Q35FMDum6v1H8aoH/avGP55aMzxxKHJEAut2ANxiXfUzc3BCblIEh6gYbobp92joKcil5Mq9ylx/Lqf06Xws+5ssJGheGRlBOtlOf5Tldtq3pHNLQhoewIXSFmyQTBA5Tcd+1sjVO9JTid5EWKHRfkucfHKiwSTYERrE+lM4K0tB0wLP31th7nnb6wjfWtEek88l2bN3fwP7zweMdY4h/G3dBDIDeU1xwRHvsbkNsd/uCcFmlQQ3clERlrV0j86hMDzJRBv8jYYX/XEgiCmYlu6l9cAeAg8Z3meZRd6v7mPwvfBwe+t/GbZAAoZhH3tF39TTDIcYKx0oDr0ro4itkTBTWb/crYLExW1pIz2KZ3IqhKhjcgGQn81BG+4lNqephdLk0rVvLieLvk/EDEELCa9CCuBMq+E/e7MtWfUEtX6KByno6I5vlqijoEoyjiQZn7sHFfPkFbu3kdaH22SkL5qeaK/vaUqGJU8QXeStbmDlC0nWYxGsJwghK8moOrCo/+9LPOdeBr4StUVBsNd3GPnD/NaSQkTZKOb7T9pHqnNjCLy09zTkYGABMAxtnoqc99CLRecyXOVK5D0JyohBHZ3DkBqGAu7sv0pA0qNR9OcY0gHfFlfb39gr+/Rv0MysI+gKa5Pvyg+sE4Elg/7iZgcJzmlGjNRVES0n1wnS7hvK9zsqW9rWGheCNkMg+5LIldF4FbyhFuOXs3Avq/n2XC9qMMN725Qg4zO2rptOdk9zP0o6l5aQWpRqk8KdI5j4uECf3ma/SZo5as74H6/sa0x0Ac6bxdDMZxjEsXmbyN9A7bxgP2O1Pd152P5CHs7FPh03rSaE4eLZsvZvfGdaYXZGlnu/PqinCxHBmsgKtNzbR6VWxH4ENtp6FYYwRjAVj4RiLeQrAnG58xuparbUWo6kxUo9OZy3sPtntWBAHcRAHcRDnsbd5HKPBolh8qmcRSROAYPF4NiDcb5FSUotC8gsI/CsFIkXcxuc+5ePUmZo1QZiHm+bzd8F8MB/Osy7ooQnDTR8jIC7Q21BoR+wA3wY1i7Gk+ii3X1klEQS41TjeaK9OXW6sM8gggwwyyDyNIIOQkYyCCGKX8O0aoatdyX12pizsgZtymmHWong/2pGTk3jFfAmuMm+qSGiYgjAiRlPv8NvDJ0Jy3vjyFCEyG8cfijb3c8UxJ62EFoyM/YPFny/Ya/Zni+8pCHS2B5toTlwJRjvTMn3n4tDDRHGTgcF1XtUGckefAQ5t+Hnl1zqDnHo7RS386+brLg5v4zsPxiJgVMGeQi+iUgSvVOCUMg2x3BmW8RyPGCFhUscV3mlHGRxniQD0fMdRXhQRFLk2Z2NR16WpHX5YfRx9okrveF+umHOFLkXE2Ec+8gV7f/OuoA3Y9WPOcTMvIlFAwZq4kQY0JM/uI/eVGyFhQsywfMYuKkIxUkmwGbli9S5Inc8MyyZQCAVZvnYZhKJVQdSE6RlAnoqQOMMM+718s7uih85e1S3fXss58v/LU359XYOklWSrKU9Dtfq+DnhiSyy4vN2furqdGjN6pbq2Y5kM+rhRT/fim7+JOXl6d/REp2QSlg8rYJTGuUe3jkh9Ypc7TjMjjaT9+yar2aVSIzDOZea4ceKwrq1bGbMLWTtZN8Kj7kVw0nbLZoS61FVCrnlrSwMbMovpEWG5OKJ4+m44r7fr/iLr9keynuXPoPMo65XOK+lR7UStR2feWXZmnMPn8/nhuZG4cn7KCe34EhPwagI7Tej4KnHbEofBB3Oe96WYkOVl0Q8WWmf48xCdaWtLwXOEIAJnWHC+xlBdN6ksMJuGeiVJ0QQ5D7f+j4BvqylJ2ThhVpKap2wcw++LAlOt0xkPTFVeeNItjEEUR7RvmXCc4FNC5VUdMIrDaIAFLhLacYmcj4NV3XKoHmuzRjXDmZRU9qkJSTwaCAEzi+lQWKcUu6QUUSDxAJLiSo3cj//PubRNULJ0Oje7Q9tqPbnClDSSalvkvTVFS+QmsVr2IqczU8sBwUnV8HA8Gp24TfiFFqMqscfs+74qdyXtJ/0ezqzUd16mmSpP8iox9l/5S0I0JtuOQtLQ9of4qaMTAlz89/xTCxLYwoVa1vGYhBsEMXR35FmDEwYRYNabtSizp30YOFcLETIrzUv60OeWdb5Pp642DsxgOHYjlBieqmr0p1PVAJDbRPYQRnpj0LN5Awf1V8chue2H/sBsRgwrD5iMZAcYwgT7jJeGfJBFed7ptHGNkzixo9jmqE05biSykqCEzXEoZcxYB+2te0NsrdUsm9HPGxh1fHCxsGxZ4nugBTveYzPQZQAPIJ82fFR4K8KcXnHAbzZ2Pebjgd+vwUpxdlDRlMMoNgf+0FLxv1tgkgpDiSI0l2wddgf3PYNdU3dt/OrpN4HTGiUBXfcWwFTTKt65HoQZJp1B+AMCe4aOt/zH9qnJyFuY2A30BIxxGwpoe0ma+vcFuVdktZUkjnHkI3hgSvM4CHntK+DQ2bQwHIoDMxhWX4t+hDq3XRVBLvN9cGRmiJSJKlwOVOpx/dYzpEO9OThwY2UvnK/qJfGZMVaJAmIUVDE3cK6MoEr+AGfBoMFCZ0RVQbVTPFp9MN4Jk1pL6HLdcFBqWECBNE+SCpYGSb0qJGX0xWKf4+oxg6MCmB+gVBD6ThCCfjahBYwjMh2jEBV0HiXCA5IKUnJxb0aiBx0x5MehFrMo1+4p4Kd1bdpuszUO7DefXwVZkB2g1jUcz+5zJTp1y3U9M/naAvl1IGQS4fbvz2N7kyPFiJdnlVrgxXhxECQ95TRDLW9jSN5ETqW5pNBhg7iE4aUyIx9VvgbMs+pUYZQqS6tZCdpNhA2KJs88IFuUDcmldEPdKyXTlXOghoaxKstc/sn9RG5I2wNtyTz1QB7vogckPlrVYDxQ2YBlgAHGjy3BXQ3l4F2o65TG9jmnYvUgvqO2vZiEFaRN4geI3jImEMhfBFOCYR+4/2qGiYVZjlGhOGP8nDQJhfV1mwfyYWofD+IEgMYxMfyWUIEMWyOw7liCXchD8xJD/wottr4c6WWVNJQ1oQhMYCnG9BLzynXe1jFN9E7sDlNYjl3PgDBzGDcGcVnwkEzqIldeN5i0jy2fr7vCNJZmfDTsrZvICzCzt8SAKQBBxtnEC38coNnQE4kSyBqwCfAxi6GoPbCpsl6mAwoDgxAWn9LJXjoiHhJbHPi6ispdd2wycxJIZV2hqTjT4ZLGMo4raab6ql1jXsexigpW+ZWJ4Zkp1VZA8lahyQcvLiKkuNN6AQqPhYKIKrYnOH2RqK2FqzV+7TuOmVfzpC953kzlZCIA61iQITZkNms5tVfhUfEryiihAt1eHkQLeru3jnpge+HIoGXadBghl4SyBdgejWebEfYIEfGjg/6fETKpKDRKll+DQ9BZuU8j8x/adeGv3RZKviFYBjC0j2F85xiouHqnYqdhWIEbn9XkYEobF06Jdjr14BWsKpIDDh0Axx/jxB/xqC+dJh9vX7vMsJjro+14YTIOW5fs/oTwEoxbdsQesE7v3cwPbJdpvTm7+GMCS7Uwdo0RrowGgf1zsF+z9jesLVl73Z6LazYAPlu3LRujSzDqsfNLqp0otpnBpFRpBqyXkU4vT9OCnECXaBvXcbR8gz2xplsRbcvKZlUuYgMmn9sLbAN6YdR+sLWYaqolG3yqt5pvGMza5RSibUcY3Z1OBDRmHY1/7OsqVwdTbooAwnf6pSM1O7c2k/SJxpSKcqH2Hxwj6u2QyvgZ9cOFBe8cqEtT0NzxqNfeKNB69wsU2BRo3Sf59qkKJ9rNsneOT9Gi7igWjVn6StqZIKuF45NecqBtKUktw1EcTZexCYJSpoJPnttGiGqmlKEUqusVSJbxkW5Nq/5IBa7IhtF5ClF/E1wTu29uzrCPXAdOiQqRZY6NpiDoBf4TBCnVnPj1Wtgb9L3CJAUoiQsvyWcx5bnU6Ku9LEvgqYb6mkqf+JOGTuoWSsqgMWl2BHR20iOitWuzPcL31fOWbllKM+knOy7kVIWHth8bdLJd5iJ/QJcdHCFxZXJ1TQEBgrin/M1K57YdvL1d8LnIWpUhu/nYuvu153zetnP+HKf3PTfxIzMjZZB5Nx6RNABZIN/t3byA76/obvGo5oR2lOmJA9IOaFnRtN9PpWiZYF2J5esDt3HcLMbCwNCGsKp/rculY2CH8E8lOWCM2+whtvGkJFxblVNEYy7pE0ekJZr1iQ/rVnzCKHIdIWTXjU2Ng9siceSkDKopTcGFUoce9mznrTK9mV3ihaF0JAOQJSqUpZ54KksZnUj5uhY1pUrN+1l9pRo9JUcTx4uITNWQtDKEB1FsCAsPfPSVGLvV+YaAbyY1RJ64uVtnbpZggyjUtsrG5SfPoAgECqMFAJFAzeKtoqHVKXcD7SLQq8nKuEF9UIO+0v9eOOg4mPUqV8RnFFhPVonMMJ/lcZQmGlCl4szC38WrTXgUnRnu3ZbyG+vdouuc3UXxjcdfefrpOzeu4KZPmDVFfXczopurevUpofCPEGDoR04NXGKezJEjvayC/s7fuJvM8eVHFSdeaI+KgcVlRz6jNrxxPQf0r5w9ZdfcbUf69rpZP2LFO6zFTZMENc6O0MBH0OiVmnaI7DI3KEe0moa6rU/w2adwiSco6s7EEd0hRMxg5FDk96VukjsNIictc8hmMKuHKFLzsnG2307VB6xCJ4B08xvpXKqE8pjTZl4UrTPZoNObZfopq82yHqZu6E7MiOtJ7CTpvS1V4REeU35V2F9rafYk3sTzTe7Uc/Tmsxt94OTE6ev1gd747JG6Sw2wB9/lzy37EE+qUzU4qJDXNOMoO0rExRJVWW8R8AJjl9UocrOokclxGbfDYwVxmEd40nyeP4TMnHMGNQCqaiJflwSfvKLyuT3NLbV1EyldpU/IctbnbgFSQyOr+Zm+wFJv3dmZAGWK0DpVWBxN2//Qzmf2mJly67oocqU+IfNZ1g1ItCDWEqRbeqHLmOttnOke0YS5OjWn0ViaKwC8QrurenWi7WsUNDyMrB1xyHXajSAg14nNl3sn5R0mt+F2oRBZh2t8uAaHGNJpc2CxAJ7PyPMSRqn6gFIJxqpI5Muw/NCAMKknW9Qg8RAzmZEebZeEZINjuDZjvoauOJjWoHwwGXQi+PIDSAOozzW5ZcPDeARApdWDSKfBZSoGl4cujr/ydbDABx0ObW0eb3Bt9zRRij2SGztdAVgdS4Fn59Knfy8MGzy6AHGJXMzB+keikOrcDRRTuwNeC/sDGBepwx0Xjm/ukCWmT6GUigOZYwCu+Pl7Bm6aayc4KorbpoK6U/yBJqUlxZ5SArk+UyunUosP6TyRm9BOYJEyptcuoanwAhJ2xMznOSgMSdtdpb2cFepnGRWrHoSVFaoxZ+pEYrBHNDvuRhU408GA9/qE7Dq7SocBfvQCYxcQZXTUiXd7prxXIyoMeqQ2JHqA0AzWdQn+kjFi7YJoA4c10Tns9k0BsjF+EKGVA10xt+koDSTZFOK4HWPhAhf8QcoYK4WGAHpwbvdIkGFDooifjF6GEso4CwLx4LLYRNbV4L+AdmN7yEAYRpuczcq+d03KVgKXVWvTCzz3cAVaTH1ZMtfk4GX5BvCqZeQvx1u0OTSYc7s7GNplkuTjQAFm1bolx9dLGa2jTzk46NKhbbtF2ZVnRpLlQGgMjCPFD5F4MwsrmgEKgh+UVfIabilEFCotL/vLeWL601yAj9p0SWmgzBKHrOrSuCLIbabzMoij7EQe45Affd7/Gz7WofJSPkPUSn+U3XTewLIibAu6Wex3g0+u1hkG2r1Nm7Tk0mTmHTdclp3iizPcg4j8bZSpBj0JS3WR8xZNZmUJs8MwCNgXBQzofFENJzrXY4uvKKetIZlEdPeRYCo7xZsEszBp8JNacAH+Xz3F8VwuB6WKPCMAlUDLeaLU1Hhi7fwAAGMZp860XfWf386MC1p3GtZK6TrS0ZmCWB9C/SjNTlXah+Rx4LFHqJW8J7XxoJ+ZbQMm8yBAtB6J+bo+J8s+v7wC4tycc9PFMTJR5BPjqU+b1ICB0nPrUetVK0Iib/1ZMq0z3JbAexz8rPeRlzypRgS3d9ZroBZJDOMe+9PbkqokN6uvp2WKhK6FsAnNq7xaVZ9U34rp/1mQO5PZn5vFT/zvWha73Sd++ItPOoRfLiJTXVXHmLyEjF4cYnsc0u3Ov/BF6JL42UJuYurF8npamBzc/0/Li1XDu3jmUUw/6Z2PnNp3FfQp9meiiPLGdsiP48BUZLROH+myizUBINYjsp3CX2uXyG6gzII4YsTXncJhdhTP0Tg9HJpwJLozovT4hAwwJ4p+jFhFXv6bevLCNzprnr3dXeVqXQ9NU2iXGeMyCnnBR60LqkK4KLOimLtqtgHfsBhjGGFsaxa965KH/ua+z7zML5lo67Yvy8CzBtDYLiCT3PQ6LMpohtljYANms7aRzwYtCnMzNbPpOhtt89hf7JKGpwwkF/mcTPxedkB3wrNrls/AsOnQi9Twyk33rLEFmZY5zQWr1v+bxLDXHWejYdCnufLlA56dXIy4ZJrbMLmSJmKoXUanYHFi8kvekcUt0TJfsR12DodG9HSRm2wk7KzUEFntFNiNyEXwZ0LnkDoen4qByTYAmFCB8Cow1DtjLWrqWp3oKXFJZvcrubd006twl9e5U6a8yEEBhAmgLcqmNGBOUt4fxKsoQuqMmGPRCeVJgxS3+sVIgniyDC8nEEWK2zPT7CDijETrBkmk0aoTB2SyUlWKQlkqyTx7jQNCJveEMAHJVYgak4D5mYzjgkhp3lJ/m8RGJOOM4Me4e/J0lJfTLNHoJI0Jn8w69gJXF4AtypwYw5DKmsjjRCQxuFWZofRa4dQIWeVV/3VS4JQCYOswFCB7b71lsIuCsQ3zy3X41n87oT26A6bH+XrKhvUJWLLH0uqI+gBeQ4cFHQ0Dh2E4kakbTCLdQxeKx8N2Bzb4FAV2otNdsl3VA4UqITr22DGDaP4TGMyYX3MdFWgiWVIDs69Rq8MVech5SqAAt7JjsECf8Ow/8l/5EVLDAozpAy4goGi7I5aesDKP562HlZNzpyjY9vHOk5NVom60J0bnB1RVDMWJGt66VN5QxEgu7HhzoBP+j3THNCLZJjMU7m3u2wROmnZyB/SABYZ0JCAk2LrwdrA3vv2aXLPuP+k8+l3GWfDhe0BqF2D/QJIZLS3cWjTYndIr9CW8zLCxUeKaPCtwZ5Cc4wTNTahiszIruXki4DUb4y0E0f6QY6QscvjwgO+JT+Jn0wQleoyOHaWDELJ236tIppjS4Y76lhjTWBrJTdzeM3X6/wOeigcDAGmqGsfx81SiNdokToIIDTpHssiUzgSFRCwNbwd787ZfE5Mmt6fzQKsZx1g7rBmKS7QNBxPZPyP5Is+gqMXb3KLR7pQe0JfwMsPGRolr8qzAnUEyxCmam1DFZmVWcvNEwGs2dodYSF3Fjz5mghoQqwfUIWgSEAfONPdFivihZhGn0kX2SdWYRDQsFKX3TlRWiOjMlIYbXZGbEmYLHsE/9wxJOJxBqAsh/CsOLjnijycEX3TR8RPfvlUdMFGBaAEThzGaz8ACMzSrnWK0HvDHE9iiTVCXRjw6YdmlRsozUvmtKiL/t6uqy03fC6pUQNVUpHOZ+RU5HCZ3BrMTxVuDtVU1W3DTVKYuUS11WmX1qrNTa77is0t9Uo2arY26eg0Gq2DVsBOPF6pildXW2XGqHHQDIcg4smLDCnC5OTaZ7/k5dLnduNhKoy3DaCFR34AuQQM6ArBNm52AbOPhULQ84jHFjiM4NYhvZYfaAmoqADYFZRtFKakG5FcnspgNS85QNarvorm9kkb+JTWbybLS/OWl1V1nYRyByvWVSoUFxRacerjdsKIqLMMrZYmcr0hAvkPNGSKxh1BUyUD+lIfYqumfWIxOxpsGZLCcTZCPQU6etifPBoB2DGA729LO9L5/GRVZXB5wCTtLXwueByQZNLCPN/tTy5PagzmwJWunhpnBznFhZBite69O8mSPmopuOhnAxMlWME1nHbH8QJJKYKPq6ucEu4BLBAdZcG4sEA9QTFHPDt4aXrnmoHbKhSkFSTgLg0BFWUAiGw+Ylh8zaHyPZ8PsQRXHdNGVnP8WbsBnomU653fVXHZgOu5a1GQYMdZJmykTaxpafzaMnso0UjtL2GJn04phKqcdhwXHphhiDjtgHfZzdjcODHKkZXgePh425R0RWpRMtBlvWpjCdonI/D7jBmjTMGt7/sh6BZbZMkZxiOAIRJjj0H4ZTVjJhGJWBLJkJQYBKgN2LxfGP5i+cddmYSpTonLJYIPPBNg7J+6kp9nI6ccjpAYKjr14KcWyDo6B+6BZTTpPYoZHk0YbWTiAii81p7PAg6lsLwlqmOjS7s3z41hkr1Uux2VCoK28dKgG0cPCiP+QeK7POuspoY0oHXY+zSIRiQNNvI4gqSLzsDDqFwsLJJ81jeYu3u0qhu7S+YshxHPYh15s6MZhPNRPTMNtCx15LhcrgRxbIUQ95dJGEPdKO6VpDg03aBFzaF0GPOMBE8M52xvHt6LSI+eUltoqVOGFyTxIxSCqJrTxmUEusjNnDkSo0ZQNLqSBTDIQjdOUiYkmndtZRz3NzwGjv5ViupO9UMgAfvy5QWUozFCVtNtUUNAgJXhHmjGvTdrkpE7kw4lNpQX/5kQwnUWTZwohNFZeRQQ+DVlRcKLncGKa7k4QzKUcxFHELbk5R5HhEe+9JxNhptKUJ1ZWlCF6oOIsxJ5i5DZPqx0m0FMCPa4OyiS6U5Ty2b4Th1hF1cQkMgE+sN1VmNxHWqPqqk9Mje94Cn2JEtXJEs7gzJciHZnCOBZkyL59tJ+E9VmHVZhWEpFHyesKfvI8PitR3eW4JNdrsJeRa4H5HLSqfTOwagLuqH+SW1xgaBxOknvosL24KEuXWNXwLL4qMd1qPC9X2zBXcFFy8cy1YVPVOc3lzLirUhyT6MaJ09O4mTZCOJ3W6s2T0VZkqyAOt2Ug9Pjg14WalHmb4m4RsYyu8/i8ncuxEJ4cPX6AmGMM8zOYZ4+nof3QUhvEdm0NetdHFwfGsgUbQXzrJW368iiN43A8kGMCS7HLGYC9GGzZmPVYp7c50Nhaz6IsyFBYMnEa0d6bEefeaQNi1hiNEoZRbzs93sQB+wNltDmCkkjyukmQDBgbhq07bSqNrjgCKSOmA4T6rARbjd24Z6yfrRbPs+dHWowB5xhG83o1CK/z+lLI2P0S6/o5MROWP88r/67oVJKjVLNcii0Pt/oGAlIBkK5ELlEx96mRZ9c6mcr20ahlGymX6AjwCz0uP4KiEkdBEaQkuo8qPqZByHRXabKw66N/VU5RjZviv8SEjaAxDIPcb664FWCd5AB5YjHGML97QOnl7mKTZ0VHmt03G1CYj6Hk5rcyX+ggkyJFFGbCUAEdPwLpstl+ywuo3noHABW1CCoRMiesw7oZXEYzEgkUr0DCCGzdskvPheWcblnRXa5KylpFlgFdtQrXskch7cZ9qhLkRbAIDgSQgPGMIJ0/hSjgyqvCyZV2SVMPf6C3ciVuFr8A+RUip7wEcXoOh1q3EqzTHCFPLMYY5rcPbK5G7CrBwIqONLtvNqEwH0PJzW8lvtBBJkWLLMyEqQI6fkTSZbP9lhdYvfUOAappEVQeZE5Yh3UzuoRmJBIoXn2EEdi6ZZeeC8vZXQizaSg9rlVkCdBVK3AtexbuIBl8mqk4gzlWaR3dBDQ8aIUKfJEG7Ef3YjRSsS5vF3VVUIEeqsKGDkZEq75n04zzPQpnBvaE6Ko4pucSwEVvL7hLBl+1qcphh+yqWwkwkx4IyhsQnbZtmKLl/F+Lpj67IzTkdqaTPYIOlJk52JMxVanpoj2i4jH1Y8xiWa1D9z3Tqo8t7s1QE9bFX4I2VqxnmwL+/D+wY8bXPkjee9OLCT+ilr64Cz+pmIeP+Kmv08vpwzCHd5ovBxDMNqEMI8fFT03Pp1ePtjzhi1NJzzb9IpGk4BsIwcaRFTueQKNtEB0o649ctcs/BaRxzJjpbFOCGlxfbgbYj7Kp4goWZMb38G879rvYOzUoqaW1s4gRVT320JRFCb/K4zKZTFUBB3+rKoyqFqjJMn/q5TwLzqmxyKCiMeMJ39cBHVU8ClmbOjMpOvuh7kBf7VvxU1f4zscSe8ouKgDWdYkU0hZ4qK0WtvCeto0CDgWj+FQa5BJZTe+mzkgqtuf+VSTe9zU6hTf5lzFNIwxcsvHdS0KeTcZBljZRlK7R7upcPv/A+gaB23RQQGfr5XrPJk3KI2WWO+w3G+EAmqftIwpSpthQyhldnAITpEGF/C9JLIKiqCZaMRlfdj4cOzDXw0wGqdZmCBIWfakPqKaQUFEjUWDLwtzLEX9ni5fh2yGmFJchNiLaXOaofoD0+ti9x3oFGlwm+soXY69areCyjnG4hCFdX2TL/dGQ6ZN+xV1T7KPpceEQ0QYPXhQPhKa9vUl+05RSBWa+yky/XHJjUZaGoKt1u9wzSRfIoHOFMgWDijKzVCcg5m2WKG2Q98bYqW2cv95B39Nn/K/1bfN95Eh/vyio8zLy/2vu/Xtu/jnevn39+uXL58+fPn14uL+/u7u9vbm5vr66ury8uDg/Pzs7PT05OT4+Ojo8PDjY31+tlsvFYj4XRZ4fDHq9TqfV4jiGaTTq9VqtUqFpknzpRBAHUMT9F3LuY+dY2Ze2hXVumclT8+g+MQ3GXuoMrVDrS12uSdWxm1XpqQzfRcbco+aa8cliXfp+ftplYJsRah0LVKS2MJ+nlOCBbqjCGqlOVN9KQnVvLan9Ws0MWnQzm2m5uNW2ub4tbfbB19bSS09cs9zDrfvjwqsGv+HR0xzXJ4BWEJ5ISJqfm3PtBMZi0Ph5XkvfkElTW6m0epQHZKKJygpid7xYaCML3V69Tk5TyNYgB+b59ao+5bQudYszhVJhbnpBPUnDbvpLJAVa0oTxcMkWCYU6GRiscWRWpHpAn18kV5cWGK6yw0B0/6HU0hYIu4pzrXcWUwzDZa7+RMVgpeTK7s2FV/3YCb1sDJn0shUoEPtLWZwoUzxSa+j9YQmBgjgUkmaD2/0hF3ZuAWBOuejDD1ehgGEZPJILL/qx42rKSKcR5VnLoRDXq7g4UCSsszv23DZQ0EyPbiZpdf4e+9tk/HunoB0ivUosNdKeMSn9XuNJg3VaZEUW1QkupO9RjtiJACtRIRCc4atsEJh4VJI88yWdIDKmurLDGe+EUCoYMzzrsS34nklTTTVkp1mmkJOiw2uX9Kxcv0MJRCbvtb7F36XP0Q6tklHOZtNmbal0yTZMDlqXpfR3c3LtajPDNF3SK0ebQZ052PizF8MPD4mk7ZAjP96aFMz3aJ6XazYO0LSdZKmikzc5KZHVULjELX1qgDr9V+kLdII2elLz+eLGPuJrcSPULMvaKQVHN0vz+vZmzrBd8z3XDmbpwo5un5Xd2GAVHNpkSiC8gv0pamPHN1TlT9RmA2s0GfK+UKbcaRZF2qs7xI6f6zEdzzDf+ZcyH0w5JUKFaCMYQLRnOu/k/qIpd2KlmsxXGppNVT2bZZY6z4WUud8NZLOo8nkx38PDGNyz6LPMbSiq5CDl/ey4FzFuOcmFy0N9Dqh6YAydbqE8ssFmXWaMeqc4Dm0jMIO7zJSJfGvfa8MqcL+/qc/WywUb5wSknauzigYhUAUETRpPdA6HoesFY6vW3MeZpmUSxVsPi5PItcb2GPJstUAapGjBftx1dqDfNGw3Ccwu4RcL1pvh8AiUUcdJR/p7T9obxc5mU49Peucz7OYWk6Sb6+oFxJGLq7Nlkvo9v3eX+T46Wy7DXbZEq637rFoVQBHcZQLf4FHtLkNrYOqaLQuzV3dCGapY6v/EcNcHO9l3v1u+UGoh4lBsbQr0EXZ+YcbxeT+6zfr9hbJwbrIFH/Dg+6rp6W3WxgpY4TpbYddYDsMaelNhzqrHEEeOj08PDzmATWL/XFJK8kANQap2Xt+N373vUxlIn6D8e3o+g4PJBy/h3MN0PtXcqIrsxFD65QnmvdkVKAbARHqYKjEoWU7pqDR5a9XQ1ra2p2UVopmxdaNzRsvEzkwX0ymRxWHi9pdofxr9VgiwsDUBcbEcPFN7U8rGegDO+gpWPW9kjaTU9e3Hny3TFHRaZIK8Wv5axqVjsGlIO982PuaQMJNeO4HMzzXqhyPXJJ+d8LMByYLNKNcxvoJqHCSfjhRlOknfLje43jien6DtiNbRf1tE6ALEgjBBPthutSMs7yxcE8Z47ehnMDPItacdvH+P75b9UGrTAuWLlVZjNdg3xko9W1ydOVjnQ63LrDwxqShXF/ymrFlX9UI5Jys/lHhZXQ1DXBkeRBPMG6EHb84vDixNuz0wyQRiLp+6PPBRkrzBgBLe+br9E+B05pEw3ZOnTn1GgM6SpcM10JrbccyauRCNSZ5dOtVxb15jOKqT5zkCMD277YYsHia927eoywmOP3+GiGLhEjmNs1makkezGWk1wduV9mh6QKIqXyhUdiiAO/yeI5tjNUynVUP95hjL3vq0jmH9Q/Lq1Jh6+JtvHFJpdDuczUrxsJmq0eGQ1e7IXXtgEUWWDSleu6ZMsNCJjhTd9frXubKUnZ61ryyD73jpv20cmy/566+vc9ZozBPmVV6C6oK7QewUugR5ScaddpI7VvsII2os8BsZNKgrI1/lNMXnoKTBYWxf/mZ3/5xUE/uxAbiLnFtOfk1BUpBeAVkDAvNgy4tdM6asBTvFhwDNRQx3wT4vgjSHJrMxzHa3dHBQPY+KYnraPZ9Oz7tAqzND3Nk4R9RoMicvc03Ep2+V1JefdCMRzGYrhTA6Onl629T9HD4SMfTd4Yn3dj6/9Z4cvkMLxGPjp67JeVuqEexDJo00pgklsrO/TkW0bueLxGzLRRvS6wtwmMzw2cHF7Pnry1e66lV5FEEn7VhVvFBliOGppwaOWof3NExS33XLv93Pk/LHUGOisDCJQ1f/D3kW234IJ4sCH669yrE8iXB9DU+47BltbAZ+to+g63b/7JNPVn1GSQJMq0wdJiLQomT6jFZaPVE6T3+JxNJQ/akaVEgmmQg25TBVYRr2Td6cmhBjTb2GfQzNdH+qJAIETlSBWunm1IatgWQf8LDuS3ClbbEws6DQ4XZHNPB8DOOZCkJb1sDBJkjbI6VMRyvBr7EXADFkmaLKcORC7Dl0+1lvra5OZJ8E1OIg+4/9M2VlrjPAjKdhMenwINAdJ6JJBO+8BjdQ8QYrDWxla4QEoCq1xBVoJwZ4aThDSGNS+WCgKfc1FvaECRMmQtvJdGqjMNiEFcCCEraHYSUkFJWCoxLJJMfnEZcTzhNvOeU4w/Sk+/DKZNrHaaNSdaIpkU3i5ARQdJJDPZyZQJV5MOeX13tvCnUXRhWDYtNrGOPF1HgEgMydRJr9iKxOOE5AdOB53MaJ7+BUejofdwtNQJyby6mbtSYfwzhI4lQKarkMFoBp5WpIEzk2Y+2wrY8iIHAlzKDg+BJ9ay/HNzjauhu3kBGQMnGYDi6PNdulCyj22NYbBHbQDrQIhijMzdR4MyqTqOaK7hK86IVkZEyjxO9lB/RIxOya5TMwzB16URqximb0QmMr4hafFoWY+NuIEd7oRI5BN36xXdekglLID2wbOj2d+qrXOa1OR4sxRMHIJ5hCuEcCT4vINHT1ah+395dpxGlCWRYp9Sz+CkYpxRt8tJWCF/OqE3un8qIkCvGLJWZGYjiyFiU10KjECfpBvAxIDSjKkR1Y0I+3t0f8gpQxlA6HaSv2TxktIComYGQ5tCv2U3B660Osb6RQ4p15K43iH7xImDEOWeyFAR8HiLFz4k56WhjRmiD9o4cSbr9MsEsHXD9dn07bOou01HuGEodlcN/SpdNRnGkhKUnNnMt1TSCTDpcfyzveJYdecEeuyffQ5TV6DfqvlQt5eblYP9FwFvpvPl+nOu27Mb0Xw5Sm19N1dEK+iKb6xJIyruMyHoS4uJ38OebM9fAavG5XU3R5Oa3sDE6sN59fswci9yJRyQFF+8IneWlfdEwRdSgHk8lQHJgZwB7l3xEof/Sy+vaknGFJyRSnpIosz/sxzQGbF2kM2LFdFRNi29iUhF085lbZkvXQ1WG4JY3McvNSur0ci5L0VSavnnZNX0ziOsufKIX3tysakBdJjVv4oC9bt6VmeQZzO9K85ZfAcGBCJZ86fRRpoNOKGUxkjZIvaSIp/g1AL0LaoprGgd8neo8UAVd2SD1mQ0s0pBXsNabGLKsGT7sqjQCzQzQYWyVKIeutmqsPeDJFQaKcyiO5f6Id3OsSdYowaxdl/cdFOLuZxFk75i2LSiGiR7F9Y/RlDC6TKDP2EMofP/vlk6JGZrCOMTXJTFlB+kpGnvGu4NrKqUHBl/vL+07+Q1HiDrWqSAiDotGUFRlbJYXc0yjnnyOtXXJBu8ASyfKCOelR6og4T0wCwCMtatWw8qg+dx51EDr9OzZM1E6/+Fj+REyIitmHYdAggblpepeIkvPFvtI+J6zda6LskGQ+mfvfq4uIzupm7QlyUzIA31V40mRBnx4NeZ8rUoJzKRN0KEORkxWPcixyFPE/5bbTZmtee14U1F6MxvZ2cKsea8t9E9n+VZAp2n6V0s+kAnVDYtrPS7qFup1Dur9MBHAuRMe7e8MZ4RwIDqKBy0VX8341C7xDzCH+2WWDu9G0n4+6jqA3RHpusctFmpCiSzarWctBZA8S0LKlz3vY/P+5LZhB97IntK9f4UeLbZ8H4aaJ1wvovf18dn3Cf8NN+WzmWq5PWHq4biq3O8Fs5bY31VcWvr6my2qz6VZxeUGJWV+IGPHXtur6wOoQBLJTgMvwgOeqFMDtmHMKKpMgEW24t4Qbuw6T3sZRPL/opqk6Ic+iQK5J7UXJ3Vo+t3yO0E+HCfqXVbh5GN9iYn1B+0BwliAWNubdZCOCBTAYRQGCwJ8ydIkRRzGJ6vBKQjhwLhBKqR4QXM3Yggl5iFBqIKxQplxwNZWKow2jc8XVQ725hEAWhlNumR1dRUmjDmAdKCkY04TU1tQPTAXW2ADgw64mec+2sfCWduo4ijdkUjlgCOPPPU0ZZ4F2IJf5c15eMp2EHslSsu40q2/QyZpJQeh3TSpJy2lc3zrkJemQnJRgzMKRJLuS1L+9OLBTahvff6oTWjazqyFBHTNwV5awEMMT3HY63/sgmhhF04Z4oM5C4a247+Yp1f1bB9OhMvAArQ9DKKm0oz7ybWj3pJEeHd88AL+JBTkyuAdQVMnyNsnj754hxVnuPGkJtfaXuUWiaNSNanmB6NZF7vnksrarUEn16JDywiE6n3o2gsEwpjKfuXrLQSNGGWW0hDP+ZovJL+h6ZSjmIKvvs6gjht7Gyyw7zNQvZx5OCU14fCJtQo+7nqM24NrpI+pqDUJqBxUYpgQGBZ7lotDzPobJNjG1UZ70pEtzu687uNXjaTolk6ZBzw0ZyN67FGlGXZwGnAojXyBL1s8vmd9C/0NbgLE3RyrlIZyWXOd1k0nV6MJUS9201W/vHwz11W4v2mXQiFNAgTkj6I3+yV3aYRY165I64NwWyN7qM2XVAVgOY35TYw3/BEYuKWJV0TGTZWxGOc4dSQA1mVLMC1YgpbnSzvnSUk0e3TTVLNjVGqWVJdWZXM5V/smMneJmIEOHSx0G1rXMkupRLHWXdIeKA5hnDJJBUwKTXNPkqzggAEObrEsbWEA7mug+RRg+Y2gIG1Xk5P5H6hTv5AkeNGFL4cllg8a2StE4TOQ3j/iaplAvNQpIIArUjhGa0W5teb3dIrKV4cyO6GzWV0WWXwEhLe/dH9DSKz4OZY6s1sbA0axPGBHG3J2oY/DzRDgnqEzeWQ3EmziYWuFfd1fm2Z+CLyx17n0NuceD3s+QUQr0RKeybXfuyEmH+ubRnLZ1Q0e/Ung/ICt04CRTUj3dumRsI/Ltboukpad/f0ymnDv9QMkypfR84sCHJ1NS2P7Mb+SJJvaHE4qDxGhFoiJ3dCFKGSqY05P13GIPBsO7jqAnD3am2SGU/XAkEASWk7fVjHNnnChJQ9WR7TJMLYuiyPpFsRuHewpOJe3PRYYuh4y465h9piurSbKmckZopfxBW9y6rIpdEFcxBZK7rtGYeBA3vgWuuAjhZZBf5C9msrZ4vhyUKkt3u8Ts+cVyvDU6AEnC9hLO8ty8QcUt0ngg6bBm9ITPaosI7FI5iX0my+mc4TFJ8tyF8xK7Ws57scWQ8ylJRwDltKIMRv6p7AnUIK3ogTeRvlq3E005WdgF0xUaEG9kT1T+MMp/oLD+NiaMqxOdKN3oHtMex9P+t1gx1DeFwmOS8c6V+LDqBwxSban9bvUv3cC7wb2BMVj6nEw7mE5HsMCIluLMIMsTLuskbyujzNMT0xrFg9HlhGgFCnXVDqsK4r69LuvsNozJMgixNJFsJM/blIHKdQKoaFZEusoBpeu6oaAdvvM8Xkks5f2h/vikzEPrzOTzcli7sK9Aj1DqAh7AH1iqeJXJCDpXpYQ12Q/Ogr6KYR/+hXUdQ0V17D36THbOQBhnnIlnI7/3bWxiMKC5/fRDwIkSmkhv9Jms/CCnTaWjHNMFczu3toLjj3k8Xv2Ip2Bsa74A3RYMDeK1MklMs8hMPjp+E3syM5mhJpdhnKouP9yzto1Q5fEbUzkaSycqJYuuor5SFEpXsR/YpFXdDjLpkMaUTAVtDEF14DTEleHcmEbQ0mUgYeIEBarkFJWy6zIfLI+MJ48GV/fVdkjoVxPor2BGh6UCcmbFK8oZyQbyl2CbarmCMJpXgUk2nd8I32PO3KbLBxR6LnHMHrX5NXIQvHlThKuaEYuu1hiu5S8WvkJu5Lfv7UxY+Cp/B57vH7vkpLu+Tb02o7gtU8pOGljABq/T0KIB3o9ABcjCx3QVMJPrYd6fwMsgvyCocSuC52+4mpIYZzXxawZ1mtgGouHC04aiaDe2+g0l8jSwxZ1IgBiyWoTNJTX0ijrfczbWrjvCKlyZJ/bU2hljZk41SBg9XP/c+I3A+2XjPx5xjY01EATe0Mb20yD/qfHZyEY2p016y/pVW3zYHGlhKgqGjooeZZSs6nBkVE679nCYiPMOsIho0eR0ASZ7uab7eeEVuf93r5VMME3nOYbHfCYlXG11iKJqjABKYlNB+y9w8cn79cwIApeX9xcTUrS3x/rTi8sVAxetv3Np5RNebWRPaJ4CVzZcXSOnuYCHgCKJXf412RWUy/TUYxkPprWydk8796u+072I8sCLy/G1y6SHWc2v8veEN9Z6+pUqzMDOBCh8vBidrq7O8GWd9bhgIXjtNiiYZUWmcjTb7uk0Elni1Op7dk1WyZwIM+W94ngx2h3EGWtKoV0/PSqiQGIwoHn/ArIR2dKB169X8xmchDFvSUrULgl0D2GnhPNgnO/pZiO51pmDOplDgw9Wy7Hqm37PDFoTV1NDG5WpPQASpr8kUk+bTzJpyKxXwjOBOVFDrBssbGeK9P9DIScFAYKjnuTGJbD6CpdapqZIF5L53qaXTV1bibbMmsaIM9l5CPK1Q7VEaDeE1WgfYgvTWIVVmphXsoy7ERWIt8LmQeEWJwIkneX2yqu16GDBl30QXs5hEXJOLS7i01rbHJyZmJa5CQpO2w1GkRrlMCHwuDqrGaxivtLm1O8glhcrn716g+QUyBqhDr9oW6zT/oDOzoIP9H643jOtpooI3UpV5svnUG7gzOlEG5SBc7C42Rjbi9WJSRjVC8UPo+lYbCiK+ERD2Vmg5VtASNy3ce785XXYuyuYwsjy5xerxZ7t1kPW2QedlLzRmh0oDJ6H1q+0Y3TzNoRWagnlJ5WboEF7R68nrX7BpeNtmvITJZ0UrYmYz0lRd0TGLEjtcN715nwoHUReBsYoSEaGqtC7UXIDY27agx2MM4j1KPDBylguphPrNWlqGj6kXnwEottv43RMpiOpwK8myMdL/KIyZ8Nkz/FmYczRXqWWuCpRaHt2ntZhg7ytB0/ibodJnr/D3JO51vYcYp3Rdmks5rMTq5VS7hXdGZI6FcZVmuT57NoIWqR9SjKG3D+PDs9UvlmOe5yDvrsko4FEoAsWyV/M+TzOUbu+bTDgqgR7p3t5zEFudxCnlU23/WlYJCctkU6xDekMpEZumQTHHDjNxkBR0aYDbb/co+2yxoGt0Kno5eH9aTc+XpXbNvKjOcRVbUdCu0ZlFvoNaGVp5Wv/e2SBjvoxSIwRrGZkqW4KOklCollmoBmR/KQBUDmSLWr80ir2sH+iLvr8XSNmPNNEeQ8Ws9hpYjQlqwmkqpAH9EBiqrYwm6bJHhgyM3pgF+tN8elQ+IpqmdDCuM97B/PzyWDGnZnHZ3jzov42dREhkAxNZZRjxxlFKDdpYyFueBflY5oDo07LB8o0uSt//YZsZoLQ/goAvIuP8SlyTBJ3nQeynuHNUv1EyvxPZSh1BzxqR+Yb+JGw56+yCuVN+ruKvwLqt4SZ8s69546+yD7IXmd9Swrx0pu5KAbeIFD6Ef5R9UH12u6LrXBh3LyfQAD9EuDIAVcf/jlfRLyLiOLKYXPdlnY/vY8q9J9+DCJOuyDyQPIypwZKd4km0PgxXISr8NQzL72S3Ym78CHBykJuL6NuJg/7t1H8LkcqPNhxINFF9XFHDPbNnbhcbigVd94fbYVPiLPcqd8vN5tFFISvb+q7GvboKSOV8E5ue3q8PD6UZP96qFVvd5/csgPST7/hEW/+lIJ4E+wDHIafYrRCZ/lj/hG/5A85cz99Cj2AR+etvhVJ0AfFyY8BPEbyw8z+lw7A8O6xe+p4MhhJ7oMRHLJWhkyO0f63GuTC4laHZXTcq2gSkc/FycPedcRGO+ugwQ49lWKD9ghT9VMJWgVnzWPzUfIy+TDJSX/4b766o8Ev2IUU8Cb5o4aW2stwliJ7F38BSnyYvAc1IJCU89vwY4Z3/44x4ZlaceTupCO1RkB2dE9xMh/x0SjeuRfu0+Yl9wzWz3ehyQ3+94kFZQd9PXgVyDT0znk8K89YIvLsp+w25u1W5luJCBUAjn4Vxfo7lVVhiFYWe3RLaZFleY7c4MLdSU620b2xESIRrptgkQpE6PPYVyAIYgweILVTCbdH4d65TJ8GjL0TGF+RQivnLD2mjwL68lSGGNAxwkRTvuuhSfBBXje81feGP1S4HMnSPvxbIoIDAQt5TC580NES7dHD/MP8f3LQ3Wh6/GIw2wEwzkDA/MCQGdz6MH0YTvn/BQx94Mtg5f4C4wSTYQHHGin2sP6kH0xpKYqYs0oIFYBmiXguGFbdtAS/AjJY6B4QrP93f4LvwKpfG8IWaB3AICTyc860PVMGgcRjuTUIPb18fVNILpIP4tcTPBu0YhzVphefxh3QoUf3gA4PysGu3rqUlhAFoQKhoErfSJY/9poxt+9XcjD3bD3k98V0aa2tKyLIfLUIqB1CJFf69Im5SdDwSenHlGqjuFkUAPDvyOjR8WbjUNMPim7fZx2nY+znoF2bhHwN3f79fpCh7FjSB41tRfm9VPLM8qRGhmSbhoJ52Me+Tp0eOUEKA11n4WEURxmen09Ww3IILgvMhOmoyEWWb4Qg7IFZQJVCgG8tqoEUXAe74POjL7iEBkF+Mhl8zFdBhgm62zcqq6Yl3zU2nWcXZJ18cH1h7ynMo5UqANp5XhfFWniCIuYBxJZO9t6QLNdUpfCZl4AHugLjOWFPdCwp4YD8jSBxZAILc10aYdyoQIJC8dIQSZc58GJUy4Diw36Kwxegsi+TUD3FVuRVXfNPVeHBSBAC0HFLxpu4R8Hmyjt1kjgNmgA5UxgU8GsTro+GYeWh9tXiEN0BC6oYZNbQfhxF83HB97sSy7FE7lR4M6/kAZ31ic88Ajvg82zPthaUKxbKWgNQe2QmwJq8CGViV2jsHJ0wmE4VtBrpeXV7f9t1uH2/1sbbIXPxJ59z5auksUUXtahFiq0aiheePQ0v2mb7A77+T0PzA3b7iwpZ2biC3DV1HzA8yseltNkMsSk0PugOdd4rgS7Rkrd6uV8GPqsgQgAN0/JZOAPKwAFFHgPIzTmnIfW6mGrcrV5HQtIO7VjYVZhM5LI6AzLJ+gf4vNYOZFNuA6d0fTU/Dc927x2d4trB6cHJGDzF3fGFE3c6bHlGNysLbMzTOl8Bqnx1eVp32lM2ZL0794Pl6ZLMxn1bo0+QTjrC6IcUOHpXVl5mtKn0m1RxUlSaaJqQ5EpPcfgA8vwlWMHTBK7Mgpz38LfmFLn1WUodAvU5dw64MxBvihtDLztUGZyyF89JxblE43H8AV/fG7fGe/uyzU1x07EIVgdFzpTqehkKrg7R+UzofMBX/kkj8Fvd74etwOoQjAzujkB2Z0KR6hVnKCYUdI3cLsmSm+t51mx3dZrZnX61KHTcwHApIb9OVRb9yD1YoN3++Bn3bB6LsSSNptkc6SDchVfmPb1waufzJ2JUF+u+XVwXTQM2rTPsvSEAfN6QGZZ70wMSoE809WVxHyytRkyOCibKYBo633xcQ6+PBTUub7AstRyy5BVPcHadwKK6KzQlzT8wnvm0zmu50YTaUoxg2SvwYuYXAe3Jeh62rrt6T15lgtuqcaqSQVGCnYF7Xh7Ll6XwdOYuXbyWs0EMAPXQZXVmnoEIxHbGV9OR2E3OG6yGltfrmtx9ru9QeKq/jtgXHh4GOqi2dXu8n9H1LUgEptC2Les+Abd2zNei6WL8YPIauovFrQ/d4nSyoS3LQGCvAaGtQy7mU43BQIOkd9wzybQpMXijyrQdnu5NWaj3rESaWyS16xhI9KjICzM8yES5dryV+73VZAlQtV+kOFUS694gF7WIBW1WCP6NPhAPJpx0UnolknTSlDe/MkkYhWVYF0WmpJmkOt/HV2Z9f2jOVhtvrswsDhLeMCUj7ko/3hMF257Xx/plLTwpqMFj+2HonibF8nDPDqtKqhuuZNecTxPgFDJ3SCtqBRY7LRKtVR0Za4/ZsoHkcmR2u70je7OWcUSXvK8baBKkVZ+hNBainjyQTWyb/FhSt0vKwCzvSD2q6b33aWXE00rCOO7K/BejAowoYQeVLF8K5e0cyhTKdUrpOUhjSgLrw92JIZFEQssOzskmVfjEMQMdLit5LXJIZoSUoWRSA3yzewQQhCNQ7RUL6lNhql558oLjaX3kQJAgp8IpGBKNqdcQ1CyUdH0Zl34CZ1sZxldJvdB1GZns5hqRcKPxG0/l8kBq8LUDLcQCUwga5A6Y7gIcKrcOmlyniieqqm9ndPvpycaNbNCGLhxBcpMKSf3nF8JcVdX8SFloxu2Z7D4upqwPftuO5vbwtiUcu7uxRSeXsiBk7FGSIih7V1JDnFBsVpHNGlwbpBAQohd0l5vbcv6rTNhjufKgbLosx52puljr48I00Q5srZQ38Tn5ZjVLqorEYeU5ql0UfFVzyuZ2uyfO1VEjXUWG31DaGCm3XDApRVfrCECnxgTKJR2qs4Q7IlLtGFMQHjMhqV+wNHXk5LEZMBQ5fD9TFTLf6pZIXKL+vi5yM15IcQu5jWFkubkEs8ninezQ6RqWiYlQEakGRkWQUzHlNKwxW9SKSVZb4d5vDFAbSB87trtYmQ33ahL0NXKTJkRcLV03qzE0RpAA9wJGEM/V8mzjKQVBJppiMrdL7A+sp346WAzCk6BbTG50BuJTmbxHObU2s2UbnQUwgXBOOS12g7B/8xbI/w8egOueGi7tDvXTf7gzgyJjaEDcYd95qaeUu50qOaZVHOYl8r+B3ZtYJyascvwxuIWLKeim/Q085q4ToO71fR7QjqymXIqqapM0bcsZd383/GaoHy7/WPlXSjp1Fy4++QJ33wYcdmX8DexIrtve3GR18of/oN5ake003KyUgmIuwsjPIT3pEq/KyIBIUIdedxiDGZYIqxuDTycrd3zxfzJt35SlIzaInE+zMMqFId0q+Zb4Y/VfsYCUmXSVIbYc8Yii40s5WCpEBVTlF0pgv3n3rm8tqyLGo06Nqc7pX3QfuTQ18nkR/XL8zVh+l0w4jw3U5zF1hchnTHFyA71DbBRyIXYCT3tqzLwUUn3pDHId5eggGJ/lwClnSBLN5I1LnALEZfBjFvRjqNI0z6EJ/G/jGGSQZHAteeJ0Wf4C61/DHKktjJ9p/1rLfrhFExRX1qX7G9i9W68G4r3YBbKU2KY2Uuj1Pl1FQOBdSmXlxrFkng9Dr8fA0RS+Ac+lnIWXdtCnC4j1MoZMmJBZjDBitG85nusVEZwX38t4LdkSpYI5lMsz4/KQUEQ6sGgX2sTvhO0kzBlkmK6QGYgCGNlagW8BRPFAVB1S4pjMji1eOpGMTUwgJfDCEGBjMEg5Ct1Kitdv4ThYcswou4R5skB+EwThcI5ha0EfCNpYaUXk95AkN6ZUHAX+aHaKvTqu0Sa8Wg+seRx6uG7OTXVLB2J/H+VTae//FvYA0E1gsc3arwNkxLmSGtRWZ1glWvMqime1LbV0FnZuo6ni5ooHCHlPhDkOoRChsem8YlAShRPp4deMZhAInZ/vPq5veKr0gZoYOhGZUaw2vdVT3vpurUgXvhdHT7VNalTqmPpEBflt7IAEnENRSsSTYTspoaiKXMXTqpcI8FIy4BaQLp0sJ2AfhAMtZp3O+w3c/rwDT0w5YjgKW2oLwCOTeCmo6h3Nbz09TIjkxDZ2W6CQ1T1N/i5IQOJ7oASOt8AA3jX84oNf/mt0cC2+SFP85nOI7ZtjG5u3P5lsP751occarCkkVIa/gdtvputP+oBANCHlBDoUX/IlrEK8QzvDnfpXcBcQaEAQLUp4rcQXVN8qERe9jiKf0KxMMYVxFLwdulV2g2jQnaLcXbHKDEherWvTBk0RBxuE5jyMioywRnsS28tpiIMa2G7tIaircOXp+zZ21XodedWVdQ7yt2E8CnC9va1naRrArtCbd7/WLRbJtS2hLBmGjmqSSZMwclR8gaNX3wIGhiicsgCwylEF+Q83jUqlH4efETzba7qFqplwwzGZtmwDmaS0uO5uS/QXOLi3fJDKEMhVv5gDCMikU38Xd/Ab65QEBqeqXEbbvm7/M3dO4WkqkxqdZGcGwYg7ShrAhAP2PYNDxnyRTo/uM/yUcknFkzPvJvu2oqDtiAJ5G4gY4oaSq97X0yYXvC8SYknfiDic48WW09/DHdCCX9xZ3JMpQ2B9dMPaimnW6YTq0maiLObKgZxGgCbtvEyYI9qYrMjBasK2tMSKbeqX3Hq7OoGQAhelrYIfCJRL0VtLHcO1p0pIHJy6i/kC+3j7hu2UE6r1tsqX8i0lnmG8WBq7qUJ6rXYJADnvV3bMM6GgMeh2bOgV0jX7ZYRThQyfAYTvZ3q7uJvQuK4fFSlsihRHfFFi1OzZdRIwcVQTuejj215Zx2MYnSdpTA5Wc17MZu87ACPYYoLy6XZLCbHCB2FQAaPNYJRhy28hxtvA90OvN63ZdpqI4aRNKQuag9MAwfso0KnimYc56EVd/gLuAC+IVaM4PaKydGAQBMRuJsypvvAjJGvrt/HF0ADBLx/1Ve4ud8dbHVhbW5hdnWUjs+jJndFGGP3Jz2XblQYt6e6RIqOxgngI97spi6cY4FzpXw9VJwklu1i0uot0dLnRDzWw2gSVlTXxpiwDZmp8OQCwr85Cc5lSfydSI/AMDlWoAKrJ3JpZ17fTsGeZ5jSpVT8NdwsAilt7Q3lyHduj+6ypgUjLZNGqkcLBlTkfLy8WzK7ar1Fsxv5421iFEzENJeacxkPQK7PBNkRMql+xEKp/vb/GrvL8G91h+ZGUDHx5Y75kyx9+8fTanlM9b3LJlvPlns8Er6O3nuurH5wftasMzYYf1HtfCfgd01PNB4toLl/87gdfefM9XsRbfnBfGRcNrgbGbn77vps3EkJrsJ77gxXIrb5YCWGGs+BkS08NSafDnoXORdBkxR5+tfLbJOkbOwYrbborMplEu8fDb3kvmlnhEkgVQ6UyCdw5k2IbBNBZrZ4R1l9thm7PTIdjJdpkKtG5C5rpZwxqknAFE1w+cOWbp7kvoda7FFIMfMDLuR8/MtaeVcfslUzrjkq/JLn6mxZMfQBKjiaZpFcZfGYrj3IZwjrhgOs0j+N+GK0sc9twSommOV7SA9FGzQqXNOQErdDNbCIfqkdP5q2lOQGgNVBHqiopz3O5k7UyUVUeobN5kHY1mnbOxOjpeV3CiOZe60He6CWFExajFsZcalgDb60n2oYzzoR6tu6ypsn2zKKl7RAszYbCEnAkaGG9QzlyxIKec+kTxCCROWpKJyimJY+v+QQuIuAeBcs0DVzUw8Haf/3jOsoAqUloHDDrhZjRDvprjian2Y4qHHO4doSoAYQCZx5CeyOK15qtipzEmiGSLVE9P3nkWe8efrInsSaHLKSos9pKtaoLC43vAm/g959eO+I6XLLVqsqbspnL8I75qfvXrq/pllW53d7cbD76+GPzvrfN5mLPDsbRcloemJ8Nl7RNVKLd9ddULACTMACP3NB0egTNs62MPzwdeamWL30HCLse4IEiJsZK11+j0pO1wyoFOtNzmWFughnnEAH/TkGnPGn1hndWPTAUpIu2tVP74KKzc60OrLQkaGmKLNoMTpowrgPpFkdkC+cfbo8P6lwijZacC0FH1mbmMg9Pp6bDvAem2fGd056v7XSzQdnl5byYtxl3SdKvbEuqc+tpt/ReR66IzJu5rHF7TsnR0QWBrQSC84CkWWeo88qdI1G4amojVYNNDSNrUCv+3xfE1eOf0dW8yenEV6lp8NFF2DhdtTzQsR1MOrMPWkCDq8H+jbuNLCK4WEatHKw0yix6s+kjZvFb6vpIXeTvp1TTddNSIke/ZZIY0ClYKdGyV6qc0Mpdy2mc2rZ5mrX9bZV/eFGZ2iD46bRcEuWwyjCDuXXGr5++/fGLF1c/dH/zrANdJ/rSzpvyo9/ZeKNwbN1bMOyQKp1l0ZHh069+j9Kjc8tgLA5epE+zJvR1XGUzckgO744cNuSLqUYoSxk1T5OErqDgfYSPpS+kckjCrSoMt827XccoZ+X5dFXIh9a1x6aTz+nBVCR9A7DeNbVsB5O2VerAT5EoeXBz02n1/g1EgPuaUJyg2nSG8BNu1vtsPi6XxbPChRc3z9w3Xnxy+9Gem/racizcN548o42r6ol8V55Kmkt09Ahb18CvU0DSfnj98c55V48Kauj7g+YSlJJhi4D1lo0hSWuGeabuuftHbkKN2uUy103fno4zWM9IYq9T0Ph1HfqCP79gm4sqnR+zllYO89WRMk9It8DFcZXYX7kyOqPqeHFBWAcHI+RdEDP42azACJdMs9gQ28+1R4VEKNdKzV4QcOo6P9Vdm/sAy0rckjc+2syjPGBpO6y7tpmhxZ661ZXKp+Gdm6+oPNjMg3DM8GSJj6ILDBoerdQ5/9xesaoaj4ydYdSR2HTHpRYdP6DOc8iStHBdEHpeZW5pDXXk6yEOHHXs4VLaj7eGxgL+I0JvyhpVlZPcSR3177nPGZ81eNXOZvOuqRBrrNILY7hczOpgMrR7mM9tRPNBZlG7mg8aUZ8HNJEfaiWiCzLlyQpmzIYGkjCJQ3pB44Qq13n5nkZCylZ+5DiStJvpHaZVfHODLGG0S/Gpd71a7MEbNn1Fi7EaFcjXDyR5EqF74tSNolLu5i8y2QLlF4p1vAXrvbdu6zYSp2w+LwKEsxitrU1G8+bIrcHE7AHjEtpIqVKr8iFn4H5uDpNlul6SrvrYO2a3vdnQC2pvbOZz+9zK1F2HLoyZyvMY5tf0Q25l96ocN4t6wVA5ciEcMTC0aVZ0W6+goB3XRfO5qfxa0enm7OGACkCtB4Ja0xwlPPGj1JlzY7G57dBaX5sX4q3by5ub1ZGT2lTaxldNG4soPuAM9RXtvGRPuw00bJE71zZPrZvPr4u8yB9oGrC+Wo8HDoytQI30TiDmkeZmcBnC1omPQ8ObJeLiopdR2y58wp9v6K7eQEHvwQk7FtV9t8QbXRXWgNeUR1v49rtR31aSWKketZdH0dA32TcZUu6bQfBRSMD/Bv6vdn9qhsM8jU16uRBJQi9ktdsfqIJsjsipMkS+9HfH7vOhERNaz90ynWtpk7FShpxKa0fQDsmPkbWFIMF5hbOAtR2FqtS0CNkVsyHeM0vzutZH+prJRF3j/HewiTIu+cike+LS9Qz1Ns17OU29WzaUX676tmiLPbMyBcOQ7tHVOCzo+feZmFRvrJAyC704y32CEftlOoag9ktjrq7R8WvmxU2dtz18+mbyF9Pr1+DXSGN33tMMei5TVPqKCjSfFabADsdySuExbNy/hOK1UPy28razD4xS3x0KAJWDDHXRuv3GCBRe28pCi0/7uskzKdVRbn2uYi0MFJU17i3vq0Jq+Tkbcy7rjGoA3qDVgmVR/iu4BaZQ4O2mpNT+VXzDTLsj7aBU7DqB6kVh1LkmRVHqvK7kXec8Lmu7MR1Ann8ssEfLfqcdqZUNNqemQOtHjqc8Dg50mwDjTEbXXPCGDCVix2Oi8VhsUeJdpKNNNdecK93uKi1t5Jwo/Ch4LR4WobvoBdYiQnfZGhRgNTH5mcwb42pJCPjuGzUZUtHcq3UEExp+Eo7LhdvtB01cFJovcIDt3Are4JuyUNHuDr5WTmWB3Cf2xWJa5eadzNz7OIjhvON1xJmxVK1kNVpboZQ7usdTcbMmPEbXt0GVXaymRQ177SnM8da7ORddJxuvFnkE1sqbQwLkVCULAjj+RU4A1NJyU3tXSYzQ+9wqy0C9Z0qHpBnoNDfbALbkUMZfVe39v4E7r7eWSgyaUtuZoFY60LJvh9jK1u834DCNwhZeY212zUdVzFZBR9vBW9q3I7FhoX/3uR9h9WAvYEmCYicE+yigM13Nin8it/CnCaYTFUslY/TTySBoBV1y2xQJHbz9+q7Ogbn2vtZCQ3MsuoUhwG/8t69+MQ2YvVgitRv1NXLk+lOHXrQStM6lvOnVx2FU+IKlb1fVBYLuzsNXuRLHoZi8xJ/n8yGTMVe/jFsgxFvQgcTbBDTiDhHqORm0EWG94ZomEMk50xh028dhlGsgXS98xVt23iVHlmD6EfBIFvGlpg6Qm/jm3u30JHxCKs76ydwsal9NVG/NqeXrIOUsyBBGprejrHqOqjc6kBxej42DG3i78Wrfqi00hTGLEZlXTEVoqqZ8+Q6B3CV207dJkCl1VQ/8LglICLxRTM1Kk2gOmC1cD3gVWyTT7Mll0gdy0rW3vhGhMssZU5lB162K9IrJrc5AXutRp96/De7cQVl6zgHNhHmeOjLrfT+bPdZOmTNG6jgGkBKGz8A2mMhkk5u1/SLQnVNlKkgQG2RRkR6doppd53L89McrV1YAtHXgb1F5Eji0lu8E1DJlfYo+sPOl/+0AvBc+lF2E4Zz5fOlVDaWh7CZFpzQQtOMwqEUw2Mpuz1jCbuevmrJA0ozY62H1hkzdCEm8LJ0oIM4uQTndUARLWvJGTWGrzzB79X+cMm2XfSaWiqPxnnIRRVhmFuJgJ6ShgQcgj2FYt8kVdEJMwTKW4E1gvbEYo2WJgsB16z/qv5YYN9N8/BL0G9fOFx7qbtfPK/JZr2PTA5bGmMd0JmEBjAO7WzvCX4xDYSwLRnIVur7XIXeee8Y3PWhdqVWeW+lB72go04FtQ7bR0g5cMUw6TZuenVot1Tt3/Zin1j/KN/RqoQM2Hnnbr2HTDFEMfalezyIMQ/Th2mpn12ynHWSmoT8nhxivby/San2+Cb3ycZgihbY+aEhrR/bqW/hJfmOcwCB8CmNvhpnywIuX/eJT1NJ2++FZx5ZFP4Of4nctzgp3JUSh04JQGwBKAobhLXg5kXjoM6n7egx2vVHGTmzwmlusMJ7tAZ0Y9mIuaZiMUaTMZ16bvLhF77n2I0S/GvJV9sg+ZR+nLRTFHBoFZqi4UWXWy0InTBgQgNpCVLcwClcRCK0w4+C/C7T75hWPXO/NzAXObro/XgxZZEIHaGM0kX1968kbp716583NzdoPfcFIDvih72m0N6+Pnj+JtkGNtpXyvcH56yTiSFHPLWtyCuy6ecnQj9riHUhf8JUsjVbDECwoJ7i65mq9ceeS1+pE60rqxa+3Tf+GBvVBUUJgl7uqwIQWySiPdlZb9Nx4N0GYnWQaOrR5tPYUOzxaqOp70DuzrUg2CW13+fevzCTRmA6VRKFdvOpGM8O9RnB5n0nSDHSIgzOZR2RHkuswTsZj4mb6tEWKL/PgyVXGnbt5jwM03nzlj5Zgkwm8c/mX92/Oe2xpnL1/bQmar8lY8HxFGbi2PXg0WlM0Oe0Ehn2OJ1Po4RRagy7tWjPpeXCzBa5p8uruth7ojK/3a/piyKs+M9eHP9evuxhHNvz3pmJq7cx+d6mvQ06bVquLJugXLUaL5kWDsW7ekOS7vXNa4VbCq0a4Hwi+vq7aPvVEtcYIvtpJ+f4B81ejGY+GGjIzHktJEtK3rjMLLZmgDssuLsbhgpR8FpPa0nQBzobUQFW8579vFkytsf9dRxRUY797vskHaZztRoaswLTFIU5kbsXrIDscRfmmHyDa/N5wvj/QFi/QFAttChJNhHRKdk7aAtLKobNlR1c76z+phhr26hO5/xhrwVAa+SyNTqaGy7HZbDx2vd2EJjdc0YpxUrgrBDMynz6i9xx7wh66eJF0b8NKByuqKZ45dv9WV5QnY2Ax+pWWiRRs5NrN4vDFhU/xY/CWf16V/O0x7eb+vA5HN9UaBXFH1vPOZf2SgZnPQ6KhRRcarANG7MzKkwKRYBMJNrk3jKvfO0g6DH5jmi73f405uDY9bwiMAhahpdy2dmlKL6ThItKtJWME2aG7gDiPRe+qDL/sQcOqnBEBSFHarw54UOxv4v3PbiA5KLK96KU7+RF7D2pKMUSI77zHxNebIMTCA/pGJpRdhAh4wIJHJjuJzPird9i8Ck3X70WiWaw+3uSfElFw+w5w2b1zOgAQlPxb8yJtiHrUE/qTXCcHeV/rp5xR8kgm03xEr6schYHgjsNKUyK+2+AoSEynBjFYiLkQ9VWCvUWCltyy+qv5n0Tz3QaqdVKu7D8SAuE6IVQDwdXCSgYR3+02VPZ6aiBwdENmdzR/vPPZUWveKjAHfi5A34UDlQoVgTMaLXYNVju8b725ShkTyJJjrbCyJDJbZU2f34RzDDCmvml+H/OEUazCJvZNrVBtXifI+rfm9SMO8LEKetp7zY3/TVErxtukU62PpIVth9Akpif5O+kcxeZj4X2hC32yooAU16SGOvOsoObTEj8y+MsLVjf/IK61Up22tU9SDfjpsi8Eymdn548UlTqJOtaRz3uc73UkI5DckC95gX6TRGMV5QcpqEjvo4EUWYpiuY+fFcT400db0SAlITYd3wgPm0eMpqi/EdFJpxM4Hmt+HPpAdJ2tWSC7IXJ62PGEOEXGEgwN5i2CkX9r3mX0BEE3FSuj9gTN3adkOlcRYCX4bTC6D20Vl9z0lUEAUvWX5/OqVoZF74OoAFGCTKoMqrkEjenRatrEq1ewc0Ah2dGI1mnpcQIdigmYeuNCkqQmtFywPFGC41SDTBkRtPH6k2H4tbPvSPFd0Oh55WoHq/nXLL7Xb2rouvH7cgGdRYIhLIJaWe35R2x875s3FqF03mD+cTAqy83P2MlHiISDxuuX5UN6g924IrUDjSa+nq47RYm0BA9BdyaECwhuTOS3madxd0Yy77U2m7HFK0oR3P5E9/tHdas/8k7RQDECOM2zKr4IKMquUGBgHeiHrhWdeUtt+Rs4sloua2OsxIaBlroFL2pTkETPLq5lc9VoPZ+LddGrpGL/9ypoYHXYqlyCOs+JL9hw/ouKINEvXPtx6xai9/258R2uN3VWM9vp0UjkfIhN3kMLctid/xYwYquBi3/XgejEzUWeNwuUypW9sQHMeCpcxFhegF34hU4bYgPetmwVIdgwa+icZwlm2aNMktWkHfJEEjLTiS38YLbZe66tRBvEXu7gm5Y/zlzhgNzssok59HYnFffjrtWP10dV+XrfJbdrG7XUCyEdKZqbdEBPtlOR11RwM2ioQMaTROtr5JqBrh4Ven4t0XZ5nNzU9bT6I3bP3ZfNkbBm874/qriW76vGLh1txvG1YZ/l7yLy8TvPHHvKnrBLptvvIPr0Dr1XMY0hE3bikulfocMT8B14nhvqRZuze+14OEOE8nqzel1NIijqHj7JRjduTJq9U0xrBf3kqXDhTp9RYZb6O2iC64MS2OdHG56AO7r4QbwzCJXUZWICBV998glajPDOeYbNPvgKDeUCyos45PJPGY1W0c9r4tBXfYrnKUUDRGVkgoZBqD1WlLEvExnHU/FVAMA5YgraiciEIkKjEPah/A++ZfSuwnX5BMdjDIAJ6bjCqU9aWSrOTp7GSO2fJ/Ipl4ZISkBHRkwmfHBD4ZgIRLsYBePEvinG+ueZGwNWBw05JAwaINZtg8zfPon/lFAB5UpMjcJ2QRWCZraLi2GRarrvtcfeVwISPbG/XZVK+q/OBHn2ESzJIUGtMVoGoY5yFJSFNvZQ1jR5FLnNK1jO8r6PYKKjptMSL9MXv9uQ3V6EnYn7VTIYXMeYN4o+ed61IO5oeuoNQsSV341D2rY0RdPWXWNz/nZHAnH0+Lu91b3IZtTZNukq5xndBVZxTs6A1EBEMTn/38U4Oe+vPpsIPhyx/iVm/Nk0uOlcx2MtmIKMPfbAfU13PUu7EO18kxw5YHn5Xdm1Er1FJxGkXMagQR9w2PbdU2P6nmLNvYkh3jf+jWYAVWLczw2Evkxb3UR1LzRMix4le4AcicI+uPsZZCsLUJIbyYXh0duut/bHRZwj/t0+Inede4iQBFK9kUHWIq9ibshNSRMvqpEwSo05F78qqfiNZ8oFfqVhsOXZOJxSAXjGR3lm1Z1G4DGr6sMiYs03yfu1j7WyRuyNrRH6PcMxKsrFd+wuA9tp2J1R7dY4OzrDQ7GLvyMrtDGPcTprlqEDLCs7ONGHqCCKfWNjU0KXoWXURrMsgEZ/n4BeDLVqjpfIcoOk+OrPJ4HkrItZ4Ef4YAAOVRtxZ1UGjdJzCovhgz2x+SV0psMK0yJJB68JoyuqqymcQ3EsLkX5jGIwsVC1pTimC+PB+P0oUFuXl8NR6+hRDjXsrXaQ0OBL5dg/oFt7SwlezG05yVRNsgOXZa/8sUtdSjmfsJ9SPTlkatFkGCthgvyJs1dQCbqoxCU8IiknlgJiaaY4poUihq8AnEsOEU5tgUwsgDFBGoUgRWlgdGNhmuQEOfDNdBd5HLSWjLTdLaGUldNlHMQl1HNOG+OVcwDUEA+HHEpl2M767snLx1eNhuS08ClgafvIZ6i4WtvCrzpeAzhnossYfv819Mjbmu4yb19sHLnrfaYBSRfQiJNtqjv+6T5e4RcbawZrVo6ZWq/s/MtD+/1rmuEOpc/ZPmH7iO2nbI/sUX5ip8ogNeTZaN2iIG+fyAyNu/3C2PrjAG75TH+jzFxQrYcf3K3sdPzcCzfod5FbdIBk/THPVTMueu43kVZTkj+DnOsvRa8epGpoks07sfI/nzaFqWX8lY+G5yf70+d3YHUEujEOY7c9HdcqqjVjSTm4NKENTntWEsnwy90Dj4K7O0EJ4jwaImeJ0GffCvRz/k4biAhFCvH5bVQOmoJ3FVngBLd4ramKjwmPqjLiJKXSKP6nINi/T1iDdQBd4HwGR5stiiHDUJ74nHsSBGULW8drZz46bKUjznJK6MWV7/6c9N2fE9/7BZithj8nwP1BG4TblLs+HXfRY1/Tb1OdgrDaevQhZE8nDUCDou0hwk0ikv1zzEWeMsYC59Z6zTkAsyQ2ItSFaomXEkAUW7RzQ/IlcmQK7o7NBNNO7AtCSggA5CSzytgpidq9R91L5abdS8Ng4tbybdGEIFUHZxHSGuyHlDONGCVjKdssUvwtgQqQbY+JmFO/SPUcxkbPjy1F0knM7U+WZVJTzBqbzErg/qk69FgMAbA2SX+L7A8ejfym+OJXbtL2lxXqIxAs9jaPM9FLSLxQ/JL226v6RTL6ttY9tAcWpJSdQYZaEJKTfQ91Xax/OP/+/KdzJgg1dvY99kfse+xXlLNEHUkVhD23NyAEIbDKDs4FPXXdZxmFY4Z7uIeX2cvsU2Kssf9QkfPfma7n1fsfjNNq5Arg/lYdkONndzWbzGYXzXwujaoQ5LDwkBAvrnR9osh887DMDFJCewZKT3ot5UZTPx1pjYb0fn5ih4DLU0qyh3J0Hdby2xRUxdtOLPPvws8WyyKXT7aE8jZR/PLCpaYUka4bSKlDVL14FuPY9s1VEBpeqXyy3vro8kl9cb1trPEZf3YicyKW2vUEUzATGNYnfKLT47vOzQNo4e3PB1cL/x94X8oZ5F0nCmfB0EIgcrWU0YmuGkHqqskF2FsNBpKXXVifK8T39UPS+nB3n8HQhoaRxC+00VpsToYWkZDN8x70JxIF8KDYqMTNqOpT2c8W2eJIm3YBI/hjImYhuZ/wcBRCbl80Er8QEkBOxUo0dfqgzZVDXRQqCbgM032Ot3CzBIhzeT7XcZpIgWvT9J07OiYP+LNLkNvqM2gVR5+B6nhOuBP6fvws3etDE1eV65kK6rXfVbPPKEeDpLUh5LqyQm+8+QtUv4fCGEoq0ox5Wv1LAD7xbl0sLNd8c+0sd1zgCzFmZQOW8/W6Ccgr15uLEzu9zEQACteR+5YthZs9EhBtlzt9klLcD+tyv3nT+ZKQJq+fqNV8Oz9M9Gpl7OYTOhhoYFMb2eWMsDIM0L5yXaXRejF9Cj74o82iDw4XHePsxFGvrrgUGDwbisCexbWkzhoBUYoi1gkwe5akKt672EmPbb/hXKC9wbPDdwY2tQ/h0KRo0eFcm23doFevUPxYDtI/ncnRJKW5HK1t6Xaz/Eo/TTW2hvu0b+nmeCiGF3/7VyDef4NHmv+c0jnaW9NtM6J2Ij8joThxGdI49Kf/w+078e0E7HUaik63noCdeDA6jftniice1MdxnKoj3jgWR9Mh3YejtSnNE8td3XHXY+hroH3JEeXkVuvpyicqZVpllPhXM21MM+PZtS9pKD1dBF/xUDqNU8JpPoFwSHNTmnrRHKBVequK9M8Y5nGzL5XYM9C6Y3HQjecV/HWanlqD4dMDOdkkWal+Mziy9iYXF85V9n0DvmE8GrlNeLFuhCsEnBpeL+WNC2ay0qtfzuE3Xp6xhK/Zxfx8nmvPnXkOqc5hqTCfTAQJFdCrjBcSTsDfSuS7TMAFvEbU3oTrHOT4Yrv9a6C/C1AWGcUq2Zek7CGpf4GSunhLZCoom6vOJoTdyGLX/Z7ruHR+GQexBUuNDTmwRU7AftI6NlkEmuc7RbJpuaHTn/hGcTE3VZHhWX6XTcJZVMaqVHWXDTwLpfouUm/Ud5ksgHjXgCEVNBoBFaKkziI4KSaSpexf7PnaCk36awA1xYeO88ax4BsFNDZcLjEHYLUVY5KMDQOJpykJH0AMl+hrIENcIP31a/Q1/IZqohrWB46whg/XDqSdtPVcJxHDdEJ9D6Sra7S7ZOKdHl2F0oVdYzIsSwROwhpQkkET6fOZ7DOFCL4L4np6JK7k/ogiiGQWU2lpTyqIwrDO4rgvIqUWFt7Ag9Uiz/LPQOPesVfdz1LmYRPLo+OV3PVhtolPzkOHCapjZzGrP2O6SB37GesQBaNkpI+erk585yjtESSVSqa3kv4JVLSkuo4R1nw3tBUsqXgoVK1KRBG/+6SU6HOktdjXVTwBN9gmuC2PfIsfhnKoTF8vPLIb0qqoTqRj0rYNh85A0PdVo5K4j0CsigQMJTETvq9NxoI/EQSlabnbFh6H+P3wYXv7HeeafPeDaBn1tz9S7K5+9+S7pbOr2yj8tqR+7Cb6XP2FRxffx3/47nvi2/WLE2X/7Ac/+J5vI98b1PfefU//hn+w9t+ocQOOV6ZbyN11db318EQX3/whfKDwS5aHTQYacZWCn7co1jPGwVA9ufbkJpwuzyym+RXzSdQd1bFT8EpOo6QlmSDWqttF6luYzfn44NpiwLQIxH4a27ZwmpvtNbpyDNK7o1nnT/Pt81SLgh3FU832/t4/r0kJ3ekJeEHXMKIXvmH+NeTV8eqMANwkDAg9YiyDRQR7FCqwhJY9HRzQN0h7G0mcSTszx6TsURsWHWJXy7K22elXojTHZtdNTgyxuTzDqxPaqLs+h1P0hXqzD7UFQlzVJct7eep7yWUgQmmy7dg2ve+c1eTTWsYnpiidgcLRJ4Y2pWWd3qWH1pPWe44LalKZsi7HzmUhB5f8XDKmlNYqp1OG82IovXr6jAR95ngAba88cbKpLmhXV5vqFD+MmaA4VFUakqplJwR0pVqMwRGl6diUr6XMsFDWqfPGbIqkRBmaD0W2cysA1vLMyRmev5EwyVa7EimLCtgW1GdX69RBxJ+37ZQ7VLz+ZHtdXb+TbffFud2G/LPZgKgvKS79QZd9Skrc59FJLraVRcsXMj3PvTfLMirmCSTUOuRs7qphoDM/3A5g0DAw6UPiw9GCDP/7eT/2wdx6xGEUYtJQS1bzIWsWcZxFAkV9lcxUV3p5rlYKyXleQtGVqoSrVR8ZGCqKoBaV0jIn8XxJNzaipDEJLcz5fMvTU0NLXdHidIwFrjDtub0H41N/7XBeliJtRGPfAD68/bwUTPxT5o3PzGIZCWxUCdgrtHZWh9HHI893RnLfSElCQXmUcmSIen+Bgqr2wncFsLdD1QcSPtEZA0jYxDuTIsO/x01QlcLBm/V6gsvLDa9miFj6ORlTCZxdTmuCgf2cbOofazz3yh2Cbthf4C80+HqAwlcSvu4gY+nTd3R+hPYbpOfDG+fmZXzxMkfMCX97M4KWjea/D07rZkBTM0qkNlYhXGGobNp20kIvV70YzJpWls1gw2x94gaq/BMZeujYOQ+VBytVnO01Yqs9YXrRa03lBZBlsNfSyuRqtgcBkWlLWtZIutkeSfWeJDdYZ+Qomy34wFlG5haCMuj/Gd0tJK+oGU8Y8wCtaUQcRbZfG/IU3bTO7jl5dbFgnl9FIW8WJr+QSMyUcUvEDmaGwy1v+PbufS17l7s1ZW4eXJcrzznZ1AVh0qLyJGNJEGwzwATODj1gArGEYiecywtPl1nk+7zb5l6RS24YcMafk+009Hf1R/G3YuLEeiRQOXEMDo3uRzzp4hyv3wnhpW3Rm7udi52rnUc7T38wwjA9dDjeoqqtOQBmGBNepKiQT9X84smAZjzz3TYxOTAsiGzXjyXys5O8lgbnvP9hBhGTD+1YMMH7duCYkX6V95t6EoAzk3hhO8VlGBWm1SmQwfBfnLp+JBooHHMAhePnYSoiZyLoiqCpiNO5uQCGSphk4nxWslykCYJWoUEa2GduDvxHTic21LjEXfXtlloOIK+Rq3USZ/GjlDhMdPlDs7XSZyTbrI0HsiY/wjHXj4fx1+jnNdFaMMGs0cSZUCQllv8oRD8Tog9L3LsoWfxMBX8l5L8/Gph5WeLRqXpwW5cj43/a8fEAafEO/eTn04dxG1gs/9XUmfyMFQCwshzlvOoC+cUAwOashNT9oboWRoaZWiqquNHEApGmyc01JeeXr60sCBmC9y7bUnc6yMLsjEIgm0PimLXs9/LtdBpZKgfPeo+0jpHvlAm4APfTek8u+qcw+aCmp/HhQ/5SKWx0UfWw1l1FvbTdSyH1Alzc0+ya7cz9bOS2OjRfji8tl007aB8NUq9rza7x7oWXcDPNrtGJdG380fFD87fgUfxMAWIeKTP6A70KAcyU0OWGbs8kjhDhIkDD+rj78Nv+junBt397NWy1Qn8Xn1reHKcuFiVij8JOXkq5/GE5H5k/wRcOZrMeyxWQsF+rWdiuSdVzTEA/FkzXNEITPzxGl8fo/Bjtr4wd1kXe92TPw2F6H/vAe53zmUbHHdJZAS6zlQfMaAC648cZTWVSWp9JAXNQ6feW/PZDxXWFnwYz9cOTmBBcKibU/J7AkUEFAnA/qS9//gJDrNxboIjdg1xxr3u2xwVjyaL8V1eHrGiRIdoS5Hvlqbg5/A2rs6/daeA1QmMUomtWKeF8qvqmRWsv3Q83aRalaMVeTInhz9vLP/6pEJMD2ZI3F7WYuZXWBn3H9WlFLO1ttY/72DFe5SfBwS+4qQmSR08AgD1a3OeJwTj8h3ZKdc1b7p2KiAGQLdsM1Zi6UPfVUHXB3k0TXJdy/okLVsURdCDx5eOxmPPH94WYfwPuGiahyO1ZpwXnW5SOUueONRJB6jDW+Z4c+37uZbu+d8eiy/VCra0fHmzQspZ4C/yIBxPfGst9mge4L4FKpdhkKjlpv5P+vldVLUQbd7dR7QE2QbU4JqZ0yWnR+1EJ+P4OEdkp6TtuWyV7KvP8nYen13IF69BhYhvp0XBpqE3PnqN5me/Jx/6NI+tOlmnv9rJjzopv9tKXsvwEt3odEGBafi0sEFZO+a/0z//kZNQwPbZI8ITfrPPYxhB0Llhaj8wqX+q3ikJAFypCLVa32t6/W7x3X2ShEvNjdAJDEchmes9rHhn25S+9/Nw7lvOYODC9ssfl54YkJSgGwkWMdaGZzVJA/rVUwXoPwuvb4FT9hhPZ+yaKQQjwizBkjliPpioRiDLewwSvT9yCP+AKdv7CkmxQZcjQK5xFw3PnVwGRZwD6Z14mj+36U3iHfAgCayWuO6xAVU8UVAApyjtU5xpYBeSJsRMwohahHfnTKjHzgoZNULWn6HvlHdd/BpBZQeqKSfPQpQAYue4BSE4EvyC91od2MNnriuqX7KhYkyrUSvYgmBd4wG/lNuZ0V2BEUP0DqCuXTRM2w0w70KHFLostMVNPcBwiRy0vib6dwBD0EJExTdsa3iahHQnxC2sGaxZgAjLXulMSVClKPplUo0hqrQCRvpP6dyltUENg8c2UmDaPL47sHCVRXCqLn/FTsl2EUCWOI+NGaNYruIC0W6Zu94JsyYowpALArcht47WKRFJtppztUsGlckS/GDfSkgDjGRdGwYSgJz42Uyl3dMsKCa2Te4tXV40NdWfqwJYIC24Sooi7Sptlu7Sn1rCbf7RILLeWNEZnD0qrx57fYacg6+8cK6vVDtmSsyiIuiXVpB2Zs2eJTWCVAlqwRQtG3HAfb7pOWkVBIEsYrYJYXl0t1NM0e62XcsuRZCXZvQ2kjOBn1XS13n4xe+6+WkH+GXo/lkQRTW3UNXewWcESpv7BY5MPkQWwmU1efF7aBBa3I+lEd/0j2gJXL7sV5D+kUnofr+NUbnZ3YOJKml11qp3jOkaJlOzQUnareDUV3cklwhNr1nnR3uepafh901ZzH3uLj0Crv5E985gBE2St3QCaW2PNW9KsNm+ziL3z1baxJWlqq2gLVLe5UAyKysWfjutmC6MLyryMWudp9PWi6eiV6vNGoS1NjXxValvD+HlpZmfE1sEsGrEtsvOOirHGHS5BV0v4o6p1dS5HoGlaLJGT/67irc29bdY39vAxe2EcywZnU3WfZ8EzZ86ey2k6RwBnp3ZdGzF1YrHzcQZh7n9NL5t8AwBf+GJANFge3KeGzGes2Vk6188CffiftoYUNzvgONXU6i7ebh0CIdscaIxLZzMvGE4TN2sXL51zv8jnzp/T8T3zIzx/hMPH1OCDW2zLWcs6e5ut+BS8+/wLD8Mrhco8A10e3QfBF84Kr0a5+XDyXiDw0DMO8f9MAV30fiyFoIAbAVd4/fTJe5UQtY2p4PzTdlwFK753LYI60GsJ7W94pqpKSjEroU5c7fKS3DUmrOiMHClUDOD163LkoNK4M9gDYDdvnW1X6W+l7Pzlh1ftcnB2Jl6VXr6k34bv7uJPfasVdrTG/bY61b6qxpVKmXKjmctmyzU6R0/fXs3WP2Xvh4fe8/rr18z7zMVF4cYxmXgWBp63yEqS1FQ2olEd/vz9zUKu4HhFXty8f649uU8O0KBuXH4qyRxrLdsyv0tnQHdMQ0AHblfpYC2MCLVnqbygKsWWUqkwmRHFGvRpoGZUmUy5LpdLCrEAYoPWPjxm3ru/I6c8iHjht0xaHaQY86xAv5GMs6sZNaTdW4gFtiBQFY2KosMuFEfz6bO0YqwYy+w109kSjC7RWxSslarZHX+VmhIAw+uKdQsILBLz5mCxJPKfOvvgM2b7rVOClj0LAtsyhD02g00DSZ439pthJxxJnCUUY8farJxKxIKCdpx6ed6eqrX+vQwq4SAcXAcs6w6aL+bI3+ADfxkhYTM5DQzfzm9sb5SI9Ed7zxk4+Afk+VlyInsMjlaj/ShYi2Zz2MUU+Tyds9a7VjK+c9AAoNuBe9SdL4Sk0JM+NknRhABPYQ1DdYadN/hdV1Q4WdGBatfNjRxpcFyv20lx/gy/Z9befryul1sw+3qPZxd/OkIuXRoRcP676YWk2bqswCWQnbF0HWcK8ZnZdL1T7p66+xl7aFwKiwHc+IiflLhHd6C3sxHIM6jIiq7ojfmzYWXv4gbLpYdKz3louuvNeXk+xkprzVVklFYMleVVaeYCzVk86H1BAAKyFOLvLNHiFW2al7eLozi4TNRpmuWBr/cAQSfALv9ZfHN3gvo852FQkr6mvqtwUyRGpfM88wK+apHoWCJKP5yyGvsmqMYCoX992I96VqnJ9uq6TA1k5dIlJ42+rYnr6TZscjSNKm1uJgPBSDL9Kj1k2Mms66vYKgsml6wZ1lnukvQBjw9JguYTR8W9sPeGAcLNBIRTiD62pgC5ZqoDqRqgfAMld5PUIuFTMaGUI0djC9qERnKir6AUYMDwEHqMumRdvn3HirTCmu1SiaUZ6i3Vi0rZ3IiLeZLn4kxd29E2DEWzmY+9wZXsc5meAUrEBk7EX3q+WZ0eYi88vyymSes+wPzFzWo5H5vxgaMVbwl8tbmUAQZHtZ8HR4Ftd90s13uA8ffiVNlDX14upgWBeTGjt9NGdTosO/teExJa1UWIaMzcRGvxABQm6dzugNLK4vwa/Smal1Z+wqhaG9FzxjoEnwyVTtu1qLfloBCOWazDJCXiOe9IMDGfp7BRWgifDzCgHg7MFMKcj2tSwc4EpHdJmmKkOBaYBn4pOc6SfXVy62BV2qiO09T2DF+UvGpykAintKdj+VgimkInLVyyuyUc3I6U4/Gr0zUBtg7As4GXnNYu0fTE04QOXDXG/RGtA5wbH2OC5DkvI+oFdaBCEhmbvXyEXl2BZNqvuvIzFBdR29TFid75Ja1QBq5kVMsnupSQyZrHNMkXwvdSNCY1qFASfF+tjG4GIVpWubDg3RPGUOwoeRJ7qQwMDm4EQ6Gjgpx75M2CSNVVmU6kpySZJv9ZdcKJIy/KtmxdzSTVOedJUCuLKsGmxBxbFQJqlJoxEljRQCyDWzIzsgyLUu4R615vN6mcTwmAq7pYhuopahFK6OXqpq0LiOn+lalSn09wFxWmnKCKuGljGcABFKdjnzfH5mUjPIXATbV1CKGqHfezfpTHVRAQqVDjseXZQe3oO0wVQDDQPdWFOWOfIQ4I2hgcDCxVa2FUJChtkp9wS9GbkHIkzD04jBTN1IJQL2b/Gi+kja8YBNPdrETO3t0W0tbONS6J2I1qzplij+ltzGXBnN+4CjLG36eUKHiquL1K5BoUXchk/xjOvTfJFL8FE0ZRZLF7yKdcEg4dItN1DESNBeAoFUoeSlw/YgHyHbcI/18JaMdJcPZ4koREvvzSUCaWTAADbWTiyOdWlfd3XY0jIwAVRByMLRToIhNShQ/Bu4K6yV3MJnqYc0uJ/omoBM0wQHoAaZqFwAm8V4oXg+I+/8GO00tgtaIbZwpICTxKAuz8yP3jzQliVRwWMCkBGS0Zsm/gp74LcskqqqTV3c4z0NkF+mPHXm92d6em+wtoIvNv/DrtNkYPzi4UwzRiLT6RuAJA3/3Gin3Hu/2s/N1StRiR3PUn3ydk9WDXcqGFi1yb4XbtD/HHzryoq3OKZtErJQTs17dmH3EYM24OAMR0NVtncVb25gRAGDknySPtEbED/3/waa+vhdlVwkONFMi/P7ZFL1fdljSfM4PWqJ7LAiNZrRrpbL3FrKLHG7ENqMx9iTpwPAaHQjFdMLjtjMVebG7jlvi8+PQpkzqYSQrnzdkZS4timY0f5CQnyzql3EFc4wr7TDge8hpjWxisBXY7sqZyQckH19b+K/9a2RxLd5MaHWkBjoCu4n9Vy4c3VaWhW4bKbcBTe/eOm5vfvGl+eGg+PW2ezZoFoZnjmnO5UZEI5MA1atTQMJAucYp2tYti7F1Wf6Dn6VLwRhOV+INPsBq62joLKyqowmq+tBgtFWwiO9hNgFgAfLRcNnD1SyoRW8pZBkGWgFsFxDI+a/L9EUUT3mKcODIO+9fYAzmc+JmB0X3NNoevUg+4zHNR6kF87Um8i3niJ0tzT2KpcDqJB+wqQD+R/LeklVCYGAtbgm3AQih0P7jddWZ3cu/kt90IsOd+CImRJjM8hBwgcEwp1PzKSWL7fnlaO5WPKNwTHkVDKQlAWImKeC3XSY51EREKpkE/vF38cH0rShFJicKU3rUub5hg9Dv5hgmBXK2Cy73dtUCl6qPclxfjmpL7s3m3iol5zgeRxJQSRKfibqZSI3P3brSzebVwzv648BVHQTji/sFfFoCwWv2RlgFZaN6hG7nhb82lWhkBkWaoMuQw8F3fHLhPIGEqrfEy26SkxlA+GU/IosrMbIBbfL3j+bHxdEIRcM37c86RZCqK2G1xSTGWLXUlASm8kw5M2rU1KaH0VoZq4U95GtdmciQzlZ3kAhaYJr5jSkHqbSHQ4GOblaxWcEWgmNJvB4bkVfHrA1MZdUH9WeV2EzZz7yjGxIYqovKM7DczVggJAyGT9UeFZkJwjur0rMyYngNFoQ96gMZzTD1FfYvoGcGI1MOL75y4s+0Y9lmD7R2veAK1pLO8bVgnze0yHWsNxdwybJuuMIiEtGpkcF+Y1r6VCGUGEmGzkCC1JaOKyTkJXmkdI6qsolF1S/Dr4LWQ0U8ll1xWBhc4vFYltdnXFLc30wWpUjBL/56FuBRXpqpQ0yhmTJaL9YYiquxu1Zc506/YhLqO/T4umFKmTw2jz465KlNGyTb7K+xmzpcxodlGOY+IZySVqSi16RYLFUkLKvNsJVd0jnVMV6VwdFSuKMZqQlkakwhMe/owE2QkUqXO07eZ0Bw0DI2lXTMRN5WYqMgjlPNCaxFlI/tGjkyvbbS5uBMpFqQgnsUxBWN0fHnGSgWvI55iUr6BABAKJZqcFcozL7WUZ3FI34V6ROQfNnkbPbpizD9NxX2d5hyVerPImORawujVqRXal1F4z5lJgebZztLbyZRc0pro9uZdvP5iJX2Rahyl0iR2QzGRbwPfwjiuMEkwrClM4yuY5hB6/srbNQsjBi1NFJvghux/ERomcdwERKE961fNNVSElDszB7dHFWPFzk3lX7AyP8J7Bh01/+AjuDNvIp+Wlh/kg1ogh31q0zhE56FZP5FbAZsyu3Su9X9PUBDptNtYyabM+9DgiE3VJYroJi1grkAOUrdbtT11i47TW+2zzam91aqb1KlVbwOXdl5KcnBtQl+IJN23yVDFHT9sAoyb6rdbHASX+z4m+XDxrYpO6/b1b/SK1sDybQStY2AeEz2uzrQKUUF75KVpBNLzc7J1hj4T6m3nS4mdO8icq84+7OjnRVXV2wLlVe1RBEBS6vbkwaRxH1wTlC//xOOP7R9bS4rW/qBJpFV/iLc/uinnUPLhEydie6Z3uWF1H+WlQf26QMfO2bnhWM906jpcAAr7RZjinnU/evn1lSyJCP5wAp+XDuuZdtPi4YeCMsKe9euMQ+ZIr+eHabsHxOUpVep7Dxcnxa+rRPOtp2HFeqYNieb8ST7KlSj59YlWc9gG22AjG1t2xlyshJaXi/z46zDJJpR8TcBc25BeLd/PulSlMYJX5enY/epmJkZ2lS3Z2FN8nL+QVyuXbML27sf3pu2cpvPy572maTnbGI79MXvBBmcXb1a0FvcF6y7pUM58SDB9G9Sdj7Bg2JA9cNt50f7AyN5Nc++TO95RpbLybKeZTpQqKIA3Q8t5H33KlE6y+oUY9pBcyHMdqevwSA3ZLJonSUt/0DSJ0YBmfa2kxj2jISBloZCutP7exRHkTCvPlopn+LESY3K3U14+mypsMmDGsOrC4doqYlEEn3GBLDe1eAdXCy844Xcj/m18KljA+IXb2M1jixXfEABJhT5dcH31Kg0KZ28qAeHn8bzaWU7Z7zF/2vzzJpFFzlccWY5qVX2BT30POX3DR6hxAeHg7ex9oFz/iwRdB8iFKcAhMOm8l9/CWcD4+bBvAi0QPBKbcZlmANiQfIGz+9K/YX++YFsbaeG3WSKkRYfaTKxJXMdJguwf1vAH2z/Ssmhj7BKHYKKGga7484rj57/7iGEk8axDaRTHb+U/lf+5vDDWxCJ2++oBBERKCI/Qfg2crwZR+qnf3q/xf2RRqXJDpbl/ALHql6uXHOAltsMhLtoZgafy613qZGjAWZf9CVmkT3ihNxeKMeOhrHC4zQGOKnFgCwpRQbi3WVpGU6VZf+HghSAhbs3HEbRhKjPhCBR3KdwPCQIpzqU+pE42q2wsfAOnJaZxgxiB/Bncm5d97he/tWBHRz2SE2TSplwvmB2CiKYzGRkkTya1zh6cBwww+RM0g/+B67yuY/IyRkfooN5U+E4SNPfZ3WIshouxe/Pjq+QTJ8Js2bXx8vPVQtfaPP9IUv3++BHY3doCAihHTmJbnwBInrnxsnhlypYkd4Lj3FuSbyDkUpaHX/gTNq9cpa1Tv0TXV/F6BxCAVHo9aX79heDC8R/QcIP/DUaSdt7PbtWY121PonZrzJjD6nMRiFS7FyPmD24jVpa+Jn/eFiu4IepI/ETuQssV8wHIE6DXA3h5Froeoj+L/CFndhtmkosReak8AroGsVzqD90SMBz6QRIGQ3eYA12bLVOo4B0XTBJEIZx/8b0iexjQ4wtrCtTuJuMLJ3vnEj0+UCvOoQDpjwniJuhJTii1IIYx8ppcmuhhsBpjHkA+3qzd8aQUShtX+/7u5vtP4AWL/LR7Z69BNUErUOkO1kFxxpwLvbL8T9PaQnbOZ259okVR89l2xYlTyIhcown7BAVyosTu/uYlWJ86VH/7jZtQvDcARsFgMVRmdqS8IQArKbYZCUYmiE/kDQh+jyvwfFl5MFD0LuWboPHOoZRkMNZLYorQW6HoBAlJHqIA/Rdg+AIMWIAxATn3i9kHkL0G4FkiWIEEzjEnJW00SdpKqlnhiiaybfHauwXorA8D+FciG2LFazCtDUYR7l0fKKMbKEW3+xokMjGtgXBO3ktNTiDKxVKTGebdauU14AW+7QgBgZzKJJRvlIkVFyjOMsQ2a4eh8SbxRXr6PtMNg/0AiVotIEJfkKuULmxN/2buN6exQuBRHQq7qQUE1keMWLU/bXgAM6Zhi4QZq9oF2EnYi7II9hV2BqjZLVbOuf2AuJLY9YACXy3fedg7ZdoQImxebBOoANjeXEWrCHa2MmPNaauNLTtqPGYJluMrc6Y5SnQmu6EDsFvmLZjdl00E97WIFUzuF6JWeTTvQ9hhNIFHa0emRxb2rpHvZleTCJhZHGU/OXZMcUbjYKMun5sYgKMZ7ClMmxluiPixE6z3vNZsG3xra7Y/1CIHmoXaPBdlUK9oOSmkan45eOqktDThcURq0DQ2HP3jA/8Ahnx84R7Q4K/Y/MNAeFeQLs5kP4QMY+z175T1CD7lXRNaE3VuUxW7oJQazJVtESOZS+NaT/Rb1zWbk2Ts38MaYV5S7KiLSKA3rbjSozvnDM1WROeFmtHtlbpMSmnfQzJ+ZGg1U3JY6Z6qCSUWDvqvTTVKpevs/sGSejZExVlzYdPWgL5n7DJqr+lQFx2l4xraifusoLPxXskJR75lqqB6kpa0vnQo5jGj1cvMpVV8ydvZvjtmH7aSs28ecUIdG1phEKBHwwS2YK3Ob4EDKewZC0Uc66srAsDU5HHm+sywPBGQReg5DBqI+e2t+DLPrxUNkr1Xn7agcHLFDa6mn/fBHk2wLQTtWm0M3vhrXyLiya4X1tQUtiKt/ZnE++pV0Rm/sgAjtSCJc/6qch6IqyeQoZnAZechRFdXlvLCnhXna5/BNoUN3qIS1UFvy+CYxHbL5r0S/V5pNzsoeujzLm8brTMr0eVPamGp7ec4f2HFxaHSWFHzXO1UK4Pc1kwxOt0GGxrJRAJZyV7tfRnPtkLZqd3RngSFl8BBvmXFTAK7uUn3bU2IGEh6kLLZL3fncA3RX7AVgj/2L2qAQN+A+3CJIWTZb4wvddA4/wBwEsz5RjvuXRzj3VbDn9DqlYzU1BOgn79NvLUdg6JFsJ8SAuj7vLmxbydoVtCA0n5kaMWqChjT7yfIWKfwQTIcYRjpt7nEGrWaDQDv6/4Bxu3+NP5TekNEziKMlp4P6dym7dxrGPIhC+xj29B2nFlogDDapfa2kXd2aOMiJnMZ4t3XfrY3s5PhCzD2MWW2uwc8sUGGuS64Fks97xss0sh4hd8JGPobrX1nS/dfQJ7MN4mv2GYZxpCJbqrRf04MU+rdvpDRxEuhKx6qRbU+G/DJgJW4Xj7Iu+uUP4/1D4D07lIKjcsq+lVnHNdkhnbBXibRZd0DCTyjGdiS69oSt/XTEhu9sz3bkAZ0dPu8x5UxuoMASdBhE00LPKLveE0VVHbCJMKkxZINJ1pg0GRzHPEc2XWCnWZuk00aiaJoGF8pDBPNVQLx9zba+WGru1CxlK2nsHLWbd7UvtPwCkJ5dIyj2ydda8o8DDSdc1C6qeoZIfoLaynzdrVk6NXyrsxdBhqYTXSl37A+QvgN/bI20rMr2XueUTJPwgP7g4G5mf5ZGQrsGQo78h3pNIF1yC3luXAQM5cAgt9RZwvZTbPrljKfWQ5NACywI2UKRoRQ+5yeJq7iDfQiKJVbexNn4LqEXb3tsad4ZNTRG8CZdiO4HrrGWzdvqGW5EUn4kdwGQa+sP1zKqY0desWCpwCsQ5RznXTzGpdqw7IL2jhoq0crv+Qu1JI7DWG0F7w23EzrIizm8rq5P3LR7aIsMnuzDmJfA+M4bA2Zl8m4z1C43gPsSRTuc9yBp6Ewh60oUAkl0wyhdrgzIWLvVm/VC+caBEjCq+bKg7V8fXEO4rrvhfcZbC3buImF1gV7/GgOokZiLk6kD5ifKpJkgeYEV3IC0VslIesYcsLtmT7ughF470Biml8ITHAeNtDn2Az71oFuc8QWaKivPecauKyFyZ22fZqpx0a53DW0kFiu7Dq2ToBdAdiYz/kQxl4gPe5oypMbQLQvmEpn9Bl3c6+L7GlZ821SYQMgzMwKqv6GS1fXv1vkWKwLRt1s3OF1uCmgX+/bpIvjrR1mj89v676C1Xfb5vXDCoBgbmW6x2bDjyqo1Dp5T8vo0b3fLPOtYTs9nHThOSJIBNYkbFMlkmZW7AIBRsiSpoNdnZecbTZxw1UF1WrMiEDe1phxO0nW72wlOsrcGsdKVhtrj9ADlmO/ya+2TnOM2SQlJ1mJXgvKPmXZU5A9SA/2BKWqStZ41ipgX0CyVm5xRCnlLtJe/le/7Zx3L+qeIZpwnv5wsnQO9ybTwBF36xjv32BL9NKvrk8lvEJUkuisdkZ8OY9WzPKPWOx5k3DMR6C/RAdwYu4y/AUFjLvkNfzY3yJUKJAQHICd4AYkf67e+USswZIjlfGnLI07/T5TziRK1i99Fsf5gOcuC2rHO7n1jZ+r4Tevn7th3xqin30C1B8EKBpjL8qklzwa7YeVKigoUCkOvm4VSrr5BisoD7bTcK0ud2QoSbUdUQFFodI0wTkfsdLUif4C3OLr7jTUTaHEiwt5Osr4eXh5sgQrOP1dVZkNmaEmS/aOs/aVaOHGTDZRbzdgnBCJ3WEqp+7PYoNWC7toaHDAd4dbhYOud5+UA1ffIKA2PtppBI9QzAcGHiG5y+E9bqKT6P3gsv5CNDA90f894HmqEZBFVy88i3/3Z7dgonY5ZHjiL9zLgDkTTJMI23bO5zaMzxj3IXS7GDSDf000M0VdE6mrFqArAfNwP1keoKO/Z15/2KRRkQwbZLJUChIkNy2XU+xO2EqXwVM6AtYigT1Ku6PEaLo1AtvUd4vzxN1gk6a72+b4Imdv53OCU5iwcQWwWYuUQS6QVX6NB7dEIF6suZ9tVbRUsClNr8WufmdFhNpAFafoTnghF1it2voSXG0dRTkMaV9Qb4tPwylA/gdawX01xJJuqubOuqWu0HdNFQBR19rt7DfFjdbylKBPQOA/F2eyfaWuLbIt7xnwY+YgGw9YHrMnuavIxpmFrdzmhLFkOkOHibrN/vT0My6Bm+IQ7PJt5nEptdWhpp7D8W6XFPp8W0m2jCovbWJ9Bmz3xOjc4JR/mIoTM2rxBbtp8WfJI8+h+7zmMHn1Va3A7wjfoDLxHuBguVmhxkTukpIXJyrICZtkyxUZ7zFOdLq4m9e5dt4nhyM15tvkubandGZx9lxJSRiI3ih5ON1LCgtQELlXsijg7Y7JkzsUXsUIgOIkOYGeyAz0JmiE5D8f6aqCAfL6WIiwQIMmNz6t8MLcP9zlt652lcw3cPt1r9+LaUxyMq6nuL86UcG/FZT/s43Fmwx8doM7hzavgKY1RppRsV/0o9dtKKPriMygrywXbZfUmd8PRq4ZtJzjgnZeALqgwjYtOvP7Adoy4NsXbReS868EAneL0QWRKfSt5eKzWB7InQBvWzZedzHghS5tFdqvEpwHh8FJzByjRu9o2XWFHVfym5kXgW/H/oyMtziF/kS/JgcB35C3NaCgi+ZILqtNBsRzEkVjKUKiGWkmTZAFnSUf/0CPQOYNqF65friBQLRy2CugdjecUSRKt4twC+L43H3khgW3C+527p53BRmkQsTVmUTb9TeGpMvdmnRz2G/8sIP9uNtPl+9JDc96EyHpzTYr8CKEHry7iPdn6y6rRd7xJADj39GjbZJWdPeiNDv2AO5qFz5MTDNC36wDCm69esJMxZLvo1m70e6hi8v3vrWS9iSqEbT1SzVbEIhG04ga2XX9tNbDaO7hCDRWlFoXctcYQbK44enxwHvulpqE0cG967cGCvoBBp/vUv1bA/35wPh0reCQ+9FVDFeWUzqXNZ8APQQIDJtKwLORuobWBmzPBkB4nFL7AmQ4FVDnXdzk1EPW1MJmftcPs93uvntH2yWtp9bRmWcZH+YDvOkEjMP61D3E6OoEjX3ObyoE/BcI5HFTgNEGYj4nJ97upK2aaM/OPjMQ7e25OEnQA/jPB2Kq2cuQsXs20i5IZFEXF0yCFeSkpkT6vyMhSbQzv+04XQegT3dSMNhrtkGLfqOC9Ahf4QEg8k0yYylpwyGG29/2NrXOsZvl4YIkLbDptNLj2tuSsh2W9uuvuN4Avp3tBp17+U8x1xpBat0suh4N7lwTrCuF1MhP2Mki2dQsQ25651TFW0/LAn217nOHnADcZbgto6B8+rON1mG2ytArhSwB3gLwHtZ8cFyARdHsY/GwbL14pxhOb3JQOURv0ZULvcs1tuCt4ZYeJoOHBj9u+XDJb2c7DzZkvaNj9ffTUoR6hL+X1+WK7jT6+GulHz285d8t7+7n23VDQUt4AuVEGN86nH7PZ2NU//f/r4MEcIfOWGHas5lXn7QUgGcdXusE68Nc78wLkVMRLrPpsDZrWs+wFsNXAVn2ddZazB8NN9u7vomhEqyTvML+KoZaJFuwnVxiy+g2xj7atxMpZ8s9RW5W/e7ycbIiHAYvfngmkzMQLZ8H9CEx5CCJMHgAQsOkIgHcYPUFUKrzkaebO0QLPVFnBD8odZi6pAaSQHSqUSiStN+c7wUFl8dGQWurs7ZIZzICyDD040QyMIOSL4agpGElGfu4XWhg138CJ4gEiC0fcVqcbgboQ7+TmjXh2rs5huTm0Fo8thLPra7TX2eyQmAe1119svLJEY4FExDu2AVtz4i8Cmqh7fvFCBGwi6NEA7BpQZBdBRBwnpKVLcYnNgTwDUvomRzBJhHB+UTTRgCvn0xJhmtsovQQAYJ4+L731dI3PAD4o2dRzDVZOj9jfji+rqpWdz9oCwB0xAHoEejXMoBQV9bp+HgmtJU/8wpIcDMjPfsQIOoYZQJtALl+QgBF6bICdmmETa/l96Xht3l/TTD1DwPI0QwQGBEYGJjGXGFy+50zObm0Gi0trW5dmjjzMI8nR1EUFQcAAAAAAAAAgCQiIiIiIolIMj2pISEhISEhISFpSJoWGm0TJPq44wk2Gw/C6XyAH4QQk9FtrFk1kEhEQkJC1LpSxsZMRiaZ3Wf/URA4z5p/oKCgoHoEgoKC0pRLrSUgXXO5D1aZPhRFRRXpQ1EURVEURVGULpedNJvNZrPZbDbb+9sMmDC7CUfe9WdNQTAwMJpRWCwsLKxmlbY2bdq6rXR16dK1yWFOcpaL3OU+z/Iyb/L+9lHvCdJLLz295fEThQ8fPjxxpc2Ec3fXn70GIWrRIA3y/oSzTMSjH9y5e85+g3jIAgAAAAAAAAAAAAAAQGNwlzkcuev55cbIuoIQERERsQohRERERK1yOPShnH0aLrvccvd4lWfe+fgmv9vf9b5cZckkSZIkSZIkSWS95CHnnh1JkiTpe2lCSpVSSimllFJKKdVVZowxxhhjempkduaMM32mEAQCgUAgNrnJ/e2Fd3n3Qad7oGeyP8lzdiQ0NDQ0NNTjHV62vD2+Q/cNT0feBXx5jfc/jqM+H6EIlBxJJXPULwQAAAAAAAAAgAYLKE/iRERERERERDplMzMzMzOz3mCXjkcMuhoCAAAAAAAAAM3CQslIhBDSUq5PMWOMMcYYaysRQgghOgoAAAAAAACN8p7n9StVSqmuMmOMMcYYY3oGeduFp0RE34Wz/yEiIiIiIiIi0llSNjMzMzMz6w0WFi4AAPARAAAAAABAs/CSRI4zTC4003HvAjn7IwIAAAAAAAAAAAAAzcJCKUmSunKNUhRFUboMz7CGvWwFAAAAAAAAgIYFChFCCCGEmooIIYQQQkhLaU3TuhUzxhhjjLUtViKEEMIIIUzHEsNchmEYRo9llCivnzKGYRg9CgAAADQUfqcTQgihpiJCCCGEENJS1upVzBhjjDHWtliJEEKIjlKllFJKdQ23u3dGvdhV2wTbUTO3wbEk9XdH9+aN6IucxNsnTBzFnxgv+tnJ7zFapKTVFyGRSCRSS4tUFIXSyqIUhCAIgiAIgqBGw7L673/F5eLi4uq1uIqm0Wg0Gs3R2hjPGo81HuPZ24WnaHQ67l2A41+7ttOTkRfLz+08DmPFTovKV7KzcORbeRXKZnIyk5nM3Gf+hicQiBXESxT9FCCI0+cZAJk4WAgIIHXIKgcznC0SET8EAkNnirxzh0G5w2CRxRUBEtkpgoV15JDoqCiyDVqM5AuSgeQrlIlGH1NZKPrUbDYqf7f2vI0yZ9aUQFQ9SAJHe4ric5BBwUlnUfkMCVA3iiL4FebKoW4/iSLZRTEZPI1loOW7LBPXPIYsTPz4XNko/CyiDswijY8V4p4XyNANEC+m1VjvLJQAu6f2WO3Jnq+99MpLGBLnGg7SrR4G/akDnacyL3eVehaa4LVf9yAcwfOHj3m1nCIcdbweowsaVTuloBstPD58IzskS+3ZY4GHft6r+c1DMz4ejR5BFPbQT68UgVSwt0Nt8+G7kD0FedHODQZ6IIg5hlJw1cWVAoga8ozF91PLaJcOYHMrM/b1debb/tlZ1uJyugeZV74OiKSlkQ1k2Mq3cu8oco8+/2s8jef9JDfvM8NVORumn5tE6DFE8UvIy3wHVq/VT53tG+3pro0aBxTdik5Ec2+XpU0HWlpB3il6Ir/ca+uNLWyZIbXqhG8ojHXh1OPV2Apu3kuCdzI2zkLLSEzIXZRAR1CgGqr06Mpp7ZEh7UThANDIqmz/JPhmk3okQvSg0nAvZo+14aacWqamQ1spvlgzB0iz38Jbkt+TQrVJ8iwaovxyCwQk82WmbZ64IqlW+8hmhuwLdLM04ZizGmE1UzkPvVOjbwlewDkYc0gEupvnA4L2dyQ+Z7wmkHGa4ReHHVlrZyg+v4MQ7Dxwkzkf5LxOhB+qDmOQCJEtJgtWaG3N6Ths7XoI9KMvj6C8IGJg0z4ceEPklkIiiRJS1j5IAlookiI48HqVJucXw4LgsaFUF0oMxnJ0bo1JEgKGBMBxu5D8Wb0o5+f/aqh0hsVLTR5sB7lQc+IWGokG03MKjQtyXmSy8MaWStuamT0WxSRj9s7KLToteNEjcTCWEc0W48rjZ1ZyJrwY8cWxaASlJbaBDuT8iDD8bgIrOWJtboNnERBYimLJjOng6cwEZPgSowcE02iDfKPlmCgtJa5OQp61mmRlVHTm6QhpcmrP8Sh/wfr/ph+IrZQjcKoO50xXSsCdkQRjKQuvpTQrgi6UKmqODn29L3/V04JxIyEojVCwF1YMHSXlSoUUG+WzoAGQI/ueKWr1cjhXcsTYhz0ToH452ErBQYuS6b7e++zFVD56OWQcyky9MfkAWXhBCTIJQDwycDzzakTNHP3abBPGCI7Y9LEKxy/l7p5ax+0W9HjtcH4k1IQkzoRil84hM0i7T06jzY2x8oxk+slvBsO+SFtbzzNP4+VXgVKVVgLxqXjzWOqsDJB/kt9Kwe7d8BWezpU4BHm0pxg1yQSiPFOPbrywMFDmQEobk/ihBCcbpJsXdyXaGt8khvw4dTJW8Dc4Iea/qR8YuNkD//vmOY6HElG88k7eUcsfDbjvCRH4BWzxQqw6w4TgqEIL4FfwO7hJiQYMNOdIpl8g5/zDaX+0atKsxbQg5rRpRxfMB7BDjy7dQnhtTpwLZJJNLjnksdIlCimgiGJKKaGMcl75lyoqqaaWGvbKdoc6GtzFxVNZCAgJKUCKkBKkDEpB2GZI7m6PdyXK5/jhByEYQTGcICl6LvJgOR5fIBSJJVKZXKFULX3nXaPV6Q1Gk9litdkdzv165MPt8foAQBAYAoXBvbzX3OAVAolCY7A4PGHH2r9XPklkCpVGZzBZbA6XxxcIRWKJVLaWTxRK1Y7IN41WpzcYTWaL1WZ3OF1uD2ApEASGQGFwBBKFxmBxeAKRRKZQaXQGk8XmcHl8gVAklkhlcoVSpdZodXqD0WS2WG129g6OTs4urm4IiuEESaHS6Awmi83h8vgCoUgskcrkCqVKrdHqgN5gNJktVpvd4XS5PQAiTCjjQiptrGNaQMhitdkdTpfb8Pj4+gEgBCMohhMkRTMsx+MLhCKxRCqTK5QqtUar0xuMJrPFarM7nC63x+sDAEFgCBQG9/L2QSBRaAwWhycQSWQKlUZnMFlsDpfHFwhFYolUJlcoVWqNVqc3GE1mi9Vmdzhdbg8ACAJDoDA4AolCY7A4PIFIIlOoNDoDNo4Rhyv/V7MvEIrEEqlMrlCq1BqtTm8wmsxTqueH1WZn7+Do5Ozi6oagGD5tB3xeGkFSqDQ6g8lic7g8vkAoEkukMrlCqVJrtDqgNxhNZovVZnc4XW4PgAgTyriQShvrvPiAGBFxEiRJkSZDlhx5ChQpUQZACEZQDCdIimZYjscXCD2DSCyRyuQKpUqt0er0BqPJbLHa7A6ny+3x+gBAEBgChcG9vH0QSBQag8XhWWIhQz4Vi83h8vgCoUgskcrkYLEMKzVaLBfr9AajyQwYC23yx/twutweABAEhkBhcAQShcZgcXgCkUSmULNodAaTxeZweXyBUCSWSGVyhVKl1mh1eoPRZLZYbXb2dLL8zE/OLq5uiLIsaXRIWciWrVwzTGWgsvjSbN2av6rVZnc4XW4PrywPdyGVhpbl36L0MS0hpEpETEJKRk5BSY06DZpoBhBhQhkXUmljnecHYRQnaZYXZVU3bdcP4zQv67Yf53U/7weAEIygGP56fwiSohmW4wVRkhVV0w3Tsh3X84MwipM0y4uyqpu264dxmpd124/zuh8AhGAExXCCpGiG5XhBlGRF1XTDtGzH9fwgjOIkzfKirOqm7fphnOZl3Xb7w/F0vlxvhDIupKJqlKM42zzY84MwQh2FUpkA6uRE2wHzKN/bOM1cnXzqgMSi5pHVs0cz8G7jyFxI2dg5OLn9qy7HPJVMQUnuyriQEBf9j1LWeX4QRnGSZnlRVnXTdv0wTvOybvtxXvfzfgAIwQiK4a/3hyApmmE5XhAlWVE13TAt23E9PwijOEmzvCirumm7fhineVm3t1/7cV73A4AQjKAYTpAUzbAcL4iSrKiabpiW7bieH4RRnKRZXpRV3bRdP4zTvKzbbn84ns6X641QxoVUVE03TMt2XM8PwihO0iwvyqpu2g76YZzmZd3247zuB5BY1DyyetaEOAhKFRIWERUTl5CUJl2GTDIDiDChjAuptLHO84MwipM0y4uyqpu264dxmpd124/zup/3A0AIRlAMf70/BEnRDMvxgijJiqrphmnZjuv5QRjFSZrlRVnVTdv1wzjNy7rtx3ndDwBCMIJiOEFSNMNyvCBKsqJqumFatuN6fhBGcZJmeVFWddN2/TBO87Juu/3heDpfrjdCGRdSUTXdMC3bcT0/CKM4SbO8KKu6aTvoh3Gal3Xbj/O6H0BiUfPI6tljCqCoVUlZRVVNXUNTm3YdOukMIMKEMi6k0sY6zw/CKE7SLC/Kqm7arh/GaV7WbT/O637eDwAhGEEx/PX+ECRFMyzHC6IkK6qmG6ZlO67nB2EUJ2mWF2VVN23XD+M0L+u2H+d1PwAIwQiK4QRJ0QzL8YIoyYqq6YZp2Y7r+UEYxUma5UVZ1U3b9cM4zcu67faH4+l8ud4IZVxIRdV0w7Rsx/X8IIziJM3yoqzqpu2gxxLGzaiH/G/9bT/O634AiUXNI6tnzZTDO4xGU6+bVqvNYy/NFk+9BrqHqXrHdlyPt+fefP4urr0Lduo9GEExnCApmmE5Hl8gFIklUplcoVSpNVqd3tB/niazxWqzO5wut8frAwBBYAgUBvfyju4VAolCY7A4PIFIIlOoNDqDmS5nMvzTF7uE2PvcbBmuD/nJlD4WisQSqUyuUKrUGq1ObzCazBarze5wutweABAEhkBhcAQShcZgcXgCkUSmUGl0BpPF5nB5/PYFQpFYIpXJFUqVWqPV6Q1Gk9litdnZOzg6Obu4uiEohhMkhUqjM5gsNofL4wuEIrFEKpMrlCq1RqsD+m7uGlhNcpvJT3NRD4AIMy+EfB3nhkr++8G0HRy9Ojm7uLq5e3h68+7DJ58BRJhQxoVU2ljn+UEYxUma5UVZ1U3b9cM4zcu67cd53c/7ASAEIyiGv94fgqRohuV4QZRkRdV0w7Rsx/X8IIziJM3yoqzqpu36YZzmZd3247zuBwAhGEExnCApmmE5XhAlWVE13TAt23E9PwijOEmzvCirumm7fhineVm33f5wPJ0v1xuhjAupqJpumJbtuJ4fhFGcpFlelFXdtB30wzjNy7rtx3ndzzBO87Ju+3Fe9/N+BIUQGDUoOCQ0LDwiMlr0GDHFDACCwBAoDI5AotAYLA4Pn4CQiBhVlvdJTkFJ9bQ0+vD5c8HDbSuuO4kAxwKW+HUlQ9c+h5XK7MZzyfhsF881t9IPbMnV9Fmmflmvb03pcILeb65eHeN3NSjT6nPmTO8U3gZdFI3NvoS6AC7popY21qLogsYpL7QFPFs2ww6lm9Sw3XzYDikxsAikm2Uz0pGyX05HFVRq5+/m4xiiR047tRhvBJEelzRuNNb0V8fxZKR7M9Gfuj9lpz2i1gWYnaUK7vm9ceIlNMcduTs7ZcsywcnC6LqE+3JamtKpm6d8XlX7zDzj9Rz+48YDM0z9r1rWBUnhZ4J+FouBE+sF+P86W9g9z1D3FGHvZxya8nX7OmTWmaDXCFO+qQBZNpsxTAlfo//si9FnQy16i3hIt5dkEvVOJ9pR0jukQ7bjDqpDlk5Pn+0Glkm12F3ikm4s6a/x0U9/T52n/McQcVnSP6697cuY0fFU2YZZl6AHqF0EIkwo40IqbayXawLEhDIupNLGel/v+/Tyz//84/v19i2+FwlMKONCKm3s/X1fbO9o3BuBMKGMC6m0sV6uAxBhQhkXUmljvVwXIMKEMi6k0sZ6uT6ACBPKuJBKG+vlegARJpRxUUKcnwD3I+ImXnG9zg+Bf/JOF+/5Kd3+9uv//smfVaOGBQIQrgQiTCjjQiptrJcrAkSYUPbHP+Pv8o/7lbt6ASGEECGEEEJDRkAIIYQQwhhjjL+wfWQff/fP/5G41RJCrtYxxhgf5KogwoQyLqTSxnq50SWllFJKKaWUUkoZY4wxxhhjjDHGOOecc84555xzzoUQQgghhBBCCCGklFJKKaWUUkoplVJKKaWUUkoppbTWWmuttdZaa62NMcaY+8RXvI114QutKz/GPX7/398nrkaNMcYc9iohwoQy7uX6ACJMKONCKm2st6RzzjnnnHPOOecQjt59EJ7m6O/ZN5M+HuDBxXSXhT5eoCRjRpQVKOOf4vOk/POv3B/3o4LSxs5DrggQYUIZF1JpY71cCeAHfRaU/1GX1rcBrcd1jDHGGGOMMcYYY3xSjAuptLFebi19CQAAAAAAgAefbQVUaWOT85d934+cSzszhPx1iSGnqcUNd72i8tuLY8QAtuhbiCUnLcki5pVjdvt2wdRcFs+2u4In9aLDeUdehcl2QpZTenY7lQ0hJdAU84YkzeVFcwX9kSECFdvab07tj5RNYV2Bl5Cch3GWxnkav5HowEcwLomsbWEbmhOQLeyiM2vI0gZy64dLCX2yrTzbjuEvyrXCRzSMxXMsjsA23EaD2z1vg+GFEFRBM8VMKXDDggtgGAMK29ANRZc62B29YqeIuySYKS7DL6wfIkSeoIea9VOMn2NpdRPpOZYvt31Sje21xZdg7LWbt7bWWmuttdZaa+3+QEGECWVcSKWN9XI9gAgTyriQShvrbTfyGpoQQgghhBBCCCHkBBBhQhkXUmljvVwJIMKEMi6k0sZ6uTJAhAllXEiljfVyFYAIE8q4kEob6+WqABEmlHEhlTbWy9UAIkwo40IqbayXqwNEmFDGhVTaWC/XAIgwoYwLqbSxXq4JEGFCGRdSaWO9XAsgwoQyLqTSxnq5NkCECWVcSKWN9XIdgAgTyriQShvr5boAESaU8X/iw53+/GeEkFS1WrfWWs/zPM/zvPXoTwghhBBCCCGEEEIIIYQQSimllFJKKaWUUnrSEGGlTbaJCBPKuJBKG+vlWgARJpRxIZU21sP/YRy6mFg8QFvoMDWcS9yj9dVfDOY3SHKZxizVsLEoWJEVciy/w7PUYQCpxm7XxUxye48behbrL4y99u47sw42mGjwl0fWQ8NNiA3Zl85lbySFp9hw3xRFi9GTOEnOYlqszsUx05BarqhDpuBwIhV21lDCyMz+ivpokRzgYBd4DZlY7CT65TN7yTBjO59hIncyBwn3RwkTARsY5T0TKLjkFp4XWoMTifMrjs5p75TewAd2epw88ES/d5nTvVUkwsEPvn3sjV6L52DQa7AAKVA4hNcwRrdhChdA8WoQYUIZF1JpY71cESDChDIupNLGerkSQIQJZVxIpY31cmWACBPKuJBKG+vlKgARJpRxIZU21stVASJMKONCKm2sl6sBRJhQxoVU2lgvVweIMKGMC6m0sV6uARBhQhkXUmljvVwTIMKEMi6k0sZ6uRZAhAllXEiljfVybYAIE8q4kEob6+U6ABEmlHEhU72fjd9tvx+PMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAhPJfgpap3fm73zI8jVh31xvwrmiinyMEQQAAAAAAM9lJ3w+yWxC5JyYz2znROwJPfNDYZsfzplZg2Pm5CqRt1C15m2JwS3hZ84OVCRfw+n1derESU4ll/PY8vHLg30SaUL4FWQv7P05Iqtg+wLC9xWcJn1lKcOe9lnfQ00cdvuGmg+81f9q69IxUowGZ6uqJbYGXW5WvN3/Hp4Bnn93VwP/+VaMv7v/nWPYJcdIidEMzGpUk8GsRS1hcK6wmGOZWw9TsEMIIWlAdsDenr2iPDaMEB51OC1Rt5Q5K7qnMxHWlouds1u5IGcP0SMQCSNDB3kjcxd7eWfvffq7ezG790bmdrJ1y/uzvZzxfA0AAAAAgFMwTMt2ctfzMQAAAAAAAAAATqComm6Ylu3ktj9eRdV0n9+03VjPpwAAAAAAAAAYr9MBAAAAAAAAAAAAAAA4KWUBYcK4kEob6+U6ABEmjAuptLFergsQYcaFVNp6uT6ACBPKuJBKG+vleoQJ40IqbezTeyMAgAgTyriQShvr5YqAaPL79ln2+S/mId++LXsXz8jwLeHYN+/zk+olleTNhy9/g/sBk7+1OZ292dXPzfIRnk4RkndR0e6bOth0r5VKK8WbD1/+evdBnJe3tP+vTa6hA5el0P+F0zSBiTvI+pdYqOEpo2yROFyuOANOw11ck+zRGsRjzGk2fsOdVkvcGSTgDpGCO2Pb7pYJiiMnzpHUCzjejWhBFQTXexpvsGHf4fEekvcWN4zUcJ7pz14mK8+9VfxFV2/gyIkzF67RTR9ci6B1ZG73cpi+S9ukCBrOrktZlFm/kUZWg7MU2rWmjmi4cLEml37YjKklyI6ytEU9u0I+3FDLC2nBkVi391UrXYuIDOAzOAGgQ7hT6rzP1u24hnuxdzEfa179ivoFiZs6VNbZ5dCX74AuQrSU6ymJGS5nqByxfsLztY2+T6xwK2cBD1aWO5ZL12zweT721YtcL73ArAIorShTBCIyJckMh/GuAIgwoYwLqbSxXq4GEGFCGRdS6YBsHICe4uKuEca32XLg9ihDlO1Ild19ZMuhMK1oK3KTW3Tlv6ayELwGrXNPVDx1QU+Ki/O+wtdw7PNSnDjDitpK5YygnesCRJhQVsglV6k/roOwEvq1Zus4maCFfuaASeQ8m1KBS0RS5rQpp+lJP5MePFKKkSPGYHJG0NQcNnHvn5aflqldRw3GzW+UZtDMdq9jABEmlHEhlTbZOiJMKNv8+eFLuZBKG+vlShBshFQad2noHtdteGHj1h/Yzz6Lp6dJC/kLrpaDD/m1nEsA9DNHahYBuDG3uNsRLSTilAFAYKcNwFLLD/axTDvCkcNN2J8YYg5+llebaQFylgNpHxelKzE1QmbkL2O40Koz2E1Pg5yCgQkPTbCGTVXYi5KZ/CB97LiAK3uxXlEHOLJwUkSsSYruE/faM/vO+RSJJDEVzmx2kqIUT9f6lNt2uoTd92d20gXeO2MnlcoH1prrsbMWmqbVsVZ3u/LwtRNLygoJ+hkvCqMWeI8LNAb2DC/i5KMefsfv+B3Njbu7uz+UVOluTnr6cuafa4gxnN7hpMvfNEh+fTZ/5es6gz5C/bbOt7onH+Fv/e8HekGvuHuvaYnAoLc8Ya1hIgh6xd27QUuv4FLTsqfLlAf0Ht0y/Gx8l2mq9ZAH2tMH4n1HW/2OBC+15cn+FJnIDAt/HL16TKEhDyW11/s4Ex+7GMaJnP6DyxZWbDC8/9o/vWweLn6uub21z7+lfPlneUHLjwbhn8pPf/v/KyzUJHzPqz5mfN3eye8NQmYb02lCHtdPVfseeoUQIpFSSpkqpZQqXU/oNCGXaGi4CYSM+stK0zQtp2mapuXKOqGUUqXvASGEKDRomqZpOTCfJ6NeCCFEUuiEUkqVvieklDKVUkpZbBBCCJFIOF826oWUEvbie0EppTKllFKZUkqpTClV6iBTpdRW7Zn0p1/+83//JnX18Rz1NLJ+VrIhBVo4scYZG5iueSZlv33m+s+ffxLm8sfrN/1lvkLuwFxcuCE1SPyR6apZzWQbQXoIG0bMoWY1qxlsfw7SQ9gwYg41qxntJqZ7FlewOSncMELfZq9rWgAbpkG4xl9Z6EHQ0YdXXz1Z+PmJv+Oc/hp+k++Hg62FBcpuAKQsWJG0wAIL88ECoIUuWlgALEDFvOVPH3fwtyqxl+8B+UNx/vj1a9GX3QdAKbpYF5wDS4ouECQ5DUfK6TWpNcQVH+B+dCmmozAvBf7EG0f2ICUdwdk/0T2lcsPlJyxVKufvs/6JLir5S/kOfqL1o5RECDsVD3OaN/sym0r8zHTz9/e/X8uw5VOI87ADYaFxpTiXMB1mYcgpeIoGuEE+rLA2NHkAWH+NEFbG7lgFMTXNKoBYDVxWUYDqaIeGPXCnQkCArQZPlqOVTQKdZRZoaAc5poAF4akpB0CTS0nSQxMXH2irYFiZCBzNAaHf2HlfOrUmHv7QpwYAf5vzB+GpNfwcFK1/u1K/MXyldgM80m0YuuvpIXXo9JD9Q0DkZzyjlU/g8tP7r8j5J7B/Af3L4cPyG+ubZTwYC5u7H8d8n/5dT2I3E3xWwJvLT9s+0T+xLiGzXtH0weE8znqgw/35e/8dMjPtbMjdlQWyfxLKdhPuRmZXw/7j/ST7igP9+lVyzvd7sO0J6q4PNPT8faiNaEjw//hfuuohh33UVQvVnBZvaQPBrmSXVjLlMGvSYbqRTiuty2XDoVJBjPRlMulj7NTSuXw7fntB89NN6OFXoITJQpqkdok8Rd6Ev03z5tjhNa+vgceOZFDOCAK+d8yI1s8WaFxHEFIQJr2NmPRiMsmNidWwLpbP+rRPaev79bWmUHcX0UrnZudhf3iokUatRjJxE3lmoG1zs5FO3CBDczLjZVRBpAxFLvUCNYhmBN9BZis35g7F+SSv58Yc9oBtt6Y3vtXsOujjnZHR9jay/li3I6RRm00HTIf4kr3HRuyAGg/E0aNDt9Q8YP2/JQGA+W12syFD9hjcsIATvDqCy2uL599mcB6llJVxwFApePWbgS2z2YRJVspycdcCVBortWdQWQoPpGI0i/TasyBUsILFlgLpIlXMA82GwgU3exPKzeCtrXoBDiAS5Gplyoyjt3kMAA==) format("woff2"); - font-display: auto; -} diff --git a/werewolves/build.rs b/werewolves/build.rs new file mode 100644 index 0000000..f6d8125 --- /dev/null +++ b/werewolves/build.rs @@ -0,0 +1,82 @@ +use std::{ + fs::File, + io::{Read, Write}, +}; + +const STYLESHEET_PATH: &str = "../style/faction.scss"; + +fn main() { + println!("cargo::rerun-if-changed=../style/main.scss"); + println!("cargo::rerun-if-changed=../target/site/pkg/werewolves.wasm"); + + let mut sheet_file = File::create(STYLESHEET_PATH).unwrap(); + let mut out = String::new(); + for faction in [ + "village", + "wolves", + "offensive", + "defensive", + "intel", + "starts-as-villager", + "damned", + "drunk", + ] { + let name = faction.replace("-", "_"); + out += format!( + r#" +.{faction} {{ + --faction-color: ${name}_color; + --faction-border: ${name}_border; + --faction-color-faint: ${name}_color_faint; + --faction-border-faint: ${name}_border_faint; + + &.box {{ + background-color: ${name}_color; + border: 1px solid ${name}_border; + + .selected:not(.faint) {{ + color: white; + background-color: ${name}_border; + }} + .selected.faint {{ + color: white; + background-color: ${name}_border_faint; + }} + + &.hover:not(.selected):hover {{ + color: white; + background-color: ${name}_border; + }} + + &.faint:not(.selected) {{ + border: 1px solid ${name}_border_faint; + background-color: ${name}_color_faint; + + &.hover:hover {{ + background-color: ${name}_border_faint; + }} + }} + }} + + &.underline {{ + text-decoration: ${name}_color underline; + + &.faint {{ + text-decoration: ${name}_color_faint underline; + }} + }} + + &.text-color {{ + color: ${name}_border; + + &.faint {{ + color: ${name}_border_faint; + }} + }} +}} + "# + ) + .as_str(); + } + sheet_file.write_all(out.as_bytes()).unwrap(); +} diff --git a/werewolves/index.html b/werewolves/index.html deleted file mode 100644 index bf43efa..0000000 --- a/werewolves/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - werewolves - - - - - - - - - - - - - diff --git a/werewolves/index.scss b/werewolves/index.scss deleted file mode 100644 index cb78ec0..0000000 --- a/werewolves/index.scss +++ /dev/null @@ -1,3144 +0,0 @@ -@use 'sass:color'; - -$wolves_color: rgba(255, 0, 0, 0.7); -$village_color: rgba(0, 0, 255, 0.7); -$connected_color: hsl(120, 68%, 50%); -$disconnected_color: hsl(0, 68%, 50%); -$client_shadow_color: hsl(260, 55%, 61%); -$client_shadow_color_2: hsl(240, 55%, 61%); -$client_filter: drop-shadow(5px 5px 0 $client_shadow_color) drop-shadow(5px 5px 0 $client_shadow_color_2); -$village_border: color.change($village_color, $alpha: 1.0); -$wolves_border: color.change($wolves_color, $alpha: 1.0); -$intel_color: color.adjust($village_color, $hue: -30deg); -$intel_border: color.change($intel_color, $alpha: 1.0); -$defensive_color: color.adjust($village_color, $hue: -60deg); -$defensive_border: color.change($defensive_color, $alpha: 1.0); -$offensive_color: color.adjust($village_color, $hue: 30deg); -$offensive_border: color.change($offensive_color, $alpha: 1.0); -$starts_as_villager_color: color.adjust($village_color, $hue: 60deg); -$starts_as_villager_border: color.change($starts_as_villager_color, $alpha: 1.0); -$damned_color: color.adjust($village_color, $hue: 45deg); -$damned_border: color.change($damned_color, $alpha: 1.0); -$drunk_color: color.adjust($village_color, $hue: 150deg); -$drunk_border: color.change($drunk_color, $alpha: 1.0); - -$wolves_border_faint: color.change($wolves_border, $alpha: 0.3); -$village_border_faint: color.change($village_border, $alpha: 0.3); -$offensive_border_faint: color.change($offensive_border, $alpha: 0.3); -$defensive_border_faint: color.change($defensive_border, $alpha: 0.3); -$intel_border_faint: color.change($intel_border, $alpha: 0.3); -$starts_as_villager_border_faint: color.change($starts_as_villager_border, $alpha: 0.3); -$damned_border_faint: color.change($damned_border, $alpha: 0.3); -$drunk_border_faint: color.change($drunk_border, $alpha: 0.3); - -$wolves_color_faint: color.change($wolves_color, $alpha: 0.1); -$village_color_faint: color.change($village_color, $alpha: 0.1); -$offensive_color_faint: color.change($offensive_color, $alpha: 0.1); -$defensive_color_faint: color.change($defensive_color, $alpha: 0.1); -$intel_color_faint: color.change($intel_color, $alpha: 0.1); -$starts_as_villager_color_faint: color.change($starts_as_villager_color, $alpha: 0.1); -$damned_color_faint: color.change($damned_color, $alpha: 0.1); -$drunk_color_faint: color.change($drunk_color, $alpha: 0.1); - -@mixin flexbox() { - display: -webkit-box; - display: -moz-box; - display: -ms-flexbox; - display: -webkit-flex; - display: flex; -} - -@mixin flex($values) { - -webkit-box-flex: $values; - -moz-box-flex: $values; - -webkit-flex: $values; - -ms-flex: $values; - flex: $values; -} - -@mixin order($val) { - -webkit-box-ordinal-group: $val; - -moz-box-ordinal-group: $val; - -ms-flex-order: $val; - -webkit-order: $val; - order: $val; -} - -.wrapper { - @include flexbox(); -} - -.item { - @include flex(1 200px); - @include order(2); -} - -html, -body { - margin: 0; -} - -body { - min-height: 100vh; - max-width: 100vw; - top: 0px; - left: 0px; - font-family: 'Liberation Serif'; - - font-size: 1.5vh; - user-select: none; - color: rgba(255, 255, 255, 1); - background: black; - - scrollbar-width: thin; - scrollbar-color: rgba(255, 255, 255, 0.7) black; -} - -app { - max-width: 100vw; - width: 100vw; - min-height: 100vh; - display: flex; - flex-direction: column; - top: 0; - left: 0; -} - -.big-screen { - align-content: center; - align-items: center; - justify-content: center; - height: 100vh; - width: 100%; - position: fixed; - left: 0; - top: 0; - margin: 0; - font-size: 2.7vw; -} - -$link_color: #432054; -$link_hover_color: hsl(280, 55%, 61%); -$link_bg_color: #fff6d5; -$border_color: #432054; -$shadow_color: hsl(280, 55%, 61%); -$shadow_color_2: hsl(300, 55%, 61%); -$link_filter: drop-shadow(5px 5px 0 $shadow_color) drop-shadow(5px 5px 0 $shadow_color_2); -$link_select_filter: invert(100%); - -$error_color: hsla(0, 95%, 61%, 0.7); -$error_shadow_color: hsla(340, 95%, 61%, 0.7); -$error_shadow_color_2: hsla(0, 95%, 61%, 0.7); -$error_filter: drop-shadow(5px 5px 0 $error_shadow_color) drop-shadow(5px 5px 0 $error_shadow_color_2); - -$host_nav_height: 36px; -$host_nav_top_pad: 10px; -$host_nav_bottom_pad: 10px; -$host_nav_total_height: $host_nav_height + $host_nav_top_pad + $host_nav_bottom_pad; - -nav.host-nav { - position: sticky; - backdrop-filter: brightness(70%); - display: flex; - align-items: flex-start; - flex-direction: row; - padding-bottom: 10px; - padding-top: 10px; - padding-left: 5vw; - padding-right: 5vw; - gap: 10px; - height: $host_nav_height; - overflow-x: scroll; - scrollbar-width: none; - white-space: nowrap; -} - - -.default-button { - font-size: 1.3rem; - border: 1px solid rgba(255, 255, 255, 1); - padding: 5px; - background-color: black; - color: #cccccc; - cursor: pointer; - width: fit-content; - text-align: center; - - &:hover { - background-color: white; - color: color.invert(#cccccc); - } - - &.mode-set { - background-color: white; - color: black; - - &:hover { - background-color: rgba(255, 255, 255, 0.3); - color: #cccccc, - } - } -} - -.player-list, -.targets { - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: center; - align-content: center; - gap: 10px; - justify-content: space-evenly; - - &>* { - flex-grow: 1; - } -} - -.lobby-player-list { - overflow: hidden; - padding-bottom: 80px; - flex-shrink: 1; - - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 10px; - justify-items: center; - justify-content: space-evenly; -} - -.player { - flex-grow: 0; - display: flex; - justify-content: stretch; - - margin: 0px; - min-width: 10rem; - max-width: 10vw; - height: 4rem; - text-align: center; - - justify-content: center; - - &.marked { - filter: hue-rotate(90deg); - } - - block-size: max-content; - - &>button { - width: 160px; - height: 75px; - border: 1px solid $disconnected_color; - background-color: color.change($disconnected_color, $alpha: 0.15); - color: $disconnected_color; - - &:hover { - filter: brightness(150%); - background-color: color.change($disconnected_color, $alpha: 0.15); - color: $disconnected_color; - } - } - - &.connected { - &>button { - background-color: color.change($connected_color, $alpha: 0.15); - border: 1px solid $connected_color; - color: $connected_color; - - &:hover { - filter: brightness(150%); - } - } - } - - - &.dead { - filter: grayscale(100%); - } - - .number { - padding-top: 3px; - margin: 0px; - - &.not-set { - border: 2px solid rgba(255, 0, 0, 0.3); - background-color: rgba(255, 0, 0, 0.7); - } - } -} - -.submenu { - // border: 1px solid rgba(255, 255, 255, 0.7); - padding: 10px; - position: relative; - // position: fixed; - // left: 0%; - - // top: 1px; - align-self: stretch; - z-index: 5; - - & button { - width: 100%; - } - - &>span { - font-size: 1rem; - margin-bottom: 0; - } -} - -.click-backdrop { - z-index: 4; - background-color: rgba(0, 0, 0, 0.7); - position: fixed; - top: 0; - left: 0; - height: 200vh; - width: 100vw; - background-size: cover; -} - -.player-container { - width: 100%; - margin-left: 10vw; - margin-right: 10vw; -} - -.start-game { - align-self: center; - margin-bottom: 30px; - font-size: 2rem; - border: 1px solid rgba(0, 255, 0, 0.7); - background-color: black; - color: rgba(0, 255, 0, 0.7); - cursor: pointer; - - position: relative; - display: inline-flex; - justify-content: center; - - &:hover { - background-color: rgba(0, 255, 0, 0.3); - } - - &:disabled { - border: 1px solid rgba(255, 0, 0, 1); - color: rgba(255, 0, 0, 1); - filter: none; - background-color: rgba(255, 0, 0, 0.1); - - &:hover { - background-color: rgba(255, 0, 0, 0.3); - filter: none; - } - } -} - -button { - font-size: 1rem; - padding-top: 2px; - padding-bottom: 2px; - - border: none; - - outline: inherit; - padding-left: 5px; - padding-right: 5px; - background-color: #000; - - &:disabled { - background-color: rgba(128, 128, 128, 0.5); - color: rgb(128, 128, 128); - cursor: not-allowed; - } - - &:disabled:hover::after { - content: attr(reason); - overflow-y: hidden; - position: absolute; - margin-top: 100px; - min-width: 20vw; - color: rgba(255, 0, 0, 1); - background-color: black; - border: 1px solid rgba(255, 0, 0, 0.3); - padding: 3px; - z-index: 4; - align-self: center; - justify-self: center; - } -} - -.host-setup { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - font-size: 1.5em; - overflow-y: hidden; - width: 100%; -} - -.settings { - list-style: none; - - display: flex; - flex-direction: column; - margin-left: 20px; - margin-right: 20px; - - gap: 30px; - - &>p { - text-align: center; - margin: 0px; - padding: 0px; - font-size: 0.7em; - } - - .settings-info { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - gap: 5px; - text-align: left; - width: fit-content; - } -} - -.wolves-intro { - & button { - align-self: center; - } -} - -.wolves-list { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: space-evenly; - min-height: 70vh; - align-items: center; - - &>* { - height: max-content; - } - - .identity { - font-size: 1.5rem; - } -} - -.day-char { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - // min-width: 1vw; - align-items: center; -} - -.red { - color: red; -} - -.character { - text-align: center; - border: 3px solid rgba(0, 0, 0, 0.4); - // min-width: 20%; - flex-shrink: 1; - flex-grow: 1; - - .headline { - display: flex; - flex-direction: column; - align-items: center; - flex-wrap: nowrap; - overflow: hidden; - gap: 5px; - - } - - .role { - font-size: 1.5rem; - - } - - &.wolves { - padding-top: 20px; - padding-bottom: 20px; - - &>.role { - margin: 0; - } - - display: flex; - flex-direction: column; - justify-content: center; - min-width: 15vw; - } -} - -h1, -h2, -h3, -h4, -h5 { - text-align: center; -} - -button.confirm { - align-self: center; - margin: 30px; - font-size: 2rem; -} - -.roles-in-setup { - padding: 1rem; - border: 4px solid $village_color_faint; - background-color: color.change($village_color_faint, $alpha: 0.05); - - zoom: 120%; - - &>h3 { - margin: 0; - text-align: center; - color: white; - font-weight: normal; - } -} - -.role-list { - list-style: none; - - display: flex; - flex-wrap: wrap; - flex-direction: row; - justify-content: center; - padding: 20px; - - gap: 10px; -} - -.role-card { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - min-width: 320px; -} - - -.role-card button { - min-width: 25px; - min-height: 25px; - background-color: rgba(255, 255, 255, 0.3); - margin: 0px; - margin-left: 10px; - margin-right: 10px; - cursor: pointer; - - &:hover { - background-color: rgba(255, 255, 255, 0.7); - } -} - -rolecard { - display: flex; - flex-direction: row; - align-items: stretch; - width: 100%; - text-align: center; - // gap: 20px; - justify-content: space-between; -} - - - -bool_spacer { - min-width: 25px; - min-height: 25px; - margin: 0px; - margin-left: 10px; - margin-right: 10px; - margin-top: 5px; - margin-bottom: 5px; - background-color: rgba(255, 255, 255, 0.5); -} - -bool_role { - display: flex; - flex-direction: row; - align-items: stretch; - width: 100%; - text-align: center; - // gap: 20px; - justify-content: space-between; -} - -.wolves { - background-color: $wolves_color; -} - -.role-card.wolves bool_role input[type="checkbox"] { - min-width: 25px; - min-height: 25px; - opacity: 100%; - accent-color: $wolves_color; - margin: 0px; - margin-left: 10px; - margin-right: 10px; -} - - -.role-card.village bool_role input[type="checkbox"] { - min-width: 25px; - min-height: 25px; - opacity: 100%; - accent-color: $village_color; - margin: 0px; - margin-left: 10px; - margin-right: 10px; -} - -.error-container { - position: fixed; - top: 10vh; - width: 100vw; - display: flex; - flex-direction: row; - align-content: center; -} - -.error-container button { - background: transparent; - font-size: 2rem; - position: sticky; - display: inline-block; - - &:hover { - filter: invert(20%); - font-size: 3rem; - } -} - -.error-message { - display: flex; - flex-direction: row; - align-items: center; - width: 80%; - margin: 30px; - text-align: center; - // gap: 20px; - justify-content: center; - gap: 30px; - background-color: $error_color; - border: 1px solid color.change($error_color, $alpha: 1.0); - backdrop-filter: grayscale(100%); - - - padding-left: 5vw; - padding-right: 5vw; -} - - -.character { - background-color: $village_color; - width: fit-content; - padding-left: 10px; - padding-right: 10px; - padding-top: 5px; - padding-bottom: 5px; - margin: 10px; - - &.wolves { - background-color: $wolves_color; - } -} - - -.character.selected { - filter: hue-rotate(30deg); -} - -.character:hover { - filter: brightness(80%); -} - - -client { - list-style: none; - - // font-size: 0.7rem; - display: flex; - // flex-wrap: wrap; - flex-direction: column; - margin-left: 20px; - margin-right: 20px; - padding: 30px; - - gap: 30px; - border: 2px solid black; -} - -clients { - list-style: none; - - // font-size: 0.7rem; - display: flex; - flex-wrap: wrap; - flex-direction: row; - font-size: 2rem; -} - -.role-reveal-cards { - list-style: none; - - display: flex; - flex-wrap: wrap; - flex-direction: row; - justify-content: space-evenly; - color: black; - align-items: center; - align-content: center; - - gap: 10px; - height: var(--role-reveal-cards-height); -} - -.role-reveal-card { - justify-content: center; - // min-width: 5cm; - flex-grow: 1; - display: flex; - align-items: center; - align-content: center; - flex-direction: column; - gap: 10px; - padding: 20px; - border: 1px solid $wolves_color; - background-color: color.change($wolves_color, $alpha: 0.1); - min-width: 100px; - color: white; - - & p.number { - font-size: 2rem; - } - - & p { - text-align: center; - } - - &>button { - border: 1px solid $wolves_color; - $bg: color.change($wolves_color, $alpha: 0.2); - background-color: $bg; - - &:hover { - background-color: white; - color: color.change($wolves_color, $alpha: 1.0); - } - } - - &.ready { - border: 1px solid $village_color; - background-color: color.change($village_color, $alpha: 0.2); - } -} - -.pronouns { - font-size: 70%; - filter: opacity(70%); -} - -.row-list { - list-style: none; - - display: flex; - flex-wrap: wrap; - flex-direction: row; - font-size: 2rem; - - justify-content: center; - align-content: center; - align-items: center; - - &.margin-20 { - margin-left: 20px; - margin-right: 20px; - } - - &.margin-5 { - margin-left: 5px; - margin-right: 5px; - } -} - -.gap { - gap: 10px; -} - - - -.column-list { - list-style: none; - justify-content: center; - align-content: center; - align-items: center; - - display: flex; - flex-direction: column; - font-size: 2rem; - margin-left: 20px; - margin-right: 20px; - - padding-left: 5px; - padding-right: 5px; - padding-top: 5px; - padding-bottom: 5px; -} - -@media only screen and (max-width : 1899px) { - .content { - margin-left: 5vw; - margin-right: 5vw; - display: flex; - flex-basis: content; - } - - .story { - padding-bottom: 100px; - } -} - -@media only screen and (max-width : 799px) { - .story-characters { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - gap: 3px; - row-gap: 5px; - justify-content: space-between; - overflow-x: scroll; - padding-bottom: 20px; - } -} - -@media only screen and (min-width : 800px) { - .story-characters { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 3px; - row-gap: 5px; - justify-content: space-between; - } -} - -@media only screen and (min-width : 1900px) { - .content { - margin-left: 5vw; - margin-right: 5vw; - display: flex; - flex-basis: content; - min-height: 100vh; - } -} - -.sp-ace { - margin: 10px; -} - -.cover-of-darkness { - background-color: #000; - // background-color: purple; - color: #fff; - font-size: 3rem; - position: fixed; - top: 0; - left: 0; - height: 100vh; - width: 100vw; - display: flex; - flex-direction: column; - justify-content: center; - text-align: center; - text-wrap: wrap; - - p { - padding: 30px; - } - - & button { - width: fit-content; - text-align: center; - align-self: center; - } -} - -.small { - font-size: 1.2rem; -} - -.client-nav { - max-width: 100%; - padding: 10px; - height: 38px; - display: flex; - flex-direction: row; - justify-content: baseline; - gap: 10px; - - & button { - text-wrap: nowrap; - overflow: hidden; - } -} - -.ident { - gap: 0px; - margin: 0px; - padding: 0px; - - .submenu { - margin-top: 10px; - margin-bottom: 10px; - // display: flex; - justify-content: center; - // visibility: collapse; - display: none; - z-index: 5; - - .button-container { - display: flex; - align-items: stretch; - } - - &.shown { - display: flex; - flex-direction: row; - align-items: baseline; - } - - button { - font-size: 1rem; - } - } - - &:active, - &:focus, - &:hover { - .submenu { - // visibility: visible; - display: flex; - } - } -} - -.baseline { - align-items: baseline; - // justify-content: space-evenly; -} - -error { - position: absolute; - top: 0; - left: 0; -} - -.identity { - list-style: none; - - display: flex; - flex-direction: column; - gap: 0px; - font-size: 1rem; - justify-content: flex-start; - margin: 0px; - padding: 0px; - - p { - margin: 0px; - padding: 0px; - text-wrap: nowrap; - overflow: hidden; - } -} - -.identity-span { - list-style: none; - - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 2px; - font-size: 1em; - margin: 0px; - padding: 0px; - align-items: center; - - span { - margin: 0px; - padding: 0px; - text-wrap: nowrap; - overflow: hidden; - } - - .number { - padding-right: 5px; - font-size: 1.2em; - } -} - -.binary { - margin: 0; - padding: 0; - font-size: 1.5vw; - - .button-container { - text-align: center; - padding: 0; - margin: 0; - display: flex; - flex: 1 1 0; - gap: 20px; - margin-top: 20px; - justify-content: space-around; - width: 100%; - - button { - background-color: $wolves_color_faint; - border: 3px solid $wolves_border_faint; - font-size: 3rem; - font-weight: bold; - align-self: center; - padding: 20px; - width: 100%; - height: 100%; - margin: 0; - - &:hover { - background-color: $wolves_border_faint; - color: white; - } - } - } - -} - -// input { -// background-color: rgba(255, 255, 255, 0.1); -// color: white; -// border: 2px solid rgba(255, 255, 255, 0.2); -// margin: 10px; -// } -input, -select { - border: 1px solid rgba(255, 255, 255, 0.7); - background-color: rgba(255, 255, 255, 0.07); - color: white; - font-size: 1em; - - &:focus { - outline: 1px solid white; - background-color: white; - color: black; - } -} - -.info-update { - border: 1px solid rgba(255, 255, 255, 0.5); - padding: 30px 0px 30px 0px; - // font-size: 2rem; - align-content: stretch; - margin: 0; - position: fixed; - left: 5vw; - z-index: 3; - background-color: #000; - width: 90vw; - - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - gap: 10px; - - &>input { - border: 1px solid rgba(255, 255, 255, 0.25); - background-color: black; - - color: white; - padding: 0; - font-size: 1.5em; - - &:focus { - background-color: white; - color: black; - outline: 1px solid rgba(255, 255, 255, 0.25); - } - } - - &>button { - font-size: 1.1em; - } - - &>* { - margin: 0; - width: 80% !important; - text-align: center; - } -} - -.game-start-role { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - text-align: center; - align-items: center; - width: 100%; - height: 80vh; - justify-content: center; - - &>p { - font-size: 1.5em; - } - - &>button { - font-size: 1.5rem; - width: min(5cm, 30vw); - } -} - -.client-lobby-player-list { - @extend .column-list; - gap: 10px; - - &>.identity { - align-self: flex-start; - } - - &>button { - width: 90vw; - align-self: center; - $leave_color: rgba(255, 0, 0, 0.6); - color: $leave_color; - border: 1px solid $leave_color; - - &:hover { - background-color: $leave_color; - color: black; - } - - margin-bottom: 1cm; - } - - &>.list-actual { - @extend .row-list; - align-items: stretch; - align-content: stretch; - margin: 0; - - gap: 10px; - - width: 100%; - - &>* { - width: 4cm; - border: 1px solid white; - padding: 10px; - text-align: center; - - &:hover { - background-color: #fff; - color: #000; - } - } - } - -} - -.character-picker, -.target-picker { - display: flex; - flex-direction: column; - width: 100%; - align-items: center; - color: white; - height: var(--target-picker-height); - justify-content: center; - $marked_bg: color.change($wolves_color, $alpha: 0.3); - $marked_border: color.change($wolves_color, $alpha: 1.0); - $village_bg: color.change($village_color, $alpha: 0.3); - $village_border: color.change($village_color, $alpha: 1.0); - - .character { - padding: 0.5cm; - - & * { - font-size: 1.5rem; - } - - &.marked { - background-color: $marked_bg; - border: 1px solid $marked_border; - - &:hover { - color: white; - background-color: $marked_border; - } - } - - &.dead { - filter: saturate(0%); - border: 1px solid rgba(255, 255, 255, 0.05); - } - - &.recent-death { - $bg: rgba(128, 128, 128, 0.5); - background-color: $bg; - border: 1px solid color.change($bg, $alpha: 1.0); - - &:hover { - background-color: color.change($bg, $alpha: 1.0); - } - } - - background-color: $village_bg; - border: 1px solid $village_border; - - &:hover { - color: white; - background-color: $village_border; - } - } -} - -.align-start { - align-self: flex-start; -} - -.align-end { - align-self: flex-end; -} - -.slot-container { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - gap: 3px; - font-size: 0.7em; - - .slot-options { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - gap: 3px; - align-items: center; - - opacity: 30%; - - &:hover { - opacity: 100%; - } - } -} - -.slot-auras { - padding-top: 5px; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - gap: 2px; - - .slot-aura-list { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 3px; - - span::after { - content: ', '; - } - - span:last-child::after { - content: ''; - } - } -} - -.increment-decrement { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - text-align: center; - justify-content: center; - align-items: center; - align-content: center; - - &>span { - flex-grow: 3; - } - - &>button { - width: max-content; - font-size: 3rem; - flex-grow: 1; - } -} - -.setup-slot { - text-align: center; - - & button span { - cursor: pointer; - } - - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - gap: 3px; - - &>.submenu { - width: 30vw; - // position: absolute; - - .assign-list { - gap: 10px; - - & .submenu button { - width: 10vw; - } - } - - .assignees { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: center; - gap: 5px; - } - } -} - -.add-role { - color: white; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - align-items: center; - gap: 10px; - font-size: 1.5rem; - - .role-box { - width: 1.25em; - height: 1.25em; - display: flex; - align-items: center; - justify-content: center; - - &>* { - flex-shrink: 1; - width: 1em; - } - } - - cursor: pointer; -} - -.icon-role-add { - height: 48px; - width: 48px; -} - -.icon-fit { - height: 1em; -} - -.icon-15pct { - width: 15%; -} - -.village { - --faction-color: $village_color; - --faction-border: $village_border; - --faction-color-faint: $village_color_faint; - --faction-border-faint: $village_border_faint; - - background-color: $village_color; - border: 1px solid $village_border; - - &.hover:hover { - color: white; - background-color: $village_border; - } - - &.faint { - border: 1px solid $village_border_faint; - background-color: $village_color_faint; - - &.hover:hover { - background-color: $village_border_faint; - } - } -} - -.wolves { - --faction-color: $wolves_color; - --faction-border: $wolves_border; - --faction-color-faint: $wolves_color_faint; - --faction-border-faint: $wolves_border_faint; - - background-color: $wolves_color; - border: 1px solid $wolves_border; - - &.hover:hover { - color: white; - background-color: $wolves_border; - } - - &.faint { - border: 1px solid $wolves_border_faint; - background-color: $wolves_color_faint; - - &.hover:hover { - background-color: $wolves_border_faint; - } - } -} - -.intel { - --faction-color: $intel_color; - --faction-border: $intel_border; - --faction-color-faint: $intel_color_faint; - --faction-border-faint: $intel_border_faint; - - background-color: $intel_color; - border: 1px solid $intel_border; - - &.hover:hover { - color: white; - background-color: $intel_border; - } - - &.faint { - border: 1px solid $intel_border_faint; - background-color: $intel_color_faint; - - &.hover:hover { - background-color: $intel_border_faint; - } - } -} - -.defensive { - --faction-color: $defensive_color; - --faction-border: $defensive_border; - --faction-color-faint: $defensive_color_faint; - --faction-border-faint: $defensive_border_faint; - - background-color: $defensive_color; - border: 1px solid $defensive_border; - - &.hover:hover { - color: white; - background-color: $defensive_border; - } - - &.faint { - border: 1px solid $defensive_border_faint; - background-color: $defensive_color_faint; - - &.hover:hover { - background-color: $defensive_border_faint; - } - } -} - -.offensive { - --faction-color: $offensive_color; - --faction-border: $offensive_border; - --faction-color-faint: $offensive_color_faint; - --faction-border-faint: $offensive_border_faint; - - background-color: $offensive_color; - border: 1px solid $offensive_border; - - &.hover:hover { - color: white; - background-color: $offensive_border; - } - - &.faint { - border: 1px solid $offensive_border_faint; - background-color: $offensive_color_faint; - - &.hover:hover { - background-color: $offensive_border_faint; - } - } -} - -.starts-as-villager { - --faction-color: $starts_as_villager_color; - --faction-border: $starts_as_villager_border; - --faction-color-faint: $starts_as_villager_color_faint; - --faction-border-faint: $starts_as_villager_border_faint; - - background-color: $starts_as_villager_color; - border: 1px solid $starts_as_villager_border; - - &.hover:hover { - color: white; - background-color: $starts_as_villager_border; - } - - &.faint { - border: 1px solid $starts_as_villager_border_faint; - background-color: $starts_as_villager_color_faint; - - &.hover:hover { - background-color: $starts_as_villager_border_faint; - } - } -} - -.damned { - --faction-color: $damned_color; - --faction-border: $damned_border; - --faction-color-faint: $damned_color_faint; - --faction-border-faint: $damned_border_faint; - - background-color: $damned_color; - border: 1px solid $damned_border; - - &.hover:hover { - color: white; - background-color: $damned_border; - } - - &.faint { - border: 1px solid $damned_border_faint; - background-color: $damned_color_faint; - - &.hover:hover { - background-color: $damned_border_faint; - } - } -} - -.drunk { - background-color: $drunk_color; - border: 1px solid $drunk_border; - - &.hover:hover { - color: white; - background-color: $drunk_border; - } - - &.faint { - border: 1px solid $drunk_border_faint; - background-color: $drunk_color_faint; - - &.hover:hover { - background-color: $drunk_border_faint; - } - } -} - -.scapegoat { - @extend .wolves; -} - -.assignments { - display: flex; - flex-direction: row; - gap: 0; - flex-wrap: wrap; - font-size: 0.5em; - gap: 10px; - - .assignment { - color: white; - text-align: center; - padding-left: 10px; - padding-right: 10px; - // border: 1px solid white; - - &>* { - cursor: pointer; - } - } -} - -.roles-add-list { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - gap: 5px; - row-gap: 10px; - - font-size: 2em; -} - -.top-settings { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 10px; -} - -.setup-screen { - .inactive { - filter: brightness(0%); - } - - margin-top: 2%; - font-size: 1.5vw; - - height: 100vh; - - .setup { - height: 85%; - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 5%; - } - - .defensive { - background-color: color.change($defensive_color, $lightness: 30%); - border: 1px solid color.change($defensive_border, $lightness: 40%); - } -} - - - -.category { - text-align: center; - display: flex; - flex-direction: column; - - &.add-list { - @media only screen and (max-width : 599px) { - width: 100%; - } - - @media only screen and (min-width : 600px) { - width: 160px; - } - - .hidden { - display: none; - } - - width: auto; - flex-wrap: wrap; - gap: 1px; - - - &>.title { - font-size: 0.5em !important; - margin-bottom: 0px !important; - cursor: pointer; - } - - .category-list { - gap: 1px; - } - } - - &.big { - margin-bottom: 30px; - width: 30%; - } - - &.final { - margin-top: 1cm; - margin-bottom: 1cm; - } - - & .title { - text-shadow: black 1px 1px; - margin-bottom: 10px; - } - - & .count { - text-align: right; - left: -40px; - position: relative; - - width: 0; - height: 0; - - .scapegoats { - color: rgba(255, 0, 255, 0.7); - font-size: 2em; - position: absolute; - } - } - - .category-list { - text-align: left; - display: flex; - flex-wrap: nowrap; - flex-direction: column; - gap: 5px; - - .slot { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - - .attributes { - margin-left: 10px; - align-self: flex-end; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - gap: 10px; - } - - .role { - text-shadow: black 1px 1px; - - width: 100%; - filter: saturate(40%); - padding-left: 10px; - padding-right: 10px; - - &.wakes { - border: 2px solid yellow; - } - } - } - } -} - -li.change, -li.choice { - width: fit-content; - - &:hover { - .li-icon { - filter: brightness(5000%); - } - - backdrop-filter: invert(15%); - } -} - -.li-icon { - filter: grayscale(100%) brightness(150%); -} - -.icon { - width: 32px; - height: 32px; - - &:hover { - filter: contrast(120%) brightness(120%); - } -} - -.qrcode { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - z-index: 100; - position: fixed; - top: 0; - left: 0; - margin: 5vw; - width: 90vw; - height: 90vh; - gap: 1cm; - - img { - height: 70%; - width: 100%; - } - - .details { - font-size: 5vw; - border: 1px solid $village_border; - background-color: color.change($village_color, $alpha: 0.3); - - text-align: center; - - &>* { - margin-top: 0.5cm; - margin-bottom: 0.5cm; - } - } -} - -.result { - display: flex; - justify-content: center; - align-content: center; - align-items: center; - flex-direction: column; - width: 100%; - height: 100%; -} - -.result-list { - display: flex; - flex-direction: row; - flex-wrap: wrap; - width: 100%; - justify-content: space-evenly; - row-gap: 0.5cm; - - .identity { - padding: 1cm; - border: 1px solid white; - font-size: 2em; - text-align: center; - } -} - -.check-icon { - width: 40vw; - height: 40vh; - align-self: center; -} - -.insomniac { - display: flex; - width: 100%; - height: 100%; - flex-direction: column; - justify-content: center; - align-items: center; - - &.prompt { - font-size: 2em; - } -} - -.arcanist-result { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - width: 100%; - gap: 10px; - - img { - width: max-content !important; - height: max-content !important; - } -} - -.prompt { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - width: 100%; -} - -.page { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - width: 100%; - height: 100%; -} - -.signin { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - justify-content: center; - - &.full-height { - height: 100vh; - max-width: 100vw; - } - - .signin-box { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - gap: 3px; - - .field { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - width: 100%; - } - - & label { - font-size: 1.25em; - } - - & input { - height: 2em; - width: 70%; - - &#number { - text-align: center; - width: 3ch; - } - } - - &>button { - margin-top: 7px; - } - } -} - -.submenu:has(.signin) { - position: absolute; - width: max-content; - - & input { - font-size: 1rem !important; - } -} - -.attribute-span { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - align-items: center; - align-content: baseline; - justify-items: baseline; - gap: 1ch; - - padding-top: 2px; - padding-bottom: 2px; - padding-left: 2px; - padding-right: 2px; - - .inactive { - filter: grayscale(100%); - border: none; - } - - // img { - // vertical-align: sub; - // } -} - -.alignment-eq, -.roleblock-span { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 1ch; - align-items: center; -} - -.highlight-span { - height: max-content; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - align-items: center; - gap: 5px; - word-wrap: normal; - - .name { - color: white; - } - - .dead { - text-decoration: line-through; - font-style: italic; - } - - &:hover::after { - content: attr(role); - overflow-y: hidden; - position: absolute; - margin-top: 60px; - color: white; - background-color: black; - border: 1px solid white; - padding: 3px; - z-index: 4; - align-self: center; - justify-self: center; - } -} - -.character-span { - height: max-content; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - align-items: center; - gap: 1ch; - - .dead { - text-decoration: line-through; - font-style: italic; - } - - .number { - color: rgba(255, 255, 0, 0.7); - } - - .role { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - align-items: center; - font-size: 1.5vh; - - img { - vertical-align: sub; - } - - padding-top: 5px; - padding-bottom: 5px; - - padding-left: 10px; - padding-right: 10px; - height: 100%; - border: none; - gap: 5px; - - &.wolves { - background-color: color.change($wolves_color, $alpha: 0.1); - } - - &.intel { - background-color: color.change($intel_color, $alpha: 0.1); - } - - &.defensive { - background-color: color.change($defensive_color, $alpha: 0.1); - } - - &.offensive { - background-color: color.change($offensive_color, $alpha: 0.1); - } - - &.village { - background-color: color.change($village_color, $alpha: 0.1); - } - } - - padding-right: 10px; - - &.wolves, - &.intel, - &.offensive, - &.defensive, - &.village { - background-color: inherit; - } - - &.wolves { - border: 1px solid $wolves_border_faint; - } - - &.intel { - border: 1px solid $intel_border_faint; - } - - &.defensive { - border: 1px solid $defensive_border_faint; - } - - &.offensive { - border: 1px solid $offensive_border_faint; - } - - &.village { - border: 1px solid $village_border_faint; - } - - .icon { - margin: 0; - } -} - - -.post-game { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - width: 100%; -} - - -.role-page { - width: 100%; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - justify-content: center; - - h1 { - text-align: center; - // align-self: flex-start; - font-size: 4vw; - } - - .yellow { - color: yellow; - } - - .red { - color: red; - } -} - -.icons { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: center; - align-items: center; - gap: 30px; - - @media only screen and (min-width : 1600px) { - width: 100%; - } - - flex-shrink: 1; - - img { - max-height: 100%; - flex-shrink: 1; - } -} - -.icon-info { - flex-shrink: 1; -} - -.info-icon-grow { - flex-grow: 1; - width: 100%; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - - img { - flex-grow: 1; - } -} - -.info-icon-list-grow { - padding: 20px 0 20px 0; - flex-grow: 1; - width: 100%; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - - img { - flex-grow: 1; - } -} - -.info-player-list { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - width: 100%; - justify-content: center; - gap: 10px; - - &.masons, - &.large { - font-size: 2rem; - flex-wrap: wrap; - } -} - -.info-player-boxes { - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - justify-content: center; - gap: 10px; - overflow-y: hidden; - - .identity { - // flex-grow: 1; - font-size: auto; - flex-direction: row; - align-items: center; - padding: 5px 10px 5px 10px; - - .number { - color: rgba(255, 255, 0, 0.7); - font-size: 2em; - padding-right: 1cm; - } - - .pronouns { - display: none; - } - } - - flex-wrap: wrap; - text-align: center; -} - -.two-column { - display: grid; - grid-template-columns: 3fr 2fr; - height: 100%; -} - -.seer-check { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - height: 100%; - align-items: center; - justify-content: space-around; -} - -.role-title-span { - // display: grid; - // grid-template-columns: 1fr 100fr; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - height: 2rem; - width: fit-content; - - - padding-top: 5px; - padding-bottom: 5px; - padding-left: 5px; - padding-right: 10px; - width: 100%; - align-items: center; - - img { - vertical-align: text-bottom; - max-height: 2rem; - padding-left: 10px; - flex-shrink: 1; - } - - span { - flex-grow: 1; - } - - text-align: center; -} - -.false-positives { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - font-weight: bold; - font-size: 0.5em; - - gap: 10px; -} - -.bottom-bound { - display: flex; - flex-direction: column; - justify-content: center; - gap: 10px; -} - -.joined { - $joined_color: rgba(0, 255, 0, 0.7); - $joined_border: color.change($joined_color, $alpha: 1); - $joined_bg: color.change($joined_color, $alpha: 0.3); - color: white; - border: 1px solid $joined_border; - background-color: $joined_bg; - padding: 5px 10px 5px 10px; - font-size: 3rem; - text-align: center; -} - -.not-joined { - $joined_color: rgba(255, 0, 0, 0.7); - $joined_border: color.change($joined_color, $alpha: 1); - $joined_bg: color.change($joined_color, $alpha: 0.3); - color: white; - border: 1px solid $joined_border; - background-color: $joined_bg; - padding: 5px 10px 5px 10px; - font-size: 3rem; - text-align: center; -} - -.victory { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: center; - align-items: center; - font-size: 3vw; - height: max-content; - gap: 1cm; - padding: 1cm; -} - - -.end-screen { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - width: 100vw; - height: 100vh; - align-items: center; - justify-content: center; -} - -.inline-icons { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: center; - gap: 10px; - - width: 100%; -} - -:root.big-screen { - --information-height: 75vh; - --target-picker-height: 100%; - --role-reveal-cards-height: 100vh; -} - -:root:not(.big-screen) { - --information-height: auto; - --target-picker-height: auto; - --role-reveal-cards-height: auto; -} - -.information { - font-size: 2.0rem; - font-stretch: condensed; - padding-left: 5%; - padding-right: 5%; - text-align: center; - - - - display: flex; - flex-direction: column; - flex-wrap: nowrap; - justify-content: space-around; - align-items: center; - gap: 10px; - - height: var(--information-height); - - h1, - h2, - h3, - h4, - h5, - h6 { - margin: 0; - - &:first-child { - padding-top: 10px; - } - - &:last-child { - padding-bottom: 10px; - } - } - - img { - flex-shrink: 1; - flex-grow: 1; - } - - .subtext { - font-size: 1.5rem; - } - - .arcanist-targets { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 1ch; - font-size: 1.5rem; - align-items: center; - - .and { - font-style: italic; - opacity: 50%; - font-size: 0.7em; - } - } -} - -.setup-aura { - &.active { - $active_color: color.change($connected_color, $alpha: 0.7); - border: $active_color 1px solid; - color: $active_color; - background-color: color.change($active_color, $alpha: 0.2); - - &:hover { - background-color: $active_color; - color: white; - } - } -} - -.aura-title { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - gap: 3px; - // text-align: center; - align-items: center; - - .title { - flex-grow: 1; - } - - img, - .icon { - flex-shrink: 1; - } -} - -.guardian-select { - max-height: 100vh; -} - -.story-text { - font-size: 1.7em; -} - - -.dialog { - z-index: 5; - width: 100vw; - height: 100vh; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - position: fixed; - top: 0; - left: 0; - align-items: center; - justify-content: center; - color: white; - - .dialog-box { - border: 1px solid white; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - padding-left: 30px; - padding-right: 30px; - padding-top: 10px; - padding-bottom: 10px; - background-color: black; - - .options { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 20px; - - &>button { - min-width: 4cm; - font-size: 1em; - } - } - } - - .close-dialog { - align-self: flex-end; - width: 100%; - margin: 0; - border: 1px solid $wolves_border; - color: $wolves_border; - - &:hover { - background-color: $wolves_border_faint; - } - } -} - -dialog::backdrop { - background-color: rgba(0, 0, 0, 0.7); -} - -.about { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - justify-content: center; - gap: 10px; - - h1, - h2, - h3, - h4, - h5, - h6 { - margin: 0; - } - - p { - margin: 0; - text-align: center; - } - - a { - text-decoration: underline dotted; - color: white; - } - - .links { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - width: 100%; - gap: 10px; - } - - .build-info { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - justify-content: center; - text-align: center; - - label { - color: hsl(280, 65%, 43%); - } - } - - .redir-url { - user-select: text; - color: rgba(255, 255, 255, 0.7); - } -} - -.footer { - width: 100vw; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - margin-top: auto; - max-height: 1cm; - justify-content: center; - background-color: #000; - z-index: 3; - padding: 10px 0 10px 0; - border-top: 1px solid white; -} - -.has-confirm { - cursor: pointer; -} - -.dimmed { - filter: opacity(70%); -} - -.test-screen { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - gap: 10px; - align-items: center; - - width: 80vw; - margin-left: 10vw; - margin-right: 10vw; - - .test-screen-selector { - .category { - .selected { - background-color: rgba(0, 255, 0, 0.7); - border: 1px solid rgba(0, 255, 0, 1.0); - color: black; - } - - label { - font-size: 2em; - } - - button:not(:hover) { - color: white; - } - - gap: 10px; - - display: flex; - flex-direction: column; - flex-wrap: nowrap; - max-width: 80vw; - - .test-screens { - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: center; - gap: 10px; - margin: 0; - padding-left: 0; - - li { - margin: 0; - list-style: none; - } - } - } - } -} - - -.prompt-test, -.result-test { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - min-width: 40vw; - align-items: center; - - .close { - width: 100%; - } - - font-size: 2em; - - .result-number, - .prompt-number { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 20px; - } - - .result-options, - .prompt-options { - display: flex; - flex-direction: column; - flex-wrap: wrap; - align-items: center; - gap: 5px; - margin-top: 10px; - - .option-set { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 5px; - } - - .result-option, - .prompt-option { - width: 100%; - padding: 5px; - border: 1px solid white; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - gap: 5px; - } - } -} - -.inc-dec { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 20px; - - .inc-dec-content { - flex-grow: 1; - } -} - -.top-of-day-info { - width: 100%; - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: flex-start; - padding: 10px; - - gap: 10vw; - - .info-tidbit { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - gap: 5px; - - label { - font-size: 1.5em; - opacity: 70%; - } - - .parity { - font-size: 2em; - } - - .parity-pct { - font-size: 1.25em; - } - - .last-nights-kills { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 2cm; - - .identity { - .number { - color: red; - font-size: 1.5em; - } - - text-align: center; - font-size: 1.25em; - } - } - - .current-day { - color: red; - font-size: 3em; - flex-grow: 1; - } - } -} - -.option-menu { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - gap: 5px; -} - -.tabs { - display: flex; - flex-direction: row; - flex-wrap: wrap; - // gap: 3px; - margin: 0; - align-self: flex-start; - width: 100%; - - .tab-button:not(.selected) { - flex-grow: 1; - // color: white; - cursor: pointer; - } - - .tab-button { - color: white; - flex-grow: 1; - cursor: pointer; - text-shadow: 2px 2px black; - } -} - - -.story { - display: flex; - flex-direction: row; - flex-wrap: wrap; - // width: 100vw; - justify-content: space-evenly; - row-gap: 5px; - margin: 5vh 5vw 0px 5vw; - - .character-headline { - display: flex; - flex-direction: row; - gap: 3px; - align-items: center; - cursor: pointer; - - .icon-spacer { - height: 32px; - width: 32px; - } - - padding: 0.2em 1em 0.2em 1em; - min-width: 5cm; - - .identity { - text-align: center; - flex-grow: 1; - } - } - - - .actions { - width: 100%; - // min-height: 30vh; - display: flex; - flex-direction: column; - } - - - .no-content { - filter: grayscale(60%); - background-color: rgba(255, 255, 255, 0.05); - border: 1px solid rgba(255, 255, 255, 0.3); - cursor: default; - - // backdrop-filter: brightness(20%); - &:hover { - background-color: rgba(255, 255, 255, 0.05); - } - } - - .sub-headline { - display: none; - // margin-left: 0.5cm; - // font-size: 1.5em; - // font-style: italic; - } - - .action, - .change { - font-size: 1.25em; - display: flex; - flex-direction: row; - gap: 1ch; - flex-wrap: wrap; - align-items: center; - } - - .character-details { - display: flex; - flex-grow: 1; - - border-top: none; - flex-direction: column; - flex-wrap: nowrap; - gap: 3px; - padding: 2px 3px 2px 3px; - - } - - .story-time { - width: 100%; - - .time { - width: 100%; - font-size: 1.5em; - font-weight: bold; - padding: 3px 0px 3px 0px; - display: block; - - &:hover { - backdrop-filter: brightness(150%); - } - } - - .details { - display: flex; - - flex-direction: column; - flex-wrap: nowrap; - } - } -} - -dialog { - background-color: transparent; - border: none; -} - -.object-submenu { - display: flex; - flex-direction: column; - align-items: center; - gap: 5px; - - .object { - width: 100%; - background-color: black; - } - - menu { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - gap: 3px; - align-items: center; - width: 100%; - margin: 0; - padding: 0; - - &>button, - &>div, - &>div>button { - width: 100%; - } - } -} - -.wolves-highlight { - color: $wolves_color; - - .number { - color: $wolves_border; - } -} - -.village-highlight { - color: $village_color; - - .number { - color: $village_border; - } -} - -.intel-highlight { - color: $intel_color; - - .number { - color: $intel_border; - } -} - -.defensive-highlight { - color: $defensive_color; - - .number { - color: $defensive_border; - } -} - -.offensive-highlight { - color: $offensive_color; - - .number { - color: $offensive_border; - } -} - -.starts-as-villager-highlight { - color: $starts_as_villager_color; - - .number { - color: $starts_as_villager_border; - } -} - -.damned-highlight { - color: $damned_color; - - .number { - color: $damned_color; - } -} - - -.dead-chat { - height: 100%; - // width: 100%; - // max-width: 100vw; - padding: 0px 3% 0 3%; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - flex-grow: 1; - overflow-x: hidden; - gap: 3px; - - .chat-messages { - &:first-child { - margin-top: auto; - } - - user-select: text; - padding-inline-start: 0px; - overflow-y: scroll; - display: flex; - flex-direction: column; - margin: 0; - flex-grow: 1; - max-width: 100%; - max-height: 95vh; - - } - - .message { - display: flex; - flex-direction: row; - flex-wrap: wrap; - margin-left: 0; - gap: 1ch; - align-items: baseline; - - .dead-ident { - font-weight: bold; - - &[pronouns]:hover::after { - content: attr(pronouns); - overflow-y: hidden; - position: relative; - color: white; - background-color: black; - border: 1px solid white; - padding: 3px; - z-index: 4; - align-self: center; - justify-self: center; - } - } - - .time { - flex-shrink: 1; - opacity: 50%; - font-size: 1em; - } - - .message-content { - flex-grow: 1; - font-size: 1.2em; - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: baseline; - gap: 1ch; - } - - .time-change { - width: 100%; - text-align: center; - } - } - - form { - max-width: 100%; - margin: 0; - flex-grow: 1; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - padding-bottom: 10px; - max-height: 5ch; - } - - #message-input { - padding: 5px 0px 5px 0px; - padding-inline: 0px 3px 0px 3px; - align-self: flex-end; - width: 100%; - flex-grow: 1; - } -} - -.vote-summary { - list-style: none; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - font-size: 2em; - - li { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: baseline; - - .id { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: baseline; - } - - .votes { - margin-left: 1ch; - } - } -} - -.voting-mode { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - gap: 1ch; - font-size: 2em; - align-items: center; - - .clear { - width: 100%; - } - - .mode-buttons { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - flex-grow: 1; - width: 100%; - - &>button { - flex-grow: 1; - } - } -} - -.vote-char { - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: baseline; -} - -.voter-id { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 1ch; - - .number { - font-weight: bold; - } - - .name { - font-style: italic; - } -} - -.vote-char { - display: flex; - flex-direction: column; - flex-wrap: nowrap; - align-items: center; - min-width: 5cm; - max-width: 9cm; - overflow-x: hidden; -} - -.vote-buttons { - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: 1ch; -} - -.host-dead-chat { - height: calc(100vh - $host_nav_total_height); - width: 100%; -} diff --git a/werewolves/src/app.rs b/werewolves/src/app.rs new file mode 100644 index 0000000..465aa02 --- /dev/null +++ b/werewolves/src/app.rs @@ -0,0 +1,130 @@ +pub mod pages { + werewolves_macros::include_path!("werewolves/src/app/pages"); +} + +pub mod components { + werewolves_macros::include_path!("werewolves/src/app/components"); + pub mod input { + werewolves_macros::include_path!("werewolves/src/app/components/input"); + } +} + +pub mod class; +pub mod storage; + +use codee::string::JsonSerdeCodec; +use gloo::storage::Storage; +use leptos::prelude::*; +use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context}; +use leptos_router::{ + components::{ProtectedRoute, Route, Router, Routes}, + path, +}; +use leptos_use::storage::{UseStorageOptions, use_local_storage, use_local_storage_with_options}; +use reactive_stores::Store; +use serde::{Deserialize, Serialize}; + +use crate::{ + app::{ + components::Nav, + pages::{GamePage, Main, NotFound, Signin, Signup, UserSettings}, + storage::{ + LocalStorage, SessionStorage, Stored, + user::{AuthContext, AuthContextStoreFields, PasswordlessUser, UserSession, UserToken}, + }, + }, + state::{InitOrUpdateStore, SessionState}, +}; + +pub fn shell(options: LeptosOptions) -> impl IntoView { + view! { + + + + + + + + + + + + + + } +} + +#[derive(Debug, Clone, Serialize, PartialEq, Eq, Deserialize)] +pub struct TutorialSettings { + pub enabled: bool, +} + +impl Default for TutorialSettings { + fn default() -> Self { + Self { enabled: true } + } +} + +impl Stored for TutorialSettings { + const STORAGE_KEY: &str = "tutorial-settings"; +} + +#[component] +pub fn App() -> impl IntoView { + // Provides context that manages stylesheets, titles, meta tags, etc. + provide_meta_context(); + let auth_store = Store::new(AuthContext::new()); + provide_context(auth_store); + let session_store = Store::new(SessionState::new()); + provide_context(session_store); + Effect::new(move || auth_store.init_or_update()); + Effect::new(move || session_store.init_or_update()); + + let (tut_read, tut_write, _) = + use_local_storage::(TutorialSettings::STORAGE_KEY); + provide_context((tut_read, tut_write)); + + let is_logged_in = move || { + auth_store + .initialized() + .get() + .then_some(auth_store.session().get().is_some()) + }; + let not_logged_in = move || Some(auth_store.session().get().is_none()); + + view! { + + // sets the document title + + + // content for this welcome page + <Router> + <main> + <Nav /> + <Routes fallback=NotFound> + <Route path=path!("/") view=Main /> + <ProtectedRoute + path=path!("/signin") + view=|| view! { <Signin /> } + condition=not_logged_in + redirect_path=|| "/" + /> + <ProtectedRoute + path=path!("/signup") + view=|| view! { <Signup /> } + condition=not_logged_in + redirect_path=|| "/" + /> + <ProtectedRoute + path=path!("/user/settings") + view=UserSettings + condition=is_logged_in + redirect_path=|| "/" + /> + <Route path=path!("/games/:id") view=|| view! { <GamePage /> } /> + </Routes> + + </main> + </Router> + } +} diff --git a/werewolves/src/app/class.rs b/werewolves/src/app/class.rs new file mode 100644 index 0000000..6474670 --- /dev/null +++ b/werewolves/src/app/class.rs @@ -0,0 +1,166 @@ +// Copyright (C) 2026 Emilis Bliūdžius +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +use werewolves_proto::{ + aura::AuraTitle, character::Character, game::Category, role::RoleTitle, team::Team, +}; + +pub trait PartialClass { + fn partial_class(&self) -> Option<&'static str>; +} + +impl PartialClass for AuraTitle { + fn partial_class(&self) -> Option<&'static str> { + match self { + AuraTitle::Damned => Some("damned"), + AuraTitle::Drunk => Some("drunk"), + AuraTitle::Insane + | AuraTitle::Bloodlet + | AuraTitle::Scapegoat + | AuraTitle::RedeemableScapegoat + | AuraTitle::VindictiveScapegoat + | AuraTitle::SpitefulScapegoat + | AuraTitle::InevitableScapegoat => None, + } + } +} + +pub trait Class { + fn class(&self) -> &'static str; +} + +impl Class for Character { + fn class(&self) -> &'static str { + if let Team::AnyEvil = self.team() { + return "damned"; + } + + self.role_title().category().class() + } +} + +impl Class for RoleTitle { + fn class(&self) -> &'static str { + self.category().class() + } +} + +impl Class for Category { + fn class(&self) -> &'static str { + match self { + Category::Wolves => "wolves", + Category::Villager => "village", + Category::Intel => "intel", + Category::Defensive => "defensive", + Category::Offensive => "offensive", + Category::StartsAsVillager => "starts-as-villager", + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct Classes(Vec<String>); +impl<I> From<I> for Classes +where + I: Into<Vec<String>>, +{ + fn from(value: I) -> Self { + Self(value.into()) + } +} +impl core::fmt::Display for Classes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.0.join(" ").as_str()) + } +} + +pub trait AsClasses { + fn as_classes(&self) -> Classes; +} + +impl AsClasses for [&str] { + fn as_classes(&self) -> Classes { + Classes(self.iter().map(|s| s.to_string()).collect()) + } +} + +impl leptos::tachys::html::class::IntoClass for Classes { + type AsyncOutput = Self; + type State = (leptos::tachys::renderer::types::Element, Self); + type Cloneable = Self; + type CloneableOwned = Self; + + fn html_len(&self) -> usize { + let len = self.0.len(); + self.0.iter().map(|c| c.len()).sum::<usize>() + + if len == 2 { + 1 + } else if len > 2 { + len - 1 + } else { + 0 + } + } + + fn to_html(self, class: &mut String) { + class.push_str(self.0.join(" ").as_str()); + } + + fn should_overwrite(&self) -> bool { + true + } + + fn hydrate<const FROM_SERVER: bool>( + self, + el: &leptos::tachys::renderer::types::Element, + ) -> Self::State { + if !FROM_SERVER { + leptos::tachys::renderer::Rndr::set_attribute(el, "class", self.to_string().as_str()); + } + (el.clone(), self) + } + + fn build(self, el: &leptos::tachys::renderer::types::Element) -> Self::State { + leptos::tachys::renderer::Rndr::set_attribute(el, "class", self.to_string().as_str()); + (el.clone(), self) + } + + fn rebuild(self, state: &mut Self::State) { + let (el, prev) = state; + if self != *prev { + leptos::tachys::renderer::Rndr::set_attribute(el, "class", self.to_string().as_str()); + } + *prev = self; + } + + fn into_cloneable(self) -> Self::Cloneable { + self + } + + fn into_cloneable_owned(self) -> Self::CloneableOwned { + self.into() + } + + fn dry_resolve(&mut self) {} + + async fn resolve(self) -> Self::AsyncOutput { + self + } + + fn reset(state: &mut Self::State) { + let (el, _prev) = state; + leptos::tachys::renderer::Rndr::remove_attribute(el, "class"); + } +} diff --git a/werewolves/src/app/components/debug_marker.rs b/werewolves/src/app/components/debug_marker.rs new file mode 100644 index 0000000..c9373cd --- /dev/null +++ b/werewolves/src/app/components/debug_marker.rs @@ -0,0 +1,8 @@ +use leptos::prelude::*; + +#[component] +pub fn DebugMarker() -> impl IntoView { + option_env!("LOCAL_DEBUG").map(|_| { + view! { <div class="debug-marker">"DEBUG"</div> } + }) +} diff --git a/werewolves/src/app/components/error.rs b/werewolves/src/app/components/error.rs new file mode 100644 index 0000000..7800c3a --- /dev/null +++ b/werewolves/src/app/components/error.rs @@ -0,0 +1,37 @@ +use api::error::ServerError; +use leptos::{html::Div, prelude::*}; +use leptos_use::{ + UseDraggableOptions, UseDraggableReturn, core::Position, use_draggable_with_options, +}; + +pub trait ViewError: core::error::Error { + fn view(&self) -> impl IntoView; +} + +#[component] +pub fn ErrorBox(msg: RwSignal<Option<String>>) -> impl IntoView { + let el = NodeRef::<Div>::new(); + + // `style` is a helper string "left: {x}px; top: {y}px;" + let UseDraggableReturn { style, .. } = use_draggable_with_options( + el, + UseDraggableOptions::default().initial_value(Position { x: 40.0, y: 40.0 }), + ); + let content = move || { + msg.get().map(|text| { + view! { + <div class="error_container" hidden=move || msg.get().is_none()> + <div node_ref=el style=move || style.get() class="error"> + <h5>"error"</h5> + <p>{text.to_string()}</p> + <button on:click=move |ev| { + ev.prevent_default(); + msg.set(None); + }>"close"</button> + </div> + </div> + } + }) + }; + view! { {content} } +} diff --git a/werewolves/src/app/components/identity.rs b/werewolves/src/app/components/identity.rs new file mode 100644 index 0000000..d92f6bf --- /dev/null +++ b/werewolves/src/app/components/identity.rs @@ -0,0 +1,41 @@ +use leptos::prelude::*; +use werewolves_proto::message::{Identification, PublicIdentity}; + +#[component] +pub fn IdentityInline(ident: ReadSignal<PublicIdentity>) -> impl IntoView { + let number = move || { + ident + .read() + .number + .as_ref() + .map(|num| view! { <span class="number">{num.get()}</span> }.into_any()) + .unwrap_or_else(|| { + view! { <span class="number red">"?"</span> } + .into_any() + }) + }; + let pronouns = move || { + ident.read().pronouns.as_ref().map(|p| { + view! { <span class="pronouns">"("{p.clone()}")"</span> } + }) + }; + view! { + <span class="identity"> + {number} <span class="name">{move || ident.read().name.clone()}</span> {pronouns} + </span> + } +} + +#[component] +pub fn IdentificationInline(ident: Identification) -> impl IntoView { + if !ident.public.name.trim().is_empty() { + return view! { <IdentityInline ident=RwSignal::new(ident.public).read_only() /> } + .into_any(); + } + view! { + <span class="identity"> + <span class="player-id">{ident.player_id.to_string()}</span> + </span> + } + .into_any() +} diff --git a/werewolves/src/app/components/input/text.rs b/werewolves/src/app/components/input/text.rs new file mode 100644 index 0000000..851aa41 --- /dev/null +++ b/werewolves/src/app/components/input/text.rs @@ -0,0 +1,44 @@ +use core::fmt::Display; + +use leptos::prelude::*; +use uuid::Uuid; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum InputType { + #[default] + Text, + Password, +} + +impl Display for InputType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InputType::Text => f.write_str("text"), + InputType::Password => f.write_str("password"), + } + } +} + +#[component] +pub fn TextInput( + #[prop(optional)] label: Option<String>, + value: RwSignal<String>, + #[prop(optional)] autocomplete: bool, + #[prop(optional)] r#type: InputType, +) -> impl IntoView { + let id = Uuid::new_v4().to_string(); + let label = label.map(|label| { + view! { <label for=id.clone()>{label}</label> } + }); + let initial_value = move || value.read().to_string(); + view! { + {label} + <input + type=r#type.to_string() + id=id + value=initial_value + on:input:target=move |ev| value.set(ev.target().value()) + autocomplete=autocomplete + /> + } +} diff --git a/werewolves/src/app/components/link_button.rs b/werewolves/src/app/components/link_button.rs new file mode 100644 index 0000000..2a57a9b --- /dev/null +++ b/werewolves/src/app/components/link_button.rs @@ -0,0 +1,29 @@ +use leptos::prelude::*; +use leptos_router::hooks::use_url; + +#[component] +pub fn LinkButton(href: String, mut children: ChildrenFnMut) -> impl IntoView { + let url = use_url(); + let link = move || { + let already_open = url.get().path() == href; + match already_open { + true => view! { + <button + class:current=already_open + disabled=already_open + class:no-hover=already_open + > + {children()} + </button> + } + .into_any(), + false => view! { + <a href=href.clone()> + <button>{children()}</button> + </a> + } + .into_any(), + } + }; + view! { {link} } +} diff --git a/werewolves/src/app/components/modal.rs b/werewolves/src/app/components/modal.rs new file mode 100644 index 0000000..41c78b5 --- /dev/null +++ b/werewolves/src/app/components/modal.rs @@ -0,0 +1,107 @@ +use core::ops::Not; + +use leptos::ev::MouseEvent; +use leptos::prelude::*; + +#[derive(Debug, Clone, Default)] +pub enum DialogMode { + #[default] + Close, + Box, + ConfirmOrClose(Callback<()>), +} + +#[component] +pub fn DialogModal( + text: String, + #[prop(optional)] open: Option<RwSignal<bool>>, + #[prop(optional)] button_class: String, + #[prop(default = Box::new(|| ().into_any()))] mut children: ChildrenFnMut, + #[prop(optional)] mode: DialogMode, + #[prop(default = true)] close_backdrop: bool, +) -> impl IntoView { + // use generated id if not supplied + let open = open.unwrap_or_else(|| RwSignal::new(false)); + + let close_cb = { + move |ev: MouseEvent| { + ev.prevent_default(); + open.set(false); + } + }; + let close = { + view! { + <button on:click=close_cb.clone() class="close"> + "close" + </button> + } + }; + let mode_buttons = match mode { + DialogMode::Box => ().into_any(), + DialogMode::Close => view! { <div class="options">{close}</div> }.into_any(), + DialogMode::ConfirmOrClose(on_confirm) => view! { + <div class="options"> + <button on:click=move |_| on_confirm.run(())>{"confirm"}</button> + {close} + </div> + } + .into_any(), + }; + let dialog_element: NodeRef<leptos::html::Dialog> = NodeRef::new(); + let on_backdrop_click = { + let close_cb = close_cb.clone(); + move |ev: MouseEvent| { + ev.prevent_default(); + if !close_backdrop { + return; + } + #[cfg(feature = "hydrate")] + { + let Some(dialog) = dialog_element.get() else { + log::error!("dialog_element is None"); + return; + }; + + let Ok(Some(dialog_box)) = dialog.query_selector(".dialog-box") else { + log::error!(".dialog-box is None"); + return; + }; + let rect: leptos::web_sys::DomRect = dialog_box.get_bounding_client_rect(); + + let is_in_dialog = rect.top() as i32 <= ev.client_y() + && ev.client_y() <= rect.top() as i32 + rect.height() as i32 + && rect.left() as i32 <= ev.client_x() + && ev.client_x() <= rect.left() as i32 + rect.width() as i32; + + if !is_in_dialog { + close_cb(ev); + } + } + } + }; + let is_open = move || open.get(); + let modal = view! { + <dialog on:click=on_backdrop_click open=is_open node_ref=dialog_element> + <div class="dialog"> + <div class="dialog-box"> + <div class="dialog-main" class:full=matches!(mode, DialogMode::Box)> + {children()} + </div> + {mode_buttons} + </div> + </div> + </dialog> + }; + + let on_click = move |ev: MouseEvent| { + ev.prevent_default(); + open.set(true); + }; + let button = text.is_empty().not().then_some(view! { + <button class=button_class on:click=on_click> + {text.clone()} + </button> + }); + + view! { <div class="dialog-modal">{button} {modal}</div> } +} diff --git a/werewolves/src/app/components/nav.rs b/werewolves/src/app/components/nav.rs new file mode 100644 index 0000000..dfa1c85 --- /dev/null +++ b/werewolves/src/app/components/nav.rs @@ -0,0 +1,122 @@ +use core::ops::Not; + +use api::{error::ServerError, game::GameId, token::TokenString}; +use leptos::{ev::MouseEvent, prelude::*}; +use leptos_router::hooks::use_url; +use reactive_stores::Store; + +use crate::app::{ + components::LinkButton, + storage::user::{AuthContext, AuthContextStoreFields}, +}; + +#[server] +pub async fn get_active_game(token: TokenString) -> Result<Option<GameId>, ServerError> { + let db = use_context::<api::state::AppState>() + .expect("no app state") + .db; + let user = db.user().check_token(&token).await?; + Ok(db.game().get_joined_active_game(user.id).await?) +} + +#[server] +pub async fn new_game(token: TokenString) -> Result<GameId, ServerError> { + let db = use_context::<api::state::AppState>() + .expect("no app state") + .db; + let user = db.user().check_token(&token).await?; + Ok(db.game().new_game(user.id).await?.id) +} + +#[component] +pub fn Nav() -> impl IntoView { + let auth = expect_context::<Store<AuthContext>>(); + let home_button = move || view! { <LinkButton href="/".into()>"home"</LinkButton> }.into_any(); + let active_game = ServerAction::<GetActiveGame>::new(); + let url = use_url(); + + let default_view = move || { + view! { + {home_button} + <LinkButton href="/signin".into()>"signin"</LinkButton> + <LinkButton href="/signup".into()>"signup"</LinkButton> + } + }; + let buttons = move || { + auth.session().get().map(|session| { + let username = session.display_name.is_some().then_some( + view! { <span class="username">"("{session.username.clone()}")"</span> }, + ); + let new_game_action = ServerAction::<NewGame>::new(); + + Effect::new(move || { + if let Some(Ok(game_id)) = new_game_action.value().get() + && let Err(err) = gloo::utils::window() + .location() + .replace(format!("/games/{game_id}").as_str()) + { + log::error!("setting window href to [/]: {err:?}"); + } + }); + let new_game_button = move || { + url.read() + .path() + .strip_prefix("/games/") + .map(|url| !url.trim().is_empty()) + .unwrap_or_default() + .not() + .then_some({ + let create_game = move |ev: MouseEvent| { + ev.prevent_default(); + if let Some(session) = auth.session().get() { + new_game_action.dispatch(NewGame { + token: session.token.clone(), + }); + } else { + log::error!("not signed in!"); + } + }; + view! { <button on:click=create_game>"new game"</button> } + }) + }; + let active_game_button = move || { + let Some(session) = auth.session().get() else { + return None; + }; + if active_game.value().read_untracked().is_none() { + active_game.dispatch(GetActiveGame { + token: session.token, + }); + } + active_game.value().get().and_then(|resp| match resp { + Ok(Some(g)) => { + let active_path = format!("/games/{g}"); + Some(view! { <LinkButton href=active_path>"active game"</LinkButton> }) + } + Ok(None) => None, + Err(err) => { + log::error!("getting active game: {err}"); + None + } + }) + }; + view! { + {home_button} + <span class="display-name">{session.name().to_string()}</span> + {username} + {active_game_button} + {new_game_button} + <div class="right-side"> + <LinkButton href="/user/settings".into()>{"⚙️"}</LinkButton> + </div> + } + }) + }; + view! { + <nav class="header"> + <Show when=move || auth.session().get().is_some() fallback=default_view> + {buttons} + </Show> + </nav> + } +} diff --git a/werewolves/src/app/components/sample.rs b/werewolves/src/app/components/sample.rs new file mode 100644 index 0000000..60c214f --- /dev/null +++ b/werewolves/src/app/components/sample.rs @@ -0,0 +1,88 @@ +use core::num::NonZeroU8; +use leptos::prelude::*; + +use werewolves_proto::{ + message::{Identification, PublicIdentity}, + player::PlayerId, +}; + +use crate::app::TutorialSettings; + +pub trait Sample { + fn sample() -> Self; +} +const NAMES: &[&str] = &[ + "Jeff", + "Baroque", + "worm", + "Fort", + "Bejeweled", + "Bedazzled", + "Comfort Sus", +]; +const PRONOUNS: &[&str] = &[ + "he/him", + "she/her", + "they/them", + "she/they", + "he/they", + "it/its", +]; + +impl Sample for PublicIdentity { + fn sample() -> Self { + PublicIdentity { + name: NAMES[rand::random_range(0..NAMES.len())].to_string(), + pronouns: Some(PRONOUNS[rand::random_range(0..PRONOUNS.len())].to_string()), + number: NonZeroU8::new(rand::random_range(1..=20)), + } + } +} + +impl Sample for Identification { + fn sample() -> Self { + Identification { + player_id: PlayerId::new(), + public: PublicIdentity::sample(), + } + } +} + +#[component] +pub fn TutorialBox(children: Children) -> impl IntoView { + let sample_hidden = RwSignal::new(false); + let (tut_read, _) = + expect_context::<(Signal<TutorialSettings>, WriteSignal<TutorialSettings>)>(); + + view! { + <div class="tutorial-box" hidden=move || !tut_read.read().enabled> + <button + class="hide" + hidden=move || sample_hidden.get() + on:click=move |_| sample_hidden.set(true) + > + "hide" + </button> + <button + class="show" + hidden=move || !sample_hidden.get() + on:click=move |_| sample_hidden.set(false) + > + "show" + </button> + <div class="tutorial" hidden=move || sample_hidden.get()> + {children()} + </div> + </div> + } +} + +#[component] +pub fn Sample(children: Children) -> impl IntoView { + view! { <div class="sample">{children()}</div> } +} + +#[component] +pub fn Equals() -> impl IntoView { + view! { <span class="equals">{"="}</span> } +} diff --git a/werewolves/src/app/pages/game.rs b/werewolves/src/app/pages/game.rs new file mode 100644 index 0000000..91be4f6 --- /dev/null +++ b/werewolves/src/app/pages/game.rs @@ -0,0 +1,189 @@ +pub mod big; +mod host; +mod player; + +use api::{ + cbor_leptos::CborEncoding, + message::{IntoClientResponse, WrappedServerMessage}, +}; +use codee::{HybridEncoder, binary::MsgpackSerdeCodec}; +use leptos::prelude::*; +use leptos_router::hooks; +use leptos_use::{ + ReconnectLimit, UseEventSourceOptions, UseEventSourceReturn, UseWebSocketOptions, + UseWebSocketReturn, core::ConnectionReadyState, use_event_source, + use_event_source_with_options, use_websocket, use_websocket_with_options, +}; +use reactive_stores::Store; +use werewolves_proto::message::{ + ClientMessage, + host::{HostMessage, ServerToHostMessage}, +}; + +use crate::{ + ConsoleLogError, LogError, + app::{ + components::DebugMarker, + pages::game::{host::HostGamePage, player::PlayerGamePage}, + storage::user::{AuthContext, AuthContextStoreFields}, + }, + state::{RedirectAfterSignin, SessionState, SessionStateStoreFields}, +}; + +#[component] +pub fn GamePage() -> impl IntoView { + let params = hooks::use_params_map(); + let auth = expect_context::<Store<AuthContext>>(); + let state = expect_context::<Store<SessionState>>(); + Effect::new(move || { + params.read().get("id").unwrap_or_default(); + }); + let UseWebSocketReturn { + ready_state, + message, + send, + open, + close, + .. + } = use_websocket_with_options::< + WrappedServerMessage, + IntoClientResponse, + MsgpackSerdeCodec, + _, + _, + >( + format!( + "/api/games/{}", + params.read_untracked().get("id").unwrap_or_default() + ) + .as_str(), + UseWebSocketOptions::default().reconnect_limit(ReconnectLimit::Infinite), + ); + let opened = RwSignal::new(false); + let host_message = RwSignal::new(None); + let player_message = RwSignal::new(None); + let host_reply: RwSignal<Option<HostMessage>> = RwSignal::new(None); + let player_reply: RwSignal<Option<ClientMessage>> = RwSignal::new(None); + let disconnect = RwSignal::new(false); + + Effect::new({ + let close = close.clone(); + move || { + if disconnect.get() { + close(); + } + } + }); + + Effect::watch( + move || message.get(), + move |message, prev, _| { + if let Some(prev) = prev + && message == prev + { + return; + } + match message.clone() { + Some(IntoClientResponse::Host(host_msg)) => { + log::debug!("got host message: {:?}", host_msg.title()); + host_message.set(Some(host_msg)); + } + Some(IntoClientResponse::Player(player_msg)) => { + log::debug!("got player message: {:?}", player_msg.title()); + player_message.set(Some(player_msg)); + } + None => {} + } + }, + true, + ); + Effect::new({ + let send = send.clone(); + move || { + let Some(reply) = host_reply.get() else { + return; + }; + log::debug!("sending host message: {reply:?}"); + send(&WrappedServerMessage::HostMessage(reply.clone())); + host_reply.write_untracked().take(); + } + }); + Effect::new({ + let send = send.clone(); + move || { + let Some(reply) = player_reply.get() else { + return; + }; + log::debug!("sending client message: {reply:?}"); + send(&WrappedServerMessage::ClientMessage(reply.clone())); + player_reply.write_untracked().take(); + } + }); + + let status = move || match ready_state.get() { + ConnectionReadyState::Connecting => view! { + <div class="status-bar"> + <DebugMarker /> + <h1>"connecting..."</h1> + </div> + } + .into_any(), + ConnectionReadyState::Closing => view! { + <div class="status-bar"> + <DebugMarker /> + <h1>"closing"</h1> + </div> + } + .into_any(), + ConnectionReadyState::Open => { + Effect::new({ + let send = send.clone(); + let close = close.clone(); + move || { + let o = opened.get(); + if o { + return; + } + if let Some(token) = auth.token().get() { + let auth_message = WrappedServerMessage::Authentication(token.token); + log::debug!("sending auth message: {auth_message:?}"); + send(&auth_message); + opened.set(true); + } else { + close(); + if let Ok(href) = gloo::utils::window().location().href() { + state + .redirect_after_signin() + .set(Some(RedirectAfterSignin::new(href))); + } + #[cfg(feature = "hydrate")] + gloo::utils::window() + .location() + .set_href("/") + .console_log_err(); + } + } + }); + ().into_any() + } + ConnectionReadyState::Closed => view! { + <div class="status-bar disconnected"> + <DebugMarker /> + <h1>"disconnected"</h1> + </div> + } + .into_any(), + }; + + let status = option_env!("LOCAL_DEBUG").map(|_| status); + + view! { + {status} + <HostGamePage message=host_message.into() reply=host_reply.write_only() /> + <PlayerGamePage + message=player_message.into() + reply=player_reply.write_only() + disconnect=disconnect + /> + } +} diff --git a/werewolves/src/app/pages/game/big.rs b/werewolves/src/app/pages/game/big.rs new file mode 100644 index 0000000..23b5a9b --- /dev/null +++ b/werewolves/src/app/pages/game/big.rs @@ -0,0 +1,4 @@ +use leptos::prelude::*; + +#[component] +pub fn BigScreen() -> impl IntoView {} diff --git a/werewolves/src/app/pages/game/host.rs b/werewolves/src/app/pages/game/host.rs new file mode 100644 index 0000000..ed258eb --- /dev/null +++ b/werewolves/src/app/pages/game/host.rs @@ -0,0 +1,76 @@ +werewolves_macros::include_path!("werewolves/src/app/pages/game/host"); + +use std::collections::HashMap; + +use leptos::prelude::*; +use werewolves_proto::{ + game::{Category, GameSettings}, + message::{ + PlayerState, + host::{HostLobbyMessage, HostMessage, ServerToHostMessage as Srv2Host}, + }, +}; + +#[component] +pub fn HostGamePage( + message: Signal<Option<Srv2Host>>, + reply: WriteSignal<Option<HostMessage>>, +) -> impl IntoView { + let settings = RwSignal::new(GameSettings::default()); + let qr_mode = RwSignal::new(false); + let players: RwSignal<Box<[PlayerState]>> = RwSignal::new(Box::new([])); + let dialog_open = RwSignal::new(false); + let open_categories = RwSignal::new( + Category::ALL + .into_iter() + .map(|c| (c, false)) + .collect::<HashMap<_, _>>(), + ); + + Effect::watch( + move || settings.get(), + move |s: &GameSettings, _, _| { + reply.set(Some(HostMessage::Lobby(HostLobbyMessage::SetGameSettings( + s.clone(), + )))); + }, + false, + ); + Effect::watch( + move || qr_mode.get(), + move |q, _, _| reply.set(Some(HostMessage::Lobby(HostLobbyMessage::SetQrMode(*q)))), + false, + ); + let content = move || { + if let Some(message) = message.get() { + match message { + Srv2Host::Lobby { + players: p, + settings: s, + qr_mode: q, + } => { + log::info!("setting setties"); + settings.set(s); + *qr_mode.write_untracked() = q; + players.set(p); + + view! { + <Settings + open_categories=open_categories + settings=settings + players=players.read_only() + qr_mode=qr_mode + dialog_open=dialog_open + /> + } + .into_any() + } + _ => view! { <h2>{format!("{message:#?}")}</h2> }.into_any(), + } + } else { + ().into_any() + } + }; + + view! { {content} } +} diff --git a/werewolves/src/app/pages/game/host/players.rs b/werewolves/src/app/pages/game/host/players.rs new file mode 100644 index 0000000..ea992f2 --- /dev/null +++ b/werewolves/src/app/pages/game/host/players.rs @@ -0,0 +1,58 @@ +use leptos::{ev::MouseEvent, prelude::*}; +use werewolves_proto::{ + message::{Identification, PlayerState, PublicIdentity}, + player::PlayerId, +}; + +use crate::app::components::{Equals, IdentificationInline, Sample, TutorialBox}; + +#[component] +pub fn HostPlayerList(players: ReadSignal<Box<[PlayerState]>>) -> impl IntoView { + let players = move || { + players + .read() + .iter() + .map(|p| { + view! { + <button class="player" class:connected=p.connected> + <IdentificationInline ident=p.identification.clone() /> + </button> + } + }) + .collect_view() + }; + let sample_no_number = { + let mut id = Identification::sample(); + id.public.number.take(); + id + }; + + view! { + <div class="lobby-players"> + <div class="player-list">{players}</div> + </div> + <TutorialBox> + <Sample> + <button class="player"> + <IdentificationInline ident=Identification::sample() /> + </button> + <Equals /> + <span class="ok">"doesn't have lobby open on phone"</span> + </Sample> + <Sample> + <button class="player connected"> + <IdentificationInline ident=Identification::sample() /> + </button> + <Equals /> + <span class="ok">"lobby open on phone"</span> + </Sample> + <Sample> + <button class="player"> + <IdentificationInline ident=sample_no_number /> + </button> + <Equals /> + <span class="ok">"no number assigned"</span> + </Sample> + </TutorialBox> + } +} diff --git a/werewolves/src/app/pages/game/host/settings.rs b/werewolves/src/app/pages/game/host/settings.rs new file mode 100644 index 0000000..8a19a3f --- /dev/null +++ b/werewolves/src/app/pages/game/host/settings.rs @@ -0,0 +1,330 @@ +use core::ops::Not; +use std::{collections::HashMap, sync::Arc}; + +use convert_case::{Case, Casing}; +use leptos::{ev::MouseEvent, prelude::*}; +use werewolves_proto::{ + aura::AuraTitle, + game::{Category, GameSettings, SetupSlot}, + message::{PlayerState, host::HostMessage}, + role::{Role, RoleTitle}, +}; + +use crate::app::{ + class::{AsClasses, Class, PartialClass}, + components::{DialogModal, DialogMode, IdentityInline}, + pages::game::host::HostPlayerList, +}; + +#[component] +pub fn Settings( + settings: RwSignal<GameSettings>, + players: ReadSignal<Box<[PlayerState]>>, + qr_mode: RwSignal<bool>, + dialog_open: RwSignal<bool>, + open_categories: RwSignal<HashMap<Category, bool>>, +) -> impl IntoView { + let slots = move || { + settings + .read() + .slots() + .iter() + .cloned() + .map(move |s| { + let signal = RwSignal::new(s); + Effect::watch( + move || signal.get(), + move |slot_update, _, _| settings.write().update_slot(slot_update.clone()), + false, + ); + + view! { <SettingsSetupSlot setup_slot=signal players=players dialog_open=dialog_open /> } + }) + .collect_view() + }; + let qr_mode_btn = move || { + let qr_toggle = move |ev: MouseEvent| { + ev.prevent_default(); + qr_mode.set(!qr_mode.get()); + }; + match qr_mode.get() { + true => view! { <button on:click=qr_toggle>"disable qr mode"</button> }.into_any(), + false => view! { <button on:click=qr_toggle>"enable qr mode"</button> }.into_any(), + } + }; + let roles_by_category = { + let mut r: HashMap<Category, Vec<RoleTitle>> = HashMap::new(); + for role in RoleTitle::ALL { + if let Some(existing) = r.get_mut(&role.category()) { + existing.push(role); + } else { + r.insert(role.category(), vec![role]); + } + } + r + }; + let ordered_keys = { + let mut k = roles_by_category.keys().copied().collect::<Box<_>>(); + k.sort(); + k + }; + Effect::new(|| log::debug!("rendering settings")); + let categories = ordered_keys + .into_iter() + .map(|c| { + let roles_by_category = roles_by_category.clone(); + let roles = move || { + open_categories + .with(|open| open.get(&c).copied().unwrap_or_default()) + .then(|| { + roles_by_category + .get(&c) + .unwrap() + .iter() + .copied() + .map(|r| { + let add_role = move |ev: MouseEvent| { + ev.prevent_default(); + settings.write().new_slot(r); + }; + let classes = + ["add-role", r.class(), "faint", "hover", "box"].as_classes(); + view! { + <button class=classes on:click=add_role> + {r.to_string().to_case(Case::Title)} + </button> + } + }) + .collect_view() + }) + }; + let toggle = move |ev: MouseEvent| { + ev.prevent_default(); + let is_open = open_categories + .with_untracked(|open| open.get(&c).copied().unwrap_or_default()); + open_categories.write().insert(c, !is_open); + }; + let classes = ["title", c.class(), "hover", "box"].as_classes(); + view! { + <div class="category"> + <button class=classes on:click=toggle> + {c.to_string()} + </button> + <div class="roles">{roles}</div> + </div> + } + }) + .collect_view(); + + view! { + <div class="game-settings"> + <div class="top-bar">{qr_mode_btn}</div> + <div class="role-add-list">{categories}</div> + <div class="setup-slots">{slots}</div> + </div> + <HostPlayerList players=players /> + } +} +#[component] +fn SettingsSetupSlot( + setup_slot: RwSignal<SetupSlot>, + players: ReadSignal<Box<[PlayerState]>>, + dialog_open: RwSignal<bool>, +) -> impl IntoView { + let auras = move || { + let slot = setup_slot.read(); + slot.auras.is_empty().not().then(|| { + slot.auras + .iter() + .map(|a| { + view! { <span class="aura">{a.to_string().to_case(Case::Title)}</span> } + }) + .collect_view() + }) + }; + let assigned_to = move || { + setup_slot.read().assign_to.map(|a| { + match players + .read() + .iter() + .find(|p| p.identification.player_id == a) + { + Some(player) => { + let ident = RwSignal::new(player.identification.public.clone()); + view! { + <span class="assignment"> + <IdentityInline ident=ident.read_only() /> + </span> + } + .into_any() + } + None => { + view! { <span class="missing error">"missing player "{a.to_string()}</span> } + .into_any() + } + } + }) + }; + move || { + view! { + <div class="setup-slot-container"> + <DialogModal + open=dialog_open + mode=DialogMode::Box + button_class=[ + "setup-slot", + setup_slot.read().role.category().class(), + "faint", + "hover", + "box", + ] + .as_classes() + .to_string() + text=setup_slot.read().role.title().to_string().to_case(Case::Title) + close_backdrop=true + > + <SlotSettingsDialogBody setup_slot=setup_slot players=players /> + </DialogModal> + {assigned_to} + {auras} + </div> + } + } +} + +#[component] +fn SlotSettingsDialogBody( + setup_slot: RwSignal<SetupSlot>, + players: ReadSignal<Box<[PlayerState]>>, +) -> impl IntoView { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] + enum OpenTab { + #[default] + Auras, + PlayerAssignment, + } + let tab = RwSignal::new(OpenTab::default()); + let tab_view = move || match tab.get() { + OpenTab::Auras => view! { <AuraSelection setup_slot=setup_slot /> }.into_any(), + OpenTab::PlayerAssignment => { + view! { <AssignmentSelection setup_slot=setup_slot players=players /> }.into_any() + } + }; + move || { + let assigned_to = setup_slot + .read() + .assign_to + .as_ref() + .and_then(|pid| { + players + .read() + .iter() + .find(|p| p.identification.player_id == *pid) + .cloned() + }) + .map(|p| p.identification.public) + .map(|id| view! { <IdentityInline ident=RwSignal::new(id).read_only() /> }.into_any()) + .unwrap_or_else(|| view! { "none" }.into_any()); + view! { + <span class=[ + "role-title", + setup_slot.read().role.category().class(), + "underline", + "text-color", + ] + .as_classes()> + {setup_slot.read().role.title().to_string().to_case(Case::Title)} + </span> + <div class="tabs"> + <div class="tab"> + <button + on:click=move |_| tab.set(OpenTab::Auras) + class:selected=move || matches!(*tab.read(), OpenTab::Auras) + > + "auras" + </button> + <span class="detail">"currently: "{setup_slot.read().auras.len()}</span> + </div> + <div class="tab"> + <button + on:click=move |_| { tab.set(OpenTab::PlayerAssignment) } + class:selected=move || matches!(*tab.read(), OpenTab::PlayerAssignment) + > + "assignments" + </button> + <span class="detail">"currently: "{assigned_to}</span> + </div> + </div> + <div class="tab-content">{tab_view}</div> + } + } +} + +#[component] +fn AuraSelection(setup_slot: RwSignal<SetupSlot>) -> impl IntoView { + let auras = move || { + AuraTitle::ALL + .iter() + .copied() + .filter(|a| setup_slot.read().role.title().can_assign_aura(*a)) + .map(|aura| { + let toggle = move |ev: MouseEvent| { + ev.prevent_default(); + let mut slot = setup_slot.write(); + if slot.auras.contains(&aura) { + slot.auras.retain(|a| aura != *a); + } else { + slot.auras.push(aura); + } + }; + view! { + <button + class=["faint", "box", "hover", aura.partial_class().unwrap_or_default()] + .as_classes() + class:selected=setup_slot.read().auras.contains(&aura) + on:click=toggle + > + {aura.to_string().to_case(Case::Title)} + </button> + } + }) + .collect_view() + }; + + view! { <div class="toggle-list">{auras}</div> } +} + +#[component] +fn AssignmentSelection( + setup_slot: RwSignal<SetupSlot>, + players: ReadSignal<Box<[PlayerState]>>, +) -> impl IntoView { + let players = move || { + players + .read() + .iter() + .map(|p| { + let assigned = setup_slot + .read() + .assign_to + .as_ref() + .map(|assigned_id| p.identification.player_id == *assigned_id) + .unwrap_or_default(); + let ident = RwSignal::new(p.identification.public.clone()); + let pid = p.identification.player_id; + let assign = move |ev: MouseEvent| { + ev.prevent_default(); + setup_slot.write().assign_to = assigned.not().then_some(pid); + }; + + view! { + <button on:click=assign class:selected=assigned class="player-select"> + <IdentityInline ident=ident.read_only() /> + </button> + } + }) + .collect_view() + }; + + view! { <div class="toggle-list">{players}</div> } +} diff --git a/werewolves/src/app/pages/game/player.rs b/werewolves/src/app/pages/game/player.rs new file mode 100644 index 0000000..92582ce --- /dev/null +++ b/werewolves/src/app/pages/game/player.rs @@ -0,0 +1,125 @@ +werewolves_macros::include_path!("werewolves/src/app/pages/game/player"); + +use convert_case::{Case, Casing}; +use leptos::{ev::MouseEvent, prelude::*}; +use werewolves_proto::{ + message::{ + ClientDeadChat, ClientMessage, ServerToClientMessage as Srv2Client, dead::DeadChatMessage, + }, + role::RoleTitle, +}; + +use crate::{ConsoleLogError, app::components::ErrorBox}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Page { + Lobby { joined: bool }, + RoleReveal { role: RoleTitle }, + GameInProgress, + Sleep, + DeadChat, +} + +#[component] +pub fn PlayerGamePage( + message: Signal<Option<Srv2Client>>, + reply: WriteSignal<Option<ClientMessage>>, + disconnect: RwSignal<bool>, +) -> impl IntoView { + let error = RwSignal::new(None); + let dead_chat: RwSignal<Option<Vec<DeadChatMessage>>> = RwSignal::new(None); + let page: RwSignal<Option<Page>> = RwSignal::new(None); + Effect::new(move || { + let Some(message) = message.get() else { + return; + }; + match message { + Srv2Client::Disconnect => disconnect.set(true), + Srv2Client::LobbyInfo { joined, .. } => page.set(Some(Page::Lobby { joined })), + Srv2Client::GameInProgress => page.set(Some(Page::GameInProgress)), + Srv2Client::GameStart { role } => page.set(Some(Page::RoleReveal { role })), + Srv2Client::Story(game_story) => todo!("{game_story:#?}"), + Srv2Client::Update(_) => {} + Srv2Client::DeadChat(dead_chat_messages) => { + dead_chat.set(Some(dead_chat_messages.to_vec())); + page.set(Some(Page::DeadChat)); + } + Srv2Client::DeadChatMessage(dead_chat_message) => { + if let Some(chat) = dead_chat.write().as_mut() { + chat.push(dead_chat_message); + page.set(Some(Page::DeadChat)); + } else { + reply.set(Some(ClientMessage::DeadChat(ClientDeadChat::GetHistory))); + } + } + Srv2Client::Sleep => page.set(Some(Page::Sleep)), + Srv2Client::Reset => { + #[cfg(feature = "hydrate")] + gloo::utils::window().location().reload().console_log_err(); + } + Srv2Client::Error(err) => error.set(Some(err.to_string())), + } + // match message {} + }); + let content = move || { + let Some(page) = page.get() else { + return ().into_any(); + }; + match page { + Page::DeadChat => todo!("dead chat"), + Page::Sleep => view! { <h1>"go to sleep"</h1> }.into_any(), + Page::Lobby { joined } => { + let click = move |ev: MouseEvent| { + ev.prevent_default(); + reply.set(Some(if joined { + ClientMessage::Goodbye + } else { + ClientMessage::Hello + })); + }; + let text = match joined { + true => view! { + <h2>"you are in the lobby"</h2> + <p>"you're all good c:"</p> + } + .into_any(), + false => view! { + <h2>"you are not in the lobby"</h2> + <p>"join if you want to play"</p> + } + .into_any(), + }; + view! { + <div class="player-lobby" class:joined=joined> + {text} + <button on:click=click>{if joined { "leave" } else { "join" }}</button> + </div> + } + .into_any() + } + Page::GameInProgress => view! { + <div class="status-box"> + <h1>"this game is currently in progress"</h1> + </div> + } + .into_any(), + Page::RoleReveal { role } => view! { + <div class="role-reveal"> + <span class="role-text"> + "your role: " + <span class="role">{role.to_string().to_case(Case::Title)}</span> + </span> + <button on:click=move |_| { + reply.set(Some(ClientMessage::RoleAck)) + }>"got it"</button> + </div> + } + .into_any(), + } + }; + view! { + <ErrorBox msg=error /> + {content} + } + .into_any() +} diff --git a/werewolves/src/app/pages/lobby.rs b/werewolves/src/app/pages/lobby.rs new file mode 100644 index 0000000..bdf4af8 --- /dev/null +++ b/werewolves/src/app/pages/lobby.rs @@ -0,0 +1,4 @@ +use leptos::prelude::*; + +#[component] +pub fn HostLobby() -> impl IntoView {} diff --git a/werewolves/src/app/pages/main.rs b/werewolves/src/app/pages/main.rs new file mode 100644 index 0000000..9aaccc0 --- /dev/null +++ b/werewolves/src/app/pages/main.rs @@ -0,0 +1,39 @@ +use leptos::prelude::*; +use reactive_stores::Store; + +use crate::app::{ + pages::{Signin, Signup}, + storage::user::{AuthContext, AuthContextStoreFields, UserSession}, +}; + +#[component] +pub fn Main() -> impl IntoView { + let auth = expect_context::<Store<AuthContext>>(); + move || match auth.session().get() { + Some(session) => view! { <SignedInMain session=session /> }.into_any(), + None => view! { <SignedOutMain /> }.into_any(), + } +} +#[component] +pub fn SignedInMain(session: UserSession) -> impl IntoView { + view! { <h1>"welcome "<strong>{session.name().to_string()}</strong></h1> } +} + +#[component] +pub fn SignedOutMain() -> impl IntoView { + view! { + <h1>"welcome"</h1> + <div class="welcome-columns"> + <div> + <h2>"create a new account"</h2> + <h4>"with just a username"</h4> + <Signup redirect=false header=false /> + </div> + <div> + <h2>"sign in"</h2> + <h4>"with an existing account"</h4> + <Signin redirect=false header=false /> + </div> + </div> + } +} diff --git a/werewolves/src/app/pages/not_found.rs b/werewolves/src/app/pages/not_found.rs new file mode 100644 index 0000000..9759170 --- /dev/null +++ b/werewolves/src/app/pages/not_found.rs @@ -0,0 +1,13 @@ +use leptos::prelude::*; +use leptos_meta::provide_meta_context; + +#[component] +pub fn NotFound() -> impl IntoView { + // Provides context that manages stylesheets, titles, meta tags, etc. + provide_meta_context(); + + view! { + <h2>{"not found"}</h2> + <h4>"specifically, this is the 404 page"</h4> + } +} diff --git a/werewolves/src/app/pages/signin.rs b/werewolves/src/app/pages/signin.rs new file mode 100644 index 0000000..423aa4e --- /dev/null +++ b/werewolves/src/app/pages/signin.rs @@ -0,0 +1,128 @@ +use core::ops::Not; + +use api::user::{Password, Session, Username}; +use chrono::Utc; +use gloo::history::History; +use leptos::{ev::MouseEvent, prelude::*}; + +use crate::{ + app::{ + components::ErrorBox, + storage::user::{AuthContext, PasswordlessUser, UserSession, UserToken}, + }, + auth::Signin, +}; +use reactive_stores::Store; + +#[component] +pub fn Signin( + #[prop(default = true)] redirect: bool, + #[prop(optional)] header: bool, +) -> impl IntoView { + let submit = ServerAction::<Signin>::new(); + use crate::app::storage::user::AuthContextStoreFields; + let error: RwSignal<Option<String>> = RwSignal::new(None); + + let auth = expect_context::<Store<AuthContext>>(); + + if redirect { + Effect::new(move || { + if let Some(sess) = auth.session().get() + && sess.expiry > Utc::now() + && let Err(err) = gloo::utils::window().location().replace("/") + { + log::error!("setting window href to [/]: {err:?}"); + } + }); + } + + let user = RwSignal::new(String::new()); + + let pass = RwSignal::new(String::new()); + + Effect::new(move || { + if let Some(pwless) = auth.passwordless().get() { + user.set(pwless.username.to_string()); + pass.set(pwless.password.to_string()); + } + }); + let click = move |ev: MouseEvent| { + ev.prevent_default(); + let username = match Username::new(user.get()) { + Ok(u) => u, + Err(exp_range) => { + error.set(Some(format!( + "username must be between {} and {} characters", + exp_range.start(), + exp_range.end() + ))); + return; + } + }; + let password = match Password::new(pass.get()) { + Ok(p) => p, + Err(exp_range) => { + error.set(Some(format!( + "password must be between {} and {} characters", + exp_range.start(), + exp_range.end() + ))); + return; + } + }; + submit.dispatch(Signin { username, password }); + }; + Effect::new(move || match submit.value().get() { + Some(Ok(sess)) => { + log::info!("user logged in"); + auth.token().write().replace(UserToken { + token: sess.token.clone(), + expiry: sess.token_expires_at, + }); + auth.session().write().replace(sess.into()); + if let Err(err) = gloo::utils::window().location().set_href("/") { + log::error!("setting window href to [/]: {err:?}"); + submit.clear(); + } + } + Some(Err(err)) => error.set(Some(err.to_string())), + None => {} + }); + + let submit = move || { + view! { <button on:click=click>"sign in"</button> } + }; + let user_input = move || { + view! { + <input + type="text" + id="username" + value=move || user.get() + on:input:target=move |ev| user.set(ev.target().value()) + autocomplete=false + /> + } + }; + let pass_input = move || { + view! { + <input + type="password" + id="password" + value=move || pass.get() + on:input:target=move |ev| pass.set(ev.target().value()) + autocomplete=false + /> + } + }; + view! { + <form class="signin"> + <h3 hidden=header.not()>"sign in"</h3> + <label for="username">"username"</label> + {user_input} + <label for="password">"password"</label> + {pass_input} + {submit} + <ErrorBox msg=error /> + </form> + } +} diff --git a/werewolves/src/app/pages/signup.rs b/werewolves/src/app/pages/signup.rs new file mode 100644 index 0000000..7a8ca2f --- /dev/null +++ b/werewolves/src/app/pages/signup.rs @@ -0,0 +1,157 @@ +use core::ops::Not; + +use api::{ + cbor_leptos::CborPost, + error::ServerError, + user::{Password, Session, Username}, +}; +use chrono::Utc; +use gloo::history::History; +use leptos::{ + ev::{Event, MouseEvent}, + prelude::*, +}; +use leptos_meta::*; +use rand::distr::SampleString; +use reactive_stores::Store; + +use crate::{ + app::{ + components::{ErrorBox, input::TextInput}, + storage::{ + LocalStorage, + user::{AuthContext, AuthContextStoreFields, PasswordlessUser, UserSession, UserToken}, + }, + }, + auth::Signin, +}; + +#[leptos::server(CreateUser, input = CborPost)] +pub async fn create_user( + username: Username, + password: Password, + pronouns: Option<String>, +) -> core::result::Result<api::user::UserId, ServerError> { + let user = use_context::<api::state::AppState>() + .expect("no app state") + .db + .user() + .create(&username, &password, pronouns) + .await + .map_err(Into::<ServerError>::into)?; + log::info!("created user: {user:?}"); + Ok(user.id) +} + +#[component] +pub fn Signup( + #[prop(default = true)] redirect: bool, + #[prop(default = true)] header: bool, +) -> impl IntoView { + move || { + let auth = expect_context::<Store<AuthContext>>(); + let user = RwSignal::new(String::new()); + let pronouns = RwSignal::new(String::new()); + + if redirect { + Effect::new(move || { + if let Some(sess) = auth.session().get() + && sess.expiry > Utc::now() + && let Err(err) = gloo::utils::window().location().replace("/") + { + log::error!("setting window href to [/]: {err:?}"); + } + }); + } + + let submit = ServerAction::<CreateUser>::new(); + let error = RwSignal::new(None); + let generated_password = Password::new( + rand::distr::Alphanumeric.sample_string(&mut rand::rng(), Password::MAX_LEN), + ) + .expect("generate password max length"); + + let click = { + let user = user.read_only(); + let password = generated_password.clone(); + move |ev: MouseEvent| { + ev.prevent_default(); + let username = match Username::new(user.get().clone()) { + Ok(u) => u, + Err(exp_range) => { + error.set(Some(format!( + "username must be between {} and {} characters", + exp_range.start(), + exp_range.end() + ))); + return; + } + }; + let pronouns = { + let p = pronouns.get(); + p.trim().is_empty().not().then_some(p.trim().to_string()) + }; + submit.dispatch(CreateUser { + username, + pronouns, + password: password.clone(), + }); + } + }; + let login_action = ServerAction::<Signin>::new(); + let result = move || { + let value = submit.value().get()?; + match value { + Ok(_) => { + let creds = PasswordlessUser { + username: unsafe { Username::new_unchecked(user.get_untracked()) }, + password: generated_password.clone(), + }; + auth.passwordless().write().replace(creds.clone()); + login_action.dispatch(Signin { + username: creds.username, + password: creds.password, + }); + Some(view! { + <h2>"created user successfully"</h2> + <a href="/signin"> + <button>"sign in"</button> + </a> + }) + } + Err(err) => { + error.write().replace(err.to_string()); + None + } + } + }; + Effect::new(move || match login_action.value().get() { + Some(Ok(sess)) => { + auth.token().set(Some(UserToken { + token: sess.token.clone(), + expiry: sess.token_expires_at, + })); + auth.session().set(Some(sess.into())); + } + Some(Err(err)) => { + error.set(Some(format!("error signing in after signup: {err}"))); + } + None => {} + }); + + view! { + <form class="signup"> + <h3 hidden=header.not()>"sign up"</h3> + <TextInput value=user label="username".into() /> + <label for="pronouns">"pronouns"<span class="optional">"(optional)"</span></label> + + <input id="pronouns" on:input:target=move |ev| pronouns.set(ev.target().value()) /> + {{ + view! { <button on:click=click.clone()>"sign up"</button> } + }} + {result} + <ErrorBox msg=error /> + </form> + } + } +} diff --git a/werewolves/src/app/pages/user_settings.rs b/werewolves/src/app/pages/user_settings.rs new file mode 100644 index 0000000..0878196 --- /dev/null +++ b/werewolves/src/app/pages/user_settings.rs @@ -0,0 +1,44 @@ +werewolves_macros::include_path!("werewolves/src/app/pages/user_settings"); +use leptos::{ev::MouseEvent, prelude::*}; +use reactive_stores::Store; + +use crate::app::{ + TutorialSettings, + storage::user::{AuthContext, AuthContextStoreFields}, +}; + +#[component] +pub fn UserSettings() -> impl IntoView { + let auth = expect_context::<Store<AuthContext>>(); + let log_out = { + let click = move |e: MouseEvent| { + e.prevent_default(); + auth.session().set(None); + auth.token().set(None); + }; + view! { <button on:click=click>"log out"</button> } + }; + let (tut_read, tut_write) = + expect_context::<(Signal<TutorialSettings>, WriteSignal<TutorialSettings>)>(); + let tutorial_toggle_button = move || { + match tut_read.read().enabled { + true => view! { <button on:click=move |_| tut_write.write().enabled = false>"disable tutorials"</button> } + .into_any(), + false => view! { + <button on:click=move |_| tut_write.write().enabled = true>"enable tutorials"</button> + }.into_any(), + } + }; + view! { + <ul class="user-settings-list"> + <li> + <UpdateProfileButton /> + </li> + <li> + <ChangePasswordButton /> + </li> + <li>{tutorial_toggle_button}</li> + <li class="logout">{log_out}</li> + </ul> + } +} diff --git a/werewolves/src/app/pages/user_settings/change_password.rs b/werewolves/src/app/pages/user_settings/change_password.rs new file mode 100644 index 0000000..f1948c7 --- /dev/null +++ b/werewolves/src/app/pages/user_settings/change_password.rs @@ -0,0 +1,144 @@ +use api::{cbor_leptos::CborPost, error::ServerError, user::Password}; +use leptos::{ev::MouseEvent, prelude::*}; +use reactive_stores::Store; + +use crate::app::{ + components::{DialogModal, ErrorBox}, + storage::user::{AuthContext, AuthContextStoreFields}, +}; +#[server(input = CborPost)] +pub async fn change_password( + token: String, + current: Password, + new: Password, +) -> Result<(), ServerError> { + let db = use_context::<api::state::AppState>() + .expect("no app state") + .db + .user(); + let user = db.check_token(token.as_str()).await?; + db.verify_login(&user.username, ¤t).await?; + db.change_password(user.clone(), new).await?; + log::info!("changed password for {}", user.username); + Ok(()) +} + +#[component] +pub fn ChangePasswordButton() -> impl IntoView { + let auth = expect_context::<Store<AuthContext>>(); + let error = RwSignal::new(None); + let action = ServerAction::<ChangePassword>::new(); + let current = RwSignal::new(String::new()); + Effect::new(move || { + if let Some(pwless) = auth.passwordless().get() { + current.set(pwless.password.to_string()); + } + }); + let new = RwSignal::new(String::new()); + let new_confirm = RwSignal::new(String::new()); + let submit_click = move |ev: MouseEvent| { + ev.prevent_default(); + error.set(None); + let current = match Password::new(current.get()) { + Ok(c) => c, + Err(exp_range) => { + error.set(Some(format!( + "current password must be between {} and {} characters", + exp_range.start(), + exp_range.end() + ))); + return; + } + }; + if new.get() != new_confirm.get() { + error.set(Some("password confirmation does not match".into())); + return; + } + let new = match Password::new(new.get()) { + Ok(c) => c, + Err(exp_range) => { + error.set(Some(format!( + "new password must be between {} and {} characters", + exp_range.start(), + exp_range.end() + ))); + return; + } + }; + action.dispatch(ChangePassword { + new, + current, + token: auth + .token() + .get() + .map(|t| t.token.to_string()) + .unwrap_or_default(), + }); + log::info!("in submit_click"); + }; + Effect::new(move || { + let resp = action.value().get(); + if let Some(resp) = resp.as_ref() { + log::debug!("response: {resp:?}"); + } + match resp { + Some(Ok(_)) => { + log::info!("password changed!"); + auth.passwordless().set(None); + } + Some(Err(err)) => { + error.set(Some(err.to_string())); + } + None => {} + } + }); + + let pwless_info = move || { + auth.passwordless().get().map(|_| { + view! { + <p class="pwless-notice"> + <strong>"notice:"</strong> + <em> + " once you change your password for the first time, this site will no longer" + " autofill the signin/password fields for you, as you (or your browser) " + "will be responsible for managing that infomation" + </em> + </p> + } + }) + }; + + view! { + <DialogModal text="change password".into() close_backdrop=false> + <ErrorBox msg=error /> + <form> + <div class="form-fields"> + <label for="current-password">"current password"</label> + <input + id="current-password" + type="password" + autocomplete="current-password" + on:input:target=move |ev| current.set(ev.target().value()) + value=move || current.get() + /> + <label for="new-password">"new password"</label> + <input + id="new-password" + type="password" + autocomplete="new-password" + on:input:target=move |ev| new.set(ev.target().value()) + /> + <label for="confirm-new-password">"confirm new password"</label> + <input + id="confirm-new-password" + type="password" + autocomplete="new-password" + on:input:target=move |ev| new_confirm.set(ev.target().value()) + /> + </div> + {pwless_info} + <button on:click=submit_click>"submit"</button> + </form> + </DialogModal> + } +} diff --git a/werewolves/src/app/pages/user_settings/update_profile.rs b/werewolves/src/app/pages/user_settings/update_profile.rs new file mode 100644 index 0000000..0a62dc4 --- /dev/null +++ b/werewolves/src/app/pages/user_settings/update_profile.rs @@ -0,0 +1,111 @@ +use core::ops::Not; + +use api::{ + cbor_leptos::CborPost, + error::ServerError, + token::TokenString, + user::{ProfileUpdate, Session}, +}; +use leptos::{ev::MouseEvent, prelude::*}; +use reactive_stores::Store; + +use crate::app::{ + components::{DialogModal, ErrorBox}, + storage::user::{AuthContext, AuthContextStoreFields}, +}; + +#[server(input = CborPost)] +pub async fn update_profile(token: TokenString, update: ProfileUpdate) -> Result<(), ServerError> { + let db = use_context::<api::state::AppState>() + .expect("no app state") + .db + .user(); + let user = db.check_token(&token).await?; + db.update_profile(user.id, update).await?; + Ok(()) +} + +fn trim_or_none(s: String) -> Option<String> { + s.trim().is_empty().not().then_some(s.trim().to_string()) +} + +#[component] +pub fn UpdateProfileButton() -> impl IntoView { + let auth = expect_context::<Store<AuthContext>>(); + let error = RwSignal::new(None); + let display_name = RwSignal::new(String::new()); + let pronouns = RwSignal::new(String::new()); + Effect::new(move || { + if let Some(session) = auth.session().get() { + if let Some(d) = session.display_name { + display_name.set(d); + } + if let Some(p) = session.pronouns { + pronouns.set(p); + } + } + }); + let update_req = RwSignal::new(None); + let update_action = ServerAction::<UpdateProfile>::new(); + let submit = move |ev: MouseEvent| { + ev.prevent_default(); + update_action.clear(); + let Some(session) = auth.session().get() else { + return; + }; + let update = UpdateProfile { + token: session.token.clone(), + update: ProfileUpdate { + display_name: trim_or_none(display_name.get()), + pronouns: trim_or_none(pronouns.get()), + }, + }; + update_req.set(Some(update.clone())); + update_action.dispatch(update.clone()); + }; + Effect::new(move || match update_action.value().get() { + Some(Ok(_)) => { + if let Some(input) = update_req.get() + && let Some(sess) = auth.session().write().as_mut() + { + sess.display_name = input.update.display_name; + sess.pronouns = input.update.pronouns; + } + } + Some(Err(err)) => error.set(Some(err.to_string())), + None => {} + }); + let on_success = move || { + update_action + .value() + .get() + .map(|v| v.is_ok()) + .unwrap_or_default() + .then_some(view! { <p>"profile updated"</p> }) + }; + view! { + <DialogModal text="update profile".into() close_backdrop=false> + <ErrorBox msg=error /> + <form> + <label for="display-name">"display name"</label> + <input + id="display-name" + type="text" + autocomplete="nickname" + value=move || display_name.get() + on:input:target=move |ev| display_name.set(ev.target().value()) + /> + <label for="pronouns">"pronouns"</label> + <input + id="pronouns" + type="text" + autocomplete="pronouns" + value=move || pronouns.get() + on:input:target=move |ev| pronouns.set(ev.target().value()) + /> + <button on:click=submit>"update"</button> + {on_success} + </form> + </DialogModal> + } +} diff --git a/werewolves/src/app/storage/mod.rs b/werewolves/src/app/storage/mod.rs new file mode 100644 index 0000000..6ac2086 --- /dev/null +++ b/werewolves/src/app/storage/mod.rs @@ -0,0 +1,70 @@ +pub mod user; + +use core::fmt::Debug; + +use gloo::storage::Storage; +use leptos::{ + prelude::{ArcReadSignal, ArcWriteSignal, Effect, Signal, WriteSignal}, + server::codee::string::JsonSerdeCodec, +}; +use serde::{Serialize, de::DeserializeOwned}; + +pub trait Stored: + Debug + Clone + PartialEq + Send + Sync + Serialize + DeserializeOwned + 'static +{ + const STORAGE_KEY: &str; +} + +pub trait DeleteFn: Fn() + Clone + Send + Sync {} +impl<F: Fn() + Clone + Send + Sync> DeleteFn for F {} + +pub trait LocalStorage: Stored { + fn from_local_storage() -> Option<Self> { + gloo::storage::LocalStorage::get(Self::STORAGE_KEY).ok() + } + fn store_in_local_storage(&self) { + gloo::storage::LocalStorage::set(Self::STORAGE_KEY, self) + .expect(format!("storing object at [{}] in local storage", Self::STORAGE_KEY).as_str()) + } + fn delete_from_local_storage() { + gloo::storage::LocalStorage::delete(Self::STORAGE_KEY); + } + fn set_in_local_storage(value: Option<Self>) { + gloo::storage::LocalStorage::set(Self::STORAGE_KEY, value) + .expect(format!("storing object at [{}] in local storage", Self::STORAGE_KEY).as_str()) + } +} + +/// Uses session storage which ends when the tab closes +pub trait SessionStorage: Stored { + fn from_session_storage() -> Option<Self> { + gloo::storage::SessionStorage::get(Self::STORAGE_KEY).ok() + } + fn store_in_session_storage(&self) { + gloo::storage::SessionStorage::set(Self::STORAGE_KEY, self).expect( + format!( + "storing object at [{}] in session storage", + Self::STORAGE_KEY + ) + .as_str(), + ) + } + fn delete_from_session_storage() { + gloo::storage::SessionStorage::delete(Self::STORAGE_KEY); + } + fn set_in_session_storage(value: Option<Self>) { + gloo::storage::SessionStorage::set(Self::STORAGE_KEY, value).expect( + format!( + "storing object at [{}] in session storage", + Self::STORAGE_KEY + ) + .as_str(), + ) + } +} + +pub trait CookiesStorage: Stored { + fn from_cookie() -> (Signal<Option<Self>>, WriteSignal<Option<Self>>) { + leptos_use::use_cookie::<Self, JsonSerdeCodec>(Self::STORAGE_KEY) + } +} diff --git a/werewolves/src/app/storage/user.rs b/werewolves/src/app/storage/user.rs new file mode 100644 index 0000000..2729ddc --- /dev/null +++ b/werewolves/src/app/storage/user.rs @@ -0,0 +1,121 @@ +use api::{ + limited::FixedLenString, + token::TOKEN_LEN, + user::{Password, Session, Username}, +}; +use chrono::{DateTime, Utc}; +use leptos::{ + prelude::{Action, ArcRwSignal, Get, GetUntracked, Set}, + server::codee::string::JsonSerdeCodec, +}; +use reactive_stores::{Field, Patch, Store}; +use serde::{Deserialize, Serialize}; + +use crate::{ + app::storage::{LocalStorage, SessionStorage, Stored}, + state::InitOrUpdateStore, +}; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Store)] +pub struct UserToken { + pub token: FixedLenString<TOKEN_LEN>, + pub expiry: DateTime<Utc>, +} + +impl Stored for UserToken { + const STORAGE_KEY: &str = "user-login-token"; +} + +impl LocalStorage for UserToken {} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct UserSession { + pub expiry: DateTime<Utc>, + pub username: String, + pub display_name: Option<String>, + pub pronouns: Option<String>, + pub token: FixedLenString<TOKEN_LEN>, +} + +impl From<Session> for UserSession { + fn from(value: Session) -> Self { + Self { + expiry: value.token_expires_at, + username: value.username, + display_name: value.display_name, + pronouns: value.pronouns, + token: value.token, + } + } +} + +impl UserSession { + pub fn name(&self) -> &str { + self.display_name + .as_ref() + .unwrap_or(&self.username) + .as_str() + } +} + +impl Stored for UserSession { + const STORAGE_KEY: &str = "user-session"; +} + +impl SessionStorage for UserSession {} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct PasswordlessUser { + pub username: Username, + pub password: Password, +} + +impl Stored for PasswordlessUser { + const STORAGE_KEY: &str = "passwordless-user-details"; +} + +impl LocalStorage for PasswordlessUser {} + +#[derive(Debug, Clone, PartialEq, Store)] +pub struct AuthContext { + /// `token` is stored in [LocalStorage] and does not contain + /// up-to-date user info that's stored in `session` (using [SessionStorage]) + token: Option<UserToken>, + session: Option<UserSession>, + passwordless: Option<PasswordlessUser>, + initialized: bool, +} + +impl Default for AuthContext { + fn default() -> Self { + Self::new() + } +} + +impl AuthContext { + pub fn new() -> Self { + Self { + token: None, + session: None, + passwordless: None, + initialized: false, + } + } +} +impl InitOrUpdateStore for Store<AuthContext> { + fn init_or_update(&self) { + if !self.initialized().get() { + self.session().set(UserSession::from_session_storage()); + self.token().set(UserToken::from_local_storage()); + self.passwordless() + .set(PasswordlessUser::from_local_storage()); + self.initialized().set(true); + Action::new(move |auth: &Store<AuthContext>| crate::auth::try_auto_signin(*auth)) + .dispatch(*self); + } else { + UserSession::set_in_session_storage(self.session().get()); + UserToken::set_in_local_storage(self.token().get()); + PasswordlessUser::set_in_local_storage(self.passwordless().get()); + } + } +} diff --git a/werewolves/src/assets.rs b/werewolves/src/assets.rs deleted file mode 100644 index ffe8a50..0000000 --- a/werewolves/src/assets.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -werewolves_macros::static_links!("werewolves/assets" relative to "werewolves/"); diff --git a/werewolves/src/auth.rs b/werewolves/src/auth.rs new file mode 100644 index 0000000..5cb2b29 --- /dev/null +++ b/werewolves/src/auth.rs @@ -0,0 +1,144 @@ +use api::{ + cbor_leptos::CborPost, + error::ServerError, + limited::{ClampedString, FixedLenString}, + token::{TOKEN_LEN, Token, TokenString}, + user::{Password, Session, Username}, +}; +use chrono::Utc; +use leptos::prelude::*; +use reactive_stores::Store; + +use crate::app::storage::{ + LocalStorage, + user::{AuthContext, AuthContextStoreFields, PasswordlessUser, UserSession, UserToken}, +}; + +pub async fn try_auto_signin(ctx: Store<AuthContext>) -> Result<(), ServerError> { + if let Some(sess) = ctx.session().read().as_ref() { + if sess.expiry > Utc::now() { + return Ok(()); + } else { + ctx.session().write().take(); + // ctx.token().write().take(); + } + } + if let Some(token) = ctx.token().get() { + if token.expiry > Utc::now() { + match replace_token(ctx, token.token).await { + Ok(_) => return Ok(()), + Err(ServerError::ExpiredToken) => { + log::warn!("login token expired (though recorded as not?)"); + ctx.token().write().take(); + } + Err(err) => { + ctx.token().write().take(); + return Err(err); + } + } + } + } + + let Some(PasswordlessUser { username, password }) = PasswordlessUser::from_local_storage() + else { + return Ok(()); + }; + let token = signin(username.clone(), password).await?; + + ctx.token().set(Some(UserToken { + token: token.token.clone(), + expiry: token.token_expires_at, + })); + ctx.session().set(Some(UserSession { + expiry: token.token_expires_at, + username: username.to_string(), + display_name: token.display_name, + pronouns: token.pronouns, + token: token.token, + })); + Ok(()) +} + +pub async fn replace_token( + ctx: Store<AuthContext>, + token: TokenString, +) -> Result<UserSession, ServerError> { + let new_token = replace_auth_token(token).await?; + let session = UserSession { + expiry: new_token.expires_at, + username: new_token.username.to_string(), + display_name: new_token.display_name, + pronouns: new_token.pronouns, + token: new_token.token.clone(), + }; + ctx.token().set(Some(UserToken { + token: new_token.token, + expiry: new_token.expires_at, + })); + ctx.session().set(Some(session.clone())); + + Ok(session) +} + +#[leptos::server(Signin, input = CborPost)] +pub async fn signin(username: Username, password: Password) -> Result<Session, ServerError> { + let db = use_context::<api::state::AppState>() + .expect("no app state") + .db + .user(); + let sess = db.login(&username, &password).await?; + + log::info!("user logged in: {}", sess.username); + + Ok(sess) +} + +#[server(VerifyToken, input = CborPost)] +pub async fn verify_token(token: FixedLenString<TOKEN_LEN>) -> Result<(), ServerError> { + use_context::<api::state::AppState>() + .expect("no app state") + .db + .user() + .check_token(token.as_str()) + .await?; + Ok(()) +} + +#[server(input = CborPost)] +pub async fn get_me(token: FixedLenString<TOKEN_LEN>) -> Result<Session, ServerError> { + let db = use_context::<api::state::AppState>() + .expect("no app state") + .db + .user(); + db.check_token(&token).await?; + let sess = db.get_session(&token).await?; + + Ok(sess) +} + +#[server(input = CborPost)] +pub async fn replace_auth_token(token: FixedLenString<TOKEN_LEN>) -> Result<Token, ServerError> { + let db = use_context::<api::state::AppState>() + .expect("no app state") + .db + .user(); + let token = db.replace_token(&token).await?; + let user = db + .get_user(api::db::user::GetUserBy::Id(token.user_id)) + .await + .map_err(Into::<ServerError>::into)?; + Ok(Token { + token: FixedLenString::new(token.token.clone()).ok_or_else(|| { + log::error!( + "token [{}] was not of fixed length {TOKEN_LEN}", + token.token, + ); + ServerError::InternalServerError + })?, + username: unsafe { ClampedString::new_unchecked(user.username) }, + display_name: user.display_name, + pronouns: user.pronouns, + created_at: token.created_at, + expires_at: token.expires_at, + }) +} diff --git a/werewolves/src/callback.rs b/werewolves/src/callback.rs deleted file mode 100644 index 79d55a5..0000000 --- a/werewolves/src/callback.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::fmt::Debug; -use std::sync::Arc; - -use futures::SinkExt; -use yew::prelude::*; - -pub fn send_message<T: Clone + Debug + 'static, P>( - msg: T, - send: futures::channel::mpsc::Sender<T>, -) -> Callback<P> { - Callback::from(move |_| { - let mut send = send.clone(); - let msg = msg.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send.send(msg.clone()).await { - log::error!("sending message <({msg:?})> in callback: {err}") - }; - }); - }) -} - -pub fn send_fn<T, P, F>(msg_fn: F, send: futures::channel::mpsc::Sender<T>) -> Callback<P> -where - T: Clone + Debug + 'static, - F: Fn(P) -> T + 'static, - P: 'static, -{ - let msg_fn = Arc::new(msg_fn); - Callback::from(move |param| { - let mut send = send.clone(); - let msg_fn = msg_fn.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send.send((msg_fn)(param)).await { - log::error!("sending message in callback: {err}") - }; - }); - }) -} diff --git a/werewolves/src/class.rs b/werewolves/src/class.rs deleted file mode 100644 index ea2fa3e..0000000 --- a/werewolves/src/class.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -use werewolves_proto::{character::Character, game::SetupRole, team::Team}; - -pub trait Class { - fn class(&self) -> Option<&'static str>; -} - -impl Class for Character { - fn class(&self) -> Option<&'static str> { - if let Team::AnyEvil = self.team() { - return Some("damned"); - } - Some( - Into::<SetupRole>::into(self.role_title()) - .category() - .class(), - ) - } -} diff --git a/werewolves/src/clients/client/client.rs b/werewolves/src/clients/client/client.rs deleted file mode 100644 index 2de5c8e..0000000 --- a/werewolves/src/clients/client/client.rs +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::{ - ops::Not, - sync::atomic::{AtomicBool, AtomicI64, Ordering}, -}; -use std::rc::Rc; - -use chrono::{DateTime, TimeDelta, Utc}; -use gloo::storage::errors::StorageError; -use wasm_bindgen::{JsCast, prelude::Closure}; -use werewolves_proto::{ - game::story::GameStory, - message::{ - ClientDeadChat, ClientMessage, Identification, PublicIdentity, dead::DeadChatMessage, - }, - player::PlayerId, - role::RoleTitle, -}; -use yew::prelude::*; - -use crate::{ - clients::client::connection::{Connection2, ConnectionError}, - components::{ - Button, CoverOfDarkness, Footer, Identity, - client::{ClientNav, Signin}, - story::Story, - }, - storage::StorageKey, -}; - -use crate::WerewolfError; - -#[derive(PartialEq, Debug, Clone)] -pub enum ClientEvent2 { - Signin, - Disconnected, - Connecting, - ShowRole(RoleTitle), - Sleep, - Lobby { - joined: bool, - players: Rc<[PublicIdentity]>, - }, - Story(GameStory), - GameInProgress, - DeadChat { - messages: Vec<DeadChatMessage>, - }, -} - -#[derive(Default, Clone, PartialEq)] -pub struct ClientContext { - pub error_cb: Callback<Option<WerewolfError>>, -} - -static LOST_FOCUS: AtomicI64 = AtomicI64::new(0); -static IS_FOCUSED: AtomicBool = AtomicBool::new(true); -pub(super) fn time_spent_unfocused() -> Option<TimeDelta> { - if !IS_FOCUSED.load(Ordering::SeqCst) { - return None; - } - let lost_focus_ts = LOST_FOCUS.swap(0, Ordering::SeqCst); - if lost_focus_ts <= 0 { - return None; - } - let lost_focus = DateTime::from_timestamp_millis(lost_focus_ts)?; - Some(Utc::now() - lost_focus) -} - -#[function_component] -pub fn Client2(ClientProps { auto_join }: &ClientProps) -> Html { - let ident_state = use_state(|| { - PlayerId::load_from_storage() - .and_then(|pid| PublicIdentity::load_from_storage().map(|ident| (pid, ident))) - .ok() - }); - - if gloo::utils::window().onfocus().is_none() { - let on_focus = { - Closure::wrap(Box::new(move || { - IS_FOCUSED.store(true, Ordering::Relaxed); - LOST_FOCUS.store(0, Ordering::Relaxed); - }) as Box<dyn FnMut()>) - .into_js_value() - }; - gloo::utils::window().set_onfocus(Some(on_focus.as_ref().unchecked_ref())); - let on_blur = { - Closure::wrap(Box::new(move || { - LOST_FOCUS.store(Utc::now().timestamp_millis(), Ordering::SeqCst); - IS_FOCUSED.store(false, Ordering::SeqCst); - }) as Box<dyn FnMut()>) - .into_js_value() - }; - gloo::utils::window().set_onblur(Some(on_blur.as_ref().unchecked_ref())); - } - - let client_state = use_state(|| ClientEvent2::Connecting); - let ClientContext { error_cb } = use_context::<ClientContext>().unwrap_or_default(); - // let force = use_force_update(); - let (send, recv) = yew::platform::pinned::mpsc::unbounded(); - let send = use_state(|| send); - let recv = use_mut_ref(|| recv); - let connection = - use_mut_ref(|| Connection2::new(client_state.setter(), ident_state.clone(), recv)); - - let on_signin = { - let current_ident = ident_state.setter(); - let client_state = client_state.setter(); - Callback::from(move |ident: PublicIdentity| { - let pid = PlayerId::new(); - pid.save_to_storage().expect("saving player id"); - ident.save_to_storage().expect("saving ident"); - - current_ident.set(Some((pid, ident))); - client_state.set(ClientEvent2::Connecting); - }) - }; - if let ClientEvent2::Signin = &*client_state { - return html! { - <Signin callback={on_signin} /> - }; - } - let ident = if let Some(current_ident) = ident_state.as_ref() { - current_ident.clone() - } else { - match PlayerId::load_from_storage() - .and_then(|pid| PublicIdentity::load_from_storage().map(|ident| (pid, ident))) - { - Ok((pid, ident)) => { - ident_state.set(Some((pid, ident.clone()))); - (pid, ident) - } - Err(StorageError::KeyNotFound(_)) => { - client_state.set(ClientEvent2::Signin); - return html! { - // <Signin callback={on_signin}/> - }; - } - Err(err) => { - log::error!("storage error: {err}"); - error_cb.emit(Some(err.into())); - PlayerId::delete(); - PublicIdentity::delete(); - // force.force_update(); - - // client_state.set(ClientEvent2::Connecting); - client_state.set(ClientEvent2::Signin); - return html! { - // <Signin callback={on_signin} /> - }; - } - } - }; - - let content = match &*client_state { - ClientEvent2::DeadChat { messages } => { - let on_send = { - let send = send.clone(); - move |msg: String| { - if let Err(err) = - send.send_now(ClientMessage::DeadChat(ClientDeadChat::Send(msg))) - { - log::error!("sending dead chat message: {err}"); - } - } - }; - html! { - <crate::components::chat::DeadChat - on_send={on_send} - messages={messages.clone()} - /> - } - } - ClientEvent2::Signin => html! { - <Signin callback={on_signin} /> - }, - ClientEvent2::GameInProgress => html! { - <div class="game-in-progress"> - <h1>{"game in progress"}</h1> - <h3>{"if you're playing, you can come back when dead for dead chat"}</h3> - </div> - }, - ClientEvent2::Story(story) => html! { - <div class="post-game"> - <Story story={story.clone()} /> - </div> - }, - ClientEvent2::Sleep => html! { - <CoverOfDarkness message={"cool. come back when dead.".to_string()}/> - }, - ClientEvent2::Disconnected => html! { - <div class="disconnected"> - <h1>{"disconnected"}</h1> - </div> - }, - ClientEvent2::Connecting => { - if let Err(err) = connection - .try_borrow_mut() - .map_err(|_| ConnectionError::ConnectionAlreadyActive) - .and_then(|mut conn| conn.start()) - { - error_cb.emit(Some(err.into())); - } - if *auto_join { - let _ = send.send_now(ClientMessage::Hello); - } - html! {<p>{"connecting..."}</p>} - } - ClientEvent2::ShowRole(role_title) => { - let send = (*send).clone(); - let error_cb = error_cb.clone(); - let on_click = Callback::from(move |_| { - if let Err(err) = send.clone().send_now(ClientMessage::RoleAck) { - error_cb.emit(Some(err.into())); - } - }); - html! { - <div class="game-start-role"> - <p>{format!("Your role: {role_title}")}</p> - <Button on_click={on_click}>{"got it"}</Button> - </div> - } - } - ClientEvent2::Lobby { joined, players } => { - let player = { - html! { - <Identity ident={ident.1.clone()} class="zoom"/> - } - }; - let player_list = players - .iter() - .map(|ident| { - html! { - <Identity ident={ident.clone()}/> - } - }) - .collect::<Html>(); - - let button_send = (*send).clone(); - let err_cb = error_cb.clone(); - let button = if *joined { - let cb = move |_| { - if let Err(err) = button_send.send_now(ClientMessage::Goodbye) { - err_cb.emit(Some(err.into())); - } - }; - html! { - <Button on_click={cb}>{"leave"}</Button> - } - } else { - let cb = move |_| { - if let Err(err) = button_send.send_now(ClientMessage::Hello) { - err_cb.emit(Some(err.into())); - } - }; - html! { - <Button on_click={cb}>{"join"}</Button> - } - }; - let join_status = if *joined { - html! { - <span class="joined">{"you are in the lobby"}</span> - } - } else { - html! { - <span class="not-joined">{"you have not joined"}</span> - } - }; - - html! { - <div class="client-lobby-player-list"> - {player} - <h4>{"there are currently "}{players.len()}{" players in the lobby"}</h4> - {join_status} - {button} - <div class="list-actual"> - {player_list} - </div> - </div> - } - } - }; - let dead_chat = matches!(&*client_state, ClientEvent2::DeadChat { .. }); - - let nav = dead_chat.not().then_some({ - let send = (*send).clone(); - let error_cb = error_cb.clone(); - let client_nav_msg_cb = move |msg| { - if let Err(err) = send.send_now(msg) { - error_cb.emit(Some(err.into())) - } - }; - html! { - <ClientNav identity={ident_state.clone()} message_callback={client_nav_msg_cb} /> - } - }); - let footer = dead_chat.not().then_some(html! { - <Footer /> - }); - - html! { - <> - {nav} - {content} - {footer} - </> - } -} - -#[derive(Debug, Clone, PartialEq, Copy, Properties)] -pub struct ClientProps { - #[prop_or_default] - pub auto_join: bool, -} diff --git a/werewolves/src/clients/client/connection.rs b/werewolves/src/clients/client/connection.rs deleted file mode 100644 index 732d25e..0000000 --- a/werewolves/src/clients/client/connection.rs +++ /dev/null @@ -1,337 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::num::NonZeroU8; -use core::time::Duration; -use std::cell::RefCell; -use std::rc::Rc; - -use chrono::TimeDelta; -use futures::{FutureExt, SinkExt, StreamExt}; -use gloo::net::websocket::{self, futures::WebSocket}; -use instant::Instant; -use serde::Serialize; -use thiserror::Error; -use werewolves_proto::message::dead::DeadChatMessage; -use werewolves_proto::message::{ClientDeadChat, PlayerUpdate, ServerToClientMessage}; -use werewolves_proto::{ - message::{ClientMessage, Identification, PublicIdentity}, - player::PlayerId, -}; -use yew::{platform::pinned::mpsc::UnboundedReceiver, prelude::*}; - -use crate::clients::client::ClientEvent2; - -#[derive(Debug, Clone, PartialEq, Error)] -pub enum ConnectionError { - #[error("connection already active")] - ConnectionAlreadyActive, -} - -fn url() -> String { - format!("{}/connect/client", crate::clients::BASE_URL) -} - -#[derive(Clone)] -pub struct Connection2 { - state: UseStateSetter<ClientEvent2>, - ident: UseStateHandle<Option<(PlayerId, PublicIdentity)>>, - receiver: Rc<RefCell<UnboundedReceiver<ClientMessage>>>, - active: Rc<RefCell<()>>, - dead_chat: Option<Vec<DeadChatMessage>>, -} - -impl Connection2 { - pub fn new( - state: UseStateSetter<ClientEvent2>, - ident: UseStateHandle<Option<(PlayerId, PublicIdentity)>>, - receiver: Rc<RefCell<UnboundedReceiver<ClientMessage>>>, - ) -> Self { - Self { - state, - ident, - receiver, - dead_chat: None, - active: Rc::new(RefCell::new(())), - } - } - fn identification(&self) -> Identification { - match self.ident.as_ref() { - Some(ident) => Identification { - player_id: ident.0, - public: ident.1.clone(), - }, - None => Identification { - player_id: PlayerId::from_u128(0), - public: PublicIdentity { - name: String::new(), - pronouns: None, - number: None, - }, - }, - } - } - async fn connect_ws() -> WebSocket { - let url = url(); - loop { - match WebSocket::open(&url) { - Ok(ws) => break ws, - Err(err) => { - log::error!("connect: {err}"); - yew::platform::time::sleep(Duration::from_secs(1)).await; - } - } - } - } - - fn encode_message(msg: &impl Serialize) -> websocket::Message { - #[cfg(feature = "json")] - { - websocket::Message::Text(serde_json::to_string(msg).expect("message serialization")) - } - #[cfg(feature = "cbor")] - { - websocket::Message::Bytes({ - let mut v = Vec::new(); - ciborium::into_writer(msg, &mut v).expect("serializing message"); - v - }) - } - } - - pub fn start(&mut self) -> Result<(), ConnectionError> { - let active = self - .active - .try_borrow_mut() - .map_err(|_| ConnectionError::ConnectionAlreadyActive)?; - core::mem::drop(active); - let mut conn = self.clone(); - #[allow(clippy::await_holding_refcell_ref)] - yew::platform::spawn_local(async move { - let active = conn.active.clone(); - conn.active = Rc::new(RefCell::new(())); - let Ok(active_borrow) = active.try_borrow_mut() else { - log::warn!("active connection already borrowed; exiting"); - return; - }; - conn.run().await; - core::mem::drop(active_borrow); - }); - - Ok(()) - } - - #[allow(clippy::await_holding_refcell_ref)] - async fn run(&mut self) { - const CONNECT_WAIT: Duration = Duration::from_secs(3); - let url = url(); - let mut last_connect: Option<Instant> = None; - 'outer: loop { - if let Some(last_conn) = last_connect.as_ref() { - let time_since_last = Instant::now() - *last_conn; - if time_since_last <= CONNECT_WAIT { - let remaining = CONNECT_WAIT.saturating_sub(time_since_last); - if let Some(unfocused_time) = crate::clients::client::time_spent_unfocused() - && let Ok(remaining) = TimeDelta::from_std(remaining) - && remaining < unfocused_time - { - log::debug!("unfocused time: {unfocused_time}"); - last_connect = None; - continue; - } - yew::platform::time::sleep(remaining).await; - continue; - } - } - last_connect = Some(Instant::now()); - log::info!("connecting to {url}"); - let mut ws = Self::connect_ws().await.fuse(); - log::info!("connected to {url}"); - - let ident = self.identification(); - log::debug!("sending self ident: {ident}"); - if let Err(err) = ws.send(Self::encode_message(&ident)).await { - log::error!("websocket identification send: {err}"); - continue 'outer; - }; - - log::debug!("sending get state"); - if let Err(err) = ws - .send(Self::encode_message(&ClientMessage::GetState)) - .await - { - log::error!("websocket get state send: {err}"); - continue 'outer; - }; - log::debug!("beginning listening loop"); - - let mut quit = false; - const GET_CONNECTION_STATE_INTERVAL: Duration = Duration::from_secs(1); - while !quit { - let mut recv = self.receiver.borrow_mut(); - - let msg = futures::select! { - _ = gloo::timers::future::sleep(GET_CONNECTION_STATE_INTERVAL).fuse() => { - if matches!( - ws.get_ref().state(), - websocket::State::Closing | websocket::State::Closed - ) { - log::error!("connection closed on timeout check; reconnecting"); - continue 'outer; - } else { - continue; - } - } - r = ws.next() => { - match r { - Some(Ok(msg)) => msg, - Some(Err(err)) => { - log::error!("websocket recv: {err}"); - continue 'outer; - }, - None => { - log::warn!("websocket closed"); - continue 'outer; - }, - } - } - r = recv.next() => { - match r { - Some(msg) => { - log::info!("sending message: {msg:?}"); - if let Err(err) = ws.send( - Self::encode_message(&msg) - ).await { - log::error!("websocket send error: {err}"); - continue 'outer; - } - continue; - }, - None => { - log::info!("recv channel closed"); - return; - }, - } - }, - }; - core::mem::drop(recv); - let parse = { - #[cfg(feature = "json")] - { - match msg { - websocket::Message::Text(text) => { - serde_json::from_str::<ServerToClientMessage>(&text) - } - websocket::Message::Bytes(items) => serde_json::from_slice(&items), - } - } - #[cfg(feature = "cbor")] - { - match msg { - websocket::Message::Text(_) => { - log::error!("text messages not supported in cbor mode; discarding"); - continue; - } - websocket::Message::Bytes(bytes) => { - ciborium::from_reader::<ServerToClientMessage, _>(bytes.as_slice()) - } - } - } - }; - match parse { - Ok(ServerToClientMessage::DeadChat(msgs)) => { - self.dead_chat.replace(msgs.to_vec()); - self.state.set(ClientEvent2::DeadChat { - messages: msgs.to_vec(), - }); - } - Ok(ServerToClientMessage::DeadChatMessage(msg)) => { - if let Some(dead_chat) = self.dead_chat.as_mut() { - dead_chat.push(msg); - dead_chat.sort_by_key(|k| k.timestamp); - self.state.set(ClientEvent2::DeadChat { - messages: dead_chat.clone(), - }); - } else if let Err(err) = ws - .send(Self::encode_message(&ClientMessage::DeadChat( - ClientDeadChat::GetHistory, - ))) - .await - { - log::error!("sending dead chat history request: {err}"); - } - } - Ok(msg) => { - quit = matches!(msg, ServerToClientMessage::Disconnect); - if let Some(state) = self.message_to_client_state(msg) { - self.state.set(state); - } - } - Err(err) => { - log::error!("parsing server message: {err}; ignoring.") - } - } - } - } - } - - fn message_to_client_state(&self, msg: ServerToClientMessage) -> Option<ClientEvent2> { - log::debug!("received message: {msg:?}"); - Some(match msg { - ServerToClientMessage::Error(err) => { - log::error!("server: {err}"); - return None; - } - ServerToClientMessage::Story(story) => ClientEvent2::Story(story), - ServerToClientMessage::Sleep => ClientEvent2::Sleep, - ServerToClientMessage::Disconnect => ClientEvent2::Disconnected, - ServerToClientMessage::LobbyInfo { - joined, - mut players, - } => { - const LAST: NonZeroU8 = NonZeroU8::new(0xFF).unwrap(); - players.sort_by(|l, r| l.number.unwrap_or(LAST).cmp(&r.number.unwrap_or(LAST))); - ClientEvent2::Lobby { - joined, - players: players.into_iter().collect(), - } - } - ServerToClientMessage::GameStart { role } => ClientEvent2::ShowRole(role), - ServerToClientMessage::InvalidMessageForGameState => { - log::error!("invalid message for game state"); - return None; - } - ServerToClientMessage::NoSuchTarget => { - log::error!("no such target"); - return None; - } - ServerToClientMessage::Update(PlayerUpdate::Number(new_num)) => { - let Some((pid, mut ident)) = (*self.ident).clone() else { - return None; - }; - ident.number = Some(new_num); - self.ident.set(Some((pid, ident))); - return None; - } - ServerToClientMessage::GameInProgress => ClientEvent2::GameInProgress, - ServerToClientMessage::GameOver(_) | ServerToClientMessage::Reset => { - log::info!("ignoring: {msg:?}"); - return None; - } - ServerToClientMessage::DeadChat(_) | ServerToClientMessage::DeadChatMessage(_) => { - return None; - } - }) - } -} diff --git a/werewolves/src/clients/host/host.rs b/werewolves/src/clients/host/host.rs deleted file mode 100644 index d68cc58..0000000 --- a/werewolves/src/clients/host/host.rs +++ /dev/null @@ -1,1017 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::{num::NonZeroU8, ops::Not, time::Duration}; -use std::rc::Rc; - -use futures::{ - SinkExt, StreamExt, - channel::mpsc::{Receiver, Sender}, -}; -use gloo::net::websocket::{self, futures::WebSocket}; -use instant::Instant; -use serde::Serialize; -use werewolves_macros::Titles; -use werewolves_proto::{ - character::CharacterId, - error::GameError, - game::{GameOver, GameSettings, story::GameStory}, - message::{ - CharacterIdentity, CharacterState, PlayerState, PublicIdentity, - dead::DeadChatMessage, - host::{ - HostDayMessage, HostGameMessage, HostLobbyMessage, HostMessage, HostNightMessage, - PostGameMessage, ServerToHostMessage, - }, - night::{ActionPrompt, ActionResult}, - }, - player::PlayerId, -}; -use yew::{html::Scope, prelude::*}; - -use crate::{ - callback, - components::{ - Button, Footer, Lobby, LobbyPlayerAction, RoleReveal, Victory, - action::{ActionResultView, Prompt}, - chat::DeadChat, - host::{CharacterStatesReadOnly, DaytimePlayerList, Setup, VotingMode}, - settings::Settings, - story::Story, - }, - pages::RolePage, - scroll::vertical_scroll_to_horizontal, - storage::StorageKey, - test_util::TestScreens, -}; - -use crate::WerewolfError; - -fn url() -> String { - format!("{}/connect/host", crate::clients::BASE_URL) -} - -async fn connect_ws() -> WebSocket { - let url = url(); - loop { - match WebSocket::open(&url) { - Ok(ws) => break ws, - Err(err) => { - log::error!("connect: {err}"); - yew::platform::time::sleep(Duration::from_secs(1)).await; - } - } - } -} - -fn encode_message(msg: &impl Serialize) -> websocket::Message { - #[cfg(feature = "json")] - { - websocket::Message::Text(serde_json::to_string(msg).expect("message serialization")) - } - #[cfg(feature = "cbor")] - { - websocket::Message::Bytes({ - let mut v = Vec::new(); - ciborium::into_writer(msg, &mut v).expect("serializing message"); - v - }) - } -} - -async fn worker(mut recv: Receiver<HostMessage>, scope: Scope<Host>) { - const CONNECT_WAIT: Duration = Duration::from_secs(3); - let url = url(); - let mut last_connect: Option<Instant> = None; - 'outer: loop { - if let Some(last_connect) = last_connect.as_ref() { - let time_since_last = Instant::now() - *last_connect; - if time_since_last <= CONNECT_WAIT { - log::debug!("waiting to reconnect"); - yew::platform::time::sleep(CONNECT_WAIT.saturating_sub(time_since_last)).await; - log::debug!("wait over"); - continue; - } - log::debug!("reconnecting"); - } - last_connect = Some(Instant::now()); - log::debug!("connecting to {url}"); - let mut ws = connect_ws().await.fuse(); - log::debug!("connected to {url}"); - - log::debug!("sending GetState message"); - if let Err(err) = ws.send(encode_message(&HostMessage::GetState)).await { - log::error!("sending request for state: {err}"); - continue 'outer; - } - log::debug!("initial GetState message sent"); - - loop { - let msg = futures::select! { - r = ws.next() => { - match r { - Some(Ok(msg)) => { - msg - }, - Some(Err(err)) => { - log::error!("websocket recv: {err}"); - continue 'outer; - }, - None => { - log::warn!("websocket closed"); - continue 'outer; - }, - } - } - r = recv.next() => { - match r { - Some(msg) => { - log::info!("sending message: {msg:?}"); - if let Err(err) = ws.send( - encode_message(&msg) - ).await { - log::error!("websocket send error: {err}"); - continue 'outer; - } - continue; - }, - None => { - log::info!("recv channel closed"); - return; - }, - } - }, - }; - - let parse = { - #[cfg(feature = "json")] - { - match msg { - websocket::Message::Text(text) => { - serde_json::from_str::<ServerToHostMessage>(&text) - } - websocket::Message::Bytes(items) => serde_json::from_slice(&items), - } - } - #[cfg(feature = "cbor")] - { - match msg { - websocket::Message::Text(_) => { - log::error!("text messages not supported in cbor mode; discarding"); - continue; - } - websocket::Message::Bytes(bytes) => { - ciborium::from_reader::<ServerToHostMessage, _>(bytes.as_slice()) - } - } - } - }; - match parse { - Ok(ServerToHostMessage::Error(GameError::AwaitingResponse)) => {} - Ok(msg) => { - log::debug!("got message: {:?}", msg.title()); - scope.send_message::<HostEvent>(msg.into()) - } - Err(err) => { - log::error!("parsing server message: {err}; ignoring.") - } - } - } - } -} - -#[derive(Debug, Clone, Titles, PartialEq)] -pub enum HostEvent { - SetErrorCallback(Callback<Option<WerewolfError>>), - SetBigScreenState(bool), - SetState(HostState), - Continue, - Lobby { - players: Box<[PlayerState]>, - settings: GameSettings, - }, - CharacterList(Box<[CharacterState]>), - Error(GameError), - QrMode(bool), - ToOverrideView, - ReturnFromOverride, - ExpectEcho(Box<HostEvent>), - DeadChat(Vec<DeadChatMessage>), - DeadChatMessage(DeadChatMessage), -} -#[derive(Debug, Clone, PartialEq, Titles)] -pub enum HostState { - Disconnected, - Lobby { - players: Rc<[PlayerState]>, - settings: GameSettings, - }, - Day { - characters: Box<[CharacterState]>, - marked_for_execution: Box<[CharacterId]>, - day: NonZeroU8, - settings: GameSettings, - }, - GameOver { - result: GameOver, - }, - RoleReveal { - ackd: Box<[CharacterIdentity]>, - waiting: Box<[CharacterIdentity]>, - }, - Prompt(ActionPrompt, usize), - Result(Option<CharacterIdentity>, ActionResult), - ScreenOverrides { - return_to: Box<HostState>, - }, - VotingMode { - return_to: Box<HostState>, - characters: Box<[CharacterState]>, - }, - Story { - story: GameStory, - #[allow(unused)] - page: usize, - }, - CharacterStates(Box<[CharacterState]>), - InChat { - previously: Box<HostState>, - }, -} - -impl From<ServerToHostMessage> for HostEvent { - fn from(msg: ServerToHostMessage) -> Self { - match msg { - ServerToHostMessage::DeadChatMessage(msg) => HostEvent::DeadChatMessage(msg), - ServerToHostMessage::DeadChat(msgs) => HostEvent::DeadChat(msgs), - ServerToHostMessage::PlayerStates(states) => HostEvent::CharacterList(states), - ServerToHostMessage::QrMode(mode) => HostEvent::QrMode(mode), - ServerToHostMessage::Disconnect => HostEvent::SetState(HostState::Disconnected), - ServerToHostMessage::Daytime { - characters, - day, - marked: marked_for_execution, - settings, - } => HostEvent::SetState(HostState::Day { - characters, - day, - marked_for_execution, - settings, - }), - ServerToHostMessage::Lobby { players, settings } => { - HostEvent::Lobby { players, settings } - } - ServerToHostMessage::Error(err) => HostEvent::Error(err), - ServerToHostMessage::GameOver(game_over) => { - HostEvent::SetState(HostState::GameOver { result: game_over }) - } - ServerToHostMessage::ActionPrompt(prompt, page) => { - HostEvent::SetState(HostState::Prompt(prompt, page)) - } - ServerToHostMessage::ActionResult(_, ActionResult::Continue) => HostEvent::Continue, - ServerToHostMessage::ActionResult(ident, result) => { - HostEvent::SetState(HostState::Result(ident, result)) - } - ServerToHostMessage::WaitingForRoleRevealAcks { ackd, waiting } => { - HostEvent::SetState(HostState::RoleReveal { ackd, waiting }) - } - ServerToHostMessage::Story { story, page } => { - log::info!("story page: {page}"); - HostEvent::SetState(HostState::Story { story, page }) - } - } - } -} - -pub struct Host { - send: Sender<HostMessage>, - state: HostState, - error_callback: Callback<Option<WerewolfError>>, - big_screen: bool, - qr_mode: bool, - debug: bool, - expecting_echo: Option<HostEvent>, - dead_chat: Option<Vec<DeadChatMessage>>, -} - -impl Component for Host { - type Message = HostEvent; - - type Properties = (); - - fn create(ctx: &Context<Self>) -> Self { - gloo::utils::document().set_title(format!("{} — host", crate::TITLE).as_str()); - if let Some(clients) = gloo::utils::document() - .query_selector("clients") - .ok() - .flatten() - { - clients.remove(); - } - let (send, recv) = futures::channel::mpsc::channel(100); - let scope = ctx.link().clone(); - yew::platform::spawn_local(async move { worker(recv, scope).await }); - Self { - send, - state: HostState::Disconnected, - debug: option_env!("DEBUG").is_some(), - big_screen: false, - qr_mode: false, - error_callback: Callback::from(|err| { - if let Some(err) = err { - log::error!("{err}") - } - }), - expecting_echo: None, - dead_chat: None, - } - } - - fn view(&self, _ctx: &Context<Self>) -> Html { - if self.dead_chat.is_none() - && matches!(&self.state, HostState::Day { .. } | HostState::Prompt(_, _)) - { - let mut send = self.send.clone(); - let on_err = self.error_callback.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send - .send(HostMessage::InGame(HostGameMessage::GetDeadChatSince( - Default::default(), - ))) - .await - { - on_err.emit(Some(WerewolfError::Send(err))); - } - }); - } - - let content = match self.state.clone() { - HostState::InChat { .. } => { - let on_send = { - let send = self.send.clone(); - let on_err = self.error_callback.clone(); - move |msg: String| { - let mut send = send.clone(); - let on_err = on_err.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send - .send(HostMessage::InGame(HostGameMessage::SendChatMessage(msg))) - .await - { - on_err.emit(Some(WerewolfError::Send(err))) - } - }); - } - }; - let messages = self.dead_chat.clone().unwrap_or_default(); - if messages.is_empty() { - let mut send = self.send.clone(); - let on_err = self.error_callback.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send - .send(HostMessage::InGame(HostGameMessage::GetDeadChatSince( - Default::default(), - ))) - .await - { - on_err.emit(Some(WerewolfError::Send(err))); - } - }); - } - html! { - <div class="host-dead-chat"> - <DeadChat on_send={on_send} messages={messages}/> - </div> - } - } - HostState::VotingMode { characters, .. } => { - html! { - <VotingMode characters={characters.clone()}/> - } - } - HostState::ScreenOverrides { .. } => { - let send = { - let send = self.send.clone(); - let on_err = self.error_callback.clone(); - let scope = _ctx.link().clone(); - Callback::from(move |msg: ServerToHostMessage| { - scope.send_message(HostEvent::ExpectEcho(Box::new(msg.clone().into()))); - let mut send = send.clone(); - let on_err = on_err.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send.send(HostMessage::Echo(msg)).await { - on_err.emit(Some(err.into())) - } - }); - }) - }; - html! { - <TestScreens send={send} /> - } - } - HostState::CharacterStates(chars) => { - html! { - <CharacterStatesReadOnly states={chars}/> - } - } - HostState::Story { story, .. } => { - if let Some(outcome) = story - .final_village() - .ok() - .and_then(|village| village.is_game_over()) - && self.big_screen - { - html! { - <Victory outcome={outcome}/> - } - } else { - let new_lobby_click = crate::callback::send_message( - HostMessage::PostGame(PostGameMessage::NewLobby), - self.send.clone(), - ); - html! { - <div class="post-game"> - <Story story={story} /> - <Button on_click={new_lobby_click}>{"new lobby"}</Button> - </div> - } - } - } - HostState::GameOver { result } => { - let cont = self.big_screen.not().then(|| { - crate::callback::send_message( - HostMessage::PostGame(PostGameMessage::NextPage), - self.send.clone(), - ) - }); - - html! { - <Victory outcome={result} cont={cont}/> - } - } - HostState::Disconnected => html! { - <div class="disconnected"> - <h2>{"disconnected"}</h2> - </div> - }, - HostState::Lobby { players, settings } => { - if self.big_screen { - self.lobby_big_screen_show_setup(settings) - } else { - self.lobby_setup(players, settings) - } - } - HostState::Day { - characters, - day, - marked_for_execution, - settings, - } => { - if self.big_screen { - self.lobby_big_screen_show_setup(settings) - } else { - let on_mark = crate::callback::send_fn( - |target| { - HostMessage::InGame(HostGameMessage::Day( - HostDayMessage::MarkForExecution(target), - )) - }, - self.send.clone(), - ); - let on_execute = crate::callback::send_message( - HostMessage::InGame(HostGameMessage::Day(HostDayMessage::Execute)), - self.send.clone(), - ); - html! { - <DaytimePlayerList - day={day} - marked={marked_for_execution} - big_screen={self.big_screen} - characters={ - characters.into_iter().map(|c| c.into()).collect::<Box<[_]>>() - } - on_execute={on_execute} - on_mark={on_mark} - /> - } - } - } - HostState::RoleReveal { ackd, waiting } => { - let send = self.send.clone(); - let on_force_ready = self.big_screen.not().then(|| { - Callback::from(move |target: CharacterIdentity| { - let send = send.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send - .clone() - .send(HostMessage::ForceRoleAckFor(target.character_id)) - .await - { - log::error!("force role ack for [{target}]: {err}"); - } - }); - }) - }); - html! { - <RoleReveal - ackd={ackd} - waiting={waiting} - on_force_ready={on_force_ready} - allow_ready_all={self.debug} - /> - } - } - HostState::Prompt(prompt, page) => { - let send = self.send.clone(); - let on_complete = Callback::from(move |msg| { - let mut send = send.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send.send(msg).await { - log::error!("sending prompt response: {err}") - } - }); - }); - let pages = prompt.role_pages(self.big_screen); - - html! { - <Prompt - pages={pages} - page_idx={page} - prompt={prompt} - big_screen={self.big_screen} - on_complete={on_complete} - /> - } - } - HostState::Result(ident, result) => { - let send = self.send.clone(); - let on_complete = Callback::from(move |msg| { - let mut send = send.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send.send(msg).await { - log::error!("sending action result response: {err}") - } - }); - }); - - html! { - <ActionResultView - result={result} - big_screen={self.big_screen} - on_complete={on_complete} - ident={ident.map(|i| i.into())} - /> - } - } - }; - let mut nav_buttons = Vec::<Html>::new(); - let dead_chat_btn = { - let on_dead_chat = { - let scope = _ctx.link().clone(); - let state = self.state.clone(); - move |_| { - scope.send_message(HostEvent::SetState(HostState::InChat { - previously: Box::new(state.clone()), - })) - } - }; - html! { - <Button on_click={on_dead_chat}>{"chat"}</Button> - } - }; - match &self.state { - HostState::Day { characters, .. } => { - let on_vote_mode = { - let scope = _ctx.link().clone(); - let state = self.state.clone(); - let characters = characters.clone(); - move |_| { - scope.send_message(HostEvent::SetState(HostState::VotingMode { - return_to: Box::new(state.clone()), - characters: characters.clone(), - })) - } - }; - - nav_buttons.push(html! { - <Button on_click={on_vote_mode}>{"voting mode"}</Button> - }); - - nav_buttons.push(dead_chat_btn); - } - HostState::VotingMode { .. } => { - let back = crate::callback::send_message(HostMessage::GetState, self.send.clone()); - nav_buttons.push(html! { - <Button on_click={back}>{"back"}</Button> - }); - } - HostState::Prompt(_, _) | HostState::Result(_, _) => { - let on_prev_click = callback::send_message( - HostMessage::InGame(HostGameMessage::PreviousState), - self.send.clone(), - ); - - nav_buttons.push(html! { - <Button on_click={on_prev_click}>{"previous"}</Button> - }); - - let on_view_click = crate::callback::send_message( - HostMessage::InGame(HostGameMessage::SeePlayersWithRoles), - self.send.clone(), - ); - - nav_buttons.push(html! { - <Button on_click={on_view_click}>{"view players"}</Button> - }); - - let overrides_click = { - let scope = _ctx.link().clone(); - Callback::from(move |_| { - scope.send_message(HostEvent::ToOverrideView); - }) - }; - - nav_buttons.push(html! { - <Button on_click={overrides_click}>{"overrides"}</Button> - }); - - nav_buttons.push(dead_chat_btn); - - let on_skip_click = callback::send_message( - HostMessage::InGame(HostGameMessage::Night(HostNightMessage::SkipAction)), - self.send.clone(), - ); - let on_skip_click = { - Callback::from(move |_| { - on_skip_click.emit(()); - crate::components::modal::close_modal_by_id("skip-button"); - }) - }; - - nav_buttons.push(html! { - <crate::components::modal::Dialog - id={"skip-button"} - button={html!{{"skip"}}} - close_button=false - > - <h2>{"skip the current prompt?"}</h2> - <p>{"if this is the final prompt of the night, you may not be able to go back"}</p> - <Button on_click={on_skip_click}>{"skip prompt"}</Button> - </crate::components::modal::Dialog> - }); - } - HostState::CharacterStates(_) => { - let back = crate::callback::send_message(HostMessage::GetState, self.send.clone()); - nav_buttons.push(html! { - <Button on_click={back}>{"back"}</Button> - }); - } - HostState::ScreenOverrides { .. } => { - let return_click = { - let scope = _ctx.link().clone(); - Callback::from(move |_| { - scope.send_message(HostEvent::ReturnFromOverride); - }) - }; - - nav_buttons.push(html! { - <Button on_click={return_click}>{"back"}</Button> - }); - } - HostState::InChat { previously } => { - let return_click = { - let scope = _ctx.link().clone(); - let previously = (**previously).clone(); - Callback::from(move |_| { - scope.send_message(HostEvent::SetState(previously.clone())); - }) - }; - - nav_buttons.push(html! { - <Button on_click={return_click}>{"back"}</Button> - }); - } - _ => {} - } - let on_wheel = vertical_scroll_to_horizontal(".host-nav"); - - let nav = self.big_screen.not().then(|| { - html! { - <nav class="host-nav" style="z-index: 3;" onwheel={on_wheel}> - {nav_buttons} - </nav> - } - }); - let footer = - (self.big_screen.not() && matches!(self.state, HostState::Lobby { .. })).then(|| { - html! { - <Footer /> - } - }); - html! { - <> - {nav} - <div class="content"> - {content} - </div> - {footer} - </> - } - } - - fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool { - log::debug!("update: {}, current: {}", msg.title(), self.state.title()); - match &msg { - HostEvent::Continue => { - if self.big_screen { - return false; - } - let mut send = self.send.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send - .send(HostMessage::InGame(HostGameMessage::Night( - HostNightMessage::Next, - ))) - .await - { - log::error!("sending next: {err:?}") - } - }); - } - HostEvent::SetErrorCallback(cb) => { - self.error_callback = cb.clone(); - } - HostEvent::SetBigScreenState(state) => { - self.big_screen = *state; - if self.big_screen { - gloo::utils::document_element().set_class_name("big-screen") - } - - if *state { - let (mut discard_send, mut discard_recv) = futures::channel::mpsc::channel(10); - core::mem::swap(&mut discard_send, &mut self.send); - Box::leak(Box::new(discard_send)); - yew::platform::spawn_local(async move { - while discard_recv.next().await.is_some() {} - }); - } - self.debug = false; - self.error_callback = Callback::noop(); - } - HostEvent::QrMode(mode) => { - self.qr_mode = *mode; - } - HostEvent::ExpectEcho(echo) => { - self.expecting_echo.replace((**echo).clone()); - } - HostEvent::ReturnFromOverride => { - if let HostState::ScreenOverrides { return_to } = &self.state { - log::debug!("returning from screen overrides to: {}", return_to.title()); - self.state = (**return_to).clone(); - return true; - } else { - return false; - } - } - _ => {} - } - if let HostState::ScreenOverrides { .. } = &self.state { - let (state, update) = self.message_to_new_state(msg.clone()); - if let Some(mut state) = state - // re-borrow so we can borrow self immutably for [message_to_new_state] - && let HostState::ScreenOverrides { return_to } = &mut self.state - && (self.expecting_echo.is_none() - || self - .expecting_echo - .as_ref() - .map(|exp| *exp != msg) - .unwrap_or_default()) - { - log::debug!("screen override: new return_to: {}", return_to.title()); - core::mem::swap(&mut **return_to, &mut state); - self.expecting_echo.take(); - } - return update; - } - - let (state, update) = self.message_to_new_state(msg); - if let Some(state) = state { - self.state = state; - } - - update - } -} - -impl Host { - fn message_to_new_state(&mut self, msg: HostEvent) -> (Option<HostState>, bool) { - match msg { - HostEvent::DeadChatMessage(msg) => { - match self.dead_chat.as_mut() { - Some(dc) => { - dc.push(msg); - dc.sort_by_key(|d| d.timestamp); - } - None => { - self.dead_chat.replace(vec![msg]); - } - } - if let HostState::InChat { .. } = &self.state { - (None, true) - } else { - (None, false) - } - } - HostEvent::DeadChat(mut msgs) => { - match self.dead_chat.as_mut() { - Some(chat) => { - chat.append(&mut msgs); - chat.sort_by_key(|k| k.timestamp); - chat.dedup_by_key(|k| k.id); - } - None => { - self.dead_chat.replace(msgs); - } - } - if let HostState::InChat { .. } = &self.state { - (None, true) - } else { - (None, false) - } - } - HostEvent::ExpectEcho(_) => (None, false), - HostEvent::ReturnFromOverride => { - if let HostState::ScreenOverrides { return_to } = &self.state { - (Some((**return_to).clone()), true) - } else { - (None, false) - } - } - HostEvent::ToOverrideView => { - if let HostState::ScreenOverrides { .. } = &self.state { - return (None, false); - } - ( - Some(HostState::ScreenOverrides { - return_to: Box::new(self.state.clone()), - }), - true, - ) - } - HostEvent::CharacterList(char) => { - if self.big_screen { - return (None, false); - } - (Some(HostState::CharacterStates(char)), true) - } - HostEvent::QrMode(mode) => (None, true), - HostEvent::Lobby { - mut players, - settings, - } => { - const LAST: NonZeroU8 = NonZeroU8::new(0xFF).unwrap(); - players.sort_by(|l, r| { - l.identification - .public - .number - .unwrap_or(LAST) - .cmp(&r.identification.public.number.unwrap_or(LAST)) - }); - self.dead_chat = None; - ( - Some(HostState::Lobby { - settings, - players: players.into_iter().collect(), - }), - true, - ) - } - HostEvent::SetErrorCallback(callback) => (None, false), - HostEvent::SetState(state) => (Some(state), true), - HostEvent::Error(_) => (None, false), - HostEvent::SetBigScreenState(_) => (None, true), - HostEvent::Continue => (None, false), - } - } - fn lobby_big_screen_show_setup(&self, settings: GameSettings) -> Html { - if !self.qr_mode { - return html! { - <Setup settings={settings}/> - }; - } - let qrcode_url = if option_env!("LOCAL").is_some() { - String::from("http://192.168.1.162:8080/qrcode") - } else { - String::from("/qrcode") - }; - html! { - <div class="qrcode"> - <img src={qrcode_url} alt="qr code to join"/> - <div class="details"> - <h3>{"scan the qrcode to join"}</h3> - </div> - </div> - } - } - - fn lobby_setup(&self, players: Rc<[PlayerState]>, settings: GameSettings) -> Html { - let on_error = self.error_callback.clone(); - let qr_mode_toggle = { - let on_click = crate::callback::send_message( - HostMessage::Lobby(HostLobbyMessage::SetQrMode(!self.qr_mode)), - self.send.clone(), - ); - let text = if self.qr_mode { - "disable qr mode" - } else { - "enable qr mode" - }; - html! { - <Button on_click={on_click}>{text}</Button> - } - }; - - let settings = self.big_screen.not().then(|| { - let send = self.send.clone(); - let on_changed = Callback::from(move |s: GameSettings| { - let send = send.clone(); - if let Err(err) = s.save_to_storage() { - log::error!("saving settings to local storage: {err}"); - } - yew::platform::spawn_local(async move { - let mut send = send.clone(); - if let Err(err) = send - .send(HostMessage::Lobby(HostLobbyMessage::SetGameSettings(s))) - .await - { - log::error!("sending game settings update: {err}"); - } - }); - }); - let send = self.send.clone(); - let on_start = Callback::from(move |_| { - let send = send.clone(); - let on_error = on_error.clone(); - - yew::platform::spawn_local(async move { - let mut send = send.clone(); - if let Err(err) = send.send(HostMessage::Lobby(HostLobbyMessage::Start)).await { - on_error.emit(Some(err.into())) - } - }); - }); - let on_add_player = crate::callback::send_fn( - |msg: PublicIdentity| HostMessage::Lobby(HostLobbyMessage::ManufacturePlayer(msg)), - self.send.clone(), - ); - html! { - <Settings - settings={settings} - on_start={on_start} - on_update={on_changed} - players_in_lobby={players.clone()} - on_add_player={on_add_player} - qr_mode_button={qr_mode_toggle} - /> - } - }); - let on_action = self.big_screen.not().then(|| { - let on_error = self.error_callback.clone(); - let send = self.send.clone(); - Callback::from(move |(player_id, act): (PlayerId, LobbyPlayerAction)| { - let msg = match act { - LobbyPlayerAction::Kick => { - HostMessage::Lobby(HostLobbyMessage::Kick(player_id)) - } - LobbyPlayerAction::SetNumber(num) => { - HostMessage::Lobby(HostLobbyMessage::SetPlayerNumber(player_id, num)) - } - }; - let mut send = send.clone(); - let on_error = on_error.clone(); - yew::platform::spawn_local(async move { - if let Err(err) = send.send(msg).await { - on_error.emit(Some(err.into())) - } - }); - }) - }); - html! { - <div class="host-setup"> - {settings} - <Lobby players={players} on_action={on_action}/> - </div> - } - } -} diff --git a/werewolves/src/clients/mod.rs b/werewolves/src/clients/mod.rs deleted file mode 100644 index 241eb5f..0000000 --- a/werewolves/src/clients/mod.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -pub mod client { - mod client; - pub mod connection; - pub use client::*; -} -pub mod host { - mod host; - pub use host::*; -} - -const BASE_URL: &str = match option_env!("BASE_URL") { - Some(base_url) => base_url, - None => "ws://192.168.1.162:8080", -}; - -use yew::prelude::*; -#[function_component] -pub fn StoryTest() -> Html { - html! { - <crate::components::story::Story story={crate::components::story::generate_story()}/> - } -} diff --git a/werewolves/src/components/action/binary.rs b/werewolves/src/components/action/binary.rs deleted file mode 100644 index 9d337f5..0000000 --- a/werewolves/src/components/action/binary.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::Button; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct BinaryChoiceProps { - pub on_chosen: Option<Callback<bool>>, - #[prop_or_default] - pub children: Html, -} - -#[function_component] -pub fn BinaryChoice( - BinaryChoiceProps { - on_chosen, - children, - }: &BinaryChoiceProps, -) -> Html { - let on_chosen_yes = on_chosen.clone(); - let yes = on_chosen_yes - .map(|on_chosen| Callback::from(move |_| on_chosen.emit(true))) - .unwrap_or_default(); - let on_chosen = on_chosen.clone(); - let no = on_chosen - .map(|on_chosen| Callback::from(move |_| on_chosen.emit(false))) - .unwrap_or_default(); - html! { - <div class="column-list binary"> - {children.clone()} - <div class="button-container"> - <Button on_click={yes}>{"Yes"}</Button> - <Button on_click={no}>{"No"}</Button> - </div> - </div> - } -} diff --git a/werewolves/src/components/action/picker.rs b/werewolves/src/components/action/picker.rs deleted file mode 100644 index af5329a..0000000 --- a/werewolves/src/components/action/picker.rs +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::{character::CharacterId, message::CharacterIdentity}; -use yew::prelude::*; - -use crate::components::{Button, CharacterTargetCard}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct TargetPickerProps { - pub targets: Box<[CharacterIdentity]>, - pub marked: Box<[CharacterId]>, - pub mark_callback: Option<Callback<CharacterId>>, - pub continue_callback: Option<Callback<()>>, -} - -#[function_component] -pub fn TargetPicker( - TargetPickerProps { - targets, - marked, - mark_callback, - continue_callback, - }: &TargetPickerProps, -) -> Html { - let targets = targets - .iter() - .map(|t| { - let cb = mark_callback.clone(); - let marked = marked.contains(&t.character_id); - html! { - <TargetCard target={t.clone()} marked={marked} mark_callback={cb}/> - } - }) - .collect::<Html>(); - let continue_button = continue_callback.clone().map(|continue_callback| { - html! { - <Button on_click={continue_callback}> - {"continue"} - </Button> - } - }); - - html! { - <div class="target-picker"> - <div class="targets"> - {targets} - </div> - {continue_button} - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct TargetCardProps { - pub target: CharacterIdentity, - pub marked: bool, - pub mark_callback: Option<Callback<CharacterId>>, -} - -#[function_component] -pub fn TargetCard( - TargetCardProps { - target, - marked, - mark_callback, - }: &TargetCardProps, -) -> Html { - let click_target = target.character_id; - let on_click = mark_callback - .clone() - .map(|cb| Callback::from(move |_| cb.emit(click_target))) - .unwrap_or_default(); - let marked = marked.then_some("marked"); - html! { - <Button on_click={on_click} classes={classes!(marked, "character")}> - <CharacterTargetCard ident={target.clone()}/> - </Button> - } -} diff --git a/werewolves/src/components/action/prompt.rs b/werewolves/src/components/action/prompt.rs deleted file mode 100644 index 92205da..0000000 --- a/werewolves/src/components/action/prompt.rs +++ /dev/null @@ -1,449 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::ops::Not; -use std::rc::Rc; - -use werewolves_proto::{ - character::CharacterId, - message::{ - CharacterIdentity, PublicIdentity, - host::{HostGameMessage, HostMessage, HostNightMessage}, - night::{ActionPrompt, ActionResponse}, - }, -}; -use yew::prelude::*; - -use crate::components::{ - Button, CoverOfDarkness, Identity, - action::{BinaryChoice, TargetPicker, WolvesIntro}, -}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct ActionPromptProps { - pub prompt: ActionPrompt, - #[prop_or_default] - pub big_screen: bool, - pub on_complete: Callback<HostMessage>, - #[prop_or_default] - pub page_idx: usize, - #[prop_or_default] - pub pages: Rc<[Html]>, -} - -fn identity_html(props: &ActionPromptProps, ident: Option<&CharacterIdentity>) -> Option<Html> { - props - .big_screen - .not() - .then(|| { - ident.map(|ident| { - let ident: PublicIdentity = ident.into(); - html! { - <Identity ident={ident}/> - } - }) - }) - .flatten() -} - -#[function_component] -pub fn Prompt(props: &ActionPromptProps) -> Html { - if let Some(page) = props.pages.get(props.page_idx).map(|page| { - let next = props.big_screen.not().then(|| { - let send = props.on_complete.clone(); - let page_idx = props.page_idx; - let pages_total = props.pages.len(); - let prompt = props.prompt.clone(); - let on_page_next = Callback::from(move |_| { - send.emit(HostMessage::InGame(HostGameMessage::Night( - if page_idx + 1 >= pages_total && !prompt.interactive() { - HostNightMessage::ActionResponse(ActionResponse::ContinueToResult) - } else { - HostNightMessage::NextPage - }, - ))) - }); - html! { - <Button on_click={on_page_next} classes={classes!("next")}> - {"next"} - </Button> - } - }); - - html! { - <div class="page"> - {page.clone()} - {next} - </div> - } - }) { - return page; - } - - let on_complete = props.on_complete.clone(); - let continue_callback = props.big_screen.not().then(|| { - Callback::from(move |_| { - on_complete.emit(HostMessage::InGame(HostGameMessage::Night( - HostNightMessage::ActionResponse(ActionResponse::Continue), - ))) - }) - }); - let on_complete = props.on_complete.clone(); - let mark_callback = props.big_screen.not().then(|| { - Callback::from(move |target: CharacterId| { - on_complete.emit(HostMessage::InGame(HostGameMessage::Night( - HostNightMessage::ActionResponse(ActionResponse::MarkTarget(target)), - ))); - }) - }); - - let (character_id, targets, marked, role_info) = match &props.prompt { - ActionPrompt::BeholderWakes { .. } | ActionPrompt::DamnedIntro { .. } => return html! {}, - ActionPrompt::CoverOfDarkness => { - return html! { - <CoverOfDarkness next={continue_callback}/> - }; - } - ActionPrompt::WolvesIntro { wolves } => { - return html! { - <WolvesIntro - on_complete={continue_callback} - wolves={wolves.clone()} - /> - }; - } - ActionPrompt::MasonsWake { .. } => { - props - .on_complete - .emit(HostMessage::InGame(HostGameMessage::Night( - HostNightMessage::ActionResponse(ActionResponse::Continue), - ))); - props - .on_complete - .emit(HostMessage::InGame(HostGameMessage::Night( - HostNightMessage::Next, - ))); - props.on_complete.emit(HostMessage::GetState); - return html! {}; - } - ActionPrompt::RoleChange { .. } - | ActionPrompt::ElderReveal { .. } - | ActionPrompt::Insomniac { .. } => { - if !props.big_screen { - props - .on_complete - .emit(HostMessage::InGame(HostGameMessage::Night( - HostNightMessage::ActionResponse(ActionResponse::ContinueToResult), - ))); - } - return html! { - <CoverOfDarkness message={"oops".to_string()} /> - }; - } - - ActionPrompt::Guardian { - character_id, - living_players, - marked, - .. - } => { - let marked = marked.iter().cloned().collect::<Box<[CharacterId]>>(); - - return html! { - <div class="guardian-select"> - {identity_html(props, Some(character_id))} - <TargetPicker - targets={living_players.clone()} - marked={marked} - mark_callback={mark_callback} - continue_callback={continue_callback} - /> - </div> - }; - } - - ActionPrompt::Bloodletter { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"bloodletter"}}, - ), - ActionPrompt::LoneWolfKill { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"lone wolf kill"}}, - ), - ActionPrompt::Adjudicator { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"adjudicator"}}, - ), - ActionPrompt::BeholderChooses { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"beholder"}}, - ), - ActionPrompt::Empath { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"empath"}}, - ), - ActionPrompt::MasonLeaderRecruit { - character_id, - recruits_left, - potential_recruits, - marked, - } => ( - Some(character_id), - potential_recruits, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! { - <div> - <span>{"mason leader recruit"}</span> - <span>{"("}{recruits_left.get()}{" remaining)"}</span> - </div> - }, - ), - ActionPrompt::Mortician { - character_id, - dead_players, - marked, - } => ( - Some(character_id), - dead_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"mortician"}}, - ), - ActionPrompt::PowerSeer { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"power seer"}}, - ), - ActionPrompt::PyreMaster { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"pyremaster"}}, - ), - ActionPrompt::Vindicator { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"vindicator"}}, - ), - ActionPrompt::Seer { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect::<Box<[CharacterId]>>(), - html! {{"seer"}}, - ), - ActionPrompt::Protector { - character_id, - targets, - marked, - } => ( - Some(character_id), - targets, - marked.iter().cloned().collect(), - html! {{"protector"}}, - ), - ActionPrompt::Arcanist { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - [&marked.0, &marked.1].iter().filter_map(|c| **c).collect(), - html! {{"arcanist"}}, - ), - ActionPrompt::Gravedigger { - character_id, - dead_players, - marked, - } => ( - Some(character_id), - dead_players, - marked.iter().cloned().collect(), - html! {{"gravedigger"}}, - ), - ActionPrompt::Hunter { - character_id, - current_target, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect(), - { - let current_target = current_target.as_ref().cloned().map(|t| { - html! { - <> - <h3>{"current target:"}</h3> - <Identity ident={Into::<PublicIdentity>::into(t)} /> - </> - } - }); - html! { - <> - <h2>{"hunter"}</h2> - {current_target} - </> - } - }, - ), - ActionPrompt::Militia { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect(), - html! {{"militia"}}, - ), - ActionPrompt::MapleWolf { - character_id, - nights_til_starvation, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect(), - html! {<>{"maple wolf"} {(*nights_til_starvation == 0).then_some(" — starving")}</>}, - ), - ActionPrompt::WolfPackKill { - living_villagers, - marked, - } => ( - None, - living_villagers, - marked.iter().cloned().collect(), - html! {{"wolfpack kill"}}, - ), - ActionPrompt::Shapeshifter { character_id } => { - let on_complete = props.on_complete.clone(); - let on_select = props.big_screen.not().then_some({ - move |shift| { - on_complete.emit(HostMessage::InGame(HostGameMessage::Night( - HostNightMessage::ActionResponse(if shift { - ActionResponse::Shapeshift - } else { - ActionResponse::Continue - }), - ))); - } - }); - let choice = props.big_screen.not().then_some(html! { - <BinaryChoice on_chosen={on_select} /> - }); - return html! { - <div class="role-page"> - {identity_html(props, Some(character_id))} - <h1 class="wolves">{"SHAPESHIFTER"}</h1> - <div class="information wolves faint"> - <span> - {"WOULD YOU LIKE TO USE YOUR "} - <span class="yellow">{"ONCE PER GAME"}</span> - {" SHAPESHIFT ABILITY?"} - </span> - <span class="subtext"> - <span class="yellow">{"YOU WILL DIE"}</span> - {", BUT THE TARGET OF THE WOLFPACK KILL SHALL INSTEAD BECOME A WOLF"} - </span> - </div> - {choice} - </div> - }; - } - ActionPrompt::AlphaWolf { - character_id, - living_villagers, - marked, - } => ( - Some(character_id), - living_villagers, - marked.iter().cloned().collect(), - html! {{"alpha wolf"}}, - ), - ActionPrompt::DireWolf { - character_id, - living_players, - marked, - } => ( - Some(character_id), - living_players, - marked.iter().cloned().collect(), - html! {{"direwolf"}}, - ), - }; - let role_info = props.big_screen.not().then_some(html! { - <h2>{role_info}</h2> - }); - html! { - <div class="prompt"> - {identity_html(props, character_id)} - {role_info} - <TargetPicker - targets={targets.clone()} - marked={marked} - mark_callback={mark_callback} - continue_callback={continue_callback} - /> - </div> - } -} diff --git a/werewolves/src/components/action/result.rs b/werewolves/src/components/action/result.rs deleted file mode 100644 index 2e10fad..0000000 --- a/werewolves/src/components/action/result.rs +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::ops::Not; - -use werewolves_proto::message::{ - PublicIdentity, - host::{HostGameMessage, HostMessage, HostNightMessage}, - night::{ActionResponse, ActionResult}, -}; -use yew::prelude::*; - -use crate::{ - components::{Button, CoverOfDarkness, Identity}, - pages::{ - AdjudicatorResult, ArcanistResult, BeholderSawEverything, BeholderSawNothing, DrunkPage, - EmpathResult, GravediggerResultPage, InsomniacResult, MorticianResultPage, PowerSeerResult, - RoleblockPage, SeerResult, ShiftFailed, - }, -}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct ActionResultProps { - pub result: ActionResult, - #[prop_or_default] - pub ident: Option<PublicIdentity>, - pub big_screen: bool, - pub on_complete: Callback<HostMessage>, -} - -#[function_component] -pub fn ActionResultView(props: &ActionResultProps) -> Html { - let ident = props.ident.as_ref().and_then(|ident| { - props - .big_screen - .not() - .then(|| html! {<Identity ident={ident.clone()}/>}) - }); - let on_complete = props.on_complete.clone(); - let on_continue = Callback::from(move |_| { - on_complete.emit(HostMessage::InGame(HostGameMessage::Night( - HostNightMessage::ActionResponse(ActionResponse::Continue), - ))) - }); - let cont = props - .big_screen - .not() - .then(|| html! {<Button on_click={on_continue}>{"continue"}</Button>}); - let body = match &props.result { - ActionResult::ShiftFailed => html! { - <ShiftFailed /> - }, - ActionResult::Drunk => html! { - <DrunkPage /> - }, - ActionResult::BeholderSawEverything => html! { - <BeholderSawEverything /> - }, - ActionResult::BeholderSawNothing => html! { - <BeholderSawNothing /> - }, - ActionResult::PowerSeer { target, powerful } => { - html! { - <PowerSeerResult powerful={*powerful} target={target.clone().into_public()}/> - } - } - ActionResult::Adjudicator { killer, target } => { - html! { - <AdjudicatorResult killer={*killer} target={target.clone().into_public()}/> - } - } - ActionResult::Mortician(target, died_to) => html! { - <MorticianResultPage died_to={*died_to} target={target.clone().into_public()}/> - }, - ActionResult::Empath { target, scapegoat } => html! { - <EmpathResult scapegoat={*scapegoat} target={target.clone().into_public()}/> - }, - ActionResult::Insomniac(visits) => { - html! { - <InsomniacResult visits={visits.clone()}/> - } - } - ActionResult::RoleBlocked => { - html! { - <RoleblockPage /> - } - } - ActionResult::Seer(target, alignment) => html! { - <SeerResult alignment={*alignment} target={target.clone().into_public()}/> - }, - ActionResult::Arcanist((t1, t2), same) => { - html! { - <ArcanistResult alignment_eq={*same} targets={(t1.clone().into_public(), t2.clone().into_public())}/> - } - } - ActionResult::GraveDigger(target, role_title) => { - html! { - <GravediggerResultPage role={*role_title} target={target.clone().into_public()}/> - } - } - ActionResult::GoBackToSleep => { - let next = props.big_screen.not().then(|| { - let on_complete = props.on_complete.clone(); - move |_| { - on_complete.emit(HostMessage::InGame(HostGameMessage::Night( - HostNightMessage::Next, - ))) - } - }); - return html! { - <CoverOfDarkness message={"go to sleep"} next={next}> - {"continue"} - </CoverOfDarkness> - }; - } - ActionResult::SkippedByHost | ActionResult::Continue => { - props.on_complete.emit(HostMessage::GetState); - return html! { - <CoverOfDarkness /> - }; - } - }; - - html! { - <div class="result"> - {ident} - {body} - {cont} - </div> - } -} diff --git a/werewolves/src/components/action/target.rs b/werewolves/src/components/action/target.rs deleted file mode 100644 index 073e5ed..0000000 --- a/werewolves/src/components/action/target.rs +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -// use core::{fmt::Debug, ops::Not}; - -// use werewolves_proto::{ -// message::{CharacterIdentity, PublicIdentity}, -// player::CharacterId, -// }; -// use yew::prelude::*; - -// use crate::components::{Button, Identity}; - -// #[derive(Debug, Clone, PartialEq, Properties)] -// pub struct TwoTargetProps { -// pub targets: Box<[CharacterIdentity]>, -// #[prop_or_default] -// pub headline: &'static str, -// #[prop_or_default] -// pub target_selection: Option<Callback<(CharacterId, CharacterId)>>, -// } - -// #[derive(Clone)] -// enum TwoTargetSelection { -// None, -// One(CharacterId), -// Two(CharacterId, CharacterId), -// } - -// impl TwoTargetSelection { -// fn is_selected(&self, id: &CharacterId) -> bool { -// match self { -// TwoTargetSelection::None => false, -// TwoTargetSelection::One(character_id) => id == character_id, -// TwoTargetSelection::Two(cid1, cid2) => id == cid1 || id == cid2, -// } -// } -// } - -// pub struct TwoTarget(TwoTargetSelection); - -// impl Component for TwoTarget { -// type Message = CharacterId; - -// type Properties = TwoTargetProps; - -// fn create(_: &Context<Self>) -> Self { -// Self(TwoTargetSelection::None) -// } - -// fn view(&self, ctx: &Context<Self>) -> Html { -// let TwoTargetProps { -// targets, -// headline, -// target_selection, -// } = ctx.props(); -// let mut targets = targets.clone(); -// targets.sort_by(|l, r| l.number.cmp(&r.number)); - -// let target_selection = target_selection.clone(); -// let scope = ctx.link().clone(); -// let card_select = Callback::from(move |target| { -// scope.send_message(target); -// }); -// let targets = targets -// .iter() -// .map(|t| { -// html! { -// <TargetCard -// target={t.clone()} -// selected={self.0.is_selected(&t.character_id)} -// on_select={card_select.clone()} -// /> -// } -// }) -// .collect::<Html>(); -// let headline = headline -// .trim() -// .is_empty() -// .not() -// .then(|| html!(<h2>{headline}</h2>)); - -// let submit = target_selection.as_ref().map(|target_selection| { -// let selected = match &self.0 { -// TwoTargetSelection::None | TwoTargetSelection::One(_) => None, -// TwoTargetSelection::Two(t1, t2) => Some((*t1, *t2)), -// }; -// let target_selection = target_selection.clone(); -// let disabled = selected.is_none(); -// let on_click = -// selected.map(|(t1, t2)| move |_| target_selection.emit((t1, t2))); -// html! { -// <div class="button-container sp-ace"> -// <button -// disabled={disabled} -// onclick={on_click} -// > -// {"submit"} -// </button> -// </div> -// } -// }); - -// html! { -// <div class="column-list"> -// {headline} -// <div class="row-list"> -// {targets} -// </div> -// {submit} -// </div> -// } -// } - -// fn update(&mut self, _: &Context<Self>, msg: Self::Message) -> bool { -// match &self.0 { -// TwoTargetSelection::None => self.0 = TwoTargetSelection::One(msg), -// TwoTargetSelection::One(character_id) => { -// if character_id == &msg { -// self.0 = TwoTargetSelection::None -// } else { -// self.0 = TwoTargetSelection::Two(*character_id, msg) -// } -// } -// TwoTargetSelection::Two(t1, t2) => { -// if &msg == t1 { -// self.0 = TwoTargetSelection::One(*t2); -// } else if &msg == t2 { -// self.0 = TwoTargetSelection::One(*t1); -// } else { -// self.0 = TwoTargetSelection::Two(*t1, msg); -// } -// } -// } - -// true -// } -// } - -// #[derive(Debug, Clone, PartialEq, Properties)] -// pub struct OptionalSingleTargetProps { -// pub targets: Box<[CharacterIdentity]>, -// #[prop_or_default] -// pub headline: &'static str, -// #[prop_or_default] -// pub target_selection: Option<Callback<Option<CharacterId>>>, -// #[prop_or_default] -// pub children: Html, -// } - -// pub struct OptionalSingleTarget(Option<CharacterId>); - -// impl Component for OptionalSingleTarget { -// type Message = CharacterId; - -// type Properties = OptionalSingleTargetProps; - -// fn create(_: &Context<Self>) -> Self { -// Self(None) -// } - -// fn view(&self, ctx: &Context<Self>) -> Html { -// let OptionalSingleTargetProps { -// targets, -// headline, -// target_selection, -// children, -// } = ctx.props(); -// let mut targets = targets.clone(); -// targets.sort_by(|l, r| l.number.cmp(&r.number)); - -// let target_selection = target_selection.clone(); -// let scope = ctx.link().clone(); -// let card_select = Callback::from(move |target| { -// scope.send_message(target); -// }); -// let targets = targets -// .iter() -// .map(|t| { -// html! { -// <TargetCard -// target={t.clone()} -// selected={self.0.as_ref().map(|c| c == &t.character_id).unwrap_or_default()} -// on_select={card_select.clone()} -// /> -// } -// }) -// .collect::<Html>(); -// let headline = headline -// .trim() -// .is_empty() -// .not() -// .then(|| html!(<h2>{headline}</h2>)); - -// let submit = target_selection.as_ref().map(|target_selection| { -// let target_selection = target_selection.clone(); -// let sel = self.0; -// let on_click = move |_| target_selection.emit(sel); -// html! { -// <div class="button-container sp-ace"> -// <button -// onclick={on_click} -// > -// {"submit"} -// </button> -// </div> -// } -// }); - -// html! { -// <div class="column-list"> -// {headline} -// {children.clone()} -// <div class="row-list"> -// {targets} -// </div> -// {submit} -// </div> -// } -// } - -// fn update(&mut self, _: &Context<Self>, msg: Self::Message) -> bool { -// match &self.0 { -// Some(t) => { -// if t == &msg { -// self.0 = None -// } else { -// self.0 = Some(msg); -// } -// } -// None => self.0 = Some(msg), -// } -// true -// } -// } - -// #[derive(Debug, Clone, PartialEq, Properties)] -// pub struct SingleTargetProps { -// pub targets: Box<[CharacterIdentity]>, -// #[prop_or_default] -// pub headline: &'static str, -// #[prop_or_default] -// pub target_selection: Option<Callback<CharacterId>>, -// #[prop_or_default] -// pub children: Html, -// } - -// pub struct SingleTarget { -// selected: Option<CharacterId>, -// } - -// impl Component for SingleTarget { -// type Message = CharacterId; - -// type Properties = SingleTargetProps; - -// fn create(_: &Context<Self>) -> Self { -// Self { selected: None } -// } - -// fn view(&self, ctx: &Context<Self>) -> Html { -// let SingleTargetProps { -// headline, -// targets, -// target_selection, -// children, -// } = ctx.props(); -// let mut targets = targets.clone(); -// targets.sort_by(|l, r| l.number.cmp(&r.number)); -// let target_selection = target_selection.clone(); -// let scope = ctx.link().clone(); -// let card_select = Callback::from(move |target| { -// scope.send_message(target); -// }); -// let targets = targets -// .iter() -// .map(|t| { -// html! { -// <TargetCard -// target={t.clone()} -// selected={self.selected.as_ref().map(|sel| sel == &t.character_id).unwrap_or_default()} -// on_select={card_select.clone()} -// /> -// } -// }) -// .collect::<Html>(); -// let headline = headline -// .trim() -// .is_empty() -// .not() -// .then(|| html!(<h2>{headline}</h2>)); - -// let submit = target_selection.as_ref().map(|target_selection| { -// let disabled = self.selected.is_none().then_some("pick a target"); -// let target_selection = target_selection.clone(); -// let on_click = self -// .selected -// .map(|t| Callback::from(move |_| target_selection.emit(t))) -// .unwrap_or_default(); -// html! { -// <div class="button-container sp-ace"> -// <Button disabled_reason={disabled} on_click={on_click}> -// {"submit"} -// </Button> -// </div> -// } -// }); - -// html! { -// <div class="character-picker"> -// {headline} -// {children.clone()} -// <div class="row-list"> -// {targets} -// </div> -// {submit} -// </div> -// } -// } - -// fn update(&mut self, _: &Context<Self>, msg: Self::Message) -> bool { -// match &self.selected { -// Some(current) => { -// if current == &msg { -// self.selected = None; -// } else { -// self.selected = Some(msg); -// } -// } -// None => self.selected = Some(msg), -// } -// true -// } -// } - -// #[derive(Debug, Clone, PartialEq, Properties)] -// pub struct TargetCardProps { -// pub target: CharacterIdentity, -// pub selected: bool, -// pub on_select: Callback<CharacterId>, -// } - -// #[function_component] -// fn TargetCard(props: &TargetCardProps) -> Html { -// let character_id = props.target.character_id; -// let on_select = props.on_select.clone(); -// let on_click = Callback::from(move |_| on_select.emit(character_id)); - -// let marked = props.selected.then_some("marked"); -// let ident: PublicIdentity = props.target.clone().into(); -// html! { -// <Button on_click={on_click} classes={classes!(marked, "character")}> -// <Identity ident={ident}/> -// </Button> -// } -// } diff --git a/werewolves/src/components/action/wolves.rs b/werewolves/src/components/action/wolves.rs deleted file mode 100644 index a7473c0..0000000 --- a/werewolves/src/components/action/wolves.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use convert_case::{Case, Casing}; -use werewolves_proto::{ - message::{CharacterIdentity, PublicIdentity}, - role::RoleTitle, -}; -use yew::prelude::*; - -use crate::components::{Button, Identity}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct WolvesIntroProps { - pub wolves: Box<[(CharacterIdentity, RoleTitle)]>, - pub on_complete: Option<Callback<()>>, -} - -#[function_component] -pub fn WolvesIntro(props: &WolvesIntroProps) -> Html { - let on_complete = props.on_complete.clone().map(|on_complete| { - html! { - <Button on_click={Callback::from(move |_| on_complete.emit(()))}> - {"continue"} - </Button> - } - }); - html! { - <div class="role-page wolves-intro"> - <h1 class="wolves">{"THESE ARE THE WOLVES"}</h1> - <div class="wolves-list"> - { - props.wolves.iter().map(|w| html!{ - <div class="character wolves faint"> - <p class="role yellow">{w.1.to_string().to_case(Case::Title)}</p> - <Identity ident={Into::<PublicIdentity>::into(&w.0)} /> - </div> - }).collect::<Html>() - } - </div> - {on_complete} - </div> - } -} diff --git a/werewolves/src/components/attributes/align_span.rs b/werewolves/src/components/attributes/align_span.rs deleted file mode 100644 index b43adb8..0000000 --- a/werewolves/src/components/attributes/align_span.rs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (C) 2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use convert_case::{Case, Casing}; -use werewolves_proto::{ - game::{Category, SetupRole}, - role::{self, RoleTitle}, -}; -use yew::prelude::*; - -use crate::components::{AssociatedIcon, Icon, IconSource, IconType, PartialAssociatedIcon}; - -#[derive(Debug, Clone, Copy, PartialEq, Properties)] -pub struct AlignmentSpanProps { - pub alignment: role::Alignment, -} - -#[function_component] -pub fn AlignmentSpan(AlignmentSpanProps { alignment }: &AlignmentSpanProps) -> Html { - let class = match alignment { - role::Alignment::Village => "village-highlight", - role::Alignment::Wolves => "wolves-highlight", - role::Alignment::Damned => "damned-highlight", - }; - html! { - <span class={classes!("attribute-span", class)}> - <Icon source={alignment.icon()} icon_type={IconType::Fit}/> - {alignment.to_string()} - </span> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct CategorySpanProps { - pub category: Category, - #[prop_or_default] - pub icon: Option<IconSource>, - #[prop_or_default] - pub children: Html, -} - -#[function_component] -pub fn CategorySpan( - CategorySpanProps { - category, - icon, - children, - }: &CategorySpanProps, -) -> Html { - let class = category.class(); - let icon = icon.unwrap_or(match category { - Category::Wolves => IconSource::Wolves, - Category::Villager - | Category::Intel - | Category::Defensive - | Category::Offensive - | Category::StartsAsVillager => IconSource::Village, - }); - html! { - <span class={classes!("attribute-span", "faint", class)}> - <div> - <Icon source={icon} icon_type={IconType::Small}/> - </div> - {children.clone()} - </span> - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Properties)] -pub struct RoleTitleSpanProps { - pub role: RoleTitle, - #[prop_or(IconType::List)] - pub icon_type: IconType, -} - -#[function_component] -pub fn RoleTitleSpan(RoleTitleSpanProps { role, icon_type }: &RoleTitleSpanProps) -> Html { - let class = Into::<SetupRole>::into(*role).category().class(); - let icon = role.icon().unwrap_or(role.alignment().icon()); - let text = role.to_string().to_case(Case::Title); - html! { - <span class={classes!("role-title-span", "faint", class)}> - <Icon source={icon} icon_type={*icon_type}/> - <span>{text}</span> - </span> - } -} diff --git a/werewolves/src/components/attributes/comparison.rs b/werewolves/src/components/attributes/comparison.rs deleted file mode 100644 index 0acbd4a..0000000 --- a/werewolves/src/components/attributes/comparison.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::role::AlignmentEq; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[derive(Debug, Clone, Copy, PartialEq, Properties)] -pub struct AlignmentComparisonSpanProps { - pub comparison: AlignmentEq, -} - -#[function_component] -pub fn AlignmentComparisonSpan( - AlignmentComparisonSpanProps { comparison }: &AlignmentComparisonSpanProps, -) -> Html { - match comparison { - AlignmentEq::Same => html! { - <span class="alignment-eq"> - <Icon source={IconSource::Equal} icon_type={IconType::Fit}/> - {"the same"} - </span> - }, - AlignmentEq::Different => html! { - <span class="alignment-eq"> - <Icon source={IconSource::NotEqual} icon_type={IconType::Fit}/> - {"different"} - </span> - }, - } -} diff --git a/werewolves/src/components/attributes/death_span.rs b/werewolves/src/components/attributes/death_span.rs deleted file mode 100644 index b6d34fc..0000000 --- a/werewolves/src/components/attributes/death_span.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use convert_case::{Case, Casing}; -use werewolves_proto::{diedto::DiedToTitle, game::SetupRoleTitle}; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon}; - -#[derive(Debug, Clone, Copy, PartialEq, Properties)] -pub struct DiedToSpanProps { - pub died_to: DiedToTitle, -} - -#[function_component] -pub fn DiedToSpan(DiedToSpanProps { died_to }: &DiedToSpanProps) -> Html { - let icon = died_to.icon().unwrap_or(IconSource::Skull); - html! { - <span class={classes!("attribute-span",)}> - <Icon source={icon} icon_type={IconType::Fit}/> - {died_to.to_string().to_case(Case::Title)} - </span> - } -} diff --git a/werewolves/src/components/attributes/killer.rs b/werewolves/src/components/attributes/killer.rs deleted file mode 100644 index 30df935..0000000 --- a/werewolves/src/components/attributes/killer.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::role::Killer; -use yew::prelude::*; - -use crate::components::{AssociatedIcon, Icon, IconType}; - -#[derive(Debug, Clone, Copy, PartialEq, Properties)] -pub struct KillerSpanProps { - pub killer: Killer, -} - -#[function_component] -pub fn KillerSpan(KillerSpanProps { killer }: &KillerSpanProps) -> Html { - let class = match killer { - Killer::Killer => "killer", - Killer::NotKiller => "inactive", - }; - html! { - <span class={classes!("attribute-span")}> - <Icon - source={killer.icon()} - icon_type={IconType::Fit} - classes={classes!(class)} - /> - {killer.to_string()} - </span> - } -} diff --git a/werewolves/src/components/attributes/powerful.rs b/werewolves/src/components/attributes/powerful.rs deleted file mode 100644 index 5f6f996..0000000 --- a/werewolves/src/components/attributes/powerful.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::role::Powerful; -use yew::prelude::*; - -use crate::components::{AssociatedIcon, Icon, IconType}; - -#[derive(Debug, Clone, Copy, PartialEq, Properties)] -pub struct PowerfulSpanProps { - pub powerful: Powerful, -} - -#[function_component] -pub fn PowerfulSpan(PowerfulSpanProps { powerful }: &PowerfulSpanProps) -> Html { - let class = match powerful { - Powerful::Powerful => "powerful", - Powerful::NotPowerful => "inactive", - }; - html! { - <span class={classes!("attribute-span")}> - <Icon - source={powerful.icon()} - icon_type={IconType::Fit} - classes={classes!(class)} - /> - {powerful.to_string()} - </span> - } -} diff --git a/werewolves/src/components/aura.rs b/werewolves/src/components/aura.rs deleted file mode 100644 index cb3b177..0000000 --- a/werewolves/src/components/aura.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::aura::{Aura, AuraTitle}; -use yew::prelude::*; - -use crate::{ - class::Class, - components::{Icon, IconType, PartialAssociatedIcon}, -}; - -impl Class for AuraTitle { - fn class(&self) -> Option<&'static str> { - Some(match self { - AuraTitle::Damned => "damned", - AuraTitle::Drunk => "drunk", - AuraTitle::Insane => "insane", - AuraTitle::Bloodlet => "wolves", - AuraTitle::RedeemableScapegoat - | AuraTitle::SpitefulScapegoat - | AuraTitle::VindictiveScapegoat - | AuraTitle::InevitableScapegoat - | AuraTitle::Scapegoat => "scapegoat", - }) - } -} - -impl Class for Aura { - fn class(&self) -> Option<&'static str> { - self.title().class() - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct AuraSpanProps { - pub aura: AuraTitle, -} - -#[function_component] -pub fn AuraSpan(AuraSpanProps { aura }: &AuraSpanProps) -> Html { - let class = aura.class(); - let icon = aura.icon().map(|icon| { - html! { - <div> - <Icon source={icon} icon_type={IconType::Small}/> - </div> - } - }); - - html! { - <span class={classes!("attribute-span", "faint", class)}> - {icon} - {aura.to_string()} - </span> - } -} diff --git a/werewolves/src/components/button.rs b/werewolves/src/components/button.rs deleted file mode 100644 index 1f07cc7..0000000 --- a/werewolves/src/components/button.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct ButtonProperties { - pub on_click: Callback<()>, - #[prop_or_default] - pub disabled_reason: Option<String>, - #[prop_or_default] - pub children: Html, - #[prop_or_default] - pub classes: yew::Classes, -} - -#[function_component] -pub fn Button(props: &ButtonProperties) -> Html { - let on_click = props.on_click.clone(); - let on_click = Callback::from(move |_| on_click.emit(())); - html! { - <button - class={classes!("default-button", props.classes.clone())} - disabled={props.disabled_reason.is_some()} - reason={props.disabled_reason.clone()} - onclick={on_click} - > - {props.children.clone()} - </button> - } -} diff --git a/werewolves/src/components/character.rs b/werewolves/src/components/character.rs deleted file mode 100644 index e3fc97f..0000000 --- a/werewolves/src/components/character.rs +++ /dev/null @@ -1,144 +0,0 @@ -use core::ops::Not; - -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use convert_case::{Case, Casing}; -use werewolves_proto::{ - character::Character, - game::{GameTime, SetupRole}, - message::CharacterIdentity, -}; -use yew::prelude::*; - -use crate::{ - class::Class, - components::{Icon, IconSource, IconType, PartialAssociatedIcon}, -}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct CharacterCardProps { - pub char: Character, - #[prop_or_default] - pub dead: bool, - #[prop_or_default] - pub faint: bool, -} - -#[function_component] -pub fn CharacterCard(CharacterCardProps { faint, char, dead }: &CharacterCardProps) -> Html { - let class = Into::<SetupRole>::into(char.role_title()) - .category() - .class(); - let role = char.role_title().to_string().to_case(Case::Title); - let ident = char.identity(); - let pronouns = ident.pronouns.as_ref().map(|p| { - html! { - <span class="pronouns">{"("}{p}{")"}</span> - } - }); - let name = ident.name.clone(); - let source = char.role_title().icon().unwrap_or(if char.is_village() { - IconSource::Village - } else { - IconSource::Wolves - }); - - let dead = dead.then(|| { - html! { - <Icon source={IconSource::Skull} icon_type={IconType::Small}/> - } - }); - let faint = faint.then_some("faint"); - - html! { - <span class={classes!("character-span", class, faint)}> - <span class={classes!("role", class, faint)}> - <div> - {dead} - <Icon source={source} icon_type={IconType::Small}/> - </div> - {role} - </span> - <span class={classes!("number")}><b>{ident.number.get()}</b></span> - <span class="name">{name}</span> - {pronouns} - </span> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct CharacterTargetCardProps { - pub ident: CharacterIdentity, - #[prop_or_default] - pub classes: Classes, -} - -#[function_component] -pub fn CharacterTargetCard( - CharacterTargetCardProps { ident, classes }: &CharacterTargetCardProps, -) -> Html { - let name = ident.name.clone(); - - html! { - <span class={classes!("character-span", classes.clone())}> - <span class={classes!("number")}><b>{ident.number.get()}</b></span> - <span class="name">{name}</span> - </span> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct CharacterHighlightProps { - pub char: Character, - pub time: GameTime, -} - -#[function_component] -pub fn CharacterHighlight( - CharacterHighlightProps { char, time }: &CharacterHighlightProps, -) -> Html { - let class = char.class().map(|c| format!("{c}-highlight")); - let icon = char - .role_title() - .icon() - .map(|source| { - html! { - <Icon source={source} icon_type={IconType::Fit}/> - } - }) - .unwrap_or(html! { - <div class="icon-spacer"/> - }); - let dead = char.died_to().and_then(|died_to| { - let night = died_to.night(); - let day = died_to.day(); - match (time, day, night) { - (GameTime::Day { number }, Some(day), None) => number.get() > day.get(), - (GameTime::Night { number }, None, Some(night)) => *number > night, - (GameTime::Day { number }, None, Some(night)) => number.get() > night, - (GameTime::Night { number }, Some(day), None) => *number >= day.get(), - (_, None, None) | (_, Some(_), Some(_)) => true, - } - .then_some("dead") - }); - let role_text = char.role_title().to_string().to_case(Case::Title); - html! { - <span class={classes!("highlight-span", class)} role={role_text}> - {icon} - <span class={classes!("number")}><b>{char.number().get()}</b></span> - <span class={classes!("name", dead)}>{char.name()}</span> - </span> - } -} diff --git a/werewolves/src/components/chat/deadchat.rs b/werewolves/src/components/chat/deadchat.rs deleted file mode 100644 index 7009809..0000000 --- a/werewolves/src/components/chat/deadchat.rs +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright (C) 2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use chrono::{DateTime, Utc}; -use chrono_humanize::Humanize; -use yew::prelude::*; - -use wasm_bindgen::{JsCast, UnwrapThrowExt}; -use web_sys::{HtmlElement, HtmlInputElement}; -use werewolves_proto::message::{ - PublicIdentity, - dead::{DeadChatContent, DeadChatMessage}, -}; - -use crate::components::{Icon, IconSource, IconType}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct DeadChatProperties { - pub on_send: Callback<String>, - pub messages: Vec<DeadChatMessage>, -} - -#[function_component] -pub fn DeadChat(DeadChatProperties { on_send, messages }: &DeadChatProperties) -> Html { - let messages = messages - .iter() - .map(|m| { - html! { - <ChatMessage message={m.clone()} /> - } - }) - .collect::<Html>(); - let submit = { - let on_send = on_send.clone(); - move |ev: SubmitEvent| { - ev.prevent_default(); - let Some(target) = ev.target_dyn_into::<HtmlElement>() else { - return; - }; - let input = target - .query_selector("#message-input") - .expect_throw("could not find #message-input") - .expect_throw("could not find #message-input") - .dyn_into::<HtmlInputElement>() - .expect_throw("#message-input is not HtmlInputElement"); - let value = input.value().trim().to_string(); - if !value.is_empty() { - on_send.emit(value); - } - input.set_value(""); - } - }; - - let node = use_node_ref(); - - use_effect_with(node.clone(), |node| { - let Some(div) = node.cast::<HtmlElement>() else { - log::warn!("chat-messages node not attached"); - return; - }; - - let is_scrolled_to_bottom = - div.scroll_height() - div.client_height() <= div.scroll_top() + 1; - if !is_scrolled_to_bottom { - div.set_scroll_top(div.scroll_height() - div.client_height()); - } - }); - - html! { - <div class="dead-chat"> - <ol class="chat-messages" ref={node}> - {messages} - </ol> - <form onsubmit={submit}> - <input - type="text" - id="message-input" - placeholder="write to the dead" - autocomplete="off" - /> - <input type="submit" hidden=true/> - </form> - - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct DeadChatIdentProps { - pub ident: PublicIdentity, -} - -#[function_component] -pub fn DeadChatIdent(DeadChatIdentProps { ident }: &DeadChatIdentProps) -> Html { - let pronouns = ident.pronouns.clone(); - html! { - <span class="dead-ident" pronouns={pronouns}> - {ident.name.clone()} - </span> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct TimestampProps { - pub timestamp: DateTime<Utc>, -} - -#[function_component] -pub fn Timestamp(TimestampProps { timestamp }: &TimestampProps) -> Html { - let use_relative = use_state(|| false); - let lock = use_state(|| false); - - let enter = { - let lock = lock.clone(); - let use_relative = use_relative.setter(); - move |_| { - if !*lock { - use_relative.set(true); - } - } - }; - let leave = { - let lock = lock.clone(); - let use_relative = use_relative.setter(); - move |_| { - if !*lock { - use_relative.set(false); - } - } - }; - let bare_timestamp = timestamp - .naive_local() - .time() - .format("%H:%M:%S") - .to_string(); - - let timestamp_str = if *use_relative { - (*timestamp - Utc::now()).humanize() - } else { - bare_timestamp - }; - let lock_set = { - let lock = lock.clone(); - move |_| lock.set(!*lock) - }; - - html! { - <span - class="time" - onpointerenter={enter} - onpointercancel={leave.clone()} - onpointerleave={leave} - onclick={lock_set} - > - {timestamp_str} - </span> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct ChatMessageProps { - pub message: DeadChatMessage, -} - -#[function_component] -pub fn ChatMessage( - ChatMessageProps { - message: - DeadChatMessage { - id: _, - timestamp, - message, - }, - }: &ChatMessageProps, -) -> Html { - match message { - DeadChatContent::HostMessage(message) => { - html! { - <li class="message"> - <Timestamp timestamp={*timestamp} /> - <span class="red"> - // <Icon source={IconSource::Adjudicator} icon_type={IconType::Fit}/> - <strong>{"Host"}</strong> - </span> - <span class="message-content">{message.clone()}</span> - </li> - } - } - DeadChatContent::PlayerMessage { from, message } => { - html! { - <li class="message"> - <Timestamp timestamp={*timestamp} /> - <DeadChatIdent ident={from.clone().into_public()}/> - <span class="message-content">{message.clone()}</span> - </li> - } - } - DeadChatContent::Death { character, cause } => { - html! { - <li class="message"> - <Timestamp timestamp={*timestamp} /> - <Icon source={IconSource::Skull} icon_type={IconType::Fit}/> - <DeadChatIdent ident={character.clone().into_public()}/> - <span class="message-content"> - {"died to "} - {cause.title().to_string()} - </span> - </li> - } - } - DeadChatContent::TimeChange(time) => { - html! { - <li class="message"> - <span class="time-change">{time.to_string()}</span> - </li> - } - } - } -} diff --git a/werewolves/src/components/client/nav.rs b/werewolves/src/components/client/nav.rs deleted file mode 100644 index 0ed3d55..0000000 --- a/werewolves/src/components/client/nav.rs +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::{fmt::Debug, num::NonZeroU8, ops::Not}; - -use werewolves_proto::{ - message::{ClientMessage, PublicIdentity, UpdateSelf}, - player::PlayerId, -}; -use yew::prelude::*; - -use crate::{ - components::{Button, ClickableField, ClickableNumberEdit}, - storage::StorageKey, -}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct ClientNavProps { - pub identity: UseStateHandle<Option<(PlayerId, PublicIdentity)>>, - pub message_callback: Callback<ClientMessage>, -} - -#[function_component] -pub fn ClientNav( - ClientNavProps { - identity, - message_callback, - }: &ClientNavProps, -) -> Html { - const MUST_HAVE_IDENTITY: &str = "client nav must have identity"; - let pronouns = identity - .as_ref() - .and_then(|identity| { - identity.1.pronouns.as_ref().map(|pronouns| { - html! { - <span>{"("}{pronouns.as_str()}{")"}</span> - } - }) - }) - .unwrap_or_else(|| { - html! { - <span class="faint">{"(None)"}</span> - } - }); - - let number_open = use_state(|| false); - let name_open = use_state(|| false); - let pronouns_open = use_state(|| false); - let number = { - let current_value = use_state(String::new); - let message_callback = message_callback.clone(); - - let submit_ident = identity.clone(); - let current_num = identity - .as_ref() - .and_then(|identity| identity.1.number.map(|v| html! {{v.to_string()}})) - .unwrap_or_else(|| { - html! { - <span class="red">{"???"}</span> - } - }); - let open_set = number_open.setter(); - let on_submit = { - let val = current_value.clone(); - Callback::from(move |_| { - let num = match val.trim().parse::<NonZeroU8>().ok() { - Some(num) => num, - None => return, - }; - let Some(submit_ident_ref) = submit_ident.as_ref() else { - return; - }; - message_callback.emit(ClientMessage::UpdateSelf(UpdateSelf::Number(num))); - let new_ident = PublicIdentity { - name: submit_ident_ref.1.name.clone(), - pronouns: submit_ident_ref.1.pronouns.clone(), - number: Some(num), - }; - submit_ident.set(Some((submit_ident_ref.0, new_ident.clone()))); - if let Err(err) = new_ident.save_to_storage() { - log::error!("saving public identity after change: {err}"); - } - open_set.set(false); - }) - }; - let close_others = { - let name_open = name_open.clone(); - let pronouns_open = pronouns_open.clone(); - Callback::from(move |_| { - name_open.set(false); - pronouns_open.set(false); - }) - }; - html! { - <ClickableNumberEdit - value={current_value.clone()} - field_name="number" - on_submit={on_submit} - state={number_open.clone()} - on_open={close_others} - label={String::from("number")} - > - <div class="number">{current_num}</div> - </ClickableNumberEdit> - } - }; - let name = { - let name = use_state(String::new); - let on_submit = { - let ident = identity.clone(); - let message_callback = message_callback.clone(); - Callback::from(move |value: String| -> Option<PublicIdentity> { - let ident = ident.as_ref().expect(MUST_HAVE_IDENTITY); - value.trim().is_empty().not().then(|| { - let name = value.trim().to_string(); - message_callback - .emit(ClientMessage::UpdateSelf(UpdateSelf::Name(name.clone()))); - PublicIdentity { - name, - number: ident.1.number, - pronouns: ident.1.pronouns.clone(), - } - }) - }) - }; - let close_others = { - let number_open = number_open.clone(); - let pronouns_open = pronouns_open.clone(); - Callback::from(move |_| { - number_open.set(false); - pronouns_open.set(false); - }) - }; - let name_str = identity - .as_ref() - .map(|i| html! {{i.1.name.to_string()}}) - .unwrap_or(html! { - <span class="red">{"???"}</span> - }); - html! { - <ClickableTextEdit - value={name.clone()} - submit_ident={identity.clone()} - field_name="name" - on_submit={on_submit} - state={name_open.clone()} - on_open={close_others} - label={String::from("name")} - > - <div class="name">{name_str}</div> - </ClickableTextEdit> - } - }; - let pronouns = { - let pronuns_state = use_state(String::new); - - let on_submit = { - let ident = identity.clone(); - let message_callback = message_callback.clone(); - let pronuns_state = pronuns_state.clone(); - Callback::from(move |value: String| -> Option<PublicIdentity> { - let pronouns = value.trim().is_empty().not().then_some(value); - message_callback.emit(ClientMessage::UpdateSelf(UpdateSelf::Pronouns( - pronouns.clone(), - ))); - pronuns_state.set(String::new()); - ident.as_ref().map(|id| { - let mut public = id.1.clone(); - public.pronouns = pronouns; - ident.set(Some((id.0, public.clone()))); - public - }) - }) - }; - let close_others = { - let number_open = number_open.clone(); - let name_open = name_open.clone(); - Callback::from(move |_| { - number_open.set(false); - name_open.set(false); - }) - }; - html! { - <ClickableTextEdit - value={pronuns_state} - submit_ident={identity.clone()} - field_name="pronouns" - on_submit={on_submit} - state={pronouns_open} - on_open={close_others} - label={String::from("pronouns")} - > - {pronouns} - </ClickableTextEdit> - } - }; - let debug = option_env!("DEBUG").map(|_| { - let cb = message_callback.clone(); - let forgor = move |_| { - PlayerId::delete(); - PublicIdentity::delete(); - cb.emit(ClientMessage::Goodbye); - let _ = gloo::utils::window().location().reload(); - }; - - html! { - <> - <a href="/host"><Button on_click={Callback::noop()}>{"host"}</Button></a> - <Button on_click={forgor}>{"forgor 💀"}</Button> - </> - } - }); - html! { - <nav class="client-nav"> - {number} - {name} - {pronouns} - {debug} - </nav> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -struct ClickableTextEditProps { - #[prop_or_default] - pub children: Html, - pub value: UseStateHandle<String>, - pub submit_ident: UseStateHandle<Option<(PlayerId, PublicIdentity)>>, - pub on_submit: Callback<String, Option<PublicIdentity>>, - pub field_name: &'static str, - pub state: UseStateHandle<bool>, - #[prop_or(100)] - pub max_length: usize, - #[prop_or_default] - pub on_open: Option<Callback<()>>, - #[prop_or_default] - pub label: String, -} - -#[function_component] -fn ClickableTextEdit( - ClickableTextEditProps { - children, - value, - submit_ident, - field_name, - on_submit, - state, - max_length, - on_open, - label, - }: &ClickableTextEditProps, -) -> Html { - let on_input = crate::components::input_element_string_oninput(value.setter(), *max_length); - let submit_ident = submit_ident.clone(); - let message_callback = on_submit.clone(); - let value = value.clone(); - let open_set = state.setter(); - let submit = { - let submit_ident = submit_ident.clone(); - move |_| { - if let Some(new_ident) = message_callback.emit(value.trim().to_string()) - && let Some(ident) = submit_ident.as_ref() - { - submit_ident.set(Some((ident.0, new_ident.clone()))); - if let Err(err) = new_ident.save_to_storage() { - log::error!("saving public identity after change: {err}"); - } - open_set.set(false); - } - } - }; - let label = label.is_empty().not().then_some(html! { - <label>{label}</label> - }); - let options = html! { - <div class="info-update"> - {label} - <input type="text" oninput={on_input} name={*field_name} autofocus=true/> - <Button on_click={submit}>{"ok"}</Button> - </div> - }; - html! { - <ClickableField options={options} state={state.clone()} on_open={on_open.clone()}> - {children.clone()} - </ClickableField> - } -} diff --git a/werewolves/src/components/client/signin.rs b/werewolves/src/components/client/signin.rs deleted file mode 100644 index 9c7c247..0000000 --- a/werewolves/src/components/client/signin.rs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::num::NonZeroU8; - -use web_sys::HtmlInputElement; -use werewolves_proto::message::PublicIdentity; -use yew::prelude::*; - -use crate::components::Button; - -#[derive(Debug, PartialEq, Properties)] -pub struct SigninProps { - pub callback: Callback<PublicIdentity>, - #[prop_or(true)] - pub full_height: bool, -} - -#[function_component] -pub fn Signin(props: &SigninProps) -> Html { - let callback = props.callback.clone(); - let num_value = use_state(String::new); - let name_value = use_state(String::new); - let pronouns_value = use_state(String::new); - let on_input_update = |state: UseStateSetter<String>| { - move |ev: InputEvent| { - if let Some(target) = ev.target_dyn_into::<HtmlInputElement>() { - state.set(target.value()); - } - } - }; - let name_on_input = on_input_update(name_value.setter()); - let pronouns_on_input = on_input_update(pronouns_value.setter()); - let on_click_num_value = num_value.clone(); - - let on_click = Callback::from(move |_| { - let name = name_value.trim().to_string(); - let pronouns = match pronouns_value.trim() { - "" => None, - p => Some(p.to_string()), - }; - let number = on_click_num_value.parse::<NonZeroU8>().ok(); - if name.is_empty() { - return; - } - callback.emit(PublicIdentity { - name, - pronouns, - number, - }); - }); - - let on_change = crate::components::input_element_number_oninput(num_value); - let full_height = props.full_height.then_some("full-height"); - html! { - <div class={classes!("signin", full_height)}> - <div class="signin-box"> - <div class="field"> - <label for="number">{"Seat Number"}</label> - <input - oninput={on_change} - type="text" - name="number" - id="number" - // autocomplete="off" - /> - </div> - <div class="field"> - <label for="name">{"Name"}</label> - <input - oninput={name_on_input} - name="name" - id="name" - type="text" - // autocomplete="name nickname username" - /> - </div> - <div class="field"> - <label for="pronouns">{"Pronouns"}</label> - <input oninput={pronouns_on_input} name="pronouns" id="pronouns" type="text"/> - </div> - <Button on_click={on_click}>{"Submit"}</Button> - </div> - </div> - } -} diff --git a/werewolves/src/components/cover.rs b/werewolves/src/components/cover.rs deleted file mode 100644 index 645f480..0000000 --- a/werewolves/src/components/cover.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::Button; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct CoverOfDarknessProps { - #[prop_or_default] - pub next: Option<Callback<()>>, - #[prop_or_else(|| String::from("night falls"))] - pub message: String, - #[prop_or_else(|| html!("begin"))] - pub children: Html, -} - -#[function_component] -pub fn CoverOfDarkness( - CoverOfDarknessProps { - message, - next, - children, - }: &CoverOfDarknessProps, -) -> Html { - let next = next.as_ref().map(|next| { - html! { - <Button on_click={next}>{children.clone()}</Button> - } - }); - html! { - <div class="cover-of-darkness"> - <p>{message}</p> - {next} - </div> - } -} diff --git a/werewolves/src/components/dialog.rs b/werewolves/src/components/dialog.rs deleted file mode 100644 index 0f0b4f3..0000000 --- a/werewolves/src/components/dialog.rs +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use web_sys::Element; -use yew::prelude::*; - -use crate::components::Button; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct DialogProps { - #[prop_or_default] - pub children: Html, - pub options: Box<[String]>, - #[prop_or_default] - pub cancel_callback: Option<Callback<()>>, - pub callback: Callback<String>, -} - -#[function_component] -pub fn Dialog( - DialogProps { - children, - options, - cancel_callback, - callback, - }: &DialogProps, -) -> Html { - let options = options - .iter() - .map(|opt| { - let callback = callback.clone(); - let option = opt.clone(); - let cb = Callback::from(move |_| { - callback.emit(option.clone()); - }); - html! { - <Button on_click={cb}>{opt.clone()}</Button> - } - }) - .collect::<Html>(); - let backdrop_click = cancel_callback.clone().map(|cancel_callback| { - Callback::from(move |ev: MouseEvent| { - if let Some(div) = ev.target_dyn_into::<Element>() - && div.class_name() == "dialog" - { - ev.stop_propagation(); - cancel_callback.emit(()); - } - }) - }); - - html! { - <div class="click-backdrop" onclick={backdrop_click}> - <div class="dialog"> - <div class="dialog-box"> - <div class="message"> - {children.clone()} - </div> - <div class="options"> - {options} - </div> - </div> - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct WithConfirmationProps { - pub state: UseStateHandle<bool>, - #[prop_or_default] - pub children: Html, - pub confirm_callback: Callback<()>, - pub message: Html, -} - -#[function_component] -pub fn WithConfirmation( - WithConfirmationProps { - state, - children, - confirm_callback, - message, - }: &WithConfirmationProps, -) -> Html { - let about_dialog_state = state.clone(); - let confirmation_dialog = about_dialog_state.then(|| { - let cancel_signout = { - let dialog = about_dialog_state.clone(); - Callback::from(move |_| { - dialog.set(false); - }) - }; - let confirm_callback = confirm_callback.clone(); - let callback = { - let dialog = about_dialog_state.clone(); - Callback::from(move |opt: String| { - if opt == "ok" { - confirm_callback.emit(()); - } else { - dialog.set(false); - } - }) - }; - let options: Box<[String]> = Box::new([String::from("ok"), String::from("take me back")]); - html! { - <Dialog - options={options} - cancel_callback={Some(cancel_signout)} - callback={callback} - > - {message.clone()} - </Dialog> - } - }); - let confirmation_click = { - let dialog_set = about_dialog_state.setter(); - move |_| { - dialog_set.set(true); - } - }; - html! { - <> - <span class="has-confirm" onclick={confirmation_click}>{children.clone()}</span> - {confirmation_dialog} - </> - } -} diff --git a/werewolves/src/components/field.rs b/werewolves/src/components/field.rs deleted file mode 100644 index 1d6ab1e..0000000 --- a/werewolves/src/components/field.rs +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::ops::Not; -use yew::prelude::*; - -use crate::components::Button; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct ClickableFieldProps { - #[prop_or_default] - pub children: Html, - pub options: Html, - #[prop_or_default] - pub class: yew::Classes, - #[prop_or_default] - pub button_class: yew::Classes, - #[prop_or_default] - pub with_backdrop_exit: bool, - pub state: UseStateHandle<bool>, - #[prop_or_default] - pub on_open: Option<Callback<()>>, -} - -#[function_component] -pub fn ClickableField( - ClickableFieldProps { - children, - options, - class, - button_class, - with_backdrop_exit, - state, - on_open, - }: &ClickableFieldProps, -) -> Html { - let open = state.clone(); - let open_close = { - let open = open.clone(); - let on_open = on_open.clone(); - Callback::from(move |_| { - if !*open && let Some(on_open) = on_open.as_ref() { - on_open.emit(()); - } - open.set(!(*open)); - }) - }; - let submenu_open_close = open_close.clone(); - let submenu = open.clone().then(|| { - let backdrop = with_backdrop_exit.then(|| { - html! { - <div onclick={move |_| submenu_open_close.emit(())} class="click-backdrop"/> - } - }); - - html! { - <> - <nav class="submenu shown"> - {options.clone()} - </nav> - {backdrop} - </> - } - }); - html! { - <div class={class.clone()}> - <Button on_click={open_close} classes={button_class}> - {children.clone()} - </Button> - {submenu} - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct ClickableNumberEditProps { - #[prop_or_default] - pub children: Html, - pub value: UseStateHandle<String>, - pub on_submit: Callback<()>, - pub field_name: &'static str, - pub state: UseStateHandle<bool>, - #[prop_or_default] - pub on_open: Option<Callback<()>>, - #[prop_or_default] - pub label: String, -} - -#[function_component] -pub fn ClickableNumberEdit( - ClickableNumberEditProps { - children, - value, - field_name, - on_submit, - state, - on_open, - label, - }: &ClickableNumberEditProps, -) -> Html { - // let on_input = crate::components::input_element_string_oninput(value.setter(), 20); - let on_submit = on_submit.clone(); - // let label = label.is_empty().not().then_some(html! { - // <label>{label}</label> - // }); - - let options = html! { - // <div class="info-update"> - // {label} - // <input type="text" oninput={on_input} name={*field_name} autofocus=true/> - // <Button on_click={on_submit.clone()}>{"ok"}</Button> - // </div> - <NumberEdit - value={value.clone()} - on_submit={on_submit.clone()} - field_name={field_name} - label={label.clone()} - > - </NumberEdit> - }; - html! { - <ClickableField options={options} state={state.clone()} on_open={on_open.clone()}> - {children.clone()} - </ClickableField> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct NumberEditProps { - pub value: UseStateHandle<String>, - pub on_submit: Callback<()>, - pub field_name: &'static str, - #[prop_or_default] - pub label: String, -} - -#[function_component] -pub fn NumberEdit( - NumberEditProps { - value, - on_submit, - field_name, - label, - }: &NumberEditProps, -) -> Html { - let on_input = crate::components::input_element_string_oninput(value.setter(), 20); - let on_submit = on_submit.clone(); - let label = label.is_empty().not().then_some(html! { - <label>{label}</label> - }); - - html! { - <div class="info-update"> - {label} - <input type="text" oninput={on_input} name={*field_name} autofocus=true/> - <Button on_click={on_submit.clone()}>{"ok"}</Button> - </div> - } -} diff --git a/werewolves/src/components/footer.rs b/werewolves/src/components/footer.rs deleted file mode 100644 index caee7e0..0000000 --- a/werewolves/src/components/footer.rs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Dialog, WithConfirmation}; - -const SOURCE_CODE_URL: &str = "https://sectorinf.com/emilis/werewolves"; - -#[function_component] -pub fn Footer() -> Html { - let about_dialog_state = use_state(|| false); - let about_dialog = about_dialog_state.then(|| { - let cancel_signout = { - let dialog = about_dialog_state.clone(); - Callback::from(move |_| { - dialog.set(false); - }) - }; - let callback = Callback::from(move |_| ()); - let options: Box<[String]> = Box::new([]); - html! { - <Dialog - options={options} - cancel_callback={Some(cancel_signout)} - callback={callback} - > - <About /> - </Dialog> - } - }); - let about_click = { - let dialog_set = about_dialog_state.setter(); - move |_| { - dialog_set.set(true); - } - }; - - html! { - <footer class="footer"> - <button class="default-button solid" onclick={about_click}>{"about"}</button> - {about_dialog} - </footer> - } -} - -#[function_component] -pub fn About() -> Html { - let source_confirm_state = use_state(|| false); - let git_ref_confirm_state = use_state(|| false); - - let source_code_confirm = { - let confirm_callback = { - move |_| { - let _ = gloo::utils::window().location().set_href(SOURCE_CODE_URL); - } - }; - let confirm_message = html! { - <> - <h1>{"this will take you away from the game"}</h1> - <h5>{"("}<span class="redir-url">{SOURCE_CODE_URL}</span>{")"}</h5> - <h3>{"make sure this isn't an oopsie"}</h3> - </> - }; - - html! { - <WithConfirmation - state={source_confirm_state} - confirm_callback={confirm_callback} - message={confirm_message} - > - <button class="default-button">{"source code"}</button> - </WithConfirmation> - } - }; - let dirty = crate::BUILD_DIRTY.then_some(html! { - <> - {" "} - <span class="dirty">{"(dirty)"}</span> - </> - }); - let git_ref_confirm = { - let git_ref_url = format!("{SOURCE_CODE_URL}/commit/{}", crate::BUILD_ID_LONG); - let confirm_callback = { - let git_ref_url = git_ref_url.clone(); - move |_| { - let _ = gloo::utils::window().location().set_href(&git_ref_url); - } - }; - let confirm_message = html! { - <> - <h1>{"this will take you away from the game"}</h1> - <h4>{"("}<span class="redir-url">{git_ref_url}</span>{")"}</h4> - <h3>{"make sure this isn't an oopsie"}</h3> - </> - }; - - html! { - <WithConfirmation - state={git_ref_confirm_state} - confirm_callback={confirm_callback} - message={confirm_message} - > - <a> - {crate::BUILD_ID} - {dirty} - </a> - </WithConfirmation> - } - }; - - html! { - <div class="about"> - <h1>{"werewolves"}</h1> - <div class="build-info"> - <p class="build-id"> - <label>{"build: "}</label> - {git_ref_confirm} - </p> - <p class="build-time"> - <label>{"built at: "}</label> - <span class="time">{crate::BUILD_TIME}</span> - </p> - </div> - <nav class="links"> - {source_code_confirm} - </nav> - </div> - } -} diff --git a/werewolves/src/components/host/chars.rs b/werewolves/src/components/host/chars.rs deleted file mode 100644 index f6a9f30..0000000 --- a/werewolves/src/components/host/chars.rs +++ /dev/null @@ -1,36 +0,0 @@ -use werewolves_proto::message::CharacterState; -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::host::DaytimePlayerList; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct CharacterStatesProps { - pub states: Box<[CharacterState]>, -} - -#[function_component] -pub fn CharacterStatesReadOnly(CharacterStatesProps { states }: &CharacterStatesProps) -> Html { - let marked: Box<[_]> = Box::new([]); - html! { - <DaytimePlayerList - marked={marked} - characters={states.clone()} - on_mark={|_|()} - big_screen=false - /> - } -} diff --git a/werewolves/src/components/host/daytime.rs b/werewolves/src/components/host/daytime.rs deleted file mode 100644 index 4e3d2c4..0000000 --- a/werewolves/src/components/host/daytime.rs +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::{num::NonZeroU8, ops::Not}; - -use convert_case::{Case, Casing}; -use werewolves_proto::{ - character::CharacterId, - game::GameTime, - message::{CharacterState, PublicIdentity}, -}; -use yew::prelude::*; - -use crate::components::{AssociatedIcon, Button, Icon, IconType, Identity, PartialAssociatedIcon}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct DaytimePlayerListProps { - #[prop_or_default] - pub day: Option<NonZeroU8>, - pub characters: Box<[CharacterState]>, - pub marked: Box<[CharacterId]>, - #[prop_or_default] - pub on_execute: Option<Callback<()>>, - pub on_mark: Callback<CharacterId>, - pub big_screen: bool, -} - -#[function_component] -pub fn DaytimePlayerList( - DaytimePlayerListProps { - day, - characters, - on_execute, - on_mark, - marked, - big_screen, - }: &DaytimePlayerListProps, -) -> Html { - let on_select = big_screen.not().then(|| on_mark.clone()); - let mut characters = characters.clone(); - let last_nights_kills = { - let kills = characters - .iter() - .filter_map(|c| { - c.died_to - .as_ref() - .and_then(|died_to| match died_to.date_time() { - GameTime::Day { .. } => None, - GameTime::Night { number } => { - if let Some(day) = day.as_ref() - && number == day.get() - 1 - { - Some(c) - } else { - None - } - } - }) - }) - .map(|killed| { - let ident = killed.identity.clone().into_public(); - html! { - <span> - <Identity ident={ident} /> - </span> - } - }) - .collect::<Box<[_]>>(); - kills.is_empty().not().then_some(html! { - <div class="info-tidbit"> - <label>{"died last night"}</label> - <div class="last-nights-kills"> - {kills.into_iter().collect::<Html>()} - </div> - </div> - }) - }; - characters.sort_by(|l, r| l.identity.number.cmp(&r.identity.number)); - let chars = characters - .iter() - .map(|c| { - let mark_state = match c.died_to.as_ref() { - None => marked - .contains(&c.identity.character_id) - .then_some(MarkState::Marked), - Some(died_to) => match died_to.date_time() { - GameTime::Day { .. } => Some(MarkState::Dead), - GameTime::Night { number } => { - if let Some(day) = day.as_ref() - && number == day.get() - 1 - { - Some(MarkState::DiedLastNight) - } else { - Some(MarkState::Dead) - } - } - }, - }; - html! { - <DaytimePlayer - character={c.clone()} - mark_state={mark_state} - on_select={on_select.clone()} - /> - } - }) - .collect::<Html>(); - let (button_text, confirmation_text) = if marked.is_empty() { - ( - "end day".to_string(), - "really end the day with no executions?".to_string(), - ) - } else if marked.len() == 1 { - ( - "execute 1 player".to_string(), - characters - .iter() - .find(|c| c.identity.character_id == marked[0]) - .map(|c| c.identity.clone().into_public()) - .map(|id| format!("really execute {id}?")) - .unwrap_or("really execute 1 player?".to_string()), - ) - } else { - ( - format!("execute {} players", marked.len()), - format!("really execute {} players?", marked.len()), - ) - }; - let parity = { - let wolves = characters - .iter() - .filter(|c| c.died_to.is_none() && c.role.wolf()) - .count(); - let total = characters.iter().filter(|c| c.died_to.is_none()).count(); - let pct_parity = (((wolves as f64) * 100.0) / (total as f64)).round(); - html! { - <div class="info-tidbit"> - <label>{"parity"}</label> - <span class="parity"> - <span class="red">{wolves}</span> - {"/"} - <span class="total">{total}</span> - </span> - <span class="parity-pct"> - {"("} - {pct_parity} - {"%)"} - </span> - </div> - } - }; - let button = big_screen - .not() - .then_some(()) - .and_then(|_| on_execute.clone()) - .map(|on_execute| { - let on_execute = Callback::from(move |_| { - on_execute.emit(()); - crate::components::modal::close_modal_by_id("execute"); - }); - html! { - <crate::components::modal::Dialog - id="execute" - button={html!{{button_text.clone()}}} - close_button=false - > - <h3>{confirmation_text}</h3> - <Button on_click={on_execute}> - {button_text} - </Button> - </crate::components::modal::Dialog> - } - }); - let day = day.as_ref().map(|day| { - html! { - <div class="info-tidbit"> - <label>{"day"}</label> - <span class="current-day">{day.get()}</span> - </div> - } - }); - html! { - <div class="character-picker"> - <div class="top-of-day-info"> - {day} - {parity} - {last_nights_kills} - </div> - <div class="player-list"> - {chars} - </div> - {button} - </div> - } -} -#[derive(Debug, Clone, PartialEq)] -pub enum MarkState { - Marked, - DiedLastNight, - Dead, -} - -impl MarkState { - pub const fn class(&self) -> &'static str { - match self { - MarkState::Marked => "marked", - MarkState::DiedLastNight => "recent-death", - MarkState::Dead => "dead", - } - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct DaytimePlayerProps { - pub character: CharacterState, - #[prop_or_default] - pub mark_state: Option<MarkState>, - pub on_select: Option<Callback<CharacterId>>, -} - -#[function_component] -pub fn DaytimePlayer( - DaytimePlayerProps { - on_select, - mark_state, - character: - CharacterState { - player_id: _, - role, - died_to, - identity, - }, - }: &DaytimePlayerProps, -) -> Html { - let class = mark_state.as_ref().map(|s| s.class()); - let character_id = identity.character_id; - let on_click: Callback<_> = died_to - .is_none() - .then_some(()) - .and( - on_select - .clone() - .map(|on_select| Callback::from(move |_| on_select.emit(character_id))), - ) - .unwrap_or_default(); - let identity: PublicIdentity = identity.into(); - let icon = role.icon().unwrap_or_else(|| role.alignment().icon()); - let text = role.to_string().to_case(Case::Title); - let align_class = role.wolf().then_some("red"); - html! { - <Button on_click={on_click} classes={classes!(class, "character")}> - <div class="day-char"> - <span class={classes!("headline")}> - <Icon source={icon} icon_type={IconType::Small}/> - <span class={classes!(align_class)}>{text}</span> - </span> - <Identity ident={identity}/> - </div> - </Button> - } -} diff --git a/werewolves/src/components/host/setup.rs b/werewolves/src/components/host/setup.rs deleted file mode 100644 index 27786d4..0000000 --- a/werewolves/src/components/host/setup.rs +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::ops::Not; -use std::collections::HashMap; - -use convert_case::{Case, Casing}; -use werewolves_proto::{ - aura::AuraTitle, - game::{Category, GameSettings, SetupRole, SetupRoleTitle}, -}; -use yew::prelude::*; - -use crate::components::{AssociatedIcon, Icon, IconSource, IconType}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct SetupProps { - pub settings: GameSettings, -} - -#[function_component] -pub fn Setup(SetupProps { settings }: &SetupProps) -> Html { - let mut by_category: HashMap<Category, Vec<SetupRole>> = - Category::ALL.into_iter().map(|c| (c, Vec::new())).collect(); - for slot in settings.slots() { - by_category - .get_mut(&slot.role.category()) - .unwrap() - .push(slot.role.clone()); - } - - let mut categories = by_category.into_iter().collect::<Box<[_]>>(); - categories.sort_by_key(|(c, _)| match c { - Category::Wolves => 1u8, - Category::Intel => 2, - Category::Villager => 4, - Category::Defensive => 3, - Category::Offensive => 5, - Category::StartsAsVillager => 6, - }); - - let categories = categories - .into_iter() - .map(|(cat, mut members)| { - let hide = match cat { - Category::Wolves => CategoryMode::ShowExactRoleCount, - Category::Villager => CategoryMode::ShowExactRoleCount, - Category::Intel - | Category::Defensive - | Category::Offensive - | Category::StartsAsVillager => CategoryMode::HideAllInfo, - }; - let scapegoat_auras = settings - .slots() - .iter() - .filter(|s| { - !matches!(s.role, SetupRole::Scapegoat { .. }) - && s.auras.iter().any(|a| { - matches!( - a, - AuraTitle::Scapegoat - | AuraTitle::SpitefulScapegoat - | AuraTitle::InevitableScapegoat - | AuraTitle::RedeemableScapegoat - | AuraTitle::VindictiveScapegoat - ) - }) - }) - .count(); - html! { - <SetupCategory - category={cat} - roles={members.into_boxed_slice()} - mode={hide} - scapegoat_auras={scapegoat_auras} - /> - } - }) - .collect::<Html>(); - - let power_roles_count = settings - .slots() - .iter() - .filter(|r| !matches!(r.role.category(), Category::Villager | Category::Wolves)) - .count(); - - html! { - <div class="setup-screen"> - <div class="setup"> - {categories} - </div> - <div class="category big village final"> - <span class="count">{power_roles_count}</span> - <span class="title">{"Power roles from..."}</span> - </div> - </div> - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Default)] -#[allow(unused)] -pub enum CategoryMode { - #[default] - HideAllInfo, - ShowTotalCount, - ShowExactRoleCount, -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct SetupCategoryProps { - pub category: Category, - pub roles: Box<[SetupRole]>, - #[prop_or_default] - pub mode: CategoryMode, - #[prop_or_default] - pub scapegoat_auras: usize, -} - -#[function_component] -pub fn SetupCategory( - SetupCategoryProps { - category, - roles, - mode, - scapegoat_auras, - }: &SetupCategoryProps, -) -> Html { - let roles_count = match mode { - CategoryMode::HideAllInfo => None, - CategoryMode::ShowTotalCount | CategoryMode::ShowExactRoleCount => Some(html! { - <div class="count">{roles.len().to_string()}</div> - }), - }; - let mut roles_in_category = SetupRoleTitle::ALL - .into_iter() - .filter(|r| r.category() == *category) - .collect::<Box<[_]>>(); - roles_in_category.sort_by_key(|l| l.into_role().wakes_night_zero()); - - let all_roles = roles_in_category - .into_iter() - .map(|r| (r, roles.iter().filter(|sr| sr.title() == r).count())) - .filter(|(_, count)| !(matches!(category, Category::Wolves) && *count == 0)) - .map(|(r, count)| { - let as_role = r.into_role(); - let wakes = as_role.wakes_night_zero().then_some("wakes"); - let count = if matches!(r, SetupRoleTitle::Scapegoat) { - (matches!(mode, CategoryMode::ShowExactRoleCount) && count + *scapegoat_auras > 0) - .then(|| { - let auras = if *scapegoat_auras != 0 { - html! { - <span class="scapegoats">{"?"}</span> - } - } else { - html! {} - }; - html! { - <span class="count">{count + *scapegoat_auras}{auras}</span> - } - }) - } else { - (matches!(mode, CategoryMode::ShowExactRoleCount) && count > 0).then(|| { - html! { - <span class="count">{count}</span> - } - }) - }; - // let count = - // (matches!(mode, CategoryMode::ShowExactRoleCount) && count > 0).then(|| { - // html! { - // <span class="count">{count}</span> - // } - // }); - let killer_inactive = as_role.killer().killer().not().then_some("inactive"); - let powerful_inactive = as_role.powerful().powerful().not().then_some("inactive"); - let alignment = as_role.alignment().icon(); - - html! { - <div class={classes!("slot")}> - {count} - <span class={classes!("role", wakes, r.category().class())}> - {r.to_string().to_case(Case::Title)} - </span> - <div class="attributes"> - <div class="alignment"> - <Icon source={alignment} icon_type={IconType::Small}/> - </div> - <div class={classes!("killer", killer_inactive)}> - <Icon source={IconSource::Killer} icon_type={IconType::Small}/> - </div> - <div class={classes!("poweful", powerful_inactive)}> - <Icon source={IconSource::Powerful} icon_type={IconType::Small}/> - </div> - </div> - </div> - } - }) - .collect::<Html>(); - html! { - <div class="category big"> - {roles_count} - <div class={classes!("title", category.class())}> - {category.to_string().to_case(Case::Title)} - </div> - <div class={classes!("category-list")}> - {all_roles} - </div> - </div> - } -} diff --git a/werewolves/src/components/host/vote.rs b/werewolves/src/components/host/vote.rs deleted file mode 100644 index 3df06af..0000000 --- a/werewolves/src/components/host/vote.rs +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (C) 2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -use werewolves_proto::message::CharacterState; -use yew::prelude::*; - -use crate::components::{Button, IdentitySpan}; - -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum VotingActionMode { - Add, - Sub, -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct VotingModeProps { - pub characters: Box<[CharacterState]>, -} - -#[function_component] -pub fn VotingMode(VotingModeProps { characters }: &VotingModeProps) -> Html { - let votes = use_state(|| { - characters - .iter() - .filter(|c| c.died_to.is_none()) - .map(|c| (c.clone(), 0u32)) - .collect::<Box<[_]>>() - }); - let voting_mode = use_state(|| VotingActionMode::Add); - let buttons = votes - .iter() - .filter_map(|(c, v)| { - c.died_to.is_none().then_some({ - let on_select = { - let cid = c.identity.character_id; - let votes = votes.clone(); - let voting_mode = voting_mode.clone(); - move |_| { - let mut v = (*votes).clone(); - if let Some((_, votes)) = - v.iter_mut().find(|(c, _)| c.identity.character_id == cid) - { - match *voting_mode { - VotingActionMode::Add => *votes = votes.saturating_add(1), - VotingActionMode::Sub => *votes = votes.saturating_sub(1), - } - } - votes.set(v); - } - }; - html! { - <VotingPlayer character={c.clone()} votes={*v} on_select={on_select}/> - } - }) - }) - .collect::<Html>(); - let set_add = { - let mode = voting_mode.clone(); - move |_| mode.set(VotingActionMode::Add) - }; - let set_sub = { - let mode = voting_mode.clone(); - move |_| mode.set(VotingActionMode::Sub) - }; - const MODE_CLASS: &str = "mode-set"; - let (add, sub) = match *voting_mode { - VotingActionMode::Add => (Some(MODE_CLASS), None), - VotingActionMode::Sub => (None, Some(MODE_CLASS)), - }; - let mut sorted = votes.iter().filter(|(_, v)| *v > 0).collect::<Box<_>>(); - sorted.sort_by_key(|(_, v)| *v); - sorted.reverse(); - let summary = sorted - .into_iter() - .map(|(c, v)| { - html! { - <li> - <span class="id"><IdentitySpan ident={c.identity.clone().into_public()}/>{":"}</span> - <span class="votes"><span class="red">{*v}</span>{" votes"}</span> - </li> - } - }) - .collect::<Html>(); - let on_clear = { - let votes = votes.clone(); - move |_| { - let mut v = (*votes).clone(); - for (_, v) in v.iter_mut() { - *v = 0; - } - votes.set(v); - } - }; - html! { - <div class="character-picker"> - <div class="top-of-day-info"> - <div class="voting-mode"> - <Button classes={classes!("clear")} on_click={on_clear}>{"clear votes"}</Button> - <span class="red">{"voting mode"}</span> - <div class="mode-buttons"> - <Button classes={classes!(add)} on_click={set_add}>{"add"}</Button> - <Button classes={classes!(sub)} on_click={set_sub}>{"sub"}</Button> - </div> - </div> - </div> - <div class="vote-buttons"> - {buttons} - </div> - <ol class="vote-summary"> - {summary} - </ol> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct VotingPlayerProps { - pub character: CharacterState, - #[prop_or_default] - pub votes: u32, - pub on_select: Callback<()>, -} - -#[function_component] -pub fn VotingPlayer( - VotingPlayerProps { - on_select, - votes, - character: CharacterState { identity, .. }, - }: &VotingPlayerProps, -) -> Html { - let on_click = { - let on_select = on_select.clone(); - move |_| on_select.emit(()) - }; - let identity = identity.clone().into_public(); - let number = identity.number.as_ref().map(|n| { - html! { - <span class="number">{n.get()}</span> - } - }); - html! { - <Button on_click={on_click} classes={classes!("vote-char")}> - <span class="voter-id"> - {number} - <span class="name">{identity.name.clone()}</span> - </span> - <span class="votes"> - <span class="red">{*votes}</span> - {" votes"} - </span> - </Button> - } -} diff --git a/werewolves/src/components/icon.rs b/werewolves/src/components/icon.rs deleted file mode 100644 index c5087e2..0000000 --- a/werewolves/src/components/icon.rs +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::{ - aura::AuraTitle, - diedto::DiedToTitle, - role::{Alignment, Killer, Powerful, RoleTitle}, -}; -use yew::prelude::*; - -macro_rules! decl_icon { - ($($name:ident: $path:literal,)*) => { - #[allow(unused)] - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub enum IconSource { - $( - $name, - )* - } - - impl IconSource { - pub const fn source(&self) -> &'static str { - match self { - $( - Self::$name => $path, - )* - } - } - } - }; -} - -decl_icon!( - Village: "/img/village.svg", - Wolves: "/img/wolf.svg", - Killer: "/img/killer.svg", - Powerful: "/img/powerful.svg", - ListItem: "/img/li.svg", - Skull: "/img/skull.svg", - Heart: "/img/heart.svg", - Shield: "/img/shield.svg", - ShieldAndSword: "/img/shield-and-sword.svg", - Seer: "/img/seer.svg", - Hunter: "/img/hunter.svg", - MapleWolf: "/img/maple-wolf.svg", - Gravedigger: "/img/gravedigger.svg", - PowerSeer: "/img/power-seer.svg", - Scapegoat: "/img/scapegoat.svg", - Diseased: "/img/diseased.svg", - Mortician: "/img/mortician.svg", - Pyremaster: "/img/pyremaster.svg", - Sword: "/img/sword.svg", - Roleblock: "/img/roleblock.svg", - Beholder: "/img/beholder.svg", - LoneWolf: "/img/lone-wolf.svg", - Vindicator: "/img/vindicator.svg", - Apprentice: "/img/apprentice.svg", - Elder: "/img/elder.svg", - Shapeshifter: "/img/shapeshifter.svg", - Arcanist: "/img/arcanist.svg", - Adjudicator: "/img/adjudicator.svg", - Weightlifter: "/img/weightlifter.svg", - Insomniac: "/img/insomniac.svg", - BlackKnight: "/img/black-knight.svg", - Mason: "/img/mason.svg", - NotEqual: "/img/not-equal.svg", - Equal: "/img/equal.svg", - RedX: "/img/red-x.svg", - Damned: "/img/damned.svg", - Bloodlet: "/img/bloodlet.svg", - Drunk: "/img/drunk.svg", - Insane: "/img/insane.svg", -); - -impl IconSource { - pub const fn class(&self) -> Option<&'static str> { - match self { - IconSource::Killer => Some("killer"), - IconSource::Powerful => Some("powerful"), - _ => None, - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Default)] -pub enum IconType { - List, - Small, - Fit, - Icon15Pct, - Informational, - #[default] - RoleCheck, -} - -impl IconType { - pub const fn class(&self) -> &'static str { - match self { - IconType::Icon15Pct => "icon-15pct", - IconType::Fit => "icon-fit", - IconType::List => "icon-in-list", - IconType::Small => "icon", - IconType::Informational => "icon-info", - IconType::RoleCheck => "check-icon", - } - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct IconProps { - pub source: IconSource, - #[prop_or_default] - pub inactive: bool, - #[prop_or_default] - pub icon_type: IconType, - #[prop_or_default] - pub classes: Classes, -} -#[function_component] -pub fn Icon( - IconProps { - source, - inactive, - icon_type, - classes, - }: &IconProps, -) -> Html { - html! { - <img - src={source.source()} - class={classes!(source.class(), icon_type.class(), inactive.then_some("inactive"), classes.clone())} - /> - } -} - -pub trait PartialAssociatedIcon { - fn icon(&self) -> Option<IconSource>; -} - -pub trait AssociatedIcon { - fn icon(&self) -> IconSource; -} - -impl AssociatedIcon for Alignment { - fn icon(&self) -> IconSource { - match self { - Alignment::Village => IconSource::Village, - Alignment::Wolves => IconSource::Wolves, - Alignment::Damned => IconSource::Damned, - } - } -} - -impl AssociatedIcon for Killer { - fn icon(&self) -> IconSource { - IconSource::Killer - } -} - -impl AssociatedIcon for Powerful { - fn icon(&self) -> IconSource { - IconSource::Powerful - } -} - -impl PartialAssociatedIcon for RoleTitle { - fn icon(&self) -> Option<IconSource> { - Some(match self { - RoleTitle::AlphaWolf | RoleTitle::DireWolf => return None, - - RoleTitle::Bloodletter => IconSource::Bloodlet, - RoleTitle::MasonLeader => IconSource::Mason, - RoleTitle::BlackKnight => IconSource::BlackKnight, - RoleTitle::Insomniac => IconSource::Insomniac, - RoleTitle::Weightlifter => IconSource::Weightlifter, - RoleTitle::Adjudicator => IconSource::Adjudicator, - RoleTitle::Arcanist => IconSource::Arcanist, - RoleTitle::Shapeshifter => IconSource::Shapeshifter, - RoleTitle::Elder => IconSource::Elder, - RoleTitle::Apprentice => IconSource::Apprentice, - RoleTitle::LoneWolf => IconSource::LoneWolf, - RoleTitle::Villager => IconSource::Village, - RoleTitle::Beholder => IconSource::Beholder, - RoleTitle::Werewolf => IconSource::Wolves, - RoleTitle::Militia => IconSource::Sword, - RoleTitle::PyreMaster => IconSource::Pyremaster, - RoleTitle::Mortician => IconSource::Mortician, - RoleTitle::Diseased => IconSource::Diseased, - RoleTitle::Scapegoat => IconSource::Scapegoat, - RoleTitle::PowerSeer => IconSource::PowerSeer, - RoleTitle::Gravedigger => IconSource::Gravedigger, - RoleTitle::MapleWolf => IconSource::MapleWolf, - RoleTitle::Hunter => IconSource::Hunter, - RoleTitle::Empath => IconSource::Heart, - RoleTitle::Seer => IconSource::Seer, - RoleTitle::Guardian => IconSource::ShieldAndSword, - RoleTitle::Protector => IconSource::Shield, - RoleTitle::Vindicator => IconSource::Vindicator, - }) - } -} - -impl PartialAssociatedIcon for DiedToTitle { - fn icon(&self) -> Option<IconSource> { - match self { - DiedToTitle::Execution => Some(IconSource::Skull), - DiedToTitle::MapleWolf | DiedToTitle::MapleWolfStarved => Some(IconSource::MapleWolf), - DiedToTitle::Militia => Some(IconSource::Sword), - DiedToTitle::Wolfpack => None, - DiedToTitle::AlphaWolf => None, - DiedToTitle::Shapeshift => None, - DiedToTitle::Hunter => Some(IconSource::Hunter), - DiedToTitle::GuardianProtecting => Some(IconSource::ShieldAndSword), - DiedToTitle::PyreMaster => Some(IconSource::Pyremaster), - DiedToTitle::PyreMasterLynchMob => None, - DiedToTitle::MasonLeaderRecruitFail => None, - DiedToTitle::LoneWolf => None, - } - } -} - -impl PartialAssociatedIcon for AuraTitle { - fn icon(&self) -> Option<IconSource> { - match self { - AuraTitle::Damned => Some(IconSource::Damned), - AuraTitle::Drunk => Some(IconSource::Drunk), - AuraTitle::Insane => Some(IconSource::Insane), - AuraTitle::Bloodlet => Some(IconSource::Bloodlet), - AuraTitle::Scapegoat - | AuraTitle::RedeemableScapegoat - | AuraTitle::VindictiveScapegoat - | AuraTitle::SpitefulScapegoat - | AuraTitle::InevitableScapegoat => Some(IconSource::Scapegoat), - } - } -} diff --git a/werewolves/src/components/identity.rs b/werewolves/src/components/identity.rs deleted file mode 100644 index 362996b..0000000 --- a/werewolves/src/components/identity.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::message::PublicIdentity; -use yew::prelude::*; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct IdentityProps { - pub ident: PublicIdentity, - #[prop_or_default] - pub class: Classes, -} - -#[function_component] -pub fn Identity(props: &IdentityProps) -> Html { - let IdentityProps { - ident: - PublicIdentity { - name, - pronouns, - number, - }, - class, - } = props; - let pronouns = pronouns.as_ref().map(|p| { - html! { - <p class="pronouns">{"("}{p}{")"}</p> - } - }); - let not_set = number.is_none().then_some("not-set"); - let number = number - .map(|n| n.to_string()) - .unwrap_or_else(|| String::from("???")); - html! { - <div class={classes!("identity", class.clone())}> - <p class={classes!("number", not_set)}><b>{number}</b></p> - <p>{name}</p> - {pronouns} - </div> - } -} - -#[function_component] -pub fn IdentitySpan( - IdentityProps { - ident: - PublicIdentity { - name, - pronouns, - number, - }, - class, - }: &IdentityProps, -) -> Html { - let pronouns = pronouns.as_ref().map(|p| { - html! { - <span class="pronouns">{"("}{p}{")"}</span> - } - }); - let not_set = number.is_none().then_some("not-set"); - let number = number - .map(|n| n.to_string()) - .unwrap_or_else(|| String::from("???")); - html! { - <div class={classes!("identity-span", class.clone())}> - <span class={classes!("number", not_set)}><b>{number}</b></span> - <span>{name}</span> - {pronouns} - </div> - } -} diff --git a/werewolves/src/components/inc_dec.rs b/werewolves/src/components/inc_dec.rs deleted file mode 100644 index b8bcd00..0000000 --- a/werewolves/src/components/inc_dec.rs +++ /dev/null @@ -1,96 +0,0 @@ -use core::ops::Range; - -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::Button; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct IncDecU8Props { - #[prop_or_default] - pub children: Html, - #[prop_or_default] - pub class: yew::Classes, - #[prop_or_default] - pub button_class: yew::Classes, - pub value: u8, - pub value_range: Range<u8>, - pub on_update: Callback<u8>, -} - -#[function_component] -pub fn IncDecU8( - IncDecU8Props { - children, - class, - button_class, - value, - value_range, - on_update, - }: &IncDecU8Props, -) -> Html { - let value_state = use_state(|| *value); - let dec_disabled = value_range - .clone() - .next() - .and_then(|start| (start >= *value).then_some(String::from("already at minimum"))); - let dec = { - let current = *value; - let on_update = on_update.clone(); - let value_state = value_state.setter(); - Callback::from(move |_| { - let new = current.saturating_sub(1); - on_update.emit(new); - value_state.set(new); - }) - }; - let inc_disabled = value_range - .clone() - .last() - .and_then(|end| (*value >= end).then_some(String::from("already at max value"))); - let inc = { - let current = *value; - let on_update = on_update.clone(); - let value_state = value_state.setter(); - Callback::from(move |_| { - let new = current.saturating_add(1); - on_update.emit(new); - value_state.set(new); - }) - }; - html! { - <div class={classes!("inc-dec", class.clone())}> - <Button - on_click={dec} - disabled_reason={dec_disabled} - classes={button_class.clone()} - > - {"decrease"} - </Button> - <div class="inc-dec-content"> - <span class="inc-dec-count">{*value_state}</span> - {children.clone()} - </div> - <Button - on_click={inc} - disabled_reason={inc_disabled} - classes={button_class.clone()} - > - {"increase"} - </Button> - </div> - } -} diff --git a/werewolves/src/components/input.rs b/werewolves/src/components/input.rs deleted file mode 100644 index 716505d..0000000 --- a/werewolves/src/components/input.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::num::NonZeroU8; - -use web_sys::HtmlInputElement; -use yew::prelude::*; - -pub fn input_element_number_oninput(num_value: UseStateHandle<String>) -> Callback<InputEvent> { - Callback::from(move |ev: InputEvent| { - let target = if let Some(target) = ev.target_dyn_into::<HtmlInputElement>() { - target - } else { - log::error!("cannot find target for input event"); - return; - }; - let value = target.value(); - if value.is_empty() { - num_value.set(value); - return; - } - if let Ok(z) = value.trim().parse::<NonZeroU8>() { - num_value.set(z.to_string()); - } else { - target.set_value(num_value.as_str()); - } - }) -} - -pub fn input_element_string_oninput( - value: UseStateSetter<String>, - max_len: usize, -) -> Callback<InputEvent> { - Callback::from(move |ev: InputEvent| { - if let Some(target) = ev.target_dyn_into::<HtmlInputElement>() { - let mut str = target.value(); - let char_count = str.chars().count(); - if char_count > max_len { - str.truncate(max_len); - } - value.set(str); - } - }) -} diff --git a/werewolves/src/components/lobby.rs b/werewolves/src/components/lobby.rs deleted file mode 100644 index 93b3aaf..0000000 --- a/werewolves/src/components/lobby.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use std::rc::Rc; - -use werewolves_proto::{message::PlayerState, player::PlayerId}; -use yew::prelude::*; - -use crate::components::{LobbyPlayer, LobbyPlayerAction}; - -#[derive(Debug, PartialEq, Properties)] -pub struct LobbyProps { - pub players: Rc<[PlayerState]>, - #[prop_or_default] - pub on_action: Option<Callback<(PlayerId, LobbyPlayerAction)>>, -} - -#[function_component] -pub fn Lobby(LobbyProps { players, on_action }: &LobbyProps) -> Html { - html! { - <div class="lobby-player-list"> - { - players - .iter() - .map(|p| html! {<LobbyPlayer on_action={on_action} player={p.clone()} />}) - .collect::<Html>() - } - </div> - } -} diff --git a/werewolves/src/components/lobby_player.rs b/werewolves/src/components/lobby_player.rs deleted file mode 100644 index e42f278..0000000 --- a/werewolves/src/components/lobby_player.rs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::num::NonZeroU8; - -use werewolves_proto::{message::PlayerState, player::PlayerId}; -use yew::prelude::*; - -use crate::components::{ - Button, ClickableField, ClickableNumberEdit, Identity, NumberEdit, - modal::{Dialog, SubmenuDialog}, -}; - -#[derive(Debug, PartialEq, Properties)] -pub struct LobbyPlayerProps { - pub player: PlayerState, - #[prop_or_default] - pub on_action: Option<Callback<(PlayerId, LobbyPlayerAction)>>, -} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum LobbyPlayerAction { - Kick, - SetNumber(NonZeroU8), -} - -#[function_component] -pub fn LobbyPlayer(LobbyPlayerProps { player, on_action }: &LobbyPlayerProps) -> Html { - let open = use_state(|| false); - let class = if player.connected { - "connected" - } else { - "disconnected" - }; - let pid = player.identification.player_id; - let action_open = open.clone(); - let action = |action: LobbyPlayerAction| { - on_action - .as_ref() - .cloned() - .map(|on_action| { - Callback::from(move |_| { - on_action.emit((pid, action)); - action_open.set(false); - }) - }) - .unwrap_or_default() - }; - let number = use_state(String::new); - let number_open = use_state(|| false); - let submenu_open = open.clone(); - let submenu = on_action.clone().map(|on_action| { - let pid = player.identification.player_id; - let number_submit = number.clone(); - let open = submenu_open.clone(); - let on_number_submit = Callback::from(move |_| { - let number = match number_submit.trim().parse::<NonZeroU8>() { - Ok(num) => num, - Err(_) => return, - }; - on_action.emit((pid, LobbyPlayerAction::SetNumber(number))); - open.set(false); - }); - const NUMBER_DIALOG_ID: &str = "player-set-number-dialog"; - - html! { - <> - <Button on_click={(action)(LobbyPlayerAction::Kick)}>{"kick"}</Button> - // <Dialog - // id={NUMBER_DIALOG_ID.to_string()} - // button={html!{"set number"}} - // > - // <NumberEdit - // value={number} - // on_submit={on_number_submit} - // field_name="number" - // > - // </NumberEdit> - // </Dialog> - <ClickableNumberEdit - state={number_open} - value={number} - field_name="number" - on_submit={on_number_submit} - > - <div class="number">{"set number"}</div> - </ClickableNumberEdit> - </> - } - }); - let object = html! { - <div class={classes!("player", class, "column-list")}> - <Identity ident={player.identification.public.clone()}/> - </div> - }; - html! { - // <SubmenuDialog - // object={object} - // > - // {submenu} - // </SubmenuDialog> - <ClickableField - state={open} - options={submenu} - class={classes!("player", class, "column-list")} - with_backdrop_exit=true - > - <Identity ident={player.identification.public.clone()}/> - </ClickableField> - } -} diff --git a/werewolves/src/components/modal/dialog.rs b/werewolves/src/components/modal/dialog.rs deleted file mode 100644 index f3d81f9..0000000 --- a/werewolves/src/components/modal/dialog.rs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (C) 2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use wasm_bindgen::JsCast; -use web_sys::HtmlDialogElement; -use yew::prelude::*; - -use crate::components::Button; - -pub fn show_modal_by_id(id: &str) { - if let Some(dialog) = gloo::utils::document() - .get_element_by_id(id) - .and_then(|elem| elem.dyn_into::<HtmlDialogElement>().ok()) - && let Err(err) = dialog.show_modal() - { - gloo::console::error!(format!("show modal [#{}]:", id), err) - } -} - -pub fn close_modal_by_id(id: &str) { - if let Some(dialog) = gloo::utils::document() - .get_element_by_id(id) - .and_then(|elem| elem.dyn_into::<HtmlDialogElement>().ok()) - { - dialog.close(); - } -} - -pub fn show_modal_by_id_callback<ARG>(id: &str) -> Callback<ARG> { - let id = id.to_string(); - Callback::from(move |_| { - show_modal_by_id(&id); - }) -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct DialogProps { - #[prop_or_default] - pub id: String, - #[prop_or_default] - pub children: Html, - #[prop_or(true)] - pub close_backdrop: bool, - #[prop_or_default] - pub button: Html, - #[prop_or(true)] - pub close_button: bool, -} - -#[function_component] -pub fn Dialog( - DialogProps { - id, - children, - close_backdrop, - button, - close_button, - }: &DialogProps, -) -> Html { - // use generated id if not supplied - let id = if id.is_empty() { - uuid::Uuid::new_v4().to_string() - } else { - id.to_string() - }; - let close_cb = { - let id = id.clone(); - Callback::from(move |_| { - if let Some(dialog) = gloo::utils::document() - .get_element_by_id(&id) - .and_then(|elem| elem.dyn_into::<HtmlDialogElement>().ok()) - { - dialog.close() - } - }) - }; - let close = close_button.then_some({ - html! { - <Button on_click={close_cb.clone()} classes={classes!("close-dialog")}>{"close"}</Button> - } - }); - - let on_backdrop_click = close_backdrop.then_some({ - let id = id.clone(); - let close_cb = close_cb.clone(); - Callback::from(move |ev: MouseEvent| { - let Some(dialog) = gloo::utils::document() - .get_element_by_id(&id) - .and_then(|elem| elem.dyn_into::<HtmlDialogElement>().ok()) - else { - return; - }; - let Ok(Some(dialog)) = dialog.query_selector(".dialog-box") else { - return; - }; - let rect = dialog.get_bounding_client_rect(); - - let is_in_dialog = rect.top() as i32 <= ev.client_y() - && ev.client_y() <= rect.top() as i32 + rect.height() as i32 - && rect.left() as i32 <= ev.client_x() - && ev.client_x() <= rect.left() as i32 + rect.width() as i32; - - if !is_in_dialog { - close_cb.emit(()); - } - }) - }); - let modal = html! { - <dialog id={id.clone()} onclick={on_backdrop_click}> - <div class="dialog"> - <div class="dialog-box"> - {close} - {children.clone()} - </div> - </div> - </dialog> - }; - let button = (*button != html! {}).then_some({ - let on_click = show_modal_by_id_callback(&id); - - html! { - <Button on_click={on_click}>{button.clone()}</Button> - } - }); - - html! { - <div class="dialog-modal"> - {button} - {modal} - </div> - } -} diff --git a/werewolves/src/components/modal/submenu.rs b/werewolves/src/components/modal/submenu.rs deleted file mode 100644 index 34f8556..0000000 --- a/werewolves/src/components/modal/submenu.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use crate::components::Button; -use wasm_bindgen::JsCast; -use web_sys::HtmlDialogElement; -use yew::prelude::*; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct SubmenuProps { - #[prop_or_default] - pub id: String, - #[prop_or_default] - pub children: Html, - #[prop_or(true)] - pub close_backdrop: bool, - #[prop_or_default] - pub object: Html, -} - -#[function_component] -pub fn SubmenuDialog( - SubmenuProps { - id, - children, - close_backdrop, - object, - }: &SubmenuProps, -) -> Html { - // use generated id if not supplied - let id = if id.is_empty() { - uuid::Uuid::new_v4().to_string() - } else { - id.to_string() - }; - let close_cb = { - let id = id.clone(); - Callback::from(move |_| { - if let Some(dialog) = gloo::utils::document() - .get_element_by_id(&id) - .and_then(|elem| elem.dyn_into::<HtmlDialogElement>().ok()) - { - dialog.close() - } - }) - }; - - let on_backdrop_click = close_backdrop.then_some({ - let id = id.clone(); - let close_cb = close_cb.clone(); - Callback::from(move |ev: MouseEvent| { - let Some(dialog) = gloo::utils::document() - .get_element_by_id(&id) - .and_then(|elem| elem.dyn_into::<HtmlDialogElement>().ok()) - else { - return; - }; - let Ok(Some(dialog)) = dialog.query_selector(".object-submenu") else { - return; - }; - let rect = dialog.get_bounding_client_rect(); - - let is_in_dialog = rect.top() as i32 <= ev.client_y() - && ev.client_y() <= rect.top() as i32 + rect.height() as i32 - && rect.left() as i32 <= ev.client_x() - && ev.client_x() <= rect.left() as i32 + rect.width() as i32; - - if !is_in_dialog { - close_cb.emit(()); - } - }) - }); - let modal = html! { - <dialog id={id.clone()} onclick={on_backdrop_click}> - <div class="object-submenu"> - <div class="object"> - {object.clone()} - </div> - <menu> - {children.clone()} - </menu> - </div> - </dialog> - }; - - let open = crate::components::modal::show_modal_by_id_callback(&id); - html! { - <> - <div class="opener" onclick={open}> - {object.clone()} - </div> - {modal} - </> - } -} diff --git a/werewolves/src/components/reveal.rs b/werewolves/src/components/reveal.rs deleted file mode 100644 index ad1b3dc..0000000 --- a/werewolves/src/components/reveal.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::ops::Not; - -use werewolves_proto::message::{CharacterIdentity, PublicIdentity}; -use yew::prelude::*; - -use crate::components::{Button, Identity}; - -#[derive(Debug, PartialEq, Properties)] -pub struct RoleRevealProps { - pub ackd: Box<[CharacterIdentity]>, - pub waiting: Box<[CharacterIdentity]>, - pub on_force_ready: Option<Callback<CharacterIdentity>>, - #[prop_or_default] - pub allow_ready_all: bool, -} - -pub struct RoleReveal {} - -impl Component for RoleReveal { - type Message = CharacterIdentity; - - type Properties = RoleRevealProps; - - fn create(_ctx: &Context<Self>) -> Self { - Self {} - } - - fn view(&self, ctx: &Context<Self>) -> Html { - let RoleRevealProps { - ackd, - waiting, - on_force_ready, - allow_ready_all, - } = ctx.props(); - let mut chars = ackd - .iter() - .map(|t| (t, true)) - .chain(waiting.iter().map(|t| (t, false))) - .collect::<Box<[_]>>(); - chars.sort_by(|(l, _), (r, _)| l.number.cmp(&r.number)); - - let on_force_ready = on_force_ready.clone(); - let cards = chars - .into_iter() - .map(|(t, ready)| { - html! { - <RoleRevealCard - target={t.clone()} - is_ready={ready} - on_force_ready={on_force_ready.clone()} - /> - } - }) - .collect::<Html>(); - - let nack = waiting.clone(); - let force_all = on_force_ready - .map(|on_force_ready| { - Callback::from(move |_| { - for t in nack.clone() { - on_force_ready.emit(t); - } - }) - }) - .and_then(|on_force_all| { - allow_ready_all.then_some(html! { - <Button on_click={on_force_all}>{"force ready all"}</Button> - }) - }); - html! { - <div class="role-reveal-cards"> - {force_all} - {cards} - </div> - } - } -} - -#[derive(Debug, PartialEq, Properties)] -pub struct RoleRevealCardProps { - pub target: CharacterIdentity, - pub is_ready: bool, - pub on_force_ready: Option<Callback<CharacterIdentity>>, -} - -#[function_component] -pub fn RoleRevealCard(props: &RoleRevealCardProps) -> Html { - let class = props.is_ready.then_some("ready"); - let target = props.target.clone(); - let on_force_ready = props.on_force_ready.clone(); - let on_click = props.is_ready.not().then_some(()).and_then(|_| { - on_force_ready.map(|on_force_ready| { - let on_click = Callback::from(move |_| { - on_force_ready.emit(target.clone()); - }); - html! {<Button on_click={on_click}>{"force ready"}</Button>} - }) - }); - - let ident: PublicIdentity = props.target.clone().into(); - html! { - <div class={classes!(class, "role-reveal-card")}> - <Identity ident={ident}/> - {on_click} - </div> - } -} diff --git a/werewolves/src/components/role.rs b/werewolves/src/components/role.rs deleted file mode 100644 index 28bcb77..0000000 --- a/werewolves/src/components/role.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -use convert_case::{Case, Casing}; -use werewolves_proto::{game::SetupRole, role::RoleTitle}; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct RoleSpanProps { - pub role: RoleTitle, -} - -#[function_component] -pub fn RoleSpan(RoleSpanProps { role }: &RoleSpanProps) -> Html { - let class = Into::<SetupRole>::into(*role).category().class(); - let icon = role - .icon() - .map(|icon| { - html! { - <Icon source={icon} icon_type={IconType::Small}/> - } - }) - .unwrap_or(html! {<div class="icon-spacer"/>}); - let role_name = role.to_string().to_case(Case::Title); - html! { - <span class={classes!("role-span", class, "faint")}> - {icon} - <span class="role-name">{role_name}</span> - </span> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct RoleblockProps { - #[prop_or_default] - pub children: Html, -} - -#[function_component] -pub fn Roleblock(RoleblockProps { children }: &RoleblockProps) -> Html { - let content = if *children == html! {} { - html! {<span>{"Drunk"}</span>} - } else { - children.clone() - }; - html! { - <span class={classes!("roleblock-span")}> - <Icon source={IconSource::Roleblock} icon_type={IconType::Fit}/> - {content} - </span> - } -} diff --git a/werewolves/src/components/settings/category.rs b/werewolves/src/components/settings/category.rs deleted file mode 100644 index 0a47e62..0000000 --- a/werewolves/src/components/settings/category.rs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use convert_case::{Case, Casing}; -use werewolves_proto::role::RoleTitle; -use yew::prelude::*; - -use crate::components::Button; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct AddRoleCategoryProps { - pub category: werewolves_proto::game::Category, - pub roles: Box<[RoleTitle]>, - pub add_role: Callback<RoleTitle>, -} - -#[function_component] -pub fn AddRoleCategory( - AddRoleCategoryProps { - category, - roles, - add_role, - }: &AddRoleCategoryProps, -) -> Html { - let class = category.class(); - let hidden = use_state(|| true); - - let roles = roles - .iter() - .copied() - .map(|title| { - let on_click = { - let add_role = add_role.clone(); - let role = title; - Callback::from(move |_| add_role.emit(role)) - }; - let name = title.to_string().to_case(Case::Title); - html! { - <div class="slot"> - <Button on_click={on_click} classes={classes!("role", class)}> - {name} - </Button> - </div> - } - }) - .collect::<Html>(); - - let on_toggle = { - let hidden = hidden.clone(); - Callback::from(move |_| hidden.set(!*hidden)) - }; - let hidden = (*hidden).then_some("hidden"); - - html! { - <div class="category add-list"> - <div class={classes!("title", class, "hover")} onclick={on_toggle}> - {category.to_string().to_case(Case::Sentence)} - </div> - <div class={classes!("category-list", hidden)}> - {roles} - </div> - </div> - } -} diff --git a/werewolves/src/components/settings/settings.rs b/werewolves/src/components/settings/settings.rs deleted file mode 100644 index 8a93510..0000000 --- a/werewolves/src/components/settings/settings.rs +++ /dev/null @@ -1,357 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::{num::NonZeroU8, ops::Not}; -use std::rc::Rc; - -use convert_case::{Case, Casing}; -use werewolves_proto::{ - aura::AuraTitle, - error::GameError, - game::{Category, GameSettings, OrRandom, SetupRole, SetupSlot, SlotId}, - message::{Identification, PlayerState, PublicIdentity}, - role::RoleTitle, -}; -use yew::prelude::*; - -use crate::{ - class::Class, - components::{ - Button, ClickableField, Icon, IconType, Identity, PartialAssociatedIcon, - client::Signin, - modal::Dialog, - settings::{AddRoleCategory, SettingSlotAction, SettingsSlot}, - }, -}; - -#[derive(Debug, PartialEq, Properties)] -pub struct SettingsProps { - pub settings: GameSettings, - pub players_in_lobby: Rc<[PlayerState]>, - pub on_update: Callback<GameSettings>, - pub on_start: Callback<()>, - pub on_add_player: Callback<PublicIdentity>, - pub qr_mode_button: Html, -} - -#[function_component] -pub fn Settings( - SettingsProps { - settings, - players_in_lobby, - on_update, - on_start, - on_add_player, - qr_mode_button, - }: &SettingsProps, -) -> Html { - let players = players_in_lobby - .iter() - .map(|p| p.identification.clone()) - .collect::<Rc<[_]>>(); - let disabled_reason = settings - .check_with_player_list(&players) - .err() - .map(|err| err.to_string()); - - let roles_in_setup: Rc<[RoleTitle]> = settings - .slots() - .iter() - .map(|s| Into::<RoleTitle>::into(s.role.clone())) - .collect(); - let on_update_role = on_update.clone(); - let settings = Rc::new(settings.clone()); - let on_update_role_settings = settings.clone(); - let already_assigned_pids = settings - .slots() - .iter() - .filter_map(|r| r.assign_to) - .collect::<Box<[_]>>(); - let players_for_assign = players - .iter() - .filter(|p| !already_assigned_pids.contains(&p.player_id)) - .cloned() - .collect::<Rc<[_]>>(); - let update_role_card = Callback::from(move |act: SettingSlotAction| { - let mut new_settings = (*on_update_role_settings).clone(); - match act { - SettingSlotAction::Remove(slot_id) => new_settings.remove_slot(slot_id), - SettingSlotAction::Update(slot) => new_settings.update_slot(slot), - } - on_update_role.emit(new_settings); - }); - let roles = settings - .slots() - .iter() - .map(|slot| { - html! { - <SettingsSlot - all_players={players.clone()} - players_for_assign={players_for_assign.clone()} - roles_in_setup={roles_in_setup.clone()} - slot={slot.clone()} - update={update_role_card.clone()} - /> - } - }) - .collect::<Html>(); - - let add_roles_update = on_update.clone(); - - let add_role = { - let settings = settings.clone(); - let update = add_roles_update.clone(); - Callback::from(move |role: RoleTitle| { - let mut settings = (*settings).clone(); - settings.new_slot(role); - update.emit(settings); - }) - }; - - let add_roles_buttons = Category::ALL - .iter() - .copied() - .map(|cat| { - let roles = cat - .entire_category() - .into_iter() - .map(|c| c.into_role().title()) - .collect::<Box<[_]>>(); - html! { - <AddRoleCategory category={cat} roles={roles} add_role={add_role.clone()}/> - } - }) - .collect::<Html>(); - - let clear_bad_assigned = matches!( - settings.check_with_player_list(&players), - Err(GameError::AssignedMultipleTimes(_, _)) | Err(GameError::AssignedPlayerMissing(_)) - ) - .then(|| { - let clear_settings = settings.clone(); - let clear_update = on_update.clone(); - let clear_players = players.clone(); - let clear_bad_assigned = Callback::from(move |_| { - let mut settings = (*clear_settings).clone(); - settings.remove_assignments_not_in_list(&clear_players); - settings.remove_duplicate_assignments(); - clear_update.emit(settings); - }); - - html! { - <Button on_click={clear_bad_assigned}> - {"clear bad assignments"} - </Button> - } - }); - - let clear_all_assignments = settings - .slots() - .iter() - .any(|s| s.assign_to.is_some()) - .then(|| { - let settings = settings.clone(); - let update = on_update.clone(); - let on_click = Callback::from(move |_| { - let mut settings = (*settings).clone(); - settings - .slots() - .iter() - .filter(|s| s.assign_to.is_some()) - .map(|s| { - let mut s = s.clone(); - s.assign_to.take(); - s - }) - .collect::<Box<[_]>>() - .into_iter() - .for_each(|s| settings.update_slot(s)); - update.emit(settings); - }); - html! { - <Button on_click={on_click}>{"clear all assignments"}</Button> - } - }); - - let assignments = settings - .slots() - .iter() - .any(|s| s.assign_to.is_some()) - .then(|| { - let assignments = - settings - .slots() - .iter() - .cloned() - .filter_map(|s| { - s.assign_to - .as_ref() - .map(|a| { - players - .iter() - .find(|p| p.player_id == *a) - .map(|assign| { - let class = s.role.category().class(); - (html! { - <Identity ident={assign.public.clone()}/> - }, Some(class)) - }) - .unwrap_or_else(|| { - (html! { - <span>{"[left the lobby]"}</span> - }, None) - }) - }) - .map(|(who, class)| { - let assignments_update = on_update.clone(); - let assignments_settings = settings.clone(); - let click_slot = s.clone(); - let on_click = Callback::from(move |_| { - let mut settings = (*assignments_settings).clone(); - let mut click_slot = click_slot.clone(); - click_slot.assign_to.take(); - settings.update_slot(click_slot); - assignments_update.emit(settings); - }); - html! { - <Button classes={classes!("assignment", class)} on_click={on_click}> - <label>{s.role.to_string().to_case(Case::Title)}</label> - {who} - </Button> - } - }) - }) - .collect::<Html>(); - - html! { - <> - <label>{"assignments"}</label> - <div class="assignments"> - {assignments} - </div> - </> - } - }); - - let clear_setup = { - let update = on_update.clone(); - let on_click = Callback::from(move |_| { - update.emit(GameSettings::empty()); - }); - let disabled_reason = settings.slots().is_empty().then_some("no setup to clear"); - html! { - <Button on_click={on_click} disabled_reason={disabled_reason}> - {"clear setup"} - </Button> - } - }; - - let fill_empty_with_villagers = { - let disabled_reason = - (settings.min_players_needed() >= players.len()).then_some("no empty slots"); - let update = on_update.clone(); - let settings = settings.clone(); - let player_count = players.len(); - let on_click = Callback::from(move |_| { - let mut settings = (*settings).clone(); - settings.fill_remaining_slots_with_villagers(player_count); - update.emit(settings); - }); - html! { - <Button on_click={on_click} disabled_reason={disabled_reason}> - {"fill empty slots with villagers"} - </Button> - } - }; - - let current_roles = settings.slots().len(); - let min_roles = settings.min_players_needed(); - let min_roles_class = (current_roles < min_roles).then_some("red"); - let player_count = players_in_lobby.len(); - let player_count_class = (player_count != current_roles).then_some("red"); - const ADD_PLAYER_DIALOG_ID: &str = "add-player-dialog"; - let add_player_dialog_cb = { - let on_add_player = on_add_player.clone(); - Callback::from(move |ident| { - on_add_player.emit(ident); - crate::components::modal::close_modal_by_id(ADD_PLAYER_DIALOG_ID); - }) - }; - - html! { - <div class="settings"> - <div class="top-settings"> - {qr_mode_button.clone()} - {fill_empty_with_villagers} - {clear_setup} - {clear_all_assignments} - {clear_bad_assigned} - </div> - <Dialog - id={ADD_PLAYER_DIALOG_ID.to_string()} - button={html!{"add player"}} - close_button=false - > - <div> - <h3>{"manually add a player"}</h3> - <Signin callback={add_player_dialog_cb} full_height=false/> - </div> - </Dialog> - - <div class="roles-add-list"> - {add_roles_buttons} - </div> - <div class="settings-info"> - <span class="current-min-role-count"> - <span class="dimmed">{"current/minimum roles: "}</span> - <span class={classes!(min_roles_class)}> - <span class="current-roles"> - {current_roles} - </span> - {"/"} - <span class="min-roles"> - {min_roles} - </span> - </span> - </span> - <span class="player-role-count"> - <span class="dimmed">{"players/roles: "}</span> - <span class={classes!(player_count_class)}> - <span> - {player_count} - </span> - {"/"} - <span> - {current_roles} - </span> - </span> - </span> - </div> - <div class="roles-in-setup"> - <h3>{"roles in the game"}</h3> - <div class="role-list"> - {roles} - </div> - </div> - {assignments} - <Button - disabled_reason={disabled_reason} - classes={classes!("start-game")} - on_click={on_start.clone()} - > - {"start game"} - </Button> - </div> - } -} diff --git a/werewolves/src/components/settings/slot.rs b/werewolves/src/components/settings/slot.rs deleted file mode 100644 index e12164f..0000000 --- a/werewolves/src/components/settings/slot.rs +++ /dev/null @@ -1,569 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -use core::{num::NonZeroU8, ops::Not}; -use std::rc::Rc; - -use convert_case::{Case, Casing}; -use werewolves_proto::{ - aura::AuraTitle, - game::{OrRandom, SetupRole, SetupSlot, SlotId}, - message::Identification, - role::RoleTitle, -}; - -use yew::prelude::*; - -use crate::{ - class::Class, - components::{ - Button, ClickableField, Icon, IconType, Identity, IdentitySpan, PartialAssociatedIcon, - }, -}; - -pub enum SettingSlotAction { - Remove(SlotId), - Update(SetupSlot), -} - -#[derive(Debug, PartialEq, Properties)] -pub struct SettingsSlotProps { - pub players_for_assign: Rc<[Identification]>, - pub roles_in_setup: Rc<[RoleTitle]>, - pub slot: SetupSlot, - pub update: Callback<SettingSlotAction>, - pub all_players: Rc<[Identification]>, -} - -#[function_component] -pub fn SettingsSlot( - SettingsSlotProps { - players_for_assign, - roles_in_setup, - slot, - update, - all_players, - }: &SettingsSlotProps, -) -> Html { - let open = use_state(|| false); - let aura_open = use_state(|| false); - let open_update = open.setter(); - let update = update.clone(); - let update = Callback::from(move |act| { - update.emit(act); - }); - let role_name = slot.role.to_string().to_case(Case::Title); - let apprentice_open = use_state(|| false); - let submenu = { - let on_kick_update = update.clone(); - let slot_id = slot.slot_id; - let assign_open = use_state(|| false); - let on_kick = Callback::from(move |_| { - on_kick_update.emit(SettingSlotAction::Remove(slot_id)); - open_update.set(false); - }); - let assign_to = assign_to_submenu(players_for_assign, slot, &update, &assign_open.setter()); - let options = setup_options_for_slot( - slot, - &update, - roles_in_setup, - apprentice_open, - open.clone(), - aura_open.clone(), - ); - let assign_text = slot - .assign_to - .as_ref() - .and_then(|assign_to| all_players.iter().find(|p| p.player_id == *assign_to)) - .map(|assign_to| { - html! { - <> - <span>{"assigned to"}</span> - <Identity ident={assign_to.public.clone()} /> - </> - } - }) - .unwrap_or_else(|| html! {{"assign"}}); - html! { - <div class="option-menu"> - <Button on_click={on_kick} classes={classes!("red")}> - {"remove"} - </Button> - <ClickableField - options={assign_to} - state={assign_open} - class={classes!("assign-list")} - > - {assign_text} - </ClickableField> - {options} - </div> - } - }; - let class = slot.role.category().class(); - - let assigned_to = slot - .assign_to - .as_ref() - .copied() - .and_then(|assigned_to| all_players.iter().find(|p| p.player_id == assigned_to)) - .map(|ident| { - html! { - <IdentitySpan ident={ident.public.clone()}/> - } - }); - - let auras = slot.auras.is_empty().not().then_some({ - let list = slot - .auras - .iter() - .map(|aura| { - html! { - <span>{aura.to_string()}</span> - } - }) - .collect::<Html>(); - let title = (slot.auras.len() > 1).then_some(html! { - <span>{"auras:"}</span> - }); - html! { - <div class="slot-auras"> - {title} - <div class="slot-aura-list"> - {list} - </div> - </div> - } - }); - let other_options = display_options_for_slot(slot); - html! { - <div class="slot-container"> - <ClickableField - class={classes!("setup-slot")} - button_class={classes!(class, "faint")} - options={submenu} - state={open} - with_backdrop_exit=true - > - <span>{role_name}</span> - </ClickableField> - <div class="slot-options"> - {assigned_to} - {auras} - {other_options} - </div> - </div> - } -} - -fn assign_to_submenu( - players: &[Identification], - slot: &SetupSlot, - update: &Callback<SettingSlotAction>, - assign_setter: &UseStateSetter<bool>, -) -> Html { - let buttons = players - .iter() - .map(|p| { - let slot = slot.clone(); - let update = update.clone(); - let pid = p.player_id; - let setter = assign_setter.clone(); - let on_click = Callback::from(move |_| { - let mut slot = slot.clone(); - slot.assign_to.replace(pid); - update.emit(SettingSlotAction::Update(slot)); - setter.set(false); - }); - html! { - <Button on_click={on_click}> - <Identity ident={p.public.clone()}/> - </Button> - } - }) - .collect::<Html>(); - - html! { - <div class="assignees"> - {buttons} - </div> - } -} - -fn display_options_for_slot(slot: &SetupSlot) -> Html { - let options = match &slot.role { - SetupRole::Seer - | SetupRole::Arcanist - | SetupRole::Gravedigger - | SetupRole::Hunter - | SetupRole::Militia - | SetupRole::MapleWolf - | SetupRole::Guardian - | SetupRole::Protector - | SetupRole::Werewolf - | SetupRole::AlphaWolf - | SetupRole::DireWolf - | SetupRole::Shapeshifter - | SetupRole::LoneWolf - | SetupRole::Bloodletter - | SetupRole::Adjudicator - | SetupRole::Insomniac - | SetupRole::PowerSeer - | SetupRole::Mortician - | SetupRole::Beholder - | SetupRole::Empath - | SetupRole::Vindicator - | SetupRole::Diseased - | SetupRole::BlackKnight - | SetupRole::Weightlifter - | SetupRole::PyreMaster - | SetupRole::Villager => return html! {}, - SetupRole::Elder { knows_on_night } => html! { - <span>{"wakes night "}{knows_on_night.get()}</span> - }, - SetupRole::MasonLeader { recruits_available } => html! { - <span>{recruits_available.get()}{ - if recruits_available.get() == 1 { - " recruit" - } else { - " recruits" - } - }</span> - }, - SetupRole::Apprentice { to: None } => html! { - <span>{"random mentor"}</span> - }, - SetupRole::Apprentice { to: Some(mentor) } => { - let class = Into::<SetupRole>::into(*mentor).category().class(); - html! { - <span> - {"apprentice to "} - <span class={classes!(class, "faint")}>{mentor.to_string().to_case(Case::Sentence)}</span> - </span> - } - } - SetupRole::Scapegoat { - redeemed: OrRandom::Random, - } => html! { - <span>{"redemption random"}</span> - }, - SetupRole::Scapegoat { - redeemed: OrRandom::Determined(false), - } => html! { - <span>{"not redeemed"}</span> - }, - SetupRole::Scapegoat { - redeemed: OrRandom::Determined(true), - } => html! { - <span>{"redeemed"}</span> - }, - }; - html! { - <div class="slot-options-display"> - {options} - </div> - } -} - -fn setup_options_for_slot( - slot: &SetupSlot, - update: &Callback<SettingSlotAction>, - roles_in_setup: &[RoleTitle], - open_apprentice_assign: UseStateHandle<bool>, - slot_field_open: UseStateHandle<bool>, - open_aura_assign: UseStateHandle<bool>, -) -> Html { - let aura_assign = { - let options = AuraTitle::ALL - .into_iter() - .filter(AuraTitle::assignable) - // .map(AuraTitle::into_aura) - .filter(|aura| slot.role.title().can_assign_aura(*aura)) - .map(|aura| { - let aura_active = slot.auras.contains(&aura); - let active_class = aura_active.then_some("active"); - let toggle = { - let slot = slot.clone(); - let update = update.clone(); - Callback::from(move |_| { - let mut slot = slot.clone(); - if aura_active { - slot.auras.retain(|a| *a != aura); - } else { - slot.auras = aura.try_add_to_list(&slot.auras); - } - update.emit(SettingSlotAction::Update(slot)) - }) - }; - let icon = aura - .icon() - .map(|icon| { - html! { - // <div - <Icon source={icon} icon_type={IconType::Small}/> - } - }) - .unwrap_or_else(|| { - html! { - <div class="icon inactive"/> - } - }); - let aura_class = aura.class(); - - html! { - <Button - on_click={toggle} - classes={classes!(active_class, "setup-aura", aura_class, "faint")} - > - <span class="aura-title"> - {icon} - <span class="title">{aura.to_string().to_case(Case::Title)}</span> - <div class="icon inactive"/> - </span> - </Button> - } - }) - .collect::<Box<[_]>>(); - options.is_empty().not().then(|| { - let options = options.into_iter().collect::<Html>(); - html! { - <ClickableField - state={open_aura_assign} - options={options} - > - {slot.auras.len()}{" auras"} - </ClickableField> - } - }) - }; - let setup_options_for_role = match &slot.role { - SetupRole::MasonLeader { recruits_available } => { - let next = { - let mut s = slot.clone(); - match &mut s.role { - SetupRole::MasonLeader { recruits_available } => { - *recruits_available = - NonZeroU8::new(recruits_available.get().checked_add(1).unwrap_or(1)) - .unwrap() - } - _ => unreachable!(), - } - s - }; - let prev = recruits_available - .get() - .checked_sub(1) - .and_then(NonZeroU8::new) - .map(|new_avail| { - let mut s = slot.clone(); - match &mut s.role { - SetupRole::MasonLeader { recruits_available } => { - *recruits_available = new_avail - } - _ => unreachable!(), - } - s - }); - let increment_update = update.clone(); - let on_increment = Callback::from(move |_| { - increment_update.emit(SettingSlotAction::Update(next.clone())) - }); - - let decrement_update = update.clone(); - let on_decrement = prev - .clone() - .map(|prev| { - Callback::from(move |_| { - decrement_update.emit(SettingSlotAction::Update(prev.clone())) - }) - }) - .unwrap_or_default(); - let decrement_disabled_reason = prev.is_none().then_some("at minimum"); - Some(html! { - <> - <span>{"recruits"}</span> - <div class={classes!("increment-decrement")}> - <Button on_click={on_decrement} disabled_reason={decrement_disabled_reason}>{"-"}</Button> - <span>{recruits_available.get().to_string()}</span> - <Button on_click={on_increment}>{"+"}</Button> - </div> - </> - }) - } - SetupRole::Scapegoat { redeemed } => { - let next = { - let next_redeemed = match redeemed { - OrRandom::Random => OrRandom::Determined(true), - OrRandom::Determined(true) => OrRandom::Determined(false), - OrRandom::Determined(false) => OrRandom::Random, - }; - let mut s = slot.clone(); - match &mut s.role { - SetupRole::Scapegoat { redeemed } => *redeemed = next_redeemed, - _ => unreachable!(), - } - s - }; - let update = update.clone(); - let on_click = - Callback::from(move |_| update.emit(SettingSlotAction::Update(next.clone()))); - let body = match redeemed { - OrRandom::Determined(true) => "redeemed", - OrRandom::Determined(false) => "irredeemable", - OrRandom::Random => "random", - }; - Some(html! { - <> - <span>{"redeemed?"}</span> - <Button on_click={on_click}> - <span>{body}</span> - </Button> - </> - }) - } - SetupRole::Apprentice { to: specifically } => { - let options = roles_in_setup - .iter() - .filter(|r| r.is_mentor()) - .cloned() - .collect::<Box<[_]>>(); - - #[allow(clippy::obfuscated_if_else)] - options - .is_empty() - .not() - .then(|| { - options - .into_iter() - .filter(|o| specifically.as_ref().map(|s| s != o).unwrap_or(true)) - .map(|option| { - let open_apprentice_assign = open_apprentice_assign.clone(); - let open = slot_field_open.clone(); - let update = update.clone(); - let role_name = option.to_string().to_case(Case::Title); - let mut slot = slot.clone(); - match &mut slot.role { - SetupRole::Apprentice { to: specifically } => { - specifically.replace(option); - } - _ => unreachable!(), - } - let on_click = Callback::from(move |_| { - update.emit(SettingSlotAction::Update(slot.clone())); - open_apprentice_assign.set(false); - open.set(false); - }); - html! { - <Button on_click={on_click}> - {role_name} - </Button> - } - }) - .chain(specifically.is_some().then(|| { - let open_apprentice_assign = open_apprentice_assign.clone(); - let open = slot_field_open.clone(); - let update = update.clone(); - let role_name = "random"; - let mut slot = slot.clone(); - match &mut slot.role { - SetupRole::Apprentice { to: specifically } => { - specifically.take(); - } - _ => unreachable!(), - } - let on_click = Callback::from(move |_| { - update.emit(SettingSlotAction::Update(slot.clone())); - open_apprentice_assign.set(false); - open.set(false); - }); - html! { - <Button on_click={on_click}> - {role_name} - </Button> - } - })) - .collect::<Html>() - }) - .map(|options| { - let current = specifically - .as_ref() - .map(|r| r.to_string().to_case(Case::Title)) - .unwrap_or_else(|| String::from("random")); - html! { - <ClickableField - state={open_apprentice_assign} - options={options} - > - {"mentor ("}{current}{")"} - </ClickableField> - } - }) - } - SetupRole::Elder { knows_on_night } => { - const SAFE_NUM: NonZeroU8 = NonZeroU8::new(1).unwrap(); - let increment_slot = { - let mut s = slot.clone(); - match &mut s.role { - SetupRole::Elder { knows_on_night } => { - *knows_on_night = - NonZeroU8::new(knows_on_night.get().checked_add(1).unwrap_or(1)) - .unwrap_or(SAFE_NUM) - } - _ => unreachable!(), - } - s - }; - let decrement_slot = { - let mut s = slot.clone(); - match &mut s.role { - SetupRole::Elder { knows_on_night } => { - *knows_on_night = - NonZeroU8::new(knows_on_night.get().checked_sub(1).unwrap_or(u8::MAX)) - .unwrap_or(SAFE_NUM) - } - _ => unreachable!(), - } - s - }; - let update_decrement = update.clone(); - let decrement = Callback::from(move |_| { - update_decrement.emit(SettingSlotAction::Update(decrement_slot.clone())) - }); - let update_increment = update.clone(); - let increment = Callback::from(move |_| { - update_increment.emit(SettingSlotAction::Update(increment_slot.clone())) - }); - Some(html! { - <> - <span>{"knows on night"}</span> - <div class={classes!("increment-decrement")}> - <Button on_click={decrement}>{"-"}</Button> - <span>{knows_on_night.to_string()}</span> - <Button on_click={increment}>{"+"}</Button> - </div> - </> - }) - } - - _ => None, - }; - - html! { - <> - {aura_assign} - {setup_options_for_role} - </> - } -} diff --git a/werewolves/src/components/story/character.rs b/werewolves/src/components/story/character.rs deleted file mode 100644 index 2732b01..0000000 --- a/werewolves/src/components/story/character.rs +++ /dev/null @@ -1,714 +0,0 @@ -// Copyright (C) 2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -use core::ops::Not; -use std::{collections::HashMap, rc::Rc}; - -use werewolves_proto::{ - aura::AuraTitle, - character::{Character, CharacterId}, - diedto::DiedTo, - game::{ - GameTime, SetupRole, - night::changes::NightChange, - story::{NightChoice, StoryActionPrompt, StoryActionResult}, - }, - player::Protection, - role::{RoleBlock, RoleTitle}, -}; -use yew::prelude::*; - -use crate::{ - class::Class, - components::{ - AuraSpan, Button, CharacterHighlight, Icon, IconSource, IconType, Identity, IdentitySpan, - PartialAssociatedIcon, RoleSpan, Roleblock, - attributes::{ - AlignmentComparisonSpan, AlignmentSpan, DiedToSpan, KillerSpan, PowerfulSpan, - }, - }, -}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct CharacterStoryProps { - pub all_characters: Rc<[Character]>, - pub character: Character, - pub actions: Box<[(GameTime, Box<[NightChange]>, Box<[NightChoice]>)]>, -} - -#[function_component] -pub fn CharacterStory( - CharacterStoryProps { - all_characters, - character, - actions, - }: &CharacterStoryProps, -) -> Html { - let class = character.class(); - let mut by_time = actions - .iter() - .filter(|(_, changes, choices)| !(changes.is_empty() && choices.is_empty())) - .cloned() - .collect::<Box<[_]>>(); - by_time.sort_by_key(|s| s.0); - let open_time = use_state(|| by_time.iter().next().map(|(t, _, _)| *t)); - if let Some(current_open_time) = open_time.as_ref() - && let Some(last) = by_time.last().map(|c| c.0) - { - if last < *current_open_time || !by_time.iter().any(|(t, _, _)| t == current_open_time) { - open_time.set(Some(last)); - } else if let Some(first) = by_time.first().map(|c| c.0) - && first > *current_open_time - { - open_time.set(Some(first)); - } - } - let tabs = by_time - .into_iter() - .map(|(time, _, _)| { - let time_text = match time { - GameTime::Day { number } => format!("day {number}"), - GameTime::Night { number } => format!("night {number}"), - }; - let on_click = { - let open_time = open_time.setter(); - Callback::from(move |_| open_time.set(Some(time))) - }; - let selected = open_time - .as_ref() - .map(|open| *open == time) - .unwrap_or_default(); - let faint = selected.not().then_some("faint"); - let selected = selected.then_some("selected"); - html! { - <button - onclick={on_click} - class={classes!("tab-button", class, faint, selected, "hover")} - > - {time_text} - </button> - } - }) - .collect::<Html>(); - - let story_content = open_time - .as_ref() - .and_then(|time| actions.iter().find(|(t, _, _)| t == time)) - .map(|(time, changes, choices)| { - let choices = choices - .iter() - .map(|c| { - html! { - <Choice - all_characters={all_characters.clone()} - character={character.clone()} - choice={c.clone()} - all_choices_that_night={choices.clone()} - time={*time} - /> - } - }) - .collect::<Html>(); - let changes = changes - .iter() - .map(|c| { - html! { - <Change all_characters={all_characters.clone()} change={c.clone()} time={*time}/> - } - }) - .collect::<Html>(); - let changes = (changes == html! {}).not().then_some(html! { - <> - <span class="sub-headline">{"changes"}</span> - <div> - {changes} - </div> - </> - }); - let choices = (choices == html! {}).not().then_some(html! { - <> - <span class="sub-headline">{"choices"}</span> - <div> - {choices} - </div> - </> - }); - html! { - <> - {choices} - {changes} - </> - } - }); - html! { - <div class="character-story"> - <div class="tabs"> - {tabs} - </div> - <div class="story-content"> - {story_content} - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -struct ChoiceProps { - all_characters: Rc<[Character]>, - character: Character, - choice: NightChoice, - all_choices_that_night: Box<[NightChoice]>, - time: GameTime, -} - -#[function_component] -fn Choice( - ChoiceProps { - all_characters, - character, - choice, - all_choices_that_night, - time, - }: &ChoiceProps, -) -> Html { - let generate_prompt = |chosen: CharacterId, wording: &'static str| -> Option<Html> { - all_characters - .iter() - .find(|c| c.character_id() == chosen) - .map(|chosen| { - html! { - <> - <CharacterHighlight - char={character.clone()} - time={*time} - /> - <span>{wording}</span> - <CharacterHighlight - char={chosen.clone()} - time={*time} - /> - </> - } - }) - }; - let prompt = match &choice.prompt { - StoryActionPrompt::Guardian { - chosen, guarding, .. - } => generate_prompt(*chosen, if *guarding { "guarded" } else { "protected" }), - StoryActionPrompt::Seer { chosen, .. } => generate_prompt(*chosen, "checked"), - StoryActionPrompt::Protector { chosen, .. } => generate_prompt(*chosen, "protected"), - StoryActionPrompt::Arcanist { - chosen: (target1, target2), - .. - } => all_characters - .iter() - .find(|c| c.character_id() == *target1) - .and_then(|t1| { - all_characters - .iter() - .find(|c| c.character_id() == *target2) - .map(|t2| (t1, t2)) - }) - .map(|(t1, t2)| { - html! { - <> - <CharacterHighlight - char={character.clone()} - time={*time} - /> - <span>{"checked"}</span> - <CharacterHighlight - char={t1.clone()} - time={*time} - /> - <span>{"and"}</span> - <CharacterHighlight - char={t2.clone()} - time={*time} - /> - </> - } - }), - StoryActionPrompt::Gravedigger { chosen, .. } => generate_prompt(*chosen, "dug"), - StoryActionPrompt::Hunter { chosen, .. } => generate_prompt(*chosen, "set a trap for"), - StoryActionPrompt::Militia { chosen, .. } => generate_prompt(*chosen, "shot"), - StoryActionPrompt::MapleWolf { chosen, .. } => generate_prompt(*chosen, "ate"), - StoryActionPrompt::Adjudicator { chosen, .. } => generate_prompt(*chosen, "checked"), - StoryActionPrompt::PowerSeer { chosen, .. } => generate_prompt(*chosen, "checked"), - StoryActionPrompt::Mortician { chosen, .. } => generate_prompt(*chosen, "examined"), - StoryActionPrompt::Beholder { chosen, .. } => generate_prompt(*chosen, "beheld"), - StoryActionPrompt::MasonLeaderRecruit { chosen, .. } => { - generate_prompt(*chosen, "attempted to recruit") - } - StoryActionPrompt::WolfPackKill { chosen, .. } => { - generate_prompt(*chosen, "took the wolfpack kill and attacked") - } - StoryActionPrompt::MasonsWake { leader, .. } => all_characters - .iter() - .find(|l| l.character_id() == *leader) - .map(|leader| { - html! { - <> - <CharacterHighlight - char={character.clone()} - time={*time} - /> - <span>{"woke with the masons of"}</span> - <CharacterHighlight - char={leader.clone()} - time={*time} - /> - </> - } - }), - StoryActionPrompt::Empath { chosen, .. } => generate_prompt(*chosen, "checked"), - StoryActionPrompt::Vindicator { chosen, .. } => generate_prompt(*chosen, "protected"), - StoryActionPrompt::PyreMaster { chosen, .. } => generate_prompt(*chosen, "burned"), - StoryActionPrompt::Shapeshifter { .. } => all_choices_that_night - .iter() - .find_map(|c| match c.prompt { - StoryActionPrompt::WolfPackKill { chosen, .. } => Some(chosen), - _ => None, - }) - .and_then(|target| all_characters.iter().find(|c| c.character_id() == target)) - .map(|target| { - html! { - <> - <CharacterHighlight - char={character.clone()} - time={*time} - /> - <span>{"chose to shift into"}</span> - <CharacterHighlight - char={target.clone()} - time={*time} - /> - </> - } - }), - StoryActionPrompt::Insomniac { .. } => Some(html! { - <> - <CharacterHighlight - char={character.clone()} - time={*time} - /> - <span>{"woke in the night due to visits from: "}</span> - </> - }), - StoryActionPrompt::AlphaWolf { chosen, .. } => generate_prompt(*chosen, "killed"), - StoryActionPrompt::DireWolf { chosen, .. } => { - generate_prompt(*chosen, "roleblocked visitors to") - } - StoryActionPrompt::LoneWolfKill { chosen, .. } => generate_prompt(*chosen, "killed"), - StoryActionPrompt::Bloodletter { chosen, .. } => generate_prompt(*chosen, "bloodlet"), - StoryActionPrompt::BeholderWakes { character_id } => { - generate_prompt(*character_id, "woke again to see") - } - }; - if prompt.is_none() { - return html! {}; - } - let result = choice.result.as_ref().map(|result| match result { - StoryActionResult::RoleBlocked => html! { - <> - <span>{"but was"}</span> - <Roleblock>{"Roleblocked"}</Roleblock> - </> - }, - StoryActionResult::Seer(_, alignment) => html! { - <> - <span>{"and saw"}</span> - <AlignmentSpan alignment={*alignment}/> - </> - }, - StoryActionResult::PowerSeer { powerful, .. } => html! { - <> - <span>{"and saw"}</span> - <PowerfulSpan powerful={*powerful}/> - </> - }, - StoryActionResult::Adjudicator { killer, .. } => html! { - <> - <span>{"and saw"}</span> - <KillerSpan killer={*killer}/> - </> - }, - StoryActionResult::Arcanist(_, alignment_eq) => html! { - <> - <span>{"and saw them as"}</span> - <AlignmentComparisonSpan comparison={*alignment_eq}/> - </> - }, - StoryActionResult::GraveDigger(_, None) => html! { - <span>{"but found an empty grave"}</span> - }, - StoryActionResult::GraveDigger(_, Some(role_title)) => html! { - <> - <span>{"as"}</span> - <RoleSpan role={*role_title}/> - </> - }, - StoryActionResult::Mortician(_, died_to_title) => html! { - <> - <span>{"and found"}</span> - <DiedToSpan died_to={*died_to_title}/> - <span>{"to be the cause of death"}</span> - </> - }, - StoryActionResult::Insomniac { visits } => { - let mut visit_chars = vec![]; - for visit in visits { - match all_characters.iter().find(|c| c.character_id() == *visit) { - Some(char) => visit_chars.push(char), - None => { - log::warn!("visit chars missing {visit}"); - return html! {}; - } - } - } - visit_chars - .into_iter() - .map(|visitor| { - html! { - <CharacterHighlight - char={visitor.clone()} - time={*time} - /> - } - }) - .collect::<Html>() - } - StoryActionResult::Empath { - scapegoat: true, .. - } => { - html! {<span>{"and found their scapegoat"}</span>} - } - StoryActionResult::Empath { - scapegoat: false, .. - } => { - html! {<span>{"who was not a scapegoat"}</span>} - } - StoryActionResult::BeholderSawNothing => html! { - <> - {"and saw"} - <em>{"nothing"}</em> - </> - }, - StoryActionResult::BeholderSawEverything => html! { - <> - {"and saw"} - <em>{"everything"}</em> - </> - }, - StoryActionResult::ShiftFailed => html! { - {"however, their shift failed"} - }, - StoryActionResult::Drunk => html! { - <> - <span>{"but got"}</span> - <AuraSpan aura={AuraTitle::Drunk} /> - </> - }, - }); - html! { - <div class="action"> - {prompt} - {result} - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -struct ChangeProps { - all_characters: Rc<[Character]>, - change: NightChange, - time: GameTime, -} - -#[function_component] -fn Change( - ChangeProps { - all_characters, - change, - time, - }: &ChangeProps, -) -> Html { - match change { - NightChange::RoleChange(_, role_title) => Some(html! { - <> - <span>{"role changed to"}</span> - <RoleSpan role={*role_title}/> - </> - }), - NightChange::Kill { died_to, .. } => Some(html! { - <> - <span>{"died to"}</span> - <DiedToSpan died_to={died_to.title()}/> - </> - }), - NightChange::RoleBlock { - source, - block_type: RoleBlock::Direwolf, - .. - } => all_characters - .iter() - .find(|s| s.character_id() == *source) - .map(|source| { - html! { - <> - <span>{"had visitors role blocked by"}</span> - <CharacterHighlight - char={source.clone()} - time={*time} - /> - </> - } - }), - NightChange::Shapeshift { source, .. } => all_characters - .iter() - .find(|c| c.character_id() == *source) - .map(|source| { - html! { - <> - {"shapeshifted by"} - <CharacterHighlight - char={source.clone()} - time={*time} - /> - {"and became a werewolf"} - </> - } - }), - NightChange::ElderReveal { .. } => Some(html! { - <> - <span>{"learned they are the"}</span> - <RoleSpan role={RoleTitle::Elder}/> - </> - }), - NightChange::MasonRecruit { - mason_leader, - recruiting, - } => all_characters - .iter() - .find(|c| c.character_id() == *mason_leader) - .and_then(|mason| { - all_characters - .iter() - .find(|c| c.character_id() == *recruiting) - .map(|recruiting| (mason, recruiting)) - }) - .map(|(mason, recruiting)| { - html! { - <> - <CharacterHighlight - char={mason.clone()} - time={*time} - /> - <span>{"recruited"}</span> - <CharacterHighlight - char={recruiting.clone()} - time={*time} - /> - <span>{"into the masons"}</span> - </> - } - }), - NightChange::ApplyAura { source, aura, .. } => { - let from = all_characters - .iter() - .find(|c| c.character_id() == *source) - .map(|source| { - html! { - <> - <span>{"from"}</span> - <CharacterHighlight - char={source.clone()} - time={*time} - /> - </> - } - }); - Some(html! { - <> - <span>{"received the"}</span> - <AuraSpan aura={aura.title()}/> - <span>{"aura"}</span> - {from} - </> - }) - } - NightChange::LostAura { aura, .. } => Some(html! { - <> - <span>{"lost the"}</span> - <AuraSpan aura={aura.title()}/> - <span>{"aura"}</span> - </> - }), - NightChange::EmpathFoundScapegoat { scapegoat, .. } => all_characters - .iter() - .find(|c| c.character_id() == *scapegoat) - .map(|scapegoat| { - html! { - <> - <span>{"took on the scapegoat's curse from"}</span> - <CharacterHighlight - char={scapegoat.clone()} - time={*time} - /> - </> - } - }), - NightChange::HunterTarget { source, .. } => all_characters - .iter() - .find(|c| c.character_id() == *source) - .map(|source| { - html! { - <> - {"had the hunter's mark placed on them by"} - <CharacterHighlight - char={source.clone()} - time={*time} - /> - </> - } - }), - NightChange::Protection { target, protection } => { - let prot = match protection { - Protection::Guardian { - source, - guarding: true, - } => all_characters - .iter() - .find(|s| s.character_id() == *source) - .map(|source| { - html! { - <> - <span>{"was guarded by"}</span> - <CharacterHighlight - char={source.clone()} - time={*time} - /> - </> - } - }), - Protection::Guardian { - source, - guarding: false, - } - | Protection::Protector { source } - | Protection::Vindicator { source } => all_characters - .iter() - .find(|s| s.character_id() == *source) - .map(|source| { - html! { - <> - <span>{"was protected by"}</span> - <CharacterHighlight - char={source.clone()} - time={*time} - /> - </> - } - }), - }; - all_characters - .iter() - .find(|t| t.character_id() == *target) - .and_then(|target| prot.map(|prot| (target, prot))) - .map(|(target, prot)| { - html! { - <> - <CharacterHighlight - char={target.clone()} - time={*time} - /> - {prot} - </> - } - }) - } - } - .map(|change| { - html! { - <div class="change"> - {change} - </div> - } - }) - .unwrap_or_default() -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct CharacterStoryButtonProps { - pub character: Character, - pub choices_by_time: Box<[(GameTime, Box<[NightChange]>, Box<[NightChoice]>)]>, - pub on_click: Callback<( - Character, - Box<[(GameTime, Box<[NightChange]>, Box<[NightChoice]>)]>, - )>, -} - -#[function_component] -pub fn CharacterStoryButton( - CharacterStoryButtonProps { - character, - choices_by_time, - on_click, - }: &CharacterStoryButtonProps, -) -> Html { - let clickable = !choices_by_time - .iter() - .all(|(_, c1, c2)| c1.is_empty() && c2.is_empty()); - let role_class = character.class(); - let icon = character - .role_title() - .icon() - .map(|source| { - html! { - <Icon source={source} icon_type={IconType::Small}/> - } - }) - .unwrap_or(html! { - <div class="icon-spacer"/> - }); - let dead_icon = character - .died_to() - .map(|_| { - html! { - <Icon source={IconSource::Skull} icon_type={IconType::Small}/> - } - }) - .unwrap_or(html! { - <div class="icon-spacer"/> - }); - - let on_click = if clickable { - let cb = on_click.clone(); - let char = character.clone(); - let act = choices_by_time.clone(); - Callback::from(move |_| cb.emit((char.clone(), act.clone()))) - } else { - Callback::noop() - }; - let inactive = clickable.not().then_some("no-content"); - let hover = clickable.then_some("hover"); - html! { - <div class={classes!("character-headline", role_class, "faint", inactive, hover)} onclick={on_click}> - {icon} - <Identity ident={character.identity().into_public()}/> - {dead_icon} - </div> - } -} diff --git a/werewolves/src/components/story/error.rs b/werewolves/src/components/story/error.rs deleted file mode 100644 index 8cacb69..0000000 --- a/werewolves/src/components/story/error.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -use yew::prelude::*; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct StoryErrorProps { - pub error: String, -} - -#[function_component] -pub fn StoryError(StoryErrorProps { error }: &StoryErrorProps) -> Html { - html! { - <div class="story-error"> - {error.clone()} - </div> - } -} diff --git a/werewolves/src/components/story/gamegen.rs b/werewolves/src/components/story/gamegen.rs deleted file mode 100644 index f8f04ea..0000000 --- a/werewolves/src/components/story/gamegen.rs +++ /dev/null @@ -1,1052 +0,0 @@ -use core::{num::NonZeroU8, ops::Range}; - -use werewolves_proto::{ - character::{Character, CharacterId}, - diedto::DiedToTitle, - game::{Game, GameOver, GameSettings, OrRandom, SetupRole, SetupSlot, story::GameStory}, - message::{ - CharacterState, Identification, PublicIdentity, - host::{HostDayMessage, HostGameMessage, HostNightMessage, ServerToHostMessage}, - night::{ActionPrompt, ActionPromptTitle, ActionResponse, ActionResult, Visits}, - }, - player::PlayerId, - role::{Alignment, AlignmentEq, Killer, Powerful, RoleTitle}, -}; - -pub fn generate_story() -> GameStory { - let players = gen_players(1..32u8); - let mut players_iter = players.iter().map(|p| p.player_id); - let ( - werewolf, - dire_wolf, - shapeshifter, - alpha_wolf, - seer, - arcanist, - maple_wolf, - guardian, - vindicator, - adjudicator, - power_seer, - beholder, - gravedigger, - mortician, - insomniac, - empath, - scapegoat, - hunter, - mason_leader, - ) = ( - (SetupRole::Werewolf, players_iter.next().unwrap()), - (SetupRole::DireWolf, players_iter.next().unwrap()), - (SetupRole::Shapeshifter, players_iter.next().unwrap()), - (SetupRole::AlphaWolf, players_iter.next().unwrap()), - (SetupRole::Seer, players_iter.next().unwrap()), - (SetupRole::Arcanist, players_iter.next().unwrap()), - (SetupRole::MapleWolf, players_iter.next().unwrap()), - (SetupRole::Guardian, players_iter.next().unwrap()), - (SetupRole::Vindicator, players_iter.next().unwrap()), - (SetupRole::Adjudicator, players_iter.next().unwrap()), - (SetupRole::PowerSeer, players_iter.next().unwrap()), - (SetupRole::Beholder, players_iter.next().unwrap()), - (SetupRole::Gravedigger, players_iter.next().unwrap()), - (SetupRole::Mortician, players_iter.next().unwrap()), - (SetupRole::Insomniac, players_iter.next().unwrap()), - (SetupRole::Empath, players_iter.next().unwrap()), - ( - SetupRole::Scapegoat { - redeemed: OrRandom::Determined(false), - }, - players_iter.next().unwrap(), - ), - (SetupRole::Hunter, players_iter.next().unwrap()), - ( - SetupRole::MasonLeader { - recruits_available: NonZeroU8::new(3).unwrap(), - }, - players_iter.next().unwrap(), - ), - ); - let mut settings = GameSettings::empty(); - settings.add_and_assign(werewolf.0, werewolf.1); - settings.add_and_assign(dire_wolf.0, dire_wolf.1); - settings.add_and_assign(shapeshifter.0, shapeshifter.1); - settings.add_and_assign(alpha_wolf.0, alpha_wolf.1); - settings.add_and_assign(seer.0, seer.1); - settings.add_and_assign(arcanist.0, arcanist.1); - settings.add_and_assign(maple_wolf.0, maple_wolf.1); - settings.add_and_assign(guardian.0, guardian.1); - settings.add_and_assign(vindicator.0, vindicator.1); - settings.add_and_assign(adjudicator.0, adjudicator.1); - settings.add_and_assign(power_seer.0, power_seer.1); - settings.add_and_assign(beholder.0, beholder.1); - settings.add_and_assign(gravedigger.0, gravedigger.1); - settings.add_and_assign(mortician.0, mortician.1); - settings.add_and_assign(insomniac.0, insomniac.1); - settings.add_and_assign(empath.0, empath.1); - settings.add_and_assign(scapegoat.0, scapegoat.1); - settings.add_and_assign(hunter.0, hunter.1); - settings.add_and_assign(mason_leader.0, mason_leader.1); - settings.fill_remaining_slots_with_villagers(players.len()); - #[allow(unused)] - let ( - werewolf, - dire_wolf, - shapeshifter, - alpha_wolf, - seer, - arcanist, - maple_wolf, - guardian, - vindicator, - adjudicator, - power_seer, - beholder, - gravedigger, - mortician, - insomniac, - empath, - scapegoat, - hunter, - mason_leader, - ) = ( - werewolf.1, - dire_wolf.1, - shapeshifter.1, - alpha_wolf.1, - seer.1, - arcanist.1, - maple_wolf.1, - guardian.1, - vindicator.1, - adjudicator.1, - power_seer.1, - beholder.1, - gravedigger.1, - mortician.1, - insomniac.1, - empath.1, - scapegoat.1, - hunter.1, - mason_leader.1, - ); - let mut game = Game::new(&players, settings).unwrap(); - game.r#continue().r#continue(); - game.next().title().wolves_intro(); - game.r#continue().r#continue(); - - game.next().title().direwolf(); - game.mark(game.character_by_player_id(seer).character_id()); - game.r#continue().sleep(); - - game.next().title().seer(); - game.mark(game.character_by_player_id(werewolf).character_id()); - game.r#continue().seer(); - game.r#continue().sleep(); - - game.next().title().arcanist(); - game.mark(game.character_by_player_id(seer).character_id()); - game.mark(game.character_by_player_id(werewolf).character_id()); - game.r#continue().role_blocked(); - game.r#continue().sleep(); - - game.next().title().adjudicator(); - game.mark(game.character_by_player_id(werewolf).character_id()); - game.r#continue().adjudicator(); - game.r#continue().sleep(); - - game.next().title().power_seer(); - game.mark(game.character_by_player_id(werewolf).character_id()); - game.r#continue().power_seer(); - game.r#continue().sleep(); - - game.next_expect_day(); - game.mark_for_execution(game.character_by_player_id(dire_wolf).character_id()); - game.mark_for_execution(game.character_by_player_id(alpha_wolf).character_id()); - - game.execute().title().guardian(); - let protect = game.living_villager(); - game.mark(protect.character_id()); - game.r#continue().sleep(); - - game.next().title().vindicator(); - game.mark_villager(); - game.r#continue().sleep(); - - game.next().title().wolf_pack_kill(); - game.mark(protect.character_id()); - game.r#continue().r#continue(); - - game.next().title().shapeshifter(); - game.response(ActionResponse::Shapeshift) - .shapeshift_failed(); - game.r#continue().sleep(); - - game.next().title().maple_wolf(); - game.mark( - game.living_villager_excl(protect.player_id()) - .character_id(), - ); - game.r#continue().sleep(); - - game.next().title().hunter(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.r#continue().sleep(); - - game.next().title().beholder_chooses(); - game.mark(game.character_by_player_id(power_seer).character_id()); - game.r#continue().sleep(); - - game.next().title().seer(); - game.mark(game.character_by_player_id(werewolf).character_id()); - game.r#continue().seer(); - game.r#continue().sleep(); - - game.next().title().arcanist(); - game.mark(game.character_by_player_id(seer).character_id()); - game.mark(game.character_by_player_id(werewolf).character_id()); - game.r#continue().arcanist(); - game.r#continue().sleep(); - - game.next().title().adjudicator(); - game.mark(game.character_by_player_id(seer).character_id()); - game.r#continue().adjudicator(); - game.r#continue().sleep(); - - game.next().title().power_seer(); - game.mark(game.living_villager().character_id()); - game.r#continue().power_seer(); - game.r#continue().sleep(); - - game.next().title().gravedigger(); - game.mark(game.character_by_player_id(dire_wolf).character_id()); - assert_eq!(game.r#continue().gravedigger(), Some(RoleTitle::DireWolf)); - game.r#continue().sleep(); - - game.next().title().mortician(); - game.mark(game.character_by_player_id(dire_wolf).character_id()); - assert_eq!(game.r#continue().mortician(), DiedToTitle::Execution); - game.r#continue().sleep(); - - game.next().title().empath(); - game.mark(game.living_villager().character_id()); - assert!(!game.r#continue().empath()); - game.r#continue().sleep(); - - game.next().title().masons_leader_recruit(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.r#continue().r#continue(); - - game.next().title().masons_wake(); - game.r#continue().sleep(); - - game.next().title().insomniac(); - game.r#continue().insomniac(); - game.r#continue().sleep(); - - game.next_expect_day(); - - assert_eq!( - game.character_by_player_id(protect.player_id()).died_to(), - None - ); - - game.mark_for_execution( - game.living_villager_excl(protect.player_id()) - .character_id(), - ); - game.execute().title().guardian(); - game.mark(protect.character_id()); - game.r#continue().sleep(); - - game.next().title().vindicator(); - game.mark( - game.living_villager_excl(protect.player_id()) - .character_id(), - ); - game.r#continue().sleep(); - - game.next().title().wolf_pack_kill(); - game.mark(protect.character_id()); - game.r#continue().r#continue(); - - game.next().title().shapeshifter(); - game.r#continue().sleep(); - - game.next().title().maple_wolf(); - game.r#continue().sleep(); - - game.next().title().hunter(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.r#continue().sleep(); - - game.next().title().beholder_chooses(); - game.mark(game.character_by_player_id(power_seer).character_id()); - game.r#continue().sleep(); - - game.next().title().seer(); - game.mark(game.character_by_player_id(werewolf).character_id()); - game.r#continue().seer(); - game.r#continue().sleep(); - - game.next().title().arcanist(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.mark(game.character_by_player_id(werewolf).character_id()); - game.r#continue().arcanist(); - game.r#continue().sleep(); - - game.next().title().adjudicator(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.r#continue().adjudicator(); - game.r#continue().sleep(); - - game.next().title().power_seer(); - game.mark(game.living_villager().character_id()); - game.r#continue().power_seer(); - game.r#continue().sleep(); - - game.next().title().gravedigger(); - game.mark(game.character_by_player_id(dire_wolf).character_id()); - assert_eq!(game.r#continue().gravedigger(), Some(RoleTitle::DireWolf)); - game.r#continue().sleep(); - - game.next().title().mortician(); - game.mark(game.character_by_player_id(dire_wolf).character_id()); - assert_eq!(game.r#continue().mortician(), DiedToTitle::Execution); - game.r#continue().sleep(); - - game.next().title().empath(); - game.mark(game.character_by_player_id(scapegoat).character_id()); - assert!(game.r#continue().empath()); - game.r#continue().sleep(); - - game.next().title().masons_leader_recruit(); - game.mark(game.character_by_player_id(scapegoat).character_id()); - game.r#continue().r#continue(); - - game.next().title().masons_wake(); - game.r#continue().sleep(); - - game.next().title().insomniac(); - game.r#continue().insomniac(); - game.r#continue().sleep(); - - game.next_expect_day(); - game.mark_for_execution( - game.living_villager_excl(protect.player_id()) - .character_id(), - ); - - game.execute().title().vindicator(); - game.mark(game.character_by_player_id(shapeshifter).character_id()); - game.r#continue().sleep(); - - game.next().title().wolf_pack_kill(); - game.mark(game.character_by_player_id(empath).character_id()); - game.r#continue().r#continue(); - - game.next().title().shapeshifter(); - game.process(HostGameMessage::Night(HostNightMessage::ActionResponse( - ActionResponse::Shapeshift, - ))) - .expect("shapeshift"); - // game.r#continue().r#continue(); - - assert_eq!( - game.next(), - ActionPrompt::RoleChange { - character_id: game.character_by_player_id(empath).identity(), - new_role: RoleTitle::Werewolf - } - ); - game.r#continue().sleep(); - - game.next().title().maple_wolf(); - game.r#continue().sleep(); - - game.next().title().hunter(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.r#continue().sleep(); - - game.next().title().beholder_chooses(); - game.mark(game.character_by_player_id(gravedigger).character_id()); - game.r#continue().sleep(); - - game.next().title().seer(); - game.mark(game.character_by_player_id(shapeshifter).character_id()); - game.r#continue().seer(); - game.r#continue().sleep(); - - game.next().title().arcanist(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.mark(game.character_by_player_id(shapeshifter).character_id()); - game.r#continue().arcanist(); - game.r#continue().sleep(); - - game.next().title().adjudicator(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.r#continue().adjudicator(); - game.r#continue().sleep(); - - game.next().title().power_seer(); - game.mark(game.living_villager().character_id()); - game.r#continue().power_seer(); - game.r#continue().sleep(); - - game.next().title().gravedigger(); - game.mark(game.character_by_player_id(guardian).character_id()); - assert_eq!(game.r#continue().gravedigger(), Some(RoleTitle::Guardian)); - game.r#continue().sleep(); - - game.next().title().mortician(); - game.mark(game.character_by_player_id(guardian).character_id()); - assert_eq!(game.r#continue().mortician(), DiedToTitle::Wolfpack); - game.r#continue().sleep(); - - game.next().title().masons_leader_recruit(); - game.mark(game.character_by_player_id(shapeshifter).character_id()); - game.r#continue().sleep(); - - game.next().title().masons_wake(); - game.r#continue().sleep(); - - game.next().title().insomniac(); - game.r#continue().insomniac(); - game.r#continue().sleep(); - - game.next_expect_day(); - game.mark_for_execution(game.character_by_player_id(vindicator).character_id()); - game.execute().title().wolf_pack_kill(); - game.mark(game.character_by_player_id(mortician).character_id()); - game.r#continue().sleep(); - - game.next().title().maple_wolf(); - game.mark(game.character_by_player_id(hunter).character_id()); - game.r#continue().sleep(); - - game.next().title().hunter(); - game.mark(game.character_by_player_id(empath).character_id()); - game.r#continue().sleep(); - - game.next().title().beholder_chooses(); - game.mark(game.character_by_player_id(mortician).character_id()); - game.r#continue().sleep(); - - game.next().title().seer(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.r#continue().seer(); - game.r#continue().sleep(); - - game.next().title().arcanist(); - game.mark(game.character_by_player_id(insomniac).character_id()); - game.mark(game.character_by_player_id(empath).character_id()); - game.r#continue().arcanist(); - game.r#continue().sleep(); - - game.next().title().adjudicator(); - game.mark(game.character_by_player_id(empath).character_id()); - game.r#continue().adjudicator(); - game.r#continue().sleep(); - - game.next().title().power_seer(); - game.mark(game.character_by_player_id(empath).character_id()); - game.r#continue().power_seer(); - game.r#continue().sleep(); - - game.next().title().gravedigger(); - game.mark(game.character_by_player_id(shapeshifter).character_id()); - assert_eq!(game.r#continue().gravedigger(), None); - game.r#continue().sleep(); - - game.next().title().mortician(); - game.mark(game.character_by_player_id(werewolf).character_id()); - assert_eq!( - game.r#continue().mortician(), - DiedToTitle::GuardianProtecting - ); - game.r#continue().sleep(); - - game.next().title().masons_wake(); - game.r#continue().sleep(); - - game.next().title().insomniac(); - game.r#continue().insomniac(); - game.r#continue().sleep(); - - game.next().title().beholder_wakes(); - assert_eq!( - game.r#continue().mortician(), - DiedToTitle::GuardianProtecting - ); - game.r#continue().sleep(); - - game.next_expect_game_over(); - game.story() -} - -pub trait SettingsExt { - fn add_role(&mut self, role: SetupRole, modify: impl FnOnce(&mut SetupSlot)) -> SetupSlot; - fn add_and_assign(&mut self, role: SetupRole, assignee: PlayerId) -> SetupSlot; -} - -impl SettingsExt for GameSettings { - fn add_role(&mut self, role: SetupRole, modify: impl FnOnce(&mut SetupSlot)) -> SetupSlot { - let slot_id = self.new_slot(role.clone().into()); - let mut slot = self.get_slot_by_id(slot_id).unwrap().clone(); - slot.role = role; - modify(&mut slot); - self.update_slot(slot.clone()); - slot - } - - fn add_and_assign(&mut self, role: SetupRole, assignee: PlayerId) -> SetupSlot { - self.add_role(role, |slot| slot.assign_to = Some(assignee)) - } -} - -#[allow(unused)] -pub trait ActionPromptTitleExt { - fn wolf_pack_kill(&self); - fn cover_of_darkness(&self); - fn wolves_intro(&self); - fn role_change(&self); - fn seer(&self); - fn protector(&self); - fn arcanist(&self); - fn gravedigger(&self); - fn hunter(&self); - fn militia(&self); - fn maple_wolf(&self); - fn guardian(&self); - fn shapeshifter(&self); - fn alphawolf(&self); - fn direwolf(&self); - fn masons_wake(&self); - fn masons_leader_recruit(&self); - fn beholder_chooses(&self); - fn beholder_wakes(&self); - fn vindicator(&self); - fn pyremaster(&self); - fn empath(&self); - fn adjudicator(&self); - fn lone_wolf(&self); - fn insomniac(&self); - fn power_seer(&self); - fn mortician(&self); - fn elder_reveal(&self); - fn bloodletter(&self); -} - -impl ActionPromptTitleExt for ActionPromptTitle { - fn bloodletter(&self) { - assert_eq!(*self, ActionPromptTitle::Bloodletter); - } - fn elder_reveal(&self) { - assert_eq!(*self, ActionPromptTitle::ElderReveal); - } - fn mortician(&self) { - assert_eq!(*self, ActionPromptTitle::Mortician); - } - fn cover_of_darkness(&self) { - assert_eq!(*self, ActionPromptTitle::CoverOfDarkness); - } - fn wolves_intro(&self) { - assert_eq!(*self, ActionPromptTitle::WolvesIntro); - } - fn role_change(&self) { - assert_eq!(*self, ActionPromptTitle::RoleChange); - } - fn seer(&self) { - assert_eq!(*self, ActionPromptTitle::Seer); - } - fn protector(&self) { - assert_eq!(*self, ActionPromptTitle::Protector); - } - fn arcanist(&self) { - assert_eq!(*self, ActionPromptTitle::Arcanist); - } - fn gravedigger(&self) { - assert_eq!(*self, ActionPromptTitle::Gravedigger); - } - fn hunter(&self) { - assert_eq!(*self, ActionPromptTitle::Hunter); - } - fn militia(&self) { - assert_eq!(*self, ActionPromptTitle::Militia); - } - fn maple_wolf(&self) { - assert_eq!(*self, ActionPromptTitle::MapleWolf); - } - fn guardian(&self) { - assert_eq!(*self, ActionPromptTitle::Guardian); - } - fn shapeshifter(&self) { - assert_eq!(*self, ActionPromptTitle::Shapeshifter); - } - fn alphawolf(&self) { - assert_eq!(*self, ActionPromptTitle::AlphaWolf); - } - fn direwolf(&self) { - assert_eq!(*self, ActionPromptTitle::DireWolf); - } - fn wolf_pack_kill(&self) { - assert_eq!(*self, ActionPromptTitle::WolfPackKill); - } - fn masons_wake(&self) { - assert_eq!(*self, ActionPromptTitle::MasonsWake) - } - fn masons_leader_recruit(&self) { - assert_eq!(*self, ActionPromptTitle::MasonLeaderRecruit) - } - fn beholder_chooses(&self) { - assert_eq!(*self, ActionPromptTitle::BeholderChooses) - } - fn beholder_wakes(&self) { - assert_eq!(*self, ActionPromptTitle::BeholderWakes) - } - fn vindicator(&self) { - assert_eq!(*self, ActionPromptTitle::Vindicator) - } - fn pyremaster(&self) { - assert_eq!(*self, ActionPromptTitle::PyreMaster) - } - fn adjudicator(&self) { - assert_eq!(*self, ActionPromptTitle::Adjudicator) - } - fn power_seer(&self) { - assert_eq!(*self, ActionPromptTitle::PowerSeer) - } - fn empath(&self) { - assert_eq!(*self, ActionPromptTitle::Empath) - } - fn lone_wolf(&self) { - assert_eq!(*self, ActionPromptTitle::LoneWolfKill) - } - fn insomniac(&self) { - assert_eq!(*self, ActionPromptTitle::Insomniac) - } -} - -pub trait ActionResultExt { - fn sleep(&self); - fn r#continue(&self); - fn seer(&self) -> Alignment; - fn insomniac(&self) -> Visits; - fn arcanist(&self) -> AlignmentEq; - fn role_blocked(&self); - fn gravedigger(&self) -> Option<RoleTitle>; - fn power_seer(&self) -> Powerful; - fn adjudicator(&self) -> Killer; - fn mortician(&self) -> DiedToTitle; - fn empath(&self) -> bool; - fn drunk(&self); - fn shapeshift_failed(&self); -} - -impl ActionResultExt for ActionResult { - fn shapeshift_failed(&self) { - assert_eq!(*self, Self::ShiftFailed) - } - fn drunk(&self) { - assert_eq!(*self, Self::Drunk) - } - fn empath(&self) -> bool { - match self { - Self::Empath { scapegoat, .. } => *scapegoat, - resp => panic!("expected empath, got {resp:?}"), - } - } - fn mortician(&self) -> DiedToTitle { - match self { - Self::Mortician(_, role) => *role, - resp => panic!("expected mortician, got {resp:?}"), - } - } - fn gravedigger(&self) -> Option<RoleTitle> { - match self { - Self::GraveDigger(_, role) => *role, - resp => panic!("expected gravedigger, got {resp:?}"), - } - } - fn role_blocked(&self) { - assert_eq!(*self, ActionResult::RoleBlocked) - } - fn adjudicator(&self) -> Killer { - match self { - Self::Adjudicator { killer, .. } => *killer, - resp => panic!("expected adjudicator, got {resp:?}"), - } - } - fn power_seer(&self) -> Powerful { - match self { - Self::PowerSeer { powerful, .. } => *powerful, - resp => panic!("expected power seer, got {resp:?}"), - } - } - fn sleep(&self) { - assert_eq!(*self, ActionResult::GoBackToSleep) - } - - fn r#continue(&self) { - assert_eq!(*self, ActionResult::Continue) - } - - fn seer(&self) -> Alignment { - match self { - ActionResult::Seer(_, a) => a.clone(), - _ => panic!("expected a seer result"), - } - } - - fn arcanist(&self) -> AlignmentEq { - match self { - ActionResult::Arcanist(_, same) => same.clone(), - resp => panic!("expected an arcanist result, got {resp:?}"), - } - } - - fn insomniac(&self) -> Visits { - match self { - ActionResult::Insomniac(v) => v.clone(), - resp => panic!("expected an insomniac result, got {resp:?}"), - } - } -} -#[allow(unused)] -pub trait AlignmentExt { - fn village(&self); - fn wolves(&self); -} - -impl AlignmentExt for Alignment { - fn village(&self) { - assert_eq!(*self, Alignment::Village) - } - - fn wolves(&self) { - assert_eq!(*self, Alignment::Wolves) - } -} - -#[allow(unused)] -pub trait ServerToHostMessageExt { - fn prompt(self) -> ActionPrompt; - fn result(self) -> ActionResult; - fn daytime(self) -> (Box<[CharacterState]>, Box<[CharacterId]>, NonZeroU8); -} - -impl ServerToHostMessageExt for ServerToHostMessage { - fn daytime(self) -> (Box<[CharacterState]>, Box<[CharacterId]>, NonZeroU8) { - match self { - Self::Daytime { - characters, - marked, - day, - .. - } => (characters, marked, day), - resp => panic!("expected daytime, got {resp:?}"), - } - } - - fn prompt(self) -> ActionPrompt { - match self { - Self::ActionPrompt(prompt, _) => prompt, - Self::Daytime { .. } => panic!("{}", "[got daytime]"), - msg => panic!("expected server message <<{msg:?}>> to be an ActionPrompt"), - } - } - - fn result(self) -> ActionResult { - match self { - Self::ActionResult(_, res) => res, - msg => panic!("expected server message <<{msg:?}>> to be an ActionResult"), - } - } -} - -pub trait GameExt { - fn villager_character_ids(&self) -> Box<[CharacterId]>; - fn character_by_player_id(&self, player_id: PlayerId) -> Character; - fn next(&mut self) -> ActionPrompt; - fn r#continue(&mut self) -> ActionResult; - fn next_expect_day(&mut self) -> (Box<[CharacterState]>, Box<[CharacterId]>, NonZeroU8); - fn mark(&mut self, mark: CharacterId) -> ActionPrompt; - fn mark_and_check(&mut self, mark: CharacterId); - fn response(&mut self, resp: ActionResponse) -> ActionResult; - fn execute(&mut self) -> ActionPrompt; - fn mark_for_execution( - &mut self, - target: CharacterId, - ) -> (Box<[CharacterState]>, Box<[CharacterId]>, NonZeroU8); - fn living_villager_excl(&self, excl: PlayerId) -> Character; - fn living_villager(&self) -> Character; - #[allow(unused)] - fn get_state(&mut self) -> ServerToHostMessage; - fn next_expect_game_over(&mut self) -> GameOver; - fn prev(&mut self) -> ServerToHostMessage; - fn mark_villager(&mut self) -> ActionPrompt; -} - -impl GameExt for Game { - fn prev(&mut self) -> ServerToHostMessage { - self.process(HostGameMessage::PreviousState).unwrap() - } - fn next_expect_game_over(&mut self) -> GameOver { - match self - .process(HostGameMessage::Night(HostNightMessage::Next)) - .unwrap() - { - ServerToHostMessage::GameOver(outcome) => outcome, - resp => panic!("expected game to be over, got: {resp:?}"), - } - } - fn get_state(&mut self) -> ServerToHostMessage { - self.process(HostGameMessage::GetState).unwrap() - } - fn living_villager(&self) -> Character { - self.village() - .characters() - .into_iter() - .find(|c| c.alive() && matches!(c.role_title(), RoleTitle::Villager)) - .unwrap() - } - - fn living_villager_excl(&self, excl: PlayerId) -> Character { - self.village() - .characters() - .into_iter() - .find(|c| { - c.alive() && matches!(c.role_title(), RoleTitle::Villager) && c.player_id() != excl - }) - .unwrap() - } - - fn villager_character_ids(&self) -> Box<[CharacterId]> { - self.village() - .characters() - .into_iter() - .filter_map(|c| { - (c.alive() && matches!(c.role_title(), RoleTitle::Villager)) - .then_some(c.character_id()) - }) - .collect() - } - - fn character_by_player_id(&self, player_id: PlayerId) -> Character { - self.village() - .character_by_player_id(player_id) - .unwrap() - .clone() - } - - fn r#continue(&mut self) -> ActionResult { - self.process(HostGameMessage::Night(HostNightMessage::ActionResponse( - ActionResponse::Continue, - ))) - .unwrap() - .result() - } - - fn mark(&mut self, mark: CharacterId) -> ActionPrompt { - self.process(HostGameMessage::Night(HostNightMessage::ActionResponse( - ActionResponse::MarkTarget(mark), - ))) - .unwrap() - .prompt() - } - - fn mark_villager(&mut self) -> ActionPrompt { - self.mark(self.living_villager().character_id()) - } - - fn mark_and_check(&mut self, mark: CharacterId) { - let prompt = self.mark(mark); - match prompt { - ActionPrompt::BeholderWakes { .. } - | ActionPrompt::DamnedIntro { .. } - | ActionPrompt::Insomniac { .. } - | ActionPrompt::MasonsWake { .. } - | ActionPrompt::ElderReveal { .. } - | ActionPrompt::CoverOfDarkness - | ActionPrompt::WolvesIntro { .. } - | ActionPrompt::RoleChange { .. } - | ActionPrompt::Shapeshifter { .. } => panic!("expected a prompt with a mark"), - ActionPrompt::Arcanist { .. } => panic!("wrong call for arcanist"), - - ActionPrompt::Bloodletter { - marked: Some(marked), - .. - } - | ActionPrompt::LoneWolfKill { - marked: Some(marked), - .. - } - | ActionPrompt::Seer { - marked: Some(marked), - .. - } - | ActionPrompt::Adjudicator { - marked: Some(marked), - .. - } - | ActionPrompt::PowerSeer { - marked: Some(marked), - .. - } - | ActionPrompt::Mortician { - marked: Some(marked), - .. - } - | ActionPrompt::BeholderChooses { - marked: Some(marked), - .. - } - | ActionPrompt::MasonLeaderRecruit { - marked: Some(marked), - .. - } - | ActionPrompt::Empath { - marked: Some(marked), - .. - } - | ActionPrompt::Vindicator { - marked: Some(marked), - .. - } - | ActionPrompt::PyreMaster { - marked: Some(marked), - .. - } - | ActionPrompt::Protector { - marked: Some(marked), - .. - } - | ActionPrompt::Gravedigger { - marked: Some(marked), - .. - } - | ActionPrompt::Hunter { - marked: Some(marked), - .. - } - | ActionPrompt::Militia { - marked: Some(marked), - .. - } - | ActionPrompt::MapleWolf { - marked: Some(marked), - .. - } - | ActionPrompt::Guardian { - marked: Some(marked), - .. - } - | ActionPrompt::WolfPackKill { - marked: Some(marked), - .. - } - | ActionPrompt::AlphaWolf { - marked: Some(marked), - .. - } - | ActionPrompt::DireWolf { - marked: Some(marked), - .. - } => assert_eq!(marked, mark, "marked character"), - ActionPrompt::Bloodletter { marked: None, .. } - | ActionPrompt::Seer { marked: None, .. } - | ActionPrompt::Adjudicator { marked: None, .. } - | ActionPrompt::PowerSeer { marked: None, .. } - | ActionPrompt::Mortician { marked: None, .. } - | ActionPrompt::BeholderChooses { marked: None, .. } - | ActionPrompt::MasonLeaderRecruit { marked: None, .. } - | ActionPrompt::Empath { marked: None, .. } - | ActionPrompt::Vindicator { marked: None, .. } - | ActionPrompt::PyreMaster { marked: None, .. } - | ActionPrompt::Protector { marked: None, .. } - | ActionPrompt::Gravedigger { marked: None, .. } - | ActionPrompt::Hunter { marked: None, .. } - | ActionPrompt::Militia { marked: None, .. } - | ActionPrompt::MapleWolf { marked: None, .. } - | ActionPrompt::Guardian { marked: None, .. } - | ActionPrompt::WolfPackKill { marked: None, .. } - | ActionPrompt::AlphaWolf { marked: None, .. } - | ActionPrompt::DireWolf { marked: None, .. } - | ActionPrompt::LoneWolfKill { marked: None, .. } => panic!("no mark"), - } - } - - fn next(&mut self) -> ActionPrompt { - self.process(HostGameMessage::Night(HostNightMessage::Next)) - .unwrap() - .prompt() - } - - fn next_expect_day(&mut self) -> (Box<[CharacterState]>, Box<[CharacterId]>, NonZeroU8) { - match self - .process(HostGameMessage::Night(HostNightMessage::Next)) - .unwrap() - { - ServerToHostMessage::Daytime { - characters, - marked, - day, - .. - } => (characters, marked, day), - res => panic!("unexpected response to next_expect_day: {res:?}"), - } - } - - fn response(&mut self, resp: ActionResponse) -> ActionResult { - self.process(HostGameMessage::Night(HostNightMessage::ActionResponse( - resp, - ))) - .unwrap() - .result() - } - - fn mark_for_execution( - &mut self, - target: CharacterId, - ) -> (Box<[CharacterState]>, Box<[CharacterId]>, NonZeroU8) { - match self - .process(HostGameMessage::Day(HostDayMessage::MarkForExecution( - target, - ))) - .unwrap() - { - ServerToHostMessage::Daytime { - characters, - marked, - day, - .. - } => (characters, marked, day), - res => panic!("unexpected response to mark_for_execution: {res:?}"), - } - } - - fn execute(&mut self) -> ActionPrompt { - assert_eq!( - self.process(HostGameMessage::Day(HostDayMessage::Execute)) - .unwrap() - .prompt(), - ActionPrompt::CoverOfDarkness - ); - self.r#continue().r#continue(); - self.next() - } -} - -pub fn gen_players(range: Range<u8>) -> Box<[Identification]> { - range - .into_iter() - .map(|num| Identification { - player_id: PlayerId::from_u128(num as _), - public: PublicIdentity { - name: format!("player {num}"), - pronouns: None, - number: NonZeroU8::new(num), - }, - }) - .collect() -} diff --git a/werewolves/src/components/story/story.rs b/werewolves/src/components/story/story.rs deleted file mode 100644 index abaa15d..0000000 --- a/werewolves/src/components/story/story.rs +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::ops::Not; -use std::{collections::HashMap, rc::Rc}; - -use convert_case::{Case, Casing}; -use werewolves_proto::{ - aura::AuraTitle, - character::{Character, CharacterId}, - game::{ - GameTime, SetupRole, - night::changes::NightChange, - story::{ - DayDetail, GameActions, GameStory, NightChoice, StoryActionPrompt, StoryActionResult, - }, - }, - role::Alignment, -}; -use yew::prelude::*; - -use crate::components::{ - AuraSpan, CharacterCard, Icon, IconSource, IconType, PartialAssociatedIcon, - attributes::{ - AlignmentComparisonSpan, AlignmentSpan, CategorySpan, DiedToSpan, KillerSpan, PowerfulSpan, - }, - story::{CharacterStory, CharacterStoryButton, StoryError}, -}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct StoryProps { - pub story: GameStory, -} - -#[function_component] -pub fn Story(StoryProps { story }: &StoryProps) -> Html { - let village = match story.final_village() { - Ok(village) => village, - Err(err) => { - return html! { - <StoryError error={err.to_string()}/> - }; - } - }; - let actions_by_character = village - .characters() - .into_iter() - .map(|c| { - let actions = story - .changes - .iter() - .filter_map(|(time, act)| { - let cid = c.character_id(); - match act { - GameActions::DayDetails(_) => None, - GameActions::NightDetails(night) => Some(( - *time, - night - .changes - .iter() - .filter(|nc| { - nc.target().map(|target| target == cid).unwrap_or_default() - }) - .cloned() - .collect::<Box<[_]>>(), - night - .choices - .iter() - .filter(|nc| { - nc.prompt - .character_id() - .map(|c| c == cid) - .unwrap_or_default() - }) - .cloned() - .collect::<Box<[_]>>(), - )), - } - }) - .collect::<Box<[_]>>(); - - (c, actions) - }) - .collect::<Box<[_]>>(); - - let selected_char = use_state::< - Option<( - Character, - Box<[(GameTime, Box<[NightChange]>, Box<[NightChoice]>)]>, - )>, - _, - >(|| actions_by_character.first().cloned()); - let on_char_pick = { - let selected_char = selected_char.setter(); - Callback::from(move |(char, actions)| selected_char.set(Some((char, actions)))) - }; - let chars = actions_by_character - .into_iter() - .map(|(char, actions)| { - html! { - <CharacterStoryButton character={char} choices_by_time={actions} on_click={on_char_pick.clone()} /> - } - }) - .collect::<Html>(); - - let all_characters = village.characters().into_iter().collect::<Rc<_>>(); - let actions = selected_char.as_ref().map(|(char, actions)| { - let class = Into::<SetupRole>::into(char.role_title()) - .category() - .class(); - - html! { - <> - <CharacterCard char={char.clone()} dead={char.died_to().is_some()} faint=true/> - <div class={classes!("character-details", class, "faint")}> - <CharacterStory - character={char.clone()} - actions={actions.clone()} - all_characters={all_characters} - /> - </div> - </> - } - }); - - html! { - <div class="story"> - <div class="story-characters"> - {chars} - </div> - <div class="actions"> - {actions} - </div> - </div> - } -} diff --git a/werewolves/src/components/toggle.rs b/werewolves/src/components/toggle.rs deleted file mode 100644 index 2673edd..0000000 --- a/werewolves/src/components/toggle.rs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -// use core::{ -// fmt::{Debug, Display}, -// ops::Not, -// }; - -// use yew::prelude::*; - -// use crate::components::Button; - -// #[derive(Debug, Clone, PartialEq, Properties)] -// pub struct ToggleIterProps<T, I> -// where -// T: Debug + PartialEq + Clone + Display + 'static, -// I: Iterator<Item = T> + PartialEq + Clone + 'static, -// { -// pub iter: I, -// pub on_update: Callback<T>, -// #[prop_or_default] -// pub disabled_reason: Option<String>, -// #[prop_or_default] -// pub classes: yew::Classes, -// } - -// #[function_component] -// pub fn ToggleIter<T, I>( -// ToggleIterProps { -// iter, -// on_update, -// disabled_reason, -// classes, -// }: &ToggleIterProps<T, I>, -// ) -> Html -// where -// T: Debug + PartialEq + Clone + Display + 'static, -// I: Iterator<Item = T> + PartialEq + Clone + 'static, -// { -// let mut iter = iter.clone(); - -// let value = use_state(|| iter.next().unwrap()); -// let on_click_value = value.clone(); -// let on_click = Callback::from(move |_| on_click_value.set(on_click_value.not())); -// let children = if **value { -// on_true.clone() -// } else { -// on_false.clone() -// }; -// html! { -// <Button -// on_click={on_click} -// disabled_reason={disabled_reason.clone()} -// classes={classes} -// > -// {children} -// </Button> -// } -// } diff --git a/werewolves/src/components/victory.rs b/werewolves/src/components/victory.rs deleted file mode 100644 index 89584ce..0000000 --- a/werewolves/src/components/victory.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::game::GameOver; -use yew::prelude::*; - -use crate::components::{Button, Icon, IconSource, IconType}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct VictoryProps { - pub outcome: GameOver, - #[prop_or_default] - pub cont: Option<Callback<()>>, -} - -#[function_component] -pub fn Victory(VictoryProps { outcome, cont }: &VictoryProps) -> Html { - let cont_btn = cont.clone().map(|cont| { - html! { - <Button on_click={cont}>{"continue"}</Button> - } - }); - match outcome { - GameOver::WolvesWin => html! { - <div class="end-screen"> - <div class="victory wolves faint"> - <Icon source={IconSource::Wolves} icon_type={IconType::Informational}/> - <h1>{"Wolves Win"}</h1> - <Icon source={IconSource::Wolves} icon_type={IconType::Informational}/> - </div> - {cont_btn} - </div> - }, - GameOver::VillageWins => html! { - <div class="end-screen"> - <div class="victory village faint"> - <Icon source={IconSource::Village} icon_type={IconType::Informational}/> - <h1>{"Village Wins"}</h1> - <Icon source={IconSource::Village} icon_type={IconType::Informational}/> - </div> - {cont_btn} - </div> - }, - } -} diff --git a/werewolves/src/lib.rs b/werewolves/src/lib.rs new file mode 100644 index 0000000..3e01d4a --- /dev/null +++ b/werewolves/src/lib.rs @@ -0,0 +1,118 @@ +#![allow(clippy::expect_fun_call)] + +use core::{net::SocketAddr, str::FromStr}; +pub mod app; +pub mod auth; +#[cfg(feature = "ssr")] +pub mod server; +pub mod state; + +pub fn server_host() -> String { + const DEFAULT: &str = "192.168.1.3:3000"; + option_env!("SERVER_HOST") + .map(|u| u.trim().strip_suffix("/").unwrap_or(u.trim()).to_string()) + .unwrap_or(DEFAULT.to_string()) +} + +pub fn server_ws_url() -> String { + let host = server_host(); + if SocketAddr::from_str(&host).is_ok() { + format!("ws://{host}") + } else { + format!("wss://{host}") + } +} + +#[cfg(feature = "hydrate")] +#[wasm_bindgen::prelude::wasm_bindgen] +pub fn hydrate() { + use crate::app::*; + wasm_logger::init(wasm_logger::Config::new(log::Level::Trace)); + console_error_panic_hook::set_once(); + leptos::mount::hydrate_body(App); +} + +pub trait LogError { + fn log(self, loc: CodePath, level: log::Level); + fn log_warn(self, loc: CodePath); + fn log_err(self, loc: CodePath); + fn log_debug(self, loc: CodePath); +} + +pub struct CodePath { + pub module_path: &'static str, + pub loc: &'static std::panic::Location<'static>, +} + +#[macro_export] +macro_rules! loc { + () => { + (crate::CodePath { + module_path: log::__private_api::module_path!(), + loc: log::__private_api::loc(), + }) + }; +} + +impl<T, E> LogError for Result<T, E> +where + E: core::fmt::Display, +{ + fn log(self, loc: CodePath, lvl: log::Level) { + if let Err(err) = self { + if lvl <= log::STATIC_MAX_LEVEL && lvl <= log::max_level() { + log::__private_api::log( + log::__log_logger!(__log_global_logger), + log::__private_api::format_args!("{err}"), + lvl, + &(loc.module_path, loc.module_path, loc.loc), + (), + ); + } + } + } + + fn log_warn(self, loc: CodePath) { + if self.is_err() { + self.log(loc, log::Level::Warn); + } + } + + fn log_err(self, loc: CodePath) { + if self.is_err() { + self.log(loc, log::Level::Error); + } + } + + fn log_debug(self, loc: CodePath) { + if self.is_err() { + self.log(loc, log::Level::Debug); + } + } +} +pub trait ConsoleLogError { + fn console_log_warn(self); + fn console_log_err(self); + fn console_log_debug(self); +} + +#[cfg(feature = "hydrate")] +impl<T> ConsoleLogError for Result<T, wasm_bindgen::JsValue> { + fn console_log_warn(self) { + if let Err(err) = self { + gloo::console::warn!(err); + } + } + + fn console_log_err(self) { + if let Err(err) = self { + gloo::console::error!(err); + } + } + + fn console_log_debug(self) { + if let Err(err) = self { + gloo::console::debug!(err); + } + } +} diff --git a/werewolves/src/main.rs b/werewolves/src/main.rs index 2a15623..dc27233 100644 --- a/werewolves/src/main.rs +++ b/werewolves/src/main.rs @@ -1,110 +1,236 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -mod assets; -mod class; -mod clients; -mod scroll; -mod storage; -mod test_util; -mod components { - werewolves_macros::include_path!("werewolves/src/components"); - pub mod modal { - werewolves_macros::include_path!("werewolves/src/components/modal"); - } - pub mod attributes { - werewolves_macros::include_path!("werewolves/src/components/attributes"); - } - pub mod client { - werewolves_macros::include_path!("werewolves/src/components/client"); - } - pub mod host { - werewolves_macros::include_path!("werewolves/src/components/host"); - } - pub mod action { - werewolves_macros::include_path!("werewolves/src/components/action"); - } - pub mod settings { - werewolves_macros::include_path!("werewolves/src/components/settings"); - } - pub mod story { - werewolves_macros::include_path!("werewolves/src/components/story"); - } - pub mod chat { - werewolves_macros::include_path!("werewolves/src/components/chat"); - } -} -mod pages { - werewolves_macros::include_path!("werewolves/src/pages"); -} -mod callback; +#![allow(clippy::expect_fun_call)] +#[cfg(feature = "ssr")] +mod ssr { + pub const DEFAULT_MAX_PG_CONNECTIONS: u32 = 30; + pub const DEFAULT_PG_CONN_STRING: &str = "postgres:///townsville?host=/var/run/postgresql"; -use pages::{ErrorComponent, WerewolfError}; -use web_sys::Url; -use yew::{context::ContextProviderProps, prelude::*}; + use core::pin::Pin; -const BUILD_ID: &str = werewolves_macros::build_id!(); -const BUILD_ID_LONG: &str = werewolves_macros::build_id_long!(); -const BUILD_DIRTY: bool = werewolves_macros::build_dirty!(); -const BUILD_TIME: &str = werewolves_macros::build_time!(); -const TITLE: &str = match option_env!("LOCAL") { - Some(_) => "LOCAL werewolves", - None => "werewolves", -}; + use api::state::AppState; + use axum::{ + body::Body, + extract::{FromRef, State}, + http::{HeaderMap, HeaderValue, Request, StatusCode, Uri, header}, + response::{IntoResponse, Response}, + }; + use futures::StreamExt; + use leptos::{ + IntoView, + config::LeptosOptions, + prelude::{Render, RenderHtml}, + server_fn::codec::IntoRes, + tachys::ssr::StreamBuilder, + }; + use leptos_axum::{LeptosRoutes, ResponseOptions}; -use crate::clients::{ - client::{Client2, ClientContext}, - host::{Host, HostEvent}, -}; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Trace)); - log::debug!("starting werewolves build {BUILD_ID}"); - let document = gloo::utils::document(); - document.set_title(crate::TITLE); - let url = document.document_uri().expect("get uri"); - let url_obj = Url::new(&url).unwrap(); - let path = url_obj.pathname(); - log::warn!("path: {path}"); - let app_element = document.query_selector("app").unwrap().unwrap(); - let error_element = document.query_selector("error").unwrap().unwrap(); - let ec = yew::Renderer::<ErrorComponent>::with_root(error_element).render(); - let cb_clone = ec.clone(); - let error_callback = - Callback::from(move |err: Option<WerewolfError>| cb_clone.send_message(err)); - - if path.starts_with("/host") { - let host = yew::Renderer::<Host>::with_root(app_element).render(); - if path.starts_with("/host/big") { - host.send_message(HostEvent::SetBigScreenState(true)); - } else { - host.send_message(HostEvent::SetErrorCallback(error_callback)); - } - } else if path.starts_with("/story") { - let story = yew::Renderer::<clients::StoryTest>::with_root(app_element).render(); - } else { - yew::Renderer::<ContextProvider<ClientContext>>::with_root_and_props( - app_element, - ContextProviderProps { - context: ClientContext { - error_cb: error_callback.clone(), - }, - children: html! { - <Client2 auto_join=false/> - }, + pub async fn server_fn_handler( + State(state): State<AppState>, + request: Request<Body>, + ) -> impl IntoResponse { + leptos_axum::handle_server_fns_with_context( + move || { + leptos::context::provide_context(state.clone()); }, + request, ) - .render(); + .await + } + + pub async fn handle_http_static( + uri: Uri, + state: State<AppState>, + req: Request<Body>, + ) -> Response { + pub type PinnedStream<T> = Pin<Box<dyn futures::Stream<Item = T> + Send>>; + use mime_sniffer::MimeTypeSniffer; + // const INDEX_FILE: &[u8] = &[]; //include_bytes!("../../werewolves/dist/index.html"); + let path = req.uri().path(); + + werewolves_macros::include_dist!(DIST_FILES, "target/site"); + + let file = if let Some(file) = DIST_FILES.iter().find_map(|(file_path, file)| { + if *file_path == path { + Some(*file) + } else { + None + } + }) { + file + } else { + leptos_meta::provide_meta_context(); + let opts = state.leptos_options.clone(); + return leptos_axum::handle_response_inner( + move || leptos::prelude::provide_context(opts.clone()), + { + let opts = state.leptos_options.clone(); + move || werewolves::app::shell(opts.clone()) + }, + req, + |app, chunks, _supports_ooo| { + Box::pin(async move { + let app = + // if cfg!(feature = "islands-router") { + // app.to_html_stream_in_order_branching() + // } else { + app.to_html_stream_in_order() + // } + ; + let app = app.collect::<String>().await; + let chunks = chunks(); + Box::pin(futures::stream::once(async move { app }).chain(chunks)) + as PinnedStream<String> + }) + }, + ) + .await; + // return ( + // [(header::CONTENT_TYPE, "text/html".to_string())], + // werewolves::app::shell(state.leptos_options.clone()) + // .to_html() + // .into_bytes(), + // ) + // .into_response(); + }; + + let mime = if path.ends_with(".js") { + "text/javascript".to_string() + } else if path.ends_with(".css") { + "text/css".to_string() + } else if path.ends_with(".wasm") { + "application/wasm".to_string() + } else if path.ends_with(".svg") { + "image/svg+xml".to_string() + } else { + file.sniff_mime_type() + .unwrap_or("application/octet-stream") + .to_string() + }; + + ([(header::CONTENT_TYPE, mime)], file).into_response() } } + +#[cfg(feature = "ssr")] +#[tokio::main] +async fn main() { + use api::{db::Database, state::AppState}; + use axum::ServiceExt; + use axum::routing::get; + use axum::{Router, routing::any}; + use core::net::SocketAddr; + use core::str::FromStr; + use leptos::logging::log; + use leptos::prelude::*; + use leptos_axum::{LeptosRoutes, generate_route_list}; + use sqlx::postgres::PgPoolOptions; + use std::io::Write; + use werewolves::app::*; + + use colored::Colorize; + pretty_env_logger::formatted_builder() + .parse_default_env() + .format(|f, record| { + let time = chrono::Local::now().time().to_string().dimmed(); + + match record.file() { + Some(file) => { + let file = format!( + "[{file}{}]", + record + .line() + .map(|l| format!(":{l}")) + .unwrap_or_else(String::new), + ) + .dimmed(); + let level = match record.level() { + log::Level::Error => "[err]".red().bold(), + log::Level::Warn => "[warn]".yellow().bold(), + log::Level::Info => "[info]".white().bold(), + log::Level::Debug => "[debug]".dimmed().bold(), + log::Level::Trace => "[trace]".dimmed(), + }; + let args = record.args(); + + let arrow = "➢".bold().magenta(); + writeln!(f, "{time} {file}\n{level} {arrow} {args}") + } + _ => writeln!(f, "{time} [{}] {}", record.level(), record.args()), + } + }) + .try_init() + .unwrap(); + let default_panic = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |info| { + default_panic(info); + std::process::exit(1); + })); + let conf = get_configuration(None).unwrap(); + let addr = conf.leptos_options.site_addr; + let leptos_options = conf.leptos_options; + // Generate the list of routes in your Leptos App + let routes = generate_route_list(App); + + let pg_pool: sqlx::Pool<sqlx::Postgres> = PgPoolOptions::new() + .max_connections( + std::env::var("MAX_DB_CONNECTIONS") + .ok() + .and_then(|val| u32::from_str(&val).ok()) + .unwrap_or(ssr::DEFAULT_MAX_PG_CONNECTIONS), + ) + .connect( + std::env::var("PG_CONN_STRING") + .unwrap_or_else(|_| String::from(ssr::DEFAULT_PG_CONN_STRING)) + .as_str(), + ) + .await + .expect("could not init db"); + let db = Database::new(pg_pool.clone()); + + db.migrate().await; + let state = AppState { db, leptos_options }; + + let app = Router::new() + .route( + "/api/games/{id}", + any(werewolves::server::game_connection::handler), + ) + .route("/api/games/{id}/qr", get(werewolves::server::qr::qr_code)) + .route( + "/api/{*fn_name}", + get(ssr::server_fn_handler).post(ssr::server_fn_handler), + ) + .leptos_routes(&state, routes, { + let state = state.clone(); + move || werewolves::app::shell(state.leptos_options.clone()) + }) + .fallback(ssr::handle_http_static) + .with_state(state); + + tokio::spawn(async move { + use core::time::Duration; + + const CLEANUP_PERIOD: Duration = Duration::from_mins(30); + loop { + tokio::time::sleep(CLEANUP_PERIOD).await; + werewolves::server::clear_abandoned_game_runners().await + } + }); + + // run our app with hyper + // `axum::Server` is a re-export of `hyper::Server` + log!("listening on {}", &addr); + let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); + axum::serve( + listener, + app.into_make_service_with_connect_info::<SocketAddr>(), + ) + .await + .unwrap(); +} + +#[cfg(not(feature = "ssr"))] +pub fn main() { + // no client-side main function + // unless we want this to work with e.g., Trunk for pure client-side testing + // see lib.rs for hydration function instead +} diff --git a/werewolves/src/pages/damned.rs b/werewolves/src/pages/damned.rs deleted file mode 100644 index c7cdb58..0000000 --- a/werewolves/src/pages/damned.rs +++ /dev/null @@ -1,31 +0,0 @@ -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn DamnedIntroPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="damned">{"DAMNED"}</h1> - <div class="information damned faint"> - <span class="yellow">{"YOU ARE DAMNED"}</span> - <Icon source={IconSource::Damned} icon_type={IconType::Informational}/> - </div> - </div> - } -} - -#[function_component] -pub fn DamnedIntroPage2() -> Html { - html! { - <div class="role-page"> - <h1 class="damned">{"DAMNED"}</h1> - <div class="information damned faint"> - {"YOU RETAIN YOUR ROLE AND WIN IF EVIL WINS"} - <span class="yellow"> - {"HOWEVER, YOU CONTRIBUTE TO VILLAGE PARITY"} - </span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/drunk_page.rs b/werewolves/src/pages/drunk_page.rs deleted file mode 100644 index 36c510d..0000000 --- a/werewolves/src/pages/drunk_page.rs +++ /dev/null @@ -1,19 +0,0 @@ -use werewolves_proto::aura::AuraTitle; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon}; - -#[function_component] -pub fn DrunkPage() -> Html { - let icon = AuraTitle::Drunk.icon().unwrap_or(IconSource::Roleblock); - html! { - <div class="role-page"> - <h1 class="drunk">{"DRUNK"}</h1> - <div class="information drunk faint"> - {"YOU GOT DRUNK INSTEAD"} - <Icon source={icon} icon_type={IconType::Informational}/> - <span class="yellow">{"YOUR NIGHT ACTION DID NOT TAKE PLACE"}</span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/error.rs b/werewolves/src/pages/error.rs deleted file mode 100644 index 55b009e..0000000 --- a/werewolves/src/pages/error.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use gloo::storage::errors::StorageError; -use thiserror::Error; -use werewolves_proto::{error::GameError, message::ClientMessage}; -use yew::prelude::*; - -use crate::clients::client::connection::ConnectionError; - -#[derive(Debug, Error)] -pub enum WerewolfError { - #[error("{0}")] - Game(#[from] GameError), - #[error("local storage error: {0}")] - LocalStorage(String), - #[error("send error: {0}")] - Send(#[from] futures::channel::mpsc::SendError), - #[error("send error: {0}")] - ClientSend(#[from] yew::platform::pinned::mpsc::SendError<ClientMessage>), - #[error("connection error: {0}")] - Connection(#[from] ConnectionError), -} - -impl From<StorageError> for WerewolfError { - fn from(storage_error: StorageError) -> Self { - Self::LocalStorage(storage_error.to_string()) - } -} - -pub struct ErrorComponent { - error: Option<WerewolfError>, -} - -impl Component for ErrorComponent { - type Message = Option<WerewolfError>; - - type Properties = (); - - fn create(_ctx: &Context<Self>) -> Self { - Self { error: None } - } - - fn view(&self, ctx: &Context<Self>) -> Html { - let scope = ctx.link().clone(); - let clear = Callback::from(move |_| scope.send_message(None)); - match &self.error { - Some(err) => html! { - <div class="error-container"> - <div class="error-message"> - <p>{err.to_string()}</p> - <button onclick={clear}>{"✖"}</button> - </div> - </div> - }, - None => html!(), - } - } - - fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool { - // if msg == self.error { - // return false; - // } - self.error = msg; - true - } -} diff --git a/werewolves/src/pages/role_change.rs b/werewolves/src/pages/role_change.rs deleted file mode 100644 index 9730635..0000000 --- a/werewolves/src/pages/role_change.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use convert_case::{Case, Casing}; -use werewolves_proto::{game::SetupRole, role::RoleTitle}; -use yew::prelude::*; - -use crate::components::{Icon, IconType, PartialAssociatedIcon}; - -#[derive(Debug, Clone, Copy, PartialEq, Properties)] -pub struct RoleChangePageProps { - pub role: RoleTitle, -} - -#[function_component] -pub fn RoleChangePage(RoleChangePageProps { role }: &RoleChangePageProps) -> Html { - let class = Into::<SetupRole>::into(*role).category().class(); - let icon = role.icon().map(|icon| { - html! { - <Icon source={icon} icon_type={IconType::Fit}/> - } - }); - html! { - <div class="role-page"> - <h1 class={classes!(class)}>{"ROLE CHANGE"}</h1> - <div class={classes!("information", class, "faint")}> - {"YOUR ROLE HAS CHANGED"} - {icon} - <span> - {"YOUR NEW ROLE IS "} - <span class="yellow">{role.to_string().to_case(Case::Upper)}</span> - </span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page.rs b/werewolves/src/pages/role_page.rs deleted file mode 100644 index 0a79519..0000000 --- a/werewolves/src/pages/role_page.rs +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::ops::Not; -use std::rc::Rc; - -use werewolves_proto::{ - message::{CharacterIdentity, PublicIdentity, night::ActionPrompt}, - role::PreviousGuardianAction, -}; -use yew::prelude::*; - -use crate::{ - components::Identity, - pages::{DamnedIntroPage1, DamnedIntroPage2, RoleChangePage, WolfpackKillPage}, -}; - -werewolves_macros::include_path!("werewolves/src/pages/role_page"); -pub trait RolePage { - fn role_pages(&self, big_screen: bool) -> Rc<[yew::Html]>; -} - -impl RolePage for ActionPrompt { - fn role_pages(&self, big_screen: bool) -> Rc<[yew::Html]> { - let ident = |character_id: &CharacterIdentity| { - big_screen.not().then(|| { - html! { - <Identity ident={Into::<PublicIdentity>::into(character_id)} /> - } - }) - }; - match self { - ActionPrompt::BeholderChooses { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <BeholderPage1 /> - </> - }]), - ActionPrompt::DireWolf { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <DirewolfPage1 /> - </> - }]), - ActionPrompt::Adjudicator { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <AdjudicatorPage1 /> - </> - }]), - ActionPrompt::Seer { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <SeerPage1 /> - </> - }]), - ActionPrompt::PowerSeer { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <PowerSeerPage1 /> - </> - }]), - ActionPrompt::Arcanist { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <ArcanistPage1 /> - </> - }]), - ActionPrompt::Protector { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <ProtectorPage1 /> - </> - }]), - ActionPrompt::Empath { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <EmpathPage1 /> - </> - }]), - ActionPrompt::Hunter { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <HunterPage1 /> - </> - }]), - ActionPrompt::PyreMaster { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <PyremasterPage1 /> - </> - }]), - ActionPrompt::Militia { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <MilitiaPage1 /> - </> - }]), - ActionPrompt::MapleWolf { - character_id, - nights_til_starvation, - .. - } => [html! { - <> - {ident(character_id)} - <MapleWolfPage1 nights_til_starvation={*nights_til_starvation} /> - </> - }] - .into_iter() - .collect(), - ActionPrompt::MasonLeaderRecruit { - character_id, - recruits_left, - .. - } => Rc::new([ - html! { - <> - {ident(character_id)} - <MasonRecruitPage1 recruits_left={*recruits_left} /> - </> - }, - html! { - <> - {ident(character_id)} - <MasonRecruitPage2 /> - </> - }, - ]), - ActionPrompt::MasonsWake { leader, masons } => Rc::new([html! { - <> - {ident(leader)} - <MasonsWake leader={leader.clone()} masons={masons.clone()}/> - </> - }]), - ActionPrompt::AlphaWolf { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <AlphaWolfPage1 /> - </> - }]), - ActionPrompt::Insomniac { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <InsomniacPage1 /> - </> - }]), - ActionPrompt::ElderReveal { character_id, .. } => Rc::new([ - html! { - <> - {ident(character_id)} - <ElderPage1 /> - </> - }, - html! { - <> - {ident(character_id)} - <ElderPage2 /> - </> - }, - ]), - ActionPrompt::Guardian { - character_id, - previous: None, - .. - } => Rc::new([html! { - <> - {ident(character_id)} - <GuardianPageNoPrevProtect/> - </> - }]), - ActionPrompt::Guardian { - character_id, - previous: Some(PreviousGuardianAction::Protect(target)), - .. - } => { - if character_id.character_id == target.character_id { - Rc::new([html! { - <> - {ident(character_id)} - <GuardianPagePreviousProtectSelf /> - </> - }]) - } else { - Rc::new([ - html! { - <> - {ident(character_id)} - <GuardianPagePreviousProtect1 previous={target.clone()}/> - </> - }, - html! { - <> - {ident(character_id)} - <GuardianPagePreviousProtect2 previous={target.clone()}/> - </> - }, - ]) - } - } - - ActionPrompt::Guardian { - character_id, - previous: Some(PreviousGuardianAction::Guard(target)), - .. - } => Rc::new([html! { - <> - {ident(character_id)} - <GuardianPagePreviousGuard previous={target.clone()}/> - </> - }]), - ActionPrompt::Mortician { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <MorticianPage1 /> - </> - }]), - ActionPrompt::RoleChange { - character_id, - new_role, - } => Rc::new([html! { - <> - {ident(character_id)} - <RoleChangePage role={*new_role}/> - </> - }]), - ActionPrompt::WolfPackKill { .. } => Rc::new([html! { - <> - <WolfpackKillPage /> - </> - }]), - ActionPrompt::Gravedigger { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <GravediggerPage1 /> - </> - }]), - ActionPrompt::Vindicator { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <VindicatorPage1 /> - </> - }]), - ActionPrompt::LoneWolfKill { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <LoneWolfPage1 /> - </> - }]), - ActionPrompt::Bloodletter { character_id, .. } => Rc::new([html! { - <> - {ident(character_id)} - <BloodletterPage1 /> - </> - }]), - ActionPrompt::BeholderWakes { character_id } => Rc::new([html! { - <> - {ident(character_id)} - <BeholderWakePage1 /> - </> - }]), - ActionPrompt::DamnedIntro { character_id } => Rc::new([ - html! { - <> - {ident(character_id)} - <DamnedIntroPage1 /> - </> - }, - html! { - <> - {ident(character_id)} - <DamnedIntroPage2 /> - </> - }, - ]), - _ => Rc::new([]), - } - } -} diff --git a/werewolves/src/pages/role_page/adjudicator.rs b/werewolves/src/pages/role_page/adjudicator.rs deleted file mode 100644 index 933cad6..0000000 --- a/werewolves/src/pages/role_page/adjudicator.rs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::{message::PublicIdentity, role::Killer}; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType, IdentitySpan}; - -#[function_component] -pub fn AdjudicatorPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="defensive">{"ADJUDICATOR"}</h1> - <div class="information defensive faint"> - <h4>{"PICK A PLAYER"}</h4> - <Icon source={IconSource::Killer} icon_type={IconType::Fit}/> - <h4 class="yellow">{"YOU WILL CHECK IF THEY APPEAR AS A KILLER"}</h4> - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct AdjudicatorResultProps { - pub killer: Killer, - pub target: PublicIdentity, -} - -#[function_component] -pub fn AdjudicatorResult( - AdjudicatorResultProps { killer, target }: &AdjudicatorResultProps, -) -> Html { - let text = match killer { - Killer::Killer => "IS A KILLER", - Killer::NotKiller => "IS NOT A KILLER", - }; - let icon = match killer { - Killer::Killer => html! { - <Icon - source={IconSource::Killer} icon_type={IconType::Fit} - /> - }, - Killer::NotKiller => html! { - <Icon - source={IconSource::RedX} icon_type={IconType::Fit} - /> - }, - }; - html! { - <div class="role-page"> - <h1 class="defensive">{"ADJUDICATOR"}</h1> - <div class="information defensive faint"> - <IdentitySpan ident={target.clone()}/> - {icon} - <h3 class="yellow">{text}</h3> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/alpha_wolf.rs b/werewolves/src/pages/role_page/alpha_wolf.rs deleted file mode 100644 index d5b93f7..0000000 --- a/werewolves/src/pages/role_page/alpha_wolf.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -#[function_component] -pub fn AlphaWolfPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="wolves">{"ALPHA WOLF"}</h1> - <div class="information wolves faint"> - <span> - {"IF YOU WISH TO USE YOUR "} - <span class="yellow">{"ONCE PER GAME"}</span> - {" KILL ABILITY"} - </span> - {"POINT AT YOUR TARGET OR GO BACK TO SLEEP"} - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/arcanist.rs b/werewolves/src/pages/role_page/arcanist.rs deleted file mode 100644 index 524fb86..0000000 --- a/werewolves/src/pages/role_page/arcanist.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::{message::PublicIdentity, role::AlignmentEq}; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType, IdentitySpan}; - -#[function_component] -pub fn ArcanistPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"ARCANIST"}</h1> - <div class="information intel faint"> - {"PICK TWO PLAYERS"} - <div class="icons"> - <Icon source={IconSource::Village} - icon_type={IconType::Fit} - /> - <Icon source={IconSource::Wolves} - icon_type={IconType::Fit} - /> - </div> - <span class="yellow">{"YOU WILL COMPARE THEIR ALIGNMENTS"}</span> - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct ArcanistResultProps { - pub alignment_eq: AlignmentEq, - pub targets: (PublicIdentity, PublicIdentity), -} - -#[function_component] -pub fn ArcanistResult( - ArcanistResultProps { - alignment_eq, - targets: (t1, t2), - }: &ArcanistResultProps, -) -> Html { - let text = match alignment_eq { - AlignmentEq::Same => "ARE THE SAME", - AlignmentEq::Different => "ARE DIFFERENT", - }; - let icons = match alignment_eq { - AlignmentEq::Same => html! { - <Icon source={IconSource::Equal} icon_type={IconType::Fit} /> - }, - AlignmentEq::Different => html! { - <Icon source={IconSource::NotEqual} icon_type={IconType::Fit} /> - }, - }; - html! { - <div class="role-page"> - <h1 class="intel">{"ARCANIST"}</h1> - <div class="information intel faint"> - <div class="arcanist-targets"> - <IdentitySpan ident={t1.clone()}/> - <span class="and">{"AND"}</span> - <IdentitySpan ident={t2.clone()}/> - </div> - <div class="icons"> - {icons} - </div> - <span class="yellow">{text}</span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/beholder.rs b/werewolves/src/pages/role_page/beholder.rs deleted file mode 100644 index b1e130d..0000000 --- a/werewolves/src/pages/role_page/beholder.rs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn BeholderPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"BEHOLDER"}</h1> - <div class="information intel faint"> - {"PICK A PLAYER"} - <Icon source={IconSource::Beholder} icon_type={IconType::Fit}/> - {"YOU WILL SEE WHAT INFORMATION THEY MAY HAVE GATHERED"} - <span class="yellow">{"SHOULD THEY DIE TONIGHT"}</span> - </div> - </div> - } -} - -#[function_component] -pub fn BeholderWakePage1() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"BEHOLDER"}</h1> - <div class="information intel faint"> - {"YOUR TARGET HAS DIED"} - <Icon source={IconSource::Beholder} icon_type={IconType::Fit}/> - <span class="yellow">{"THIS IS THE LAST PIECE OF INFORMATION THEY SAW"}</span> - </div> - </div> - } -} - -#[function_component] -pub fn BeholderSawNothing() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"BEHOLDER"}</h1> - <div class="information intel faint"> - <h1>{"YOUR TARGET HAS DIED"}</h1> - <div class="info-icon-grow"> - <Icon source={IconSource::RedX} icon_type={IconType::Fit}/> - </div> - <h1>{"BUT SAW NOTHING"}</h1> - </div> - </div> - } -} - -#[function_component] -pub fn BeholderSawEverything() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"BEHOLDER"}</h1> - <div class="information intel faint"> - {"YOUR TARGET HAS DIED"} - <Icon source={IconSource::Beholder} icon_type={IconType::Fit}/> - <span> - {"BUT SAW "} - <em class="red"> - <strong>{"EVERYTHING"}</strong> - </em> - </span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/bloodletter.rs b/werewolves/src/pages/role_page/bloodletter.rs deleted file mode 100644 index 750ee1d..0000000 --- a/werewolves/src/pages/role_page/bloodletter.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn BloodletterPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="wolves">{"BLOODLETTER"}</h1> - <div class="information wolves faint"> - <span>{"PICK A PLAYER"}</span> - <span class="inline-icons"> - {"THEY'LL APPEAR AS A WOLF "} - <Icon source={IconSource::Wolves} icon_type={IconType::Fit}/> - {"KILLER"} - <Icon source={IconSource::Killer} icon_type={IconType::Fit}/> - {"AND POWERFUL"} - <Icon source={IconSource::Powerful} icon_type={IconType::Fit}/> - {"IN CHECKS FOR 2 NIGHTS"} - </span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/direwolf.rs b/werewolves/src/pages/role_page/direwolf.rs deleted file mode 100644 index 5ccdfd8..0000000 --- a/werewolves/src/pages/role_page/direwolf.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -#[function_component] -pub fn DirewolfPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="wolves">{"DIREWOLF"}</h1> - <div class="information wolves faint"> - {"CHOOSE A TARGET"} - <span class="yellow">{"ANY VISITORS TO THIS TARGET WILL BE ROLE BLOCKED"}</span> - {"YOU CANNOT CHOOSE YOURSELF OR THE SAME TARGET AS LAST NIGHT"} - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/elder.rs b/werewolves/src/pages/role_page/elder.rs deleted file mode 100644 index 0eab6b0..0000000 --- a/werewolves/src/pages/role_page/elder.rs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -#[function_component] -pub fn ElderPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="starts-as-villager">{"ELDER"}</h1> - <div class="information starts-as-villager faint"> - {"YOU ARE THE ELDER"} - <span class="yellow"> - {"IF YOU ARE EXECUTED BY THE VILLAGE FROM NOW ON "} - {"ALL POWER ROLES WILL BE LOST"} - </span> - </div> - </div> - } -} - -#[function_component] -pub fn ElderPage2() -> Html { - html! { - <div class="role-page"> - <h1 class="starts-as-villager">{"ELDER"}</h1> - <div class="information starts-as-villager faint"> - {"YOU STARTED THE GAME WITH PROTECTION FROM A NIGHT "} - {"DEATH — THIS MAY OR MAY NOT STILL BE INTACT"} - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/empath.rs b/werewolves/src/pages/role_page/empath.rs deleted file mode 100644 index 74874f4..0000000 --- a/werewolves/src/pages/role_page/empath.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -use werewolves_proto::message::PublicIdentity; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType, IdentitySpan}; - -#[function_component] -pub fn EmpathPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"EMPATH"}</h1> - <div class="information intel faint"> - {"PICK A PLAYER"} - <span class="yellow">{"YOU WILL CHECK IF THEY ARE THE SCAPEGOAT"}</span> - {"IF THEY ARE, YOU WILL TAKE ON THEIR CURSE"} - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct EmpathResultProps { - pub scapegoat: bool, - pub target: PublicIdentity, -} - -#[function_component] -pub fn EmpathResult(EmpathResultProps { scapegoat, target }: &EmpathResultProps) -> Html { - let text = match scapegoat { - true => "IS THE SCAPEGOAT", - false => "IS NOT THE SCAPEGOAT", - }; - let icon = match scapegoat { - true => html! { - <Icon - source={IconSource::Scapegoat} icon_type={IconType::Fit} - /> - }, - false => html! { - <Icon - source={IconSource::RedX} icon_type={IconType::Fit} - /> - }, - }; - html! { - <div class="role-page"> - <h1 class="intel">{"EMPATH"}</h1> - <div class="information intel faint"> - <IdentitySpan ident={target.clone()}/> - {icon} - <span class="yellow">{text}</span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/gravedigger.rs b/werewolves/src/pages/role_page/gravedigger.rs deleted file mode 100644 index 530d129..0000000 --- a/werewolves/src/pages/role_page/gravedigger.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use convert_case::{Case, Casing}; -use werewolves_proto::{message::PublicIdentity, role::RoleTitle}; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType, IdentitySpan, PartialAssociatedIcon}; - -#[function_component] -pub fn GravediggerPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"GRAVEDIGGER"}</h1> - <div class="information intel faint"> - <span> - {"PICK A "} - <span class="yellow">{"DEAD"}</span> - {" PLAYER"} - </span> - <Icon source={IconSource::Gravedigger} icon_type={IconType::Fit}/> - <span class="yellow"> - {"YOU WILL LEARN THEIR ROLE"} - </span> - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct GravediggerResultPageProps { - pub role: Option<RoleTitle>, - pub target: PublicIdentity, -} - -#[function_component] -pub fn GravediggerResultPage( - GravediggerResultPageProps { role, target }: &GravediggerResultPageProps, -) -> Html { - let text = role - .as_ref() - .map(|r| { - html! { - <> - {"WAS A "} - <span class="yellow"> - {r.to_string().to_case(Case::Upper)} - </span> - </> - } - }) - .unwrap_or_else(|| { - html! { - {"YOU FIND AN EMPTY GRAVE"} - } - }); - let icon = role - .as_ref() - .and_then(|i| i.icon()) - .unwrap_or(IconSource::Gravedigger); - html! { - <div class="role-page"> - <h1 class="intel">{"GRAVEDIGGER"}</h1> - <div class="information intel faint"> - <IdentitySpan ident={target.clone()}/> - <Icon source={icon} icon_type={IconType::Fit}/> - {text} - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/guardian.rs b/werewolves/src/pages/role_page/guardian.rs deleted file mode 100644 index 76f98e4..0000000 --- a/werewolves/src/pages/role_page/guardian.rs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::message::CharacterIdentity; -use yew::prelude::*; - -use crate::components::{CharacterTargetCard, Icon, IconSource, IconType}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct GuardianPageProps { - pub previous: CharacterIdentity, -} - -#[function_component] -pub fn GuardianPageNoPrevProtect() -> Html { - html! { - <div class="role-page"> - <h1 class="defensive">{"GUARDIAN"}</h1> - <div class="information defensive faint"> - {"PICK A PLAYER"} - <Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/> - <span class="yellow">{"CHOOSE SOMEONE TO PROTECT FROM DEATH"}</span> - </div> - </div> - } -} - -#[function_component] -pub fn GuardianPagePreviousProtectSelf() -> Html { - html! { - <div class="role-page"> - <h1 class="defensive">{"GUARDIAN"}</h1> - <div class="information defensive faint"> - {"LAST TIME YOU PROTECTED YOURSELF"} - <span class="yellow">{"YOU CANNOT PROTECT YOURSELF AGAIN TONIGHT"}</span> - </div> - </div> - } -} - -#[function_component] -pub fn GuardianPagePreviousProtect1(GuardianPageProps { previous }: &GuardianPageProps) -> Html { - html! { - <div class="role-page"> - <h1 class="defensive">{"GUARDIAN"}</h1> - <div class="information defensive faint"> - {"LAST TIME YOU PROTECTED"} - <Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/> - <div class="info-player-list"> - <CharacterTargetCard ident={previous.clone()} /> - </div> - <span class="yellow">{"IF YOU PROTECT THEM AGAIN, YOU WILL INSTEAD GUARD THEM"}</span> - </div> - </div> - } -} - -#[function_component] -pub fn GuardianPagePreviousProtect2(GuardianPageProps { previous }: &GuardianPageProps) -> Html { - html! { - <div class="role-page"> - <h1 class="defensive">{"GUARDIAN"}</h1> - <div class="information defensive faint"> - {"LAST TIME YOU PROTECTED"} - <Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/> - <div class="info-player-list"> - <CharacterTargetCard ident={previous.clone()} /> - </div> - <span class="yellow">{"IF ATTACKED WHILE GUARDED, YOU AND THEIR ATTACKER WILL INSTEAD DIE"}</span> - </div> - </div> - } -} - -#[function_component] -pub fn GuardianPagePreviousGuard(GuardianPageProps { previous }: &GuardianPageProps) -> Html { - html! { - <div class="role-page"> - <h1 class="defensive">{"GUARDIAN"}</h1> - <div class="information defensive faint"> - {"LAST TIME YOU GUARDED"} - <Icon source={IconSource::ShieldAndSword} icon_type={IconType::Fit}/> - <div class="info-player-list"> - <CharacterTargetCard ident={previous.clone()} /> - </div> - <span class="yellow">{"YOU CANNOT PROTECT THEM TONIGHT"}</span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/hunter.rs b/werewolves/src/pages/role_page/hunter.rs deleted file mode 100644 index 8373e0c..0000000 --- a/werewolves/src/pages/role_page/hunter.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn HunterPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="offensive">{"HUNTER"}</h1> - <div class="information offensive faint"> - {"SET A HUNTER'S TRAP ON A PLAYER"} - <Icon source={IconSource::Hunter} icon_type={IconType::Fit}/> - <span class="yellow"> - {"IF YOU DIE TONIGHT, OR ARE EXECUTED TOMORROW "} - {"THIS PLAYER WILL DIE AT NIGHT"} - </span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/insomniac.rs b/werewolves/src/pages/role_page/insomniac.rs deleted file mode 100644 index f56cda6..0000000 --- a/werewolves/src/pages/role_page/insomniac.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::message::night::Visits; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn InsomniacPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"INSOMNIAC"}</h1> - <div class="information intel faint"> - {"YOUR SLEEP IS INTERRUPTED"} - <Icon source={IconSource::Insomniac} icon_type={IconType::Fit}/> - {"YOU'VE NOTICED VISITORS IN THE NIGHT"} - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct InsomniacResultProps { - pub visits: Visits, -} - -#[function_component] -pub fn InsomniacResult(InsomniacResultProps { visits }: &InsomniacResultProps) -> Html { - let visitors = visits - .iter() - .map(|visitor| { - html! { - <div class="identity intel"> - <span class="number">{visitor.number.get()}</span> - <span class="name">{visitor.name.clone()}</span> - </div> - } - }) - .collect::<Html>(); - html! { - <div class="role-page"> - <h1 class="intel">{"INSOMNIAC"}</h1> - <div class="information intel faint"> - {"YOU WERE VISITED IN THE NIGHT BY:"} - <div class="info-player-boxes"> - {visitors} - </div> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/lone_wolf.rs b/werewolves/src/pages/role_page/lone_wolf.rs deleted file mode 100644 index 0b06937..0000000 --- a/werewolves/src/pages/role_page/lone_wolf.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -#[function_component] -pub fn LoneWolfPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="wolves">{"LONE WOLF"}</h1> - <div class="information wolves faint"> - <span> - {"YOU MUST KILL TONIGHT IN ANGER OVER A FELLOW "} - {"WOLF HAVING BEEN SLAIN"} - </span> - <span class="yellow"> - {"PICK A PLAYER"} - </span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/maple_wolf.rs b/werewolves/src/pages/role_page/maple_wolf.rs deleted file mode 100644 index 2d35bc0..0000000 --- a/werewolves/src/pages/role_page/maple_wolf.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[derive(Debug, Clone, Copy, PartialEq, Properties)] -pub struct MapleWolfPageProps { - pub nights_til_starvation: u8, -} - -#[function_component] -pub fn MapleWolfPage1( - MapleWolfPageProps { - nights_til_starvation, - }: &MapleWolfPageProps, -) -> Html { - let food_state = if *nights_til_starvation == 0 { - html! { - <> - <span class="red">{"YOU ARE STARVING"}</span> - {"IF YOU FAIL TO EAT TONIGHT, YOU WILL DIE"} - </> - } - } else { - let nights = if *nights_til_starvation == 1 { - html! { - <> - <span class="red">{"TOMORROW NIGHT "}</span> - </> - } - } else { - html! { - <> - {"IN "}<span class="red">{*nights_til_starvation}</span>{" NIGHTS "} - </> - } - }; - html! { - <span> - {"IF YOU FAIL TO EAT "} - {nights} - {"YOU WILL "}<span class="yellow">{"STARVE"}</span> - </span> - } - }; - html! { - <div class="role-page"> - <h1 class="offensive">{"MAPLE WOLF"}</h1> - <div class="information offensive faint"> - {"YOU CAN CHOOSE TO EAT A PLAYER TONIGHT"} - <Icon source={IconSource::MapleWolf} icon_type={IconType::Fit}/> - {food_state} - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/mason.rs b/werewolves/src/pages/role_page/mason.rs deleted file mode 100644 index 8ad1273..0000000 --- a/werewolves/src/pages/role_page/mason.rs +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use core::num::NonZeroU8; - -use werewolves_proto::message::CharacterIdentity; -use yew::prelude::*; - -use crate::components::CharacterTargetCard; - -#[derive(Debug, Clone, Copy, PartialEq, Properties)] -pub struct MasonRecruitPage1Props { - pub recruits_left: NonZeroU8, -} - -#[function_component] -pub fn MasonRecruitPage1( - MasonRecruitPage1Props { recruits_left }: &MasonRecruitPage1Props, -) -> Html { - let recruitments = match recruits_left.get() { - 0 => unreachable!(), - 1 => html! { - <> - <span class="yellow">{1}</span> - {" RECRUITMENT"} - </> - }, - num => html! { - <> - <span class="yellow">{num}</span> - {" RECRUITMENTS"} - </> - }, - }; - html! { - <div class="role-page"> - <h1 class="intel">{"MASON LEADER"}</h1> - <div class="information intel faint"> - <span>{"YOU HAVE "}{recruitments}{" LEFT"}</span> - <span> - {"RECRUITS WILL WAKE WITH YOU EVERY NIGHT"} - {" WHILE THEY ARE ALIVE AND REMAIN VILLAGE ALIGNED"} - </span> - </div> - </div> - } -} - -#[function_component] -pub fn MasonRecruitPage2() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"MASON LEADER"}</h1> - <div class="information intel faint"> - <span class="yellow">{"WOULD YOU LIKE TO RECRUIT TONIGHT?"}</span> - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct MasonsWakeProps { - pub leader: CharacterIdentity, - pub masons: Box<[CharacterIdentity]>, -} - -#[function_component] -pub fn MasonsWake(MasonsWakeProps { leader, masons }: &MasonsWakeProps) -> Html { - let title = html! { - <> - {"MASONS OF "} - <span class="yellow">{leader.name.clone()}</span> - </> - }; - let masons = masons - .iter() - .map(|mason| { - html! { - <CharacterTargetCard ident={mason.clone()}/> - } - }) - .collect::<Html>(); - html! { - <div class="role-page"> - <h1 class="intel">{title}</h1> - <div class="information intel faint"> - {"THE MASONS CONVENE AT NIGHT"} - <div class="info-player-list masons"> - {masons} - </div> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/militia.rs b/werewolves/src/pages/role_page/militia.rs deleted file mode 100644 index e8ec1e1..0000000 --- a/werewolves/src/pages/role_page/militia.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn MilitiaPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="offensive">{"MILITIA"}</h1> - <div class="information offensive faint"> - <span> - {"IF YOU WISH TO USE YOUR "} - <span class="yellow">{"ONCE PER GAME"}</span> - {" KILL ABILITY"} - </span> - <Icon source={IconSource::Sword} icon_type={IconType::Fit}/> - <span class="yellow"> - {"PICK A PLAYER "} - {"OR GO BACK TO SLEEP"} - </span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/mortician.rs b/werewolves/src/pages/role_page/mortician.rs deleted file mode 100644 index d5a8a1c..0000000 --- a/werewolves/src/pages/role_page/mortician.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::{diedto::DiedToTitle, message::PublicIdentity}; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType, IdentitySpan, PartialAssociatedIcon}; - -#[function_component] -pub fn MorticianPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"MORTICIAN"}</h1> - <div class="information intel faint"> - <span>{"PICK A "}<span class="yellow">{"DEAD"}</span>{" PLAYER"}</span> - <Icon source={IconSource::Mortician} icon_type={IconType::Fit}/> - <span class="yellow"> - {"YOU WILL LEARN THE CAUSE "} - {"OF THEIR DEATH"} - </span> - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct MorticianResultPageProps { - pub died_to: DiedToTitle, - pub target: PublicIdentity, -} - -#[function_component] -pub fn MorticianResultPage( - MorticianResultPageProps { died_to, target }: &MorticianResultPageProps, -) -> Html { - let text = match died_to { - DiedToTitle::Execution => "Execution", - DiedToTitle::MapleWolf => "Maple Wolf", - DiedToTitle::MapleWolfStarved => "Starvation", - DiedToTitle::Militia => "Militia Shot", - DiedToTitle::Wolfpack => "Wolfpack", - DiedToTitle::AlphaWolf => "Alpha Wolf", - DiedToTitle::Shapeshift => "Shapeshifting", - DiedToTitle::Hunter => "Hunter Trap", - DiedToTitle::GuardianProtecting => "Guardian", - DiedToTitle::PyreMaster => "Pyre Master", - DiedToTitle::PyreMasterLynchMob => "An Angry Mob of Villagers Against Fire", - DiedToTitle::MasonLeaderRecruitFail => "Occupational Hazard (Mason Recruit Fail)", - DiedToTitle::LoneWolf => "Lone Wolf", - }; - let icon = died_to.icon().unwrap_or(IconSource::Mortician); - html! { - <div class="role-page"> - <h1 class="intel">{"MORTICIAN"}</h1> - <div class="information intel faint"> - <IdentitySpan ident={target.clone()}/> - {"DIED TO"} - <Icon source={icon} icon_type={IconType::Fit}/> - <span class="yellow">{text}</span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/power_seer.rs b/werewolves/src/pages/role_page/power_seer.rs deleted file mode 100644 index 243b20d..0000000 --- a/werewolves/src/pages/role_page/power_seer.rs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -use werewolves_proto::{message::PublicIdentity, role::Powerful}; -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType, IdentitySpan}; - -#[function_component] -pub fn PowerSeerPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"POWER SEER"}</h1> - <div class="information intel faint"> - {"PICK A PLAYER"} - <div class="info-icon-grow"> - <Icon source={IconSource::Powerful} icon_type={IconType::Fit}/> - </div> - <span class="yellow">{"YOU WILL CHECK IF THEY ARE POWERFUL"}</span> - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct PowerSeerResultProps { - pub powerful: Powerful, - pub target: PublicIdentity, -} - -#[function_component] -pub fn PowerSeerResult(PowerSeerResultProps { powerful, target }: &PowerSeerResultProps) -> Html { - let text = match powerful { - Powerful::Powerful => "IS POWERFUL", - Powerful::NotPowerful => "IS NOT POWERFUL", - }; - let icon = match powerful { - Powerful::Powerful => html! { - <Icon - source={IconSource::Powerful} icon_type={IconType::Fit} - /> - }, - Powerful::NotPowerful => html! { - <Icon - source={IconSource::RedX} icon_type={IconType::Fit} - /> - }, - }; - html! { - <div class="role-page"> - <h1 class="intel">{"POWER SEER"}</h1> - <div class="information intel faint"> - <IdentitySpan ident={target.clone()}/> - <div class="info-icon-grow">{icon}</div> - <h3 class="yellow">{text}</h3> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/protector.rs b/werewolves/src/pages/role_page/protector.rs deleted file mode 100644 index efc271d..0000000 --- a/werewolves/src/pages/role_page/protector.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn ProtectorPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="defensive">{"PROTECTOR"}</h1> - <div class="information defensive faint"> - {"PICK A PLAYER"} - <Icon source={IconSource::Shield} icon_type={IconType::Fit}/> - <span class="yellow">{"YOU WILL PROTECT THEM FROM A DEATH TONIGHT"}</span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/pyremaster.rs b/werewolves/src/pages/role_page/pyremaster.rs deleted file mode 100644 index ba8c231..0000000 --- a/werewolves/src/pages/role_page/pyremaster.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn PyremasterPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="offensive">{"PYREMASTER"}</h1> - <div class="information offensive faint"> - {"YOU CAN CHOOSE TO THROW A PLAYER ON THE PYRE"} - <Icon source={IconSource::Pyremaster} icon_type={IconType::Fit}/> - <span> - {"IF YOU KILL "} - <span class="yellow">{"TWO"}</span> - {" GOOD VILLAGERS LIKE THIS "} - {"YOU WILL DIE AS WELL"} - </span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/seer.rs b/werewolves/src/pages/role_page/seer.rs deleted file mode 100644 index 75055ae..0000000 --- a/werewolves/src/pages/role_page/seer.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use werewolves_proto::{ - message::PublicIdentity, - role::{Alignment, RoleTitle}, -}; -use yew::prelude::*; - -use crate::components::{ - AssociatedIcon, Icon, IconSource, IconType, IdentitySpan, attributes::RoleTitleSpan, -}; - -#[function_component] -pub fn SeerPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="intel">{"SEER"}</h1> - <div class="information intel faint"> - {"PICK A PLAYER"} - <div class="icons"> - <Icon source={IconSource::Village} icon_type={IconType::Fit} /> - <Icon source={IconSource::Wolves} icon_type={IconType::Fit} /> - </div> - <span class="yellow">{"YOU WILL CHECK THEIR ALIGNMENT"}</span> - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct SeerResultProps { - pub alignment: Alignment, - pub target: PublicIdentity, -} - -#[function_component] -pub fn SeerResult(SeerResultProps { alignment, target }: &SeerResultProps) -> Html { - let text = match alignment { - Alignment::Village => "VILLAGE", - Alignment::Wolves => "WOLFPACK", - Alignment::Damned => "DAMNED", - }; - let additional_info = match alignment { - Alignment::Village => html! { - <FalselyAppearsAs - roles={RoleTitle::falsely_appear_village()} - alignment_text={text} - /> - }, - Alignment::Wolves => html! { - <FalselyAppearsAs - roles={RoleTitle::falsely_appear_wolf()} - alignment_text={text} - /> - }, - Alignment::Damned => html! { - <div class="bottom-bound"> - {"THIS PERSON IS "} - <span class="yellow">{"DAMNED"}</span> - {"THEY WIN ALONGSIDE EVIL"} - </div> - }, - }; - html! { - <div class="role-page"> - <h1 class="intel">{"SEER"}</h1> - <div class="information intel faint"> - <div class="two-column"> - <div class="seer-check"> - <IdentitySpan ident={target.clone()}/> - <Icon source={alignment.icon()}/> - <span class="yellow">{text}</span> - </div> - {additional_info} - </div> - </div> - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -struct FalselyAppearsAsProps { - roles: Box<[RoleTitle]>, - alignment_text: &'static str, -} - -#[function_component] -fn FalselyAppearsAs( - FalselyAppearsAsProps { - roles, - alignment_text, - }: &FalselyAppearsAsProps, -) -> Html { - let false_positives = roles - .iter() - .copied() - .map(|role| { - html! { - <RoleTitleSpan role={role} //icon_type={IconType::Icon15Pct} - /> - } - }) - .collect::<Html>(); - html! { - <div class="bottom-bound"> - {"ROLES THAT FALSELY APPEAR AS "} - <span class="yellow">{*alignment_text}</span> - <div class="false-positives yellow"> - {false_positives} - </div> - </div> - } -} diff --git a/werewolves/src/pages/role_page/vindicator.rs b/werewolves/src/pages/role_page/vindicator.rs deleted file mode 100644 index 0b90f41..0000000 --- a/werewolves/src/pages/role_page/vindicator.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn VindicatorPage1() -> Html { - html! { - <div class="role-page"> - <h1 class="defensive">{"VINDICATOR"}</h1> - <div class="information defensive faint"> - <span>{"A VILLAGER WAS EXECUTED"}</span> - <Icon source={IconSource::Vindicator} icon_type={IconType::Fit}/> - <span class="yellow">{"PICK A PLAYER TO PROTECT FROM A DEATH TONIGHT"}</span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/roleblock.rs b/werewolves/src/pages/roleblock.rs deleted file mode 100644 index f16dc4a..0000000 --- a/werewolves/src/pages/roleblock.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn RoleblockPage() -> Html { - html! { - <div class="role-page"> - <h1 class="wolves">{"ROLE BLOCKED"}</h1> - <div class="information wolves faint"> - {"YOU WERE ROLE BLOCKED"} - <Icon source={IconSource::Roleblock} icon_type={IconType::Informational}/> - <span class="yellow">{"YOUR NIGHT ACTION DID NOT TAKE PLACE"}</span> - </div> - </div> - } -} diff --git a/werewolves/src/pages/shift_failed.rs b/werewolves/src/pages/shift_failed.rs deleted file mode 100644 index eec5584..0000000 --- a/werewolves/src/pages/shift_failed.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn ShiftFailed() -> Html { - html! { - <div class="role-page"> - <h1 class="wolves">{"SHIFT FAILED"}</h1> - <div class={classes!("information", "wolves", "faint")}> - {"YOUR SHIFT HAS FAILED"} - <Icon source={IconSource::RedX} icon_type={IconType::Informational}/> - {"YOU RETAIN YOUR SHAPESHIFT ABILITY"} - </div> - </div> - } -} diff --git a/werewolves/src/pages/wolf_pack.rs b/werewolves/src/pages/wolf_pack.rs deleted file mode 100644 index 51d2487..0000000 --- a/werewolves/src/pages/wolf_pack.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. - -use yew::prelude::*; - -use crate::components::{Icon, IconSource, IconType}; - -#[function_component] -pub fn WolfpackKillPage() -> Html { - html! { - <div class="role-page"> - <h1 class="wolves">{"WOLF PACK KILL"}</h1> - <div class="information wolves faint"> - {"CHOOSE A TARGET TO EAT TONIGHT"} - <Icon source={IconSource::Wolves} icon_type={IconType::Fit}/> - <span class="yellow">{"WOLVES MUST BE UNANIMOUS"}</span> - </div> - </div> - } -} diff --git a/werewolves/src/scroll.rs b/werewolves/src/scroll.rs deleted file mode 100644 index 174d83c..0000000 --- a/werewolves/src/scroll.rs +++ /dev/null @@ -1,21 +0,0 @@ -use yew::WheelEvent; - -pub fn vertical_scroll_to_horizontal(selector: &str) -> impl Fn(WheelEvent) { - let selector = selector.to_string(); - move |ev: WheelEvent| { - let scroll_y = ev.delta_y(); - if scroll_y == 0.0 { - return; - } - let Some(target) = gloo::utils::document() - .query_selector(&selector) - .ok() - .flatten() - else { - return; - }; - - target.set_scroll_left(target.scroll_left() + ((scroll_y + ev.delta_x()) as i32)); - ev.prevent_default(); - } -} diff --git a/werewolves/src/server/game.rs b/werewolves/src/server/game.rs new file mode 100644 index 0000000..3fea516 --- /dev/null +++ b/werewolves/src/server/game.rs @@ -0,0 +1,227 @@ +// Copyright (C) 2025-2026 Emilis Bliūdžius +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +use crate::server::runner::{ClientUpdate, HostOrClientMessage, IdentifiedClientMessage}; +use api::game::GameId; +use chrono::Utc; +use werewolves_proto::{ + error::GameError, + game::{Game, GameOver}, + message::{ + ClientDeadChat, ClientMessage, Identification, ServerToClientMessage, + dead::DeadChatMessage, + host::{HostGameMessage, HostMessage, ServerToHostMessage}, + }, +}; + +type Result<T> = core::result::Result<T, GameError>; + +pub struct GameRunner<'a> { + game_id: GameId, + game: &'a mut Game, + roles_revealed: bool, +} + +impl<'a> GameRunner<'a> { + pub fn new(game_id: GameId, game: &'a mut Game) -> Self { + Self { + game, + game_id, + roles_revealed: false, + } + } + + pub fn game_over(&self) -> Option<GameOver> { + self.game.game_over() + } + + pub async fn process(&mut self, msg: HostOrClientMessage) -> Option<GameOver> { + let start = Utc::now(); + let msg = match msg { + HostOrClientMessage::Client(IdentifiedClientMessage { + update: ClientUpdate::ConnectStateUpdate { .. }, + .. + }) => return None, + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, .. }, + update: ClientUpdate::Message(ClientMessage::DeadChat(chat_request)), + }) => { + if let ClientDeadChat::Send(msg) = &chat_request + && msg.trim().is_empty() + { + return None; + } + let reply = match self.game.process_dead_chat_request(player_id, chat_request) { + Ok(msg) => msg, + Err(err) => ServerToClientMessage::Error(err), + }; + match reply { + ServerToClientMessage::DeadChatMessage(msg) => { + if let Err(err) = self.send_dead_message(&msg).await { + log::warn!("sending message {msg:?} to dead chat: {err}"); + } + } + other => { + super::send_player(self.game_id, player_id, other).await; + } + } + return None; + } + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, .. }, + update: ClientUpdate::Message(ClientMessage::GetState), + }) => { + let Some(char) = self.game.village().character_by_player_id(player_id) else { + super::send_player( + self.game_id, + player_id, + ServerToClientMessage::GameInProgress, + ) + .await; + + return None; + }; + if !self + .game + .village() + .dead_chat() + .all_character_ids() + .contains(&char.character_id()) + { + super::send_player( + self.game_id, + player_id, + ServerToClientMessage::GameInProgress, + ) + .await; + return None; + } + let msg = match self + .game + .process_dead_chat_request(player_id, ClientDeadChat::GetHistory) + { + Ok(msg) => msg, + Err(err) => ServerToClientMessage::Error(err), + }; + super::send_player(self.game_id, player_id, msg).await; + return None; + } + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, .. }, + .. + }) => { + log::info!("client message from player {player_id}"); + super::send_player( + self.game_id, + player_id, + ServerToClientMessage::GameInProgress, + ) + .await; + return None; + } + HostOrClientMessage::Host(msg) => msg, + }; + + let pre_time = self.game.village().time(); + let mut is_host_message = false; + match self.host_message(msg) { + Ok(ServerToHostMessage::DeadChatMessage(msg)) => { + super::send_host(self.game_id, ServerToHostMessage::DeadChatMessage(msg)).await; + is_host_message = true; + } + Ok(resp) => { + super::send_host(self.game_id, resp).await; + } + Err(err) => { + super::send_host(self.game_id, ServerToHostMessage::Error(err)).await; + } + } + let messages_for_host = self.game.dead_chats_since(start); + if !messages_for_host.is_empty() { + super::send_host( + self.game_id, + ServerToHostMessage::DeadChat(messages_for_host), + ) + .await; + } + let post_time = self.game.village().time(); + if let Some(game_over) = self.game.game_over() { + return Some(game_over); + } + if pre_time != post_time || is_host_message { + let dead = self + .game + .village() + .dead_characters() + .into_iter() + .filter_map(|c| c.died_to().map(|_| (c.character_id(), c.player_id()))); + + for (char, player) in dead { + let msgs = self + .game + .village() + .dead_chat() + .get_since(self.game.started(), char); + super::send_player(self.game_id, player, ServerToClientMessage::DeadChat(msgs)) + .await; + } + } + None + } + + pub async fn send_dead_message(&mut self, msg: &DeadChatMessage) -> Result<()> { + super::send_host( + self.game_id, + ServerToHostMessage::DeadChatMessage(msg.clone()), + ) + .await; + let player_ids = self + .game + .village() + .dead_chat() + .all_character_ids() + .into_iter() + .map(|c| { + self.game + .village() + .character_by_id(c) + .map(|c| c.player_id()) + }) + .collect::<Result<Box<_>>>()?; + super::send_to_all_players_in_game_filtered(self.game_id, |pid| { + player_ids + .contains(&pid) + .then_some(ServerToClientMessage::DeadChatMessage(msg.clone())) + }) + .await; + + Ok(()) + } + + pub fn host_message(&mut self, message: HostMessage) -> Result<ServerToHostMessage> { + if !self.roles_revealed { + return Err(GameError::NeedRoleReveal); + } + + match message { + HostMessage::GetState => self.game.process(HostGameMessage::GetState), + HostMessage::InGame(msg) => self.game.process(msg), + HostMessage::Lobby(_) | HostMessage::PostGame(_) | HostMessage::ForceRoleAckFor(_) => { + Err(GameError::GameOngoing) + } + HostMessage::Echo(echo) => Ok(echo), + } + } +} diff --git a/werewolves/src/server/game_connection.rs b/werewolves/src/server/game_connection.rs new file mode 100644 index 0000000..0bc0c51 --- /dev/null +++ b/werewolves/src/server/game_connection.rs @@ -0,0 +1,124 @@ +// Copyright (C) 2025-2026 Emilis Bliūdžius +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. +use core::{net::SocketAddr, str::FromStr}; + +use anyhow::anyhow; +use api::{ + error::ServerError, game::GameId, message::WrappedServerMessage, state::AppState, + token::TokenString, +}; +use axum::{ + extract::{ConnectInfo, Path, State, WebSocketUpgrade, ws::WebSocket}, + response::Response, +}; +use axum_extra::{ + TypedHeader, + headers::{self, Authorization, authorization::Bearer}, +}; +use codee::{Decoder, HybridDecoder, HybridEncoder}; +use colored::Colorize; +use futures::FutureExt; +use uuid::Uuid; +use werewolves_proto::{error::GameError, message::ServerToClientMessage}; + +use crate::{LogError, server::XForwardedFor}; + +pub async fn handler( + ws: WebSocketUpgrade, + user_agent: Option<TypedHeader<headers::UserAgent>>, + x_forwarded_for: Option<TypedHeader<XForwardedFor>>, + ConnectInfo(addr): ConnectInfo<SocketAddr>, + State(AppState { db, .. }): State<AppState>, + Path(game_id): Path<String>, +) -> Result<Response, ServerError> { + let game_id = GameId::from_uuid(match Uuid::from_str(&game_id) { + Ok(u) => u, + Err(_) => return Err(ServerError::NotFound), + }); + let user_agent = user_agent.map(|a| { + if a.as_str().contains("Chrome") { + "Chrome".to_string() + } else if a.as_str().contains("Firefox") { + "Firefox".to_string() + } else { + a.to_string() + } + }); + let who = x_forwarded_for + .map(|fwd| { + user_agent + .as_ref() + .map(|agent| format!("{}({})", fwd.0, agent)) + .unwrap_or_else(|| fwd.to_string()) + }) + .unwrap_or_else(|| { + format!( + "{addr}{}", + user_agent.map(|a| format!("({a})")).unwrap_or_default() + ) + }); + log::info!("{who} connected for game {game_id}."); + Ok(ws + .on_failed_upgrade(|err| log::error!("failed upgrade: {err}")) + .on_upgrade(move |mut socket| async move { + log::info!("ws up {who}"); + let token: TokenString = loop { + let get_token_result = socket.recv().await.map(|msg| -> Result<_, anyhow::Error> { + let data = msg?.into_data().to_vec(); + + match codee::binary::MsgpackSerdeCodec::decode_bin(&data)? { + WrappedServerMessage::Authentication(auth) => { + Result::<TokenString, anyhow::Error>::Ok(auth) + } + other => Err(anyhow::anyhow!("expected auth, got {other:?}")), + } + }); + match get_token_result { + Some(Ok(token)) => break token, + Some(Err(err)) => { + log::error!("get token: {err}"); + } + None => { + return; + } + }; + }; + + let user = match db.user().check_token(&token).await { + Ok(user) => user, + Err(err) => { + log::error!("check token: {err}"); + super::send_error(err, &mut socket).await; + return; + } + }; + let game = match db.game().get_game(game_id).await { + Ok(g) => g, + Err(err) => { + log::error!("get game: {err}"); + super::send_error(err.into(), &mut socket).await; + return; + } + }; + if user.id == game.host { + log::info!("transferring {}({who}) to host handler", user.username); + super::host::host_handler(socket, who.clone(), db, game, user).await + } else { + log::info!("transferring {}({who}) to player handler", user.username); + super::player::player_handler(socket, who.clone(), db, game, user).await + }; + log::info!("{} disconnected", format!("[{who}]").as_str().red()); + })) +} diff --git a/werewolves/src/server/game_end.rs b/werewolves/src/server/game_end.rs new file mode 100644 index 0000000..fa71ca3 --- /dev/null +++ b/werewolves/src/server/game_end.rs @@ -0,0 +1,64 @@ +use api::game::GameId; +use werewolves_proto::{ + game::story::GameStory, + message::{ + Identification, ServerToClientMessage, + host::{HostMessage, ServerToHostMessage}, + }, +}; + +use crate::server::runner::{ClientUpdate, HostOrClientMessage, IdentifiedClientMessage}; + +pub struct GameEnd { + game_id: GameId, + story: GameStory, +} + +impl GameEnd { + pub fn new(game_id: GameId, story: GameStory) -> Self { + Self { game_id, story } + } + + pub async fn notify_connected(&self) { + super::send_to_all_players_in_game( + self.game_id, + ServerToClientMessage::Story(self.story.clone()), + ) + .await; + } + + pub async fn process(&self, msg: HostOrClientMessage) { + match msg { + HostOrClientMessage::Host(HostMessage::Echo(msg)) => { + super::send_host(self.game_id, msg).await; + } + HostOrClientMessage::Host(HostMessage::GetState) => { + super::send_host( + self.game_id, + ServerToHostMessage::Story { + story: self.story.clone(), + page: 0, + }, + ) + .await; + } + HostOrClientMessage::Host(_) => {} + + HostOrClientMessage::Client(IdentifiedClientMessage { + update: ClientUpdate::ConnectStateUpdate { .. }, + .. + }) => {} + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, .. }, + .. + }) => { + super::send_player( + self.game_id, + player_id, + ServerToClientMessage::Story(self.story.clone()), + ) + .await + } + } + } +} diff --git a/werewolves/src/server/host.rs b/werewolves/src/server/host.rs new file mode 100644 index 0000000..8630df8 --- /dev/null +++ b/werewolves/src/server/host.rs @@ -0,0 +1,135 @@ +// Copyright (C) 2025-2026 Emilis Bliūdžius +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +use anyhow::anyhow; +use api::{ + db::{Database, user::User}, + error::ServerError, + game::GameRecord, + message::{IntoClientResponse, WrappedServerMessage}, +}; +use axum::extract::ws::{self, Message, WebSocket}; +use codee::{HybridDecoder, HybridEncoder}; +use colored::Colorize; +use tokio::sync::{broadcast, mpsc::UnboundedSender}; +use werewolves_proto::message::host::{HostMessage, ServerToHostMessage}; + +use crate::{LogError, loc}; + +pub async fn host_handler( + mut ws: WebSocket, + who: String, + db: Database, + game: GameRecord, + user: User, +) { + if user.id != game.host { + super::send_error(ServerError::NotFound, &mut ws).await; + return; + } + let (send, recv) = super::new_host_connection(game.id, db).await; + send.send(HostMessage::GetState).log_debug(loc!()); + Host::new(ws, who, send, recv).run().await; +} + +struct Host { + socket: WebSocket, + who: String, + host_send: UnboundedSender<HostMessage>, + server_recv: broadcast::Receiver<ServerToHostMessage>, +} + +impl Host { + pub fn new( + socket: WebSocket, + who: String, + host_send: UnboundedSender<HostMessage>, + server_recv: broadcast::Receiver<ServerToHostMessage>, + ) -> Self { + Self { + who, + socket, + host_send, + server_recv, + } + } + + async fn on_recv( + &mut self, + msg: Option<Result<Message, axum::Error>>, + ) -> Result<(), anyhow::Error> { + let Some(msg) = msg else { return Ok(()) }; + let msg: WrappedServerMessage = + codee::binary::MsgpackSerdeCodec::decode_bin(&msg?.into_data())?; + let msg = match msg { + WrappedServerMessage::ClientMessage(msg) => { + return Err(anyhow!("host handler got client message: {msg:?}")); + } + WrappedServerMessage::Authentication(_) => { + return Err(anyhow!("invalid point for getting authentication")); + } + WrappedServerMessage::HostMessage(msg) => msg, + }; + log::debug!( + "{}({}) {}", + "[host::incoming::message]".bold(), + self.who.dimmed(), + format!("{msg:?}").dimmed() + ); + self.host_send.send(msg)?; + Ok(()) + } + + async fn send_message(&mut self, msg: ServerToHostMessage) -> Result<(), anyhow::Error> { + log::debug!( + "sending {} message to {}", + msg.title().to_string().bold(), + self.who.dimmed() + ); + Ok(self + .socket + .send(ws::Message::Binary( + codee::binary::MsgpackSerdeCodec::encode_bin(&IntoClientResponse::Host(msg))? + .into(), + )) + .await?) + } + + pub async fn run(mut self) { + loop { + tokio::select! { + msg = self.socket.recv() => { + if let Err(err) = self.on_recv(msg).await { + log::error!("{} {err}", "[host::incoming]".bold()); + return; + } + }, + msg = self.server_recv.recv() => { + match msg { + Ok(msg) => { + if let Err(err) = self.send_message(msg).await { + log::error!("{} {err}", "[host::outgoing]".bold()) + } + }, + Err(err) => { + log::error!("{} {err}", "[host::mpsc]".bold()); + return; + } + } + } + }; + } + } +} diff --git a/werewolves/src/server/lobby.rs b/werewolves/src/server/lobby.rs new file mode 100644 index 0000000..1c453d9 --- /dev/null +++ b/werewolves/src/server/lobby.rs @@ -0,0 +1,378 @@ +// Copyright (C) 2025-2026 Emilis Bliūdžius +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. +use core::{ + num::NonZeroU8, + ops::{Deref, DerefMut}, +}; +use std::collections::HashSet; + +use api::{ + db::Database, + error::ServerError, + game::{GameId, GameRecord}, +}; +use colored::Colorize; +use tokio::sync::broadcast::Sender; +use werewolves_proto::{ + error::GameError, + game::GameSettings, + message::{ + ClientMessage, Identification, PlayerState, PublicIdentity, ServerToClientMessage, + UpdateSelf, + host::{HostLobbyMessage, HostMessage, ServerToHostMessage}, + }, + player::PlayerId, +}; + +use crate::{ + LogError, loc, + server::runner::{ClientUpdate, HostOrClientMessage, IdentifiedClientMessage}, +}; + +pub struct Lobby<'a> { + game_id: GameId, + settings: &'a mut GameSettings, + db: Database, + qr_mode: bool, + connected: HashSet<PlayerId>, +} + +impl<'a> Lobby<'a> { + pub fn new(game_id: GameId, settings: &'a mut GameSettings, db: Database) -> Self { + Self { + db, + game_id, + settings, + qr_mode: false, + connected: HashSet::new(), + } + } + + pub fn set_settings(&mut self, settings: GameSettings) { + *self.settings = settings.clone(); + } + + pub const fn settings(&self) -> &GameSettings { + &self.settings + } + + pub async fn send_lobby_info_to_clients(&mut self) -> Result<(), ServerError> { + let (players, identities) = self + .db + .game() + .get_joined_players(self.game_id) + .await? + .into_iter() + .map(|p| (p.player_id, p.public)) + .collect::<(Vec<_>, Vec<_>)>(); + let identities = identities.into_boxed_slice(); + super::send_to_all_players_in_game_filtered(self.game_id, move |pid| { + Some(ServerToClientMessage::LobbyInfo { + joined: players.contains(&pid), + players: identities.clone(), + }) + }) + .await; + Ok(()) + } + + async fn get_lobby_info(&self) -> Result<Box<[PlayerState]>, ServerError> { + Ok(self + .db + .game() + .get_joined_players(self.game_id) + .await? + .into_iter() + .map(|p| PlayerState { + connected: self.connected.contains(&p.player_id), + identification: Identification { + player_id: p.player_id, + public: p.public, + }, + }) + .collect()) + } + + pub async fn send_lobby_info_to_host(&mut self) -> Result<(), ServerError> { + let players = self.get_lobby_info().await?; + let qr_mode = self.qr_mode; + let settings = self.settings.clone(); + + super::send_host( + self.game_id, + ServerToHostMessage::Lobby { + players, + settings, + qr_mode, + }, + ) + .await; + Ok(()) + } + + pub async fn process(&mut self, msg: HostOrClientMessage) -> Option<GameRecord> { + match self.next_inner(msg.clone()).await.map_err(|err| (msg, err)) { + Err(( + HostOrClientMessage::Client(IdentifiedClientMessage { + update: ClientUpdate::ConnectStateUpdate { .. }, + .. + }), + _, + )) + | Ok(None) => None, + Ok(Some(game)) => Some(game), + Err((HostOrClientMessage::Host(_), ServerError::GameError(err))) => { + super::send_host(self.game_id, ServerToHostMessage::Error(err)).await; + None + } + Err((HostOrClientMessage::Host(_), err)) => { + log::warn!( + "server error from host request for game({}): {err}", + self.game_id + ); + super::send_host( + self.game_id, + ServerToHostMessage::Error(GameError::GenericError(err.to_string())), + ) + .await; + None + } + Err(( + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, public }, + .. + }), + err, + )) => { + log::error!("processing message from {public} [{player_id}]: {err}"); + super::send_player(self.game_id, player_id, ServerToClientMessage::Reset).await; + None + } + } + } + + async fn next_inner( + &mut self, + msg: HostOrClientMessage, + ) -> Result<Option<GameRecord>, ServerError> { + match msg { + HostOrClientMessage::Client(IdentifiedClientMessage { + update: ClientUpdate::Message(ClientMessage::DeadChat(_)), + .. + }) => { + log::warn!("dead chat message in lobby? ignoring."); + } + HostOrClientMessage::Host(HostMessage::Lobby(HostLobbyMessage::ManufacturePlayer( + public, + ))) => { + log::info!("adding player {public:?} by host request"); + let dummy = self + .db + .user() + .create_dummy_user(&public.name, public.pronouns) + .await?; + self.db + .game() + .join_game(self.game_id, dummy.id, public.number) + .await?; + + self.send_lobby_info_to_clients().await.log_debug(loc!()); + self.send_lobby_info_to_host().await.log_debug(loc!()); + } + HostOrClientMessage::Host(HostMessage::Lobby(HostLobbyMessage::SetQrMode(mode))) => { + self.qr_mode = mode; + self.send_lobby_info_to_host().await.log_debug(loc!()); + } + HostOrClientMessage::Host(HostMessage::InGame(_)) + | HostOrClientMessage::Host(HostMessage::ForceRoleAckFor(_)) => { + return Err(GameError::InvalidMessageForGameState.into()); + } + HostOrClientMessage::Host(HostMessage::PostGame(_)) => { + return Err(GameError::GameOngoing.into()); + } + HostOrClientMessage::Host(HostMessage::Lobby(HostLobbyMessage::GetState)) + | HostOrClientMessage::Host(HostMessage::GetState) => { + self.send_lobby_info_to_host().await?; + } + HostOrClientMessage::Host(HostMessage::Lobby(HostLobbyMessage::SetGameSettings( + settings, + ))) => { + *self.settings = settings; + self.send_lobby_info_to_host().await?; + } + HostOrClientMessage::Host(HostMessage::Lobby(HostLobbyMessage::SetPlayerNumber( + pid, + num, + ))) => { + self.db + .game() + .set_player_number(self.game_id, pid.into(), Some(num)) + .await?; + + self.send_lobby_info_to_clients().await.log_debug(loc!()); + self.send_lobby_info_to_host().await.log_debug(loc!()); + } + HostOrClientMessage::Host(HostMessage::Lobby(HostLobbyMessage::Start)) => { + return Ok(Some(self.db.game().start_game(self.game_id).await?)); + } + HostOrClientMessage::Client(IdentifiedClientMessage { + identity, + update: ClientUpdate::Message(ClientMessage::Hello), + }) => { + self.db + .game() + .join_game( + self.game_id, + identity.player_id.into(), + identity.public.number, + ) + .await?; + + self.send_lobby_info_to_clients().await.log_debug(loc!()); + self.send_lobby_info_to_host().await?; + } + HostOrClientMessage::Host(HostMessage::Lobby(HostLobbyMessage::Kick(player_id))) + | HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, .. }, + update: ClientUpdate::Message(ClientMessage::Goodbye), + }) => { + self.db + .game() + .leave_game(self.game_id, player_id.into()) + .await?; + + self.send_lobby_info_to_host().await?; + self.send_lobby_info_to_clients().await.log_debug(loc!()); + } + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, .. }, + update: ClientUpdate::Message(ClientMessage::GetState), + }) => { + let joined = self.db.game().get_joined_players(self.game_id).await?; + let msg = ServerToClientMessage::LobbyInfo { + joined: joined.iter().any(|p| p.player_id == player_id), + players: joined.into_iter().map(|p| p.public).collect(), + }; + super::send_player(self.game_id, player_id, msg).await; + } + HostOrClientMessage::Client(IdentifiedClientMessage { + update: ClientUpdate::Message(ClientMessage::RoleAck), + .. + }) => return Err(GameError::InvalidMessageForGameState.into()), + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, .. }, + update: ClientUpdate::Message(ClientMessage::UpdateSelf(UpdateSelf::Number(number))), + }) => { + self.db + .game() + .set_player_number(self.game_id, player_id.into(), Some(number)) + .await?; + self.send_lobby_info_to_clients() + .await + .log_debug(crate::loc!()); + self.send_lobby_info_to_host().await.log_warn(loc!()); + } + HostOrClientMessage::Client(IdentifiedClientMessage { + update: ClientUpdate::Message(ClientMessage::UpdateSelf(_)), + .. + }) => { + self.send_lobby_info_to_clients().await.log_debug(loc!()); + self.send_lobby_info_to_host().await.log_warn(loc!()); + } + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, public }, + update: ClientUpdate::ConnectStateUpdate { connected }, + }) => { + log::debug!( + "player [{public}] is now {}", + if connected { + "connected".green() + } else { + "disconnected".red() + } + ); + match connected { + true => self.connected.insert(player_id), + false => self.connected.remove(&player_id), + }; + self.send_lobby_info_to_host().await?; + } + HostOrClientMessage::Host(HostMessage::Echo(msg)) => { + super::send_host(self.game_id, msg).await; + } + } + + Ok(None) + } +} + +#[derive(Clone)] +pub struct LobbyPlayers(Vec<(Identification, Option<Sender<ServerToClientMessage>>)>); + +impl Deref for LobbyPlayers { + type Target = Vec<(Identification, Option<Sender<ServerToClientMessage>>)>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for LobbyPlayers { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl LobbyPlayers { + pub fn with_dummies(dummy_count: NonZeroU8) -> Self { + Self( + (0..dummy_count.get()) + .map(|p| { + ( + Identification { + player_id: PlayerId::from_u128(p as u128 + 1), + public: PublicIdentity { + name: format!("Player {}", p as u16 + 1), + pronouns: Some(String::from("he/him")), + number: NonZeroU8::new(p + 1), + }, + }, + None, + ) + }) + .collect(), + ) + } + pub fn find(&self, player_id: PlayerId) -> Option<&Sender<ServerToClientMessage>> { + self.iter() + .filter_map(|(id, s)| s.as_ref().map(|s| (id, s))) + .find_map(|(id, s)| (id.player_id == player_id).then_some(s)) + } + + pub fn send_if_present( + &self, + player_id: PlayerId, + message: ServerToClientMessage, + ) -> Result<bool, GameError> { + if let Some(sender) = self.find(player_id) { + sender + .send(message) + .map_err(|err| GameError::GenericError(err.to_string()))?; + Ok(true) + } else { + Ok(false) + } + } +} diff --git a/werewolves/src/server/mod.rs b/werewolves/src/server/mod.rs new file mode 100644 index 0000000..f5c0b70 --- /dev/null +++ b/werewolves/src/server/mod.rs @@ -0,0 +1,381 @@ +pub mod game; +pub mod game_connection; +pub mod game_end; +pub mod host; +pub mod lobby; +pub mod player; +pub mod qr; +pub mod role_reveal; +pub mod runner; + +use core::{ + fmt::Display, + hash::BuildHasherDefault, + sync::atomic::{AtomicUsize, Ordering}, +}; +use std::{ + collections::{HashMap, HashSet}, + hash::DefaultHasher, + sync::{Arc, LazyLock}, +}; + +use api::{db::Database, game::GameId}; +use axum::http::header; +use axum_extra::headers; +use colored::Colorize; +use tokio::{ + sync::{ + Mutex, RwLock, + broadcast::{self, Receiver, Sender}, + mpsc::{self, UnboundedSender}, + }, + task::JoinHandle, + time::Instant, +}; +use werewolves_proto::{ + message::{ + ServerToClientMessage, + host::{HostMessage, ServerToHostMessage}, + }, + player::PlayerId, +}; + +use crate::{loc, server::runner::IdentifiedClientMessage}; + +pub struct XForwardedFor(String); + +impl Display for XForwardedFor { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.0.as_str()) + } +} + +impl headers::Header for XForwardedFor { + fn name() -> &'static header::HeaderName { + static NAME: header::HeaderName = header::HeaderName::from_static("x-forwarded-for"); + &NAME + } + + fn decode<'i, I>(values: &mut I) -> Result<Self, headers::Error> + where + Self: Sized, + I: Iterator<Item = &'i header::HeaderValue>, + { + Ok(Self( + values + .next() + .and_then(|v| v.to_str().ok()) + .ok_or(headers::Error::invalid())? + .to_string(), + )) + } + + fn encode<E: Extend<header::HeaderValue>>(&self, _: &mut E) {} +} +#[derive(Debug)] +pub struct GameChannels { + recv_server_msg: Receiver<ServerToHostMessage>, + send_to_host: Sender<ServerToHostMessage>, + send_to_server: UnboundedSender<HostMessage>, + send_client_msg: UnboundedSender<IdentifiedClientMessage>, + runner_handle: Arc<JoinHandle<()>>, +} + +impl GameChannels { + pub fn new( + recv_server_msg: Receiver<ServerToHostMessage>, + send_to_host: Sender<ServerToHostMessage>, + send_to_server: UnboundedSender<HostMessage>, + send_client_msg: UnboundedSender<IdentifiedClientMessage>, + runner_handle: Arc<JoinHandle<()>>, + ) -> Self { + Self { + send_to_host, + runner_handle, + send_to_server, + send_client_msg, + recv_server_msg, + } + } +} + +impl Clone for GameChannels { + fn clone(&self) -> Self { + Self { + send_to_host: self.send_to_host.clone(), + runner_handle: self.runner_handle.clone(), + send_to_server: self.send_to_server.clone(), + send_client_msg: self.send_client_msg.clone(), + recv_server_msg: self.recv_server_msg.resubscribe(), + } + } +} + +static HOST_CHANNELS: RwLock<HashMap<GameId, GameChannels, BuildHasherDefault<DefaultHasher>>> = + RwLock::const_new(HashMap::with_hasher(BuildHasherDefault::new())); + +static PLAYER_CHANNELS: RwLock< + HashMap<(GameId, PlayerId), PlayerChannels, BuildHasherDefault<DefaultHasher>>, +> = RwLock::const_new(HashMap::with_hasher(BuildHasherDefault::new())); + +pub struct PlayerChannels { + recv_server_msg: Receiver<ServerToClientMessage>, + send_to_player: Sender<ServerToClientMessage>, +} + +impl Clone for PlayerChannels { + fn clone(&self) -> Self { + Self { + send_to_player: self.send_to_player.clone(), + recv_server_msg: self.recv_server_msg.resubscribe(), + } + } +} + +pub async fn new_host_connection( + game: GameId, + db: Database, +) -> (UnboundedSender<HostMessage>, Receiver<ServerToHostMessage>) { + let GameChannels { + recv_server_msg, + send_to_server, + .. + } = get_or_init_game(game, db).await; + (send_to_server, recv_server_msg) +} + +pub async fn get_or_init_game(game: GameId, db: Database) -> GameChannels { + let mut host_guard = HOST_CHANNELS.write().await; + + if let Some(s) = host_guard.get(&game) { + return s.clone(); + } + let (send_client_msg, client_recv) = mpsc::unbounded_channel(); + let (send_to_server, recv_host_msg) = mpsc::unbounded_channel(); + + static RUNTIME: LazyLock<tokio::runtime::Runtime> = LazyLock::new(|| { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .expect("building game runner runtime") + }); + let runner_handle = Arc::new(RUNTIME.spawn(async move { + match db.game().get_game(game).await { + Ok(game) => runner::run_game(db, game, client_recv, recv_host_msg).await, + Err(err) => log::error!("getting game {game} to start runner: {err}"), + } + })); + let (send_to_host, recv_server_msg) = broadcast::channel(0x100); + let host = GameChannels { + send_to_host, + runner_handle, + send_to_server, + send_client_msg, + recv_server_msg, + }; + if let Some(existing) = host_guard.insert(game, host.clone()) { + log::error!("host_guard already had game {game}??: {existing:?}"); + } + host +} + +pub async fn new_player_connection( + game: GameId, + player: PlayerId, + db: Database, +) -> ( + UnboundedSender<IdentifiedClientMessage>, + Receiver<ServerToClientMessage>, +) { + let GameChannels { + send_client_msg, .. + } = get_or_init_game(game, db).await; + + let mut channels = PLAYER_CHANNELS.write().await; + + let mut c = CONNECTION_COUNT.write().await; + if let Some(cnt) = c.get_mut(&player) { + *cnt += 1; + } else { + c.insert(player, 1usize); + } + core::mem::drop(c); + + if let Some(ch) = channels.get(&(game, player)) { + return (send_client_msg, ch.recv_server_msg.resubscribe()); + } + let (send_to_player, recv_server_msg) = broadcast::channel(0x100); + let host = PlayerChannels { + recv_server_msg: recv_server_msg.resubscribe(), + send_to_player, + }; + channels.insert((game, player), host); + + (send_client_msg, recv_server_msg) +} + +/// returns true if this is the last connection for this player +pub async fn player_disconnecting(player: PlayerId) -> bool { + let mut maybe_cnt = CONNECTION_COUNT.write().await; + if let Some(cnt) = maybe_cnt.get_mut(&player) { + if *cnt <= 1 { + maybe_cnt.remove(&player); + return true; + } + *cnt -= 1; + return false; + }; + + true +} + +pub async fn send_player(game: GameId, player: PlayerId, message: ServerToClientMessage) { + let title = message.title(); + if let Some(s) = PLAYER_CHANNELS + .read() + .await + .get(&(game, player)) + .map(|p| p.send_to_player.clone()) + { + if let Err(err) = s.send(message) { + log::warn!("sending [{title}] message to {player} for game {game}: {err}"); + } + } +} + +pub async fn send_host(game: GameId, message: ServerToHostMessage) { + let title = message.title(); + if let Some(s) = HOST_CHANNELS + .read() + .await + .get(&game) + .map(|h| h.send_to_host.clone()) + && let Err(err) = s.send(message) + { + log::warn!("sending [{title}] message to host for game {game}: {err}"); + } +} + +pub async fn send_to_all_players_in_game(game: GameId, message: ServerToClientMessage) { + let title = message.title(); + let senders = PLAYER_CHANNELS + .read() + .await + .iter() + .filter_map(|((game_id, _), channels)| { + (game == *game_id).then_some(channels.send_to_player.clone()) + }) + .collect::<Box<_>>(); + for sender in senders { + if let Err(err) = sender.send(message.clone()) { + log::debug!( + "error sending {title} message to all players in game {game}: {err}; continuing..." + ); + } + } +} + +pub async fn send_to_all_players_in_game_filtered<F>(game: GameId, message_fn: F) +where + F: Fn(PlayerId) -> Option<ServerToClientMessage>, +{ + let senders = PLAYER_CHANNELS + .read() + .await + .iter() + .filter_map(|((game_id, pid), channels)| { + (game == *game_id).then_some((*pid, channels.send_to_player.clone())) + }) + .collect::<Box<_>>(); + for (pid, sender) in senders { + let Some(message) = (message_fn)(pid) else { + continue; + }; + let title = message.title(); + if let Err(err) = sender.send(message.clone()) { + log::debug!( + "error sending {title} message to player {pid} (trying to send to all joined) in game {game}: {err}; continuing..." + ); + } + } +} + +async fn send_error(err: api::error::ServerError, socket: &mut axum::extract::ws::WebSocket) { + use crate::LogError; + use codee::HybridEncoder; + socket + .send(axum::extract::ws::Message::Binary( + codee::binary::MsgpackSerdeCodec::encode_bin(&ServerToClientMessage::Error( + werewolves_proto::error::GameError::GenericError(err.to_string()), + )) + .unwrap() + .into(), + )) + .await + .log_warn(loc!()); +} + +static CONNECTION_COUNT: RwLock<HashMap<PlayerId, usize, BuildHasherDefault<DefaultHasher>>> = + RwLock::const_new(HashMap::with_hasher(BuildHasherDefault::new())); + +pub async fn clear_abandoned_game_runners() { + let start = Instant::now(); + let mut hosts = HOST_CHANNELS.write().await; + let mut players = PLAYER_CHANNELS.write().await; + + let has_players = players.iter().map(|p| p.0.0).collect::<HashSet<_>>(); + let no_players_game_ids = hosts + .keys() + .filter(|g| !has_players.contains(*g)) + .copied() + .collect::<Vec<_>>(); + + let (no_hosts, has_hosts) = hosts + .iter() + .partition::<HashMap<_, _>, _>(|h| h.1.send_to_server.strong_count() == 1); + let (no_hosts_game_ids, has_hosts_game_ids) = ( + no_hosts.into_iter().map(|h| *h.0).collect::<Vec<_>>(), + has_hosts.into_iter().map(|h| *h.0).collect::<Vec<_>>(), + ); + let games_to_remove = no_players_game_ids + .clone() + .into_iter() + .filter(|pg| !has_hosts_game_ids.contains(pg)) + .collect::<HashSet<_>>(); + { + let remaining = hosts + .keys() + .filter(|k| !games_to_remove.contains(*k)) + .collect::<Vec<_>>(); + log::info!("stale game sessions to remove: {games_to_remove:?}; remaining: {remaining:?}"); + log::info!("no hosts: {no_hosts_game_ids:?}"); + log::info!("no players: {no_players_game_ids:?}"); + }; + let handles = games_to_remove + .iter() + .filter_map(|id| hosts.get(id)) + .map(|ch| ch.runner_handle.clone()) + .collect::<Vec<_>>(); + + let player_keys = players + .keys() + .filter(|k| games_to_remove.contains(&k.0)) + .copied() + .collect::<HashSet<_>>(); + for id in player_keys { + players.remove(&id); + } + for id in games_to_remove { + hosts.remove(&id); + } + for handle in handles { + if !handle.is_finished() { + handle.abort(); + } + } + let duration = start.elapsed(); + log::info!( + "{} took {duration:?}", + "[clear_abandoned_game_runners]".bold() + ) +} diff --git a/werewolves/src/server/player.rs b/werewolves/src/server/player.rs new file mode 100644 index 0000000..0965b89 --- /dev/null +++ b/werewolves/src/server/player.rs @@ -0,0 +1,329 @@ +// Copyright (C) 2025-2026 Emilis Bliūdžius +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. +use core::{net::SocketAddr, time::Duration}; +use std::sync::Arc; + +use anyhow::anyhow; +use api::{ + db::{Database, user::User}, + error::ServerError, + game::{GameId, GameRecord}, + message::{IntoClientResponse, WrappedServerMessage}, + state::AppState, +}; +use axum::{ + extract::{ + ConnectInfo, Path, State, WebSocketUpgrade, + ws::{self, Message, WebSocket}, + }, + response::Response, +}; +use axum_extra::{ + TypedHeader, + headers::{Authorization, authorization::Bearer}, +}; +use chrono::Utc; +use codee::{HybridDecoder, HybridEncoder}; +use colored::Colorize; +use tokio::sync::{broadcast::Receiver, mpsc::UnboundedSender}; +use werewolves_proto::message::{ + ClientMessage, Identification, PublicIdentity, ServerToClientMessage, UpdateSelf, +}; + +use crate::{ + LogError, loc, + server::{ + XForwardedFor, + runner::{ClientUpdate, HostOrClientMessage, IdentifiedClientMessage}, + }, +}; + +pub async fn player_handler( + ws: WebSocket, + who: String, + db: Database, + game: GameRecord, + user: User, +) { + let identity = Identification { + player_id: user.id.into(), + public: PublicIdentity { + name: user.display_name.unwrap_or(user.username), + pronouns: user.pronouns, + number: db + .game() + .get_player_number(game.id, user.id) + .await + .unwrap_or_default(), + }, + }; + + let (send, recv) = super::new_player_connection(game.id, user.id.into(), db.clone()).await; + if recv.is_closed() || send.is_closed() { + log::error!( + "recv closed: {}; send closed: {}", + recv.is_closed(), + send.is_closed() + ); + } + send.send(IdentifiedClientMessage { + identity: identity.clone(), + update: ClientUpdate::ConnectStateUpdate { connected: true }, + }) + .log_debug(loc!()); + send.send(IdentifiedClientMessage { + identity: identity.clone(), + update: ClientUpdate::Message(ClientMessage::GetState), + }) + .log_debug(loc!()); + Client::new(identity.clone(), ws, who.to_string(), send.clone(), recv) + .run() + .await; + if super::player_disconnecting(identity.player_id).await { + send.send(IdentifiedClientMessage { + identity, + update: ClientUpdate::ConnectStateUpdate { connected: false }, + }) + .log_warn(loc!()); + } +} + +// pub async fn player_handler( +// ws: WebSocketUpgrade, +// who: String, +// db: Database, +// game: GameRecord, +// user: User, +// ) -> Result<Response, ServerError> { +// // finalize the upgrade process by returning upgrade callback. +// // we can customize the callback by sending additional info such as address. +// Ok(ws.on_upgrade(move |mut socket| async move { +// // log::debug!("connected {who} as {ident}"); + +// // state +// // .send +// // .send(IdentifiedClientMessage { +// // identity: ident.clone(), +// // update: ClientUpdate::ConnectStateUpdate, +// // }) +// // .log_debug(loc!()); +// let (send, recv) = super::new_player_connection(game.id, user.id.into(), db).await; + +// Client::new(ident.clone(), socket, who.to_string(), send, recv) +// .run() +// .await; + +// // player_list.disconnect(&connection_id).await; +// // state +// // .send +// // .send(IdentifiedClientMessage { +// // identity: ident.clone(), +// // update: ClientUpdate::ConnectStateUpdate, +// // }) +// // .log_debug(loc!()); +// })) +// } + +async fn get_identification( + socket: &mut WebSocket, + who: &str, +) -> Result<Identification, anyhow::Error> { + loop { + let msg_bytes = &socket + .recv() + .await + .ok_or(anyhow::anyhow!( + "connection from {who} closed before identification" + ))? + .map_err(|err| anyhow::anyhow!("connection error from {who} at identification: {err}"))? + .into_data(); + + let res = codee::binary::MsgpackSerdeCodec::decode_bin(msg_bytes); + match res { + Ok(id) => return Ok(id), + Err(err) => { + log::error!("invalid identification message from {who}: {err}"); + continue; + } + } + } +} + +#[allow(unused)] +enum MessagePayload { + Bytes(axum::body::Bytes), + Utf8(ws::Utf8Bytes), +} + +struct Client { + ident: Identification, + socket: WebSocket, + who: String, + sender: UnboundedSender<IdentifiedClientMessage>, + receiver: Receiver<ServerToClientMessage>, +} + +impl Client { + fn new( + ident: Identification, + socket: WebSocket, + who: String, + sender: UnboundedSender<IdentifiedClientMessage>, + receiver: Receiver<ServerToClientMessage>, + ) -> Self { + Self { + ident, + socket, + who, + sender, + receiver, + } + } + fn decode_message(msg: MessagePayload) -> Result<ClientMessage, anyhow::Error> { + let decoded: WrappedServerMessage = match msg { + MessagePayload::Bytes(bytes) => codee::binary::MsgpackSerdeCodec::decode_bin(&bytes)?, + MessagePayload::Utf8(s) => codee::binary::MsgpackSerdeCodec::decode_str(&s)?, + }; + + match decoded { + WrappedServerMessage::ClientMessage(msg) => Ok(msg), + WrappedServerMessage::HostMessage(msg) => Err(anyhow!( + "got host message [{msg:?}] when expecting client message" + )), + WrappedServerMessage::Authentication(_) => Err(anyhow!( + "unexpected authentication when expecting client message" + )), + } + } + async fn on_recv(&mut self, msg: Result<Message, axum::Error>) -> Result<(), anyhow::Error> { + use crate::LogError; + + let msg = match msg { + Ok(msg) => msg, + Err(err) => return Err(err.into()), + }; + + let message: ClientMessage = match msg { + Message::Binary(bytes) => Self::decode_message(MessagePayload::Bytes(bytes))?, + Message::Text(text) => Self::decode_message(MessagePayload::Utf8(text))?, + Message::Ping(ping) => { + self.socket + .send(Message::Pong(ping)) + .await + .log_debug(loc!()); + return Ok(()); + } + Message::Pong(pong) => { + const TOO_SLOW_SECONDS: i64 = 30; + let mut pong_ts = [0u8; core::mem::size_of::<u64>()]; + pong.iter() + .take(pong_ts.len()) + .enumerate() + .for_each(|(idx, b)| pong_ts[idx] = *b); + let ts = i64::from_le_bytes(pong_ts); + let now = Utc::now().timestamp(); + let rtt_seconds = now - ts; + if rtt_seconds > TOO_SLOW_SECONDS { + self.socket + .send(Message::Close(None)) + .await + .log_debug(loc!()); + return Err(anyhow::anyhow!( + "rtt (seconds): {rtt_seconds} > {TOO_SLOW_SECONDS}" + )); + } + + return Ok(()); + } + Message::Close(Some(_)) => { + // log::debug!("sent close frame: {close_frame:?}"); + return Ok(()); + } + Message::Close(None) => { + // log::debug!("host closed connection"); + return Ok(()); + } + }; + if let ClientMessage::UpdateSelf(update) = &message { + match update { + UpdateSelf::Name(name) => self.ident.public.name = name.clone(), + UpdateSelf::Number(num) => self.ident.public.number = Some(*num), + UpdateSelf::Pronouns(pronouns) => self.ident.public.pronouns = pronouns.clone(), + } + } + + self.sender.send(IdentifiedClientMessage { + update: ClientUpdate::Message(message), + identity: self.ident.clone(), + })?; + + Ok(()) + } + + async fn send_message(&mut self, message: ServerToClientMessage) -> Result<(), anyhow::Error> { + self.socket + .send({ + ws::Message::Binary( + codee::binary::MsgpackSerdeCodec::encode_bin(&IntoClientResponse::Player( + message, + ))? + .into(), + ) + }) + .await?; + + Ok(()) + } + + async fn run(mut self) { + const PING_TIME: Duration = Duration::from_secs(3); + loop { + let sleep_fut = tokio::time::sleep(PING_TIME); + + if let Err(err) = tokio::select! { + _ = sleep_fut => { + let _ = self.socket + .send(Message::Ping(bytes::Bytes::from_owner( + Utc::now().timestamp().to_le_bytes(), + ))) + .await; + continue; + } + msg = self.socket.recv() => { + match msg { + Some(msg) => self.on_recv(msg).await, + None => { + return; + }, + } + }, + r = self.receiver.recv() => { + match r { + Ok(msg) => { + self.send_message(msg).await + } + Err(err) => { + log::debug!("[{}] recv error: {err}", self.ident.public); + return; + } + } + } + } { + log::error!("[{}][{}] {err}", self.ident.public, self.who); + return; + } + } + } +} diff --git a/werewolves/src/server/qr.rs b/werewolves/src/server/qr.rs new file mode 100644 index 0000000..d1c9d9d --- /dev/null +++ b/werewolves/src/server/qr.rs @@ -0,0 +1,40 @@ +use axum::{ + extract::Path, + http::{StatusCode, header}, + response::IntoResponse, +}; +use fast_qr::convert::{Builder, Shape, svg::SvgBuilder}; +use tower_http::normalize_path::NormalizePath; + +const DEFAULT_BASE_URL: &str = "https://wolf.emilis.dev/"; +pub const BASE_URL: &str = const { + match option_env!("BASE_URL") { + Some(qrcode) => qrcode, + None => DEFAULT_BASE_URL, + } +}; + +pub async fn qr_code(Path(game_id): Path<String>) -> impl IntoResponse { + let qr_code_url = format!( + "{}/games/{game_id}", + BASE_URL.strip_suffix('/').unwrap_or(BASE_URL) + ); + log::info!("generating QR code for game url [{qr_code_url}]"); + let qr_str = match fast_qr::QRBuilder::new(qr_code_url).build() { + Ok(qr) => SvgBuilder::default().shape(Shape::Square).to_str(&qr), + Err(err) => { + log::error!("generating qr code from [{BASE_URL}]: {err}"); + return ( + StatusCode::INTERNAL_SERVER_ERROR, + [(header::CONTENT_TYPE, "application/octet-stream")], + vec![], + ); + } + }; + + ( + StatusCode::OK, + [(header::CONTENT_TYPE, "image/svg+xml")], + qr_str.as_bytes().to_vec(), + ) +} diff --git a/werewolves/src/server/role_reveal.rs b/werewolves/src/server/role_reveal.rs new file mode 100644 index 0000000..26e51dc --- /dev/null +++ b/werewolves/src/server/role_reveal.rs @@ -0,0 +1,195 @@ +use core::ops::Not; + +use api::game::GameId; +use werewolves_proto::{ + game::Game, + message::{ + ClientMessage, Identification, ServerToClientMessage, + host::{HostMessage, ServerToHostMessage}, + }, + player::PlayerId, +}; + +use crate::server::runner::{ClientUpdate, HostOrClientMessage, IdentifiedClientMessage}; + +pub struct RoleReveal<'a> { + acks: Box<[(werewolves_proto::character::Character, bool)]>, + game: &'a mut Game, + game_id: GameId, +} +impl<'a> RoleReveal<'a> { + pub fn new(game_id: GameId, game: &'a mut Game) -> Self { + let acks = game + .village() + .characters() + .into_iter() + .map(|c| (c, false)) + .collect::<Box<[_]>>(); + Self { + acks, + game, + game_id, + } + } + async fn notify_of_role(&self, player_id: PlayerId) { + if let Some(char) = self.game.village().character_by_player_id(player_id) { + super::send_player( + self.game_id, + player_id, + ServerToClientMessage::GameStart { + role: char.initial_shown_role(), + }, + ) + .await; + } + } + pub async fn initial_sendout(&mut self) { + let characters = self.game.village().characters(); + for char in characters.iter() { + super::send_player( + self.game_id, + char.player_id(), + ServerToClientMessage::GameStart { + role: char.initial_shown_role(), + }, + ) + .await; + } + super::send_to_all_players_in_game_filtered(self.game_id, |pid| { + characters + .iter() + .any(|c| c.player_id() == pid) + .not() + .then_some(ServerToClientMessage::GameInProgress) + }) + .await; + + self.update_host().await; + } + + async fn update_host(&self) { + super::send_host( + self.game_id, + ServerToHostMessage::WaitingForRoleRevealAcks { + ackd: self + .acks + .iter() + .filter_map(|(a, ackd)| ackd.then_some(a.identity())) + .collect(), + waiting: self + .acks + .iter() + .filter_map(|(a, ackd)| ackd.not().then_some(a.identity())) + .collect(), + }, + ) + .await; + } + + pub async fn notify_non_ackd(&mut self) { + for pid in self + .acks + .iter() + .filter_map(|(c, ack)| ack.not().then_some(c.player_id())) + { + self.notify_of_role(pid).await; + } + } + + /// returns `true` once every player has ack'd + pub async fn process(&mut self, message: HostOrClientMessage) -> bool { + match message { + HostOrClientMessage::Host(HostMessage::ForceRoleAckFor(char_id)) => { + if let Some((c, ackd)) = self + .acks + .iter_mut() + .find(|(c, _)| c.character_id() == char_id) + { + *ackd = true; + let pid = c.player_id(); + self.notify_of_role(pid).await; + } + self.update_host().await; + } + HostOrClientMessage::Host(_) => { + self.update_host().await; + } + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: + Identification { + player_id, + public: _, + }, + update: ClientUpdate::Message(ClientMessage::GetState), + }) => { + if self + .acks + .iter() + .any(|(c, d)| c.player_id() == player_id && *d) + { + // already ack'd just sleep + super::send_player(self.game_id, player_id, ServerToClientMessage::Sleep).await; + return false; + } + if self + .game + .village() + .characters() + .iter() + .any(|c| c.player_id() == player_id) + { + self.notify_of_role(player_id).await; + } else { + super::send_player( + self.game_id, + player_id, + ServerToClientMessage::GameInProgress, + ) + .await; + } + } + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: + Identification { + player_id, + public: _, + }, + update: ClientUpdate::Message(ClientMessage::RoleAck), + }) => { + if let Some((_, ackd)) = self + .acks + .iter_mut() + .find(|(t, _)| t.player_id() == player_id) + { + *ackd = true; + } + self.update_host().await; + super::send_player(self.game_id, player_id, ServerToClientMessage::Sleep).await; + } + HostOrClientMessage::Client(IdentifiedClientMessage { + identity: Identification { player_id, .. }, + .. + }) => self.notify_of_role(player_id).await, + } + + if !self.acks.iter().all(|(_, ackd)| *ackd) { + return false; + } + + let playing_player_ids = self + .game + .village() + .characters() + .into_iter() + .map(|c| c.player_id()) + .collect::<Box<_>>(); + super::send_to_all_players_in_game_filtered(self.game_id, |pid| { + playing_player_ids + .contains(&pid) + .then_some(ServerToClientMessage::Sleep) + }) + .await; + + true + } +} diff --git a/werewolves/src/server/runner.rs b/werewolves/src/server/runner.rs new file mode 100644 index 0000000..887b3f4 --- /dev/null +++ b/werewolves/src/server/runner.rs @@ -0,0 +1,209 @@ +// Copyright (C) 2025-2026 Emilis Bliūdžius +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +use core::num::NonZeroU8; + +use api::{ + db::Database, + game::{GameId, GameRecord, GameRecordState}, + user::ProfileUpdate, +}; +use tokio::sync::mpsc::UnboundedReceiver; +use werewolves_proto::message::{ClientMessage, Identification, host::HostMessage}; + +use crate::{ + LogError, loc, + server::{game::GameRunner, game_end::GameEnd, lobby::Lobby, role_reveal::RoleReveal}, +}; + +#[derive(Debug, Clone, PartialEq)] +pub enum ClientUpdate { + ConnectStateUpdate { connected: bool }, + Message(ClientMessage), +} + +#[derive(Debug, Clone, PartialEq)] +pub struct IdentifiedClientMessage { + pub identity: Identification, + pub update: ClientUpdate, +} + +async fn next_message( + game_id: GameId, + client_recv: &mut UnboundedReceiver<IdentifiedClientMessage>, + host_recv: &mut UnboundedReceiver<HostMessage>, +) -> Option<HostOrClientMessage> { + tokio::select! { + client_msg = client_recv.recv() => { + match client_msg { + Some(msg) => Some(HostOrClientMessage::Client(msg)), + None => { + log::warn!("client recv for game {game_id} got None; exiting"); + None + } + } + } + host_msg = host_recv.recv() => { + match host_msg { + Some(msg) => Some(HostOrClientMessage::Host(msg)), + None => { + log::warn!("host recv for game {game_id} got None; exiting"); + None + } + } + } + } +} + +async fn add_dummies(game_id: GameId, db: &Database, dummy_count: usize) { + let Ok(joined) = db.game().get_joined_players(game_id).await else { + return; + }; + if joined.len() >= dummy_count { + return; + } + let dummies_to_add = dummy_count.saturating_sub(joined.len()); + let mut added = Vec::new(); + for i in 1..=dummies_to_add { + let Ok(user) = db + .user() + .create_dummy_user(format!("dummy {i}").as_str(), Some("they/them".into())) + .await + else { + continue; + }; + added.push((user, NonZeroU8::new(i as u8))); + } + for (u, num) in added { + db.game() + .join_game(game_id, u.id, num) + .await + .log_err(loc!()); + } +} + +pub async fn run_game( + db: Database, + mut game: GameRecord, + mut client_recv: UnboundedReceiver<IdentifiedClientMessage>, + mut host_recv: UnboundedReceiver<HostMessage>, +) { + let game_id = game.id; + add_dummies(game_id, &db, 20).await; + + loop { + match game.game_state.clone() { + GameRecordState::Lobby(mut settings) => { + let mut lobby = Lobby::new(game_id, &mut settings, db.clone()); + loop { + if let Some(new_record) = lobby + .process( + if let Some(msg) = + next_message(game_id, &mut client_recv, &mut host_recv).await + { + msg + } else { + return; + }, + ) + .await + { + game = new_record; + break; + } + game.game_state = GameRecordState::Lobby(lobby.settings().clone()); + if let Err(err) = db.game().store_game_state(&game).await { + log::error!("saving game({game_id}) state: {err}; quitting..."); + return; + } + } + } + GameRecordState::RoleReveal(mut new_game) => { + let mut role_reveal = RoleReveal::new(game_id, &mut new_game); + role_reveal.initial_sendout().await; + loop { + if role_reveal + .process( + if let Some(msg) = + next_message(game_id, &mut client_recv, &mut host_recv).await + { + msg + } else { + return; + }, + ) + .await + { + game.game_state = GameRecordState::Started(new_game); + if let Err(err) = db.game().store_game_state(&game).await { + log::error!("saving game({game_id}) state: {err}; quitting..."); + return; + } + break; + } + } + } + GameRecordState::Started(mut current_game) => { + let mut runner = GameRunner::new(game_id, &mut current_game); + loop { + if runner.game_over().is_some() + || runner + .process( + if let Some(msg) = + next_message(game_id, &mut client_recv, &mut host_recv).await + { + msg + } else { + return; + }, + ) + .await + .is_some() + { + game.game_state = GameRecordState::GameOver(current_game.story()); + if let Err(err) = db.game().store_game_state(&game).await { + log::error!("saving game({game_id}) state: {err}; quitting..."); + return; + } + break; + } + } + } + GameRecordState::GameOver(story) => { + let story = GameEnd::new(game_id, story); + story.notify_connected().await; + loop { + story + .process( + if let Some(msg) = + next_message(game_id, &mut client_recv, &mut host_recv).await + { + msg + } else { + return; + }, + ) + .await; + } + } + }; + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum HostOrClientMessage { + Host(HostMessage), + Client(IdentifiedClientMessage), +} diff --git a/werewolves/src/state.rs b/werewolves/src/state.rs new file mode 100644 index 0000000..6a94f0e --- /dev/null +++ b/werewolves/src/state.rs @@ -0,0 +1,58 @@ +use core::ops::Deref; + +use leptos::prelude::*; +use reactive_stores::Store; +use serde::{Deserialize, Serialize}; + +use crate::app::storage::{SessionStorage, Stored}; + +pub trait InitOrUpdateStore { + fn init_or_update(&self); +} + +#[derive(Debug, Default, Clone, Store)] +pub struct SessionState { + redirect_after_signin: Option<RedirectAfterSignin>, + initialized: bool, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct RedirectAfterSignin(String); +impl RedirectAfterSignin { + pub const fn new(s: String) -> Self { + Self(s) + } +} +impl Deref for RedirectAfterSignin { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.0.as_str() + } +} + +impl Stored for RedirectAfterSignin { + const STORAGE_KEY: &str = "redirect-after-signin"; +} +impl SessionStorage for RedirectAfterSignin {} + +impl SessionState { + pub fn new() -> Self { + Self { + initialized: false, + redirect_after_signin: None, + } + } +} + +impl InitOrUpdateStore for Store<SessionState> { + fn init_or_update(&self) { + if !self.initialized().get() { + self.redirect_after_signin() + .set(RedirectAfterSignin::from_session_storage()); + self.initialized().set(true); + } else { + RedirectAfterSignin::set_in_session_storage(self.redirect_after_signin().get()); + } + } +} diff --git a/werewolves/src/storage.rs b/werewolves/src/storage.rs deleted file mode 100644 index af83c2d..0000000 --- a/werewolves/src/storage.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use gloo::storage::{LocalStorage, Storage, errors::StorageError}; -use serde::{Deserialize, Serialize}; -use werewolves_proto::{game::GameSettings, message::PublicIdentity, player::PlayerId}; - -type Result<T> = core::result::Result<T, StorageError>; - -pub trait StorageKey: for<'a> Deserialize<'a> + Serialize { - const KEY: &str; - - fn load_from_storage() -> Result<Self> { - LocalStorage::get(Self::KEY) - } - - fn save_to_storage(&self) -> Result<()> { - LocalStorage::set(Self::KEY, self) - } - - fn delete() { - LocalStorage::delete(Self::KEY); - } -} - -impl StorageKey for PlayerId { - const KEY: &str = "ww_player_id"; -} - -impl StorageKey for PublicIdentity { - const KEY: &str = "ww_public_identity"; -} - -impl StorageKey for GameSettings { - const KEY: &str = "game_settings"; -} diff --git a/werewolves/src/test_util/mod.rs b/werewolves/src/test_util/mod.rs deleted file mode 100644 index c46b687..0000000 --- a/werewolves/src/test_util/mod.rs +++ /dev/null @@ -1,464 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -mod prompt; -mod result; -use core::num::NonZeroU8; - -use werewolves_proto::{ - character::CharacterId, - diedto::DiedToTitle, - message::{ - CharacterIdentity, - host::ServerToHostMessage, - night::{ActionPrompt, ActionPromptTitle, ActionResult, ActionResultTitle, Visits}, - }, - role::{Alignment, AlignmentEq, Killer, Powerful, RoleTitle}, -}; -use yew::prelude::*; - -use crate::{ - components::Button, - test_util::{prompt::PromptScreenTest, result::ResultScreenTest}, -}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct TestScreensProps { - pub send: Callback<ServerToHostMessage>, -} - -#[function_component] -pub fn TestScreens(TestScreensProps { send }: &TestScreensProps) -> Html { - let screen: UseStateHandle<Option<TestScreen>> = use_state(|| None); - let page = use_state(|| 0usize); - - let back = { - let screen = screen.setter(); - Callback::from(move |_| screen.set(None)) - }; - - let send = { - let send = send.clone(); - let page = page.clone(); - let screen = screen.clone(); - Callback::from(move |msg: ServerToHostMessage| { - match &msg { - ServerToHostMessage::ActionPrompt(prompt, new_page) => { - if *page != *new_page { - page.set(*new_page); - } - if let Some(TestScreen::Prompt(current)) = &*screen - && current != prompt - { - screen.set(Some(TestScreen::Prompt(prompt.clone()))); - } - } - ServerToHostMessage::ActionResult(_, result) => { - screen.set(Some(TestScreen::Result(result.clone()))); - } - _ => {} - } - send.emit(msg); - }) - }; - - let screen_settings = screen.as_ref().map(|screen| match screen { - TestScreen::Prompt(p) => html! { - <PromptScreenTest - prompt={p.clone()} - page={*page} - back={back} - send={send.clone()} - /> - }, - TestScreen::Result(result) => html! { - <ResultScreenTest - result={result.clone()} - send={send.clone()} - back={back} - /> - }, - }); - - html! { - <div class="test-screen"> - <TestScreenSelector screen={screen.clone()} send={send.clone()}/> - {screen_settings} - </div> - } -} - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct TestScreenSelectorProps { - pub screen: UseStateHandle<Option<TestScreen>>, - pub send: Callback<ServerToHostMessage>, -} - -#[function_component] -pub fn TestScreenSelector( - TestScreenSelectorProps { screen, send }: &TestScreenSelectorProps, -) -> Html { - let prompts = ActionPromptTitle::ALL - .into_iter() - .map(|title| { - let TestScreen::Prompt(prompt) = Into::<TestScreen>::into(title) else { - unreachable!() - }; - let picked_class = if let Some(TestScreen::Prompt(current)) = &**screen - && current.title() == title - { - Some("selected") - } else { - None - }; - let callback = { - let screen = screen.clone(); - let send = send.clone(); - Callback::from(move |_| { - let TestScreen::Prompt(prompt) = Into::<TestScreen>::into(title) else { - unreachable!() - }; - screen.set(Some(TestScreen::Prompt(prompt.clone()))); - send.emit(ServerToHostMessage::ActionPrompt(prompt, 0)); - }) - }; - let class = prompt_class(&prompt); - html! { - <li> - <Button on_click={callback} classes={classes!(class, picked_class, "hover")}> - {format!("{title:?}")} - </Button> - </li> - } - }) - .collect::<Html>(); - - let results = ActionResultTitle::ALL - .into_iter() - .filter(|title| !matches!(title, ActionResultTitle::Continue)) - .map(|title| { - let TestScreen::Result(result) = Into::<TestScreen>::into(title) else { - unreachable!() - }; - let picked_class = if let Some(TestScreen::Result(current)) = &**screen - && current.title() == title - { - Some("selected") - } else { - None - }; - let callback = { - let screen = screen.clone(); - let send = send.clone(); - Callback::from(move |_| { - let TestScreen::Result(result) = Into::<TestScreen>::into(title) else { - unreachable!() - }; - screen.set(Some(TestScreen::Result(result.clone()))); - send.emit(ServerToHostMessage::ActionResult(None, result)); - }) - }; - let class = result_class(&result); - html! { - <li> - <Button on_click={callback} classes={classes!(picked_class, class, "hover")}> - {format!("{title:?}")} - </Button> - </li> - } - }) - .collect::<Html>(); - html! { - <div class="test-screen-selector"> - <div class="category"> - <label>{"prompts"}</label> - <ul class="test-screens"> - {prompts} - </ul> - </div> - <div class="category"> - <label>{"results"}</label> - <ul class="test-screens"> - {results} - </ul> - </div> - </div> - } -} - -fn identities(num: usize) -> Box<[CharacterIdentity]> { - (1..=num) - .map(|num| { - CharacterIdentity::new( - CharacterId::from_u128(num as _), - format!("Player {num}"), - Some("they/them".into()), - NonZeroU8::new(num as _).unwrap(), - ) - }) - .collect() -} - -fn identity() -> CharacterIdentity { - identities(1).into_iter().next().unwrap() -} - -#[derive(Debug, Clone, PartialEq)] -pub enum TestScreen { - Prompt(ActionPrompt), - Result(ActionResult), -} - -impl From<ActionResultTitle> for TestScreen { - fn from(value: ActionResultTitle) -> Self { - TestScreen::Result(match value { - ActionResultTitle::SkippedByHost => ActionResult::SkippedByHost, - ActionResultTitle::RoleBlocked => ActionResult::RoleBlocked, - ActionResultTitle::Drunk => ActionResult::Drunk, - ActionResultTitle::Seer => ActionResult::Seer(identity(), Alignment::Village), - ActionResultTitle::PowerSeer => ActionResult::PowerSeer { - target: identity(), - powerful: Powerful::Powerful, - }, - ActionResultTitle::Adjudicator => ActionResult::Adjudicator { - target: identity(), - killer: Killer::Killer, - }, - ActionResultTitle::Arcanist => ActionResult::Arcanist( - (identity(), identities(2).last().cloned().unwrap()), - AlignmentEq::Same, - ), - ActionResultTitle::GraveDigger => ActionResult::GraveDigger(identity(), None), - ActionResultTitle::Mortician => { - ActionResult::Mortician(identity(), DiedToTitle::Execution) - } - ActionResultTitle::Insomniac => ActionResult::Insomniac(Visits::new(identities(2))), - ActionResultTitle::Empath => ActionResult::Empath { - target: identity(), - scapegoat: true, - }, - ActionResultTitle::BeholderSawNothing => ActionResult::BeholderSawNothing, - ActionResultTitle::BeholderSawEverything => ActionResult::BeholderSawEverything, - ActionResultTitle::GoBackToSleep => ActionResult::GoBackToSleep, - ActionResultTitle::ShiftFailed => ActionResult::ShiftFailed, - ActionResultTitle::Continue => ActionResult::Continue, - }) - } -} - -impl From<ActionPromptTitle> for TestScreen { - fn from(value: ActionPromptTitle) -> Self { - Self::Prompt(match value { - ActionPromptTitle::BeholderWakes => ActionPrompt::BeholderWakes { - character_id: identity(), - }, - ActionPromptTitle::CoverOfDarkness => ActionPrompt::CoverOfDarkness, - ActionPromptTitle::WolvesIntro => ActionPrompt::WolvesIntro { - wolves: identities(5) - .into_iter() - .zip([ - RoleTitle::Werewolf, - RoleTitle::AlphaWolf, - RoleTitle::DireWolf, - RoleTitle::LoneWolf, - RoleTitle::Bloodletter, - ]) - .collect(), - }, - ActionPromptTitle::RoleChange => ActionPrompt::RoleChange { - character_id: identities(1).into_iter().next().unwrap(), - new_role: RoleTitle::Adjudicator, - }, - ActionPromptTitle::ElderReveal => ActionPrompt::ElderReveal { - character_id: identities(1).into_iter().next().unwrap(), - }, - ActionPromptTitle::Seer => ActionPrompt::Seer { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::Protector => ActionPrompt::Protector { - character_id: identities(1).into_iter().next().unwrap(), - targets: identities(20), - marked: None, - }, - ActionPromptTitle::Arcanist => ActionPrompt::Arcanist { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: (None, None), - }, - ActionPromptTitle::Gravedigger => ActionPrompt::Gravedigger { - character_id: identities(1).into_iter().next().unwrap(), - dead_players: identities(20), - marked: None, - }, - ActionPromptTitle::Hunter => ActionPrompt::Hunter { - character_id: identities(1).into_iter().next().unwrap(), - current_target: None, - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::Militia => ActionPrompt::Militia { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::MapleWolf => ActionPrompt::MapleWolf { - character_id: identities(1).into_iter().next().unwrap(), - nights_til_starvation: 0, - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::Guardian => ActionPrompt::Guardian { - character_id: identities(1).into_iter().next().unwrap(), - previous: None, - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::Adjudicator => ActionPrompt::Adjudicator { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::PowerSeer => ActionPrompt::PowerSeer { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::Mortician => ActionPrompt::Mortician { - character_id: identities(1).into_iter().next().unwrap(), - dead_players: identities(20), - marked: None, - }, - ActionPromptTitle::BeholderChooses => ActionPrompt::BeholderChooses { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::MasonsWake => ActionPrompt::MasonsWake { - leader: identities(1).into_iter().next().unwrap(), - masons: identities(3), - }, - ActionPromptTitle::MasonLeaderRecruit => ActionPrompt::MasonLeaderRecruit { - character_id: identities(1).into_iter().next().unwrap(), - recruits_left: NonZeroU8::new(3).unwrap(), - potential_recruits: identities(20), - marked: None, - }, - ActionPromptTitle::Empath => ActionPrompt::Empath { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::Vindicator => ActionPrompt::Vindicator { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::PyreMaster => ActionPrompt::PyreMaster { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::WolfPackKill => ActionPrompt::WolfPackKill { - living_villagers: identities(20), - marked: None, - }, - ActionPromptTitle::Shapeshifter => ActionPrompt::Shapeshifter { - character_id: identities(1).into_iter().next().unwrap(), - }, - ActionPromptTitle::AlphaWolf => ActionPrompt::AlphaWolf { - character_id: identities(1).into_iter().next().unwrap(), - living_villagers: identities(20), - marked: None, - }, - ActionPromptTitle::DireWolf => ActionPrompt::DireWolf { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::LoneWolfKill => ActionPrompt::LoneWolfKill { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::Insomniac => ActionPrompt::Insomniac { - character_id: identities(1).into_iter().next().unwrap(), - }, - ActionPromptTitle::Bloodletter => ActionPrompt::Bloodletter { - character_id: identities(1).into_iter().next().unwrap(), - living_players: identities(20), - marked: None, - }, - ActionPromptTitle::DamnedIntro => ActionPrompt::DamnedIntro { - character_id: identities(1).into_iter().next().unwrap(), - }, - }) - } -} - -fn result_class(result: &ActionResult) -> Option<&'static str> { - match result.title() { - ActionResultTitle::Drunk | ActionResultTitle::RoleBlocked => Some("drunk"), - ActionResultTitle::PowerSeer - | ActionResultTitle::Adjudicator - | ActionResultTitle::Arcanist - | ActionResultTitle::GraveDigger - | ActionResultTitle::Mortician - | ActionResultTitle::Insomniac - | ActionResultTitle::Empath - | ActionResultTitle::BeholderSawNothing - | ActionResultTitle::BeholderSawEverything - | ActionResultTitle::Seer => Some("intel"), - ActionResultTitle::ShiftFailed => Some("wolves"), - ActionResultTitle::GoBackToSleep - | ActionResultTitle::Continue - | ActionResultTitle::SkippedByHost => None, - } -} - -fn prompt_class(prompt: &ActionPrompt) -> Option<&'static str> { - match prompt { - ActionPrompt::ElderReveal { .. } - | ActionPrompt::RoleChange { .. } - | ActionPrompt::CoverOfDarkness => None, - ActionPrompt::BeholderWakes { .. } - | ActionPrompt::Seer { .. } - | ActionPrompt::Arcanist { .. } - | ActionPrompt::Gravedigger { .. } - | ActionPrompt::Adjudicator { .. } - | ActionPrompt::PowerSeer { .. } - | ActionPrompt::Mortician { .. } - | ActionPrompt::BeholderChooses { .. } - | ActionPrompt::MasonsWake { .. } - | ActionPrompt::MasonLeaderRecruit { .. } - | ActionPrompt::Empath { .. } => Some("intel"), - ActionPrompt::Protector { .. } - | ActionPrompt::Guardian { .. } - | ActionPrompt::Vindicator { .. } => Some("defensive"), - ActionPrompt::Hunter { .. } - | ActionPrompt::Militia { .. } - | ActionPrompt::MapleWolf { .. } - | ActionPrompt::PyreMaster { .. } => Some("offensive"), - ActionPrompt::WolvesIntro { .. } - | ActionPrompt::WolfPackKill { .. } - | ActionPrompt::Shapeshifter { .. } - | ActionPrompt::AlphaWolf { .. } - | ActionPrompt::DireWolf { .. } - | ActionPrompt::LoneWolfKill { .. } - | ActionPrompt::Insomniac { .. } - | ActionPrompt::Bloodletter { .. } => Some("wolves"), - ActionPrompt::DamnedIntro { .. } => Some("damned"), - } -} diff --git a/werewolves/src/test_util/prompt.rs b/werewolves/src/test_util/prompt.rs deleted file mode 100644 index 510cc6b..0000000 --- a/werewolves/src/test_util/prompt.rs +++ /dev/null @@ -1,380 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use core::num::NonZeroU8; - -use web_sys::HtmlSelectElement; -use werewolves_proto::{ - message::{host::ServerToHostMessage, night::ActionPrompt}, - role::{PreviousGuardianAction, RoleTitle}, -}; - -use crate::{ - components::{Button, IncDecU8}, - pages::RolePage, - test_util::identities, -}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct PromptScreenTestProps { - pub prompt: ActionPrompt, - pub page: usize, - pub send: Callback<ServerToHostMessage>, - pub back: Callback<()>, -} - -#[function_component] -pub fn PromptScreenTest( - PromptScreenTestProps { - prompt, - page, - send, - back, - }: &PromptScreenTestProps, -) -> Html { - let options = match prompt { - ActionPrompt::WolvesIntro { wolves } => { - let on_update = { - let send = send.clone(); - Callback::from(move |new_count: u8| { - let new_prompt = ActionPrompt::WolvesIntro { - wolves: super::identities(new_count as _) - .into_iter() - .zip(RoleTitle::ALL.into_iter().filter(|w| w.wolf()).cycle()) - .collect(), - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - }) - }; - html! { - <IncDecU8 - value={wolves.len() as u8} - value_range={1..0xFF} - on_update={on_update} - > - {" wolves"} - </IncDecU8> - } - } - ActionPrompt::RoleChange { new_role, .. } => { - let roles = RoleTitle::ALL - .into_iter() - .map(|role| { - html! { - <option selected={role == *new_role}>{role.to_string()}</option> - } - }) - .collect::<Html>(); - let on_change_cb = { - let send = send.clone(); - Callback::from(move |ev: Event| { - if let Some(select) = ev.target_dyn_into::<HtmlSelectElement>() { - let selected = select.selected_index(); - if selected == -1 { - return; - } - if let Some(new_role) = RoleTitle::ALL.into_iter().nth(selected as _) { - let new_prompt = ActionPrompt::RoleChange { - character_id: super::identity(), - new_role, - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - } - } - }) - }; - let on_wheel = { - let send = send.clone(); - Callback::from(move |ev: WheelEvent| { - let Some(target) = ev.target_dyn_into::<HtmlSelectElement>() else { - return; - }; - let index = target.selected_index(); - let new_index = match ev.delta_y().total_cmp(&0.0) { - core::cmp::Ordering::Equal => return, - core::cmp::Ordering::Less => { - if index != 0 { - index - 1 - } else { - (target.children().length() - 1) as i32 - } - } - core::cmp::Ordering::Greater => { - if index + 1 < target.children().length() as i32 { - index + 1 - } else { - 0 - } - } - }; - target.set_selected_index(new_index); - if let Some(new_role) = RoleTitle::ALL.into_iter().nth(new_index as _) { - let new_prompt = ActionPrompt::RoleChange { - character_id: super::identity(), - new_role, - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - } - }) - }; - html! { - <div class="prompt-option"> - <label>{"new role"}</label> - <select onwheel={on_wheel} onchange={on_change_cb}> - {roles} - </select> - </div> - } - } - - ActionPrompt::Hunter { current_target, .. } => { - let toggle_target = current_target.is_none().then_some(super::identity()); - let on_toggle = { - let toggle_target = toggle_target.clone(); - let send = send.clone(); - Callback::from(move |_| { - let new_prompt = ActionPrompt::Hunter { - character_id: super::identity(), - current_target: toggle_target.clone(), - living_players: identities(20), - marked: None, - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - }) - }; - - let button_text = if toggle_target.is_some() { - "remove previous target" - } else { - "set previous target" - }; - html! { - <div class="prompt-options"> - <Button on_click={on_toggle}>{button_text}</Button> - </div> - } - } - ActionPrompt::MapleWolf { - nights_til_starvation, - .. - } => { - let on_update = { - let send = send.clone(); - Callback::from(move |new_nights: u8| { - let new_prompt = ActionPrompt::MapleWolf { - character_id: super::identity(), - nights_til_starvation: new_nights, - living_players: identities(20), - marked: None, - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - }) - }; - - html! { - <div class="prompt-options"> - <IncDecU8 - value={*nights_til_starvation} - value_range={0..0xFF} - on_update={on_update} - > - {" nights"} - </IncDecU8> - </div> - } - } - ActionPrompt::Guardian { previous, .. } => { - let none_disabled = previous.is_none().then_some(String::from("already set")); - let prev_none = { - let send = send.clone(); - Callback::from(move |_| { - let new_prompt = ActionPrompt::Guardian { - character_id: super::identity(), - previous: None, - living_players: super::identities(20), - marked: None, - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - }) - }; - - let prot_disabled = previous.as_ref().and_then(|prev| match prev { - PreviousGuardianAction::Protect(_) => Some(String::from("already set")), - PreviousGuardianAction::Guard(_) => None, - }); - let prev_prot = { - let send = send.clone(); - Callback::from(move |_| { - let new_prompt = ActionPrompt::Guardian { - character_id: super::identity(), - previous: Some(PreviousGuardianAction::Protect( - super::identities(2).into_iter().nth(1).unwrap(), - )), - living_players: super::identities(20), - marked: None, - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - }) - }; - let guard_disabled = previous.as_ref().and_then(|prev| match prev { - PreviousGuardianAction::Guard(_) => Some(String::from("already set")), - PreviousGuardianAction::Protect(_) => None, - }); - let prev_guard = { - let send = send.clone(); - Callback::from(move |_| { - let new_prompt = ActionPrompt::Guardian { - character_id: super::identity(), - previous: Some(PreviousGuardianAction::Guard( - super::identities(2).into_iter().nth(1).unwrap(), - )), - living_players: super::identities(20), - marked: None, - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - }) - }; - - html! { - <> - <label>{"previous protect"}</label> - <div class="option-set"> - <Button disabled_reason={none_disabled} on_click={prev_none}>{"none"}</Button> - <Button disabled_reason={prot_disabled} on_click={prev_prot}>{"protected"}</Button> - <Button disabled_reason={guard_disabled} on_click={prev_guard}>{"guarded"}</Button> - </div> - </> - } - } - ActionPrompt::MasonsWake { masons, .. } => { - let on_update = { - let send = send.clone(); - Callback::from(move |new_count: u8| { - let new_prompt = ActionPrompt::MasonsWake { - leader: super::identity(), - masons: super::identities(new_count as _), - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - }) - }; - html! { - <IncDecU8 - value={masons.len() as u8} - value_range={1..0xFF} - on_update={on_update} - > - {" masons"} - </IncDecU8> - } - } - ActionPrompt::MasonLeaderRecruit { recruits_left, .. } => { - let on_update = { - let send = send.clone(); - Callback::from(move |new_count: u8| { - let new_prompt = ActionPrompt::MasonLeaderRecruit { - character_id: super::identity(), - recruits_left: NonZeroU8::new(new_count).unwrap(), - potential_recruits: identities(20), - marked: None, - }; - send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0)); - }) - }; - html! { - <IncDecU8 - value={recruits_left.get()} - value_range={1..0xFF} - on_update={on_update} - > - {" recruits"} - </IncDecU8> - } - } - - ActionPrompt::BeholderWakes { .. } - | ActionPrompt::Protector { .. } - | ActionPrompt::Arcanist { .. } - | ActionPrompt::Gravedigger { .. } - | ActionPrompt::Militia { .. } - | ActionPrompt::Adjudicator { .. } - | ActionPrompt::PowerSeer { .. } - | ActionPrompt::Mortician { .. } - | ActionPrompt::BeholderChooses { .. } - | ActionPrompt::Empath { .. } - | ActionPrompt::Vindicator { .. } - | ActionPrompt::PyreMaster { .. } - | ActionPrompt::WolfPackKill { .. } - | ActionPrompt::AlphaWolf { .. } - | ActionPrompt::DireWolf { .. } - | ActionPrompt::LoneWolfKill { .. } - | ActionPrompt::Bloodletter { .. } - | ActionPrompt::Seer { .. } - | ActionPrompt::ElderReveal { .. } - | ActionPrompt::DamnedIntro { .. } - | ActionPrompt::Insomniac { .. } - | ActionPrompt::Shapeshifter { .. } - | ActionPrompt::CoverOfDarkness => html! {}, - }; - let prev_page_disabled = (*page == 0).then_some(String::from("on page zero")); - let prev_page = { - let send = send.clone(); - let prompt = prompt.clone(); - let page = *page; - Callback::from(move |_| { - send.emit(ServerToHostMessage::ActionPrompt( - prompt.clone(), - page.saturating_sub(1), - )); - }) - }; - let next_page_disabled = (*page + 1 >= prompt.role_pages(true).len()) - .then_some(String::from("already at last page")); - let next_page = { - let send = send.clone(); - let prompt = prompt.clone(); - let page = *page; - Callback::from(move |_| { - send.emit(ServerToHostMessage::ActionPrompt( - prompt.clone(), - page.saturating_add(1), - )); - }) - }; - html! { - <div class="prompt-test"> - <Button on_click={back.clone()} classes={classes!("close")}>{"close"}</Button> - <label>{prompt.title().to_string()}</label> - <div class="prompt-number"> - <Button - on_click={prev_page} - disabled_reason={prev_page_disabled} - > - {"previous page"} - </Button> - <span>{page.saturating_add(1)}{"/"}{prompt.role_pages(true).len().max(1)}</span> - <Button - on_click={next_page} - disabled_reason={next_page_disabled} - > - {"next page"} - </Button> - </div> - <div class="prompt-options"> - {options} - </div> - </div> - } -} diff --git a/werewolves/src/test_util/result.rs b/werewolves/src/test_util/result.rs deleted file mode 100644 index 0959b41..0000000 --- a/werewolves/src/test_util/result.rs +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright (C) 2025-2026 Emilis Bliūdžius -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -use yew::prelude::*; - -use core::num::NonZeroU8; -use std::rc::Rc; - -use web_sys::HtmlSelectElement; -use werewolves_proto::{ - diedto::DiedToTitle, - message::{ - host::{HostGameMessage, HostMessage, HostNightMessage, ServerToHostMessage}, - night::{ActionPrompt, ActionResult, ActionResultTitle, Visits}, - }, - player::RoleChange, - role::{Alignment, PreviousGuardianAction, RoleTitle}, -}; - -use crate::{components::Button, pages::RolePage, test_util::identities}; - -#[derive(Debug, Clone, PartialEq, Properties)] -pub struct ResultScreenTestProps { - pub result: ActionResult, - pub send: Callback<ServerToHostMessage>, - pub back: Callback<()>, -} - -#[function_component] -pub fn ResultScreenTest( - ResultScreenTestProps { result, send, back }: &ResultScreenTestProps, -) -> Html { - let options = match result { - ActionResult::BeholderSawNothing - | ActionResult::BeholderSawEverything - | ActionResult::GoBackToSleep - | ActionResult::ShiftFailed - | ActionResult::Continue - | ActionResult::Drunk - | ActionResult::RoleBlocked - | ActionResult::SkippedByHost => html! {}, - ActionResult::Seer(target, alignment) => { - let all = Alignment::ALL - .into_iter() - .map(|align| { - let on_click = { - let target= target.clone(); - let send = send.clone(); - Callback::from(move |_| { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::Seer(target.clone(), align), - )); - }) - }; - let disabled = (align == *alignment).then_some(String::from("already selected")) ; - html! { - <Button on_click={on_click} disabled_reason={disabled}>{align.to_string()}</Button> - } - }) - .collect::<Html>(); - html! { - <div class="prompt-options"> - <div class="option-set"> - {all} - </div> - </div> - } - } - ActionResult::PowerSeer { target, powerful } => { - let on_toggle = { - let set = !*powerful; - let send = send.clone(); - let target = target.clone(); - Callback::from(move |_| { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::PowerSeer { - target: target.clone(), - powerful: set, - }, - )); - }) - }; - let text = if powerful.powerful() { - "make not powerful" - } else { - "make powerful" - }; - html! { - <div class="prompt-options"> - <Button on_click={on_toggle}>{text}</Button> - </div> - } - } - ActionResult::Adjudicator { target, killer } => { - let on_toggle = { - let set = !*killer; - let send = send.clone(); - let target = target.clone(); - Callback::from(move |_| { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::Adjudicator { - target: target.clone(), - killer: set, - }, - )); - }) - }; - let text = if killer.killer() { - "make not killer" - } else { - "make killer" - }; - html! { - <div class="prompt-options"> - <Button on_click={on_toggle}>{text}</Button> - </div> - } - } - ActionResult::Arcanist(targets, alignment_eq) => { - let on_toggle = { - let set = !*alignment_eq; - let send = send.clone(); - let targets = targets.clone(); - Callback::from(move |_| { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::Arcanist(targets.clone(), set), - )); - }) - }; - let text = if alignment_eq.same() { - "make different" - } else { - "make same" - }; - html! { - <div class="prompt-options"> - <Button on_click={on_toggle}>{text}</Button> - </div> - } - } - ActionResult::GraveDigger(target, role_title) => { - let possibilities = [None] - .into_iter() - .chain(RoleTitle::ALL.into_iter().map(Some)) - .collect::<Rc<[_]>>(); - let roles = possibilities - .iter() - .map(|role| { - let text = role - .as_ref() - .map(|r| r.to_string()) - .unwrap_or(String::from("empty grave")); - html! { - <option selected={role == role_title}>{text}</option> - } - }) - .collect::<Html>(); - let on_change_cb = { - let send = send.clone(); - let possibilities = possibilities.clone(); - let target = target.clone(); - Callback::from(move |ev: Event| { - if let Some(select) = ev.target_dyn_into::<HtmlSelectElement>() { - let selected = select.selected_index(); - if selected == -1 { - return; - } - if let Some(new_role) = possibilities.get(selected as usize) { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::GraveDigger(target.clone(), *new_role), - )); - } - } - }) - }; - let on_wheel = { - let send = send.clone(); - let res_target = target.clone(); - let possibilities = possibilities.clone(); - Callback::from(move |ev: WheelEvent| { - let Some(target) = ev.target_dyn_into::<HtmlSelectElement>() else { - return; - }; - let index = target.selected_index(); - let new_index = match ev.delta_y().total_cmp(&0.0) { - core::cmp::Ordering::Equal => return, - core::cmp::Ordering::Less => { - if index != 0 { - index - 1 - } else { - (target.children().length() - 1) as i32 - } - } - core::cmp::Ordering::Greater => { - if index + 1 < target.children().length() as i32 { - index + 1 - } else { - 0 - } - } - }; - target.set_selected_index(new_index); - if let Some(new_role) = possibilities.get(new_index as usize) { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::GraveDigger(res_target.clone(), *new_role), - )); - } - }) - }; - html! { - <div class="result-option"> - <label>{"dug up"}</label> - <select onwheel={on_wheel} onchange={on_change_cb}> - {roles} - </select> - </div> - } - } - ActionResult::Mortician(target, died_to_title) => { - let roles = DiedToTitle::ALL - .into_iter() - .map(|died_to| { - html! { - <option selected={died_to == *died_to_title}>{died_to.to_string()}</option> - } - }) - .collect::<Html>(); - let on_change_cb = { - let send = send.clone(); - let target = target.clone(); - Callback::from(move |ev: Event| { - if let Some(select) = ev.target_dyn_into::<HtmlSelectElement>() { - let selected = select.selected_index(); - if selected == -1 { - return; - } - if let Some(died_to) = DiedToTitle::ALL.into_iter().nth(selected as _) { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::Mortician(target.clone(), died_to), - )); - } - } - }) - }; - let on_wheel = { - let send = send.clone(); - let res_target = target.clone(); - Callback::from(move |ev: WheelEvent| { - let Some(target) = ev.target_dyn_into::<HtmlSelectElement>() else { - return; - }; - let index = target.selected_index(); - let new_index = match ev.delta_y().total_cmp(&0.0) { - core::cmp::Ordering::Equal => return, - core::cmp::Ordering::Less => { - if index != 0 { - index - 1 - } else { - (target.children().length() - 1) as i32 - } - } - core::cmp::Ordering::Greater => { - if index + 1 < target.children().length() as i32 { - index + 1 - } else { - 0 - } - } - }; - target.set_selected_index(new_index); - if let Some(died_to) = DiedToTitle::ALL.into_iter().nth(new_index as _) { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::Mortician(res_target.clone(), died_to), - )); - } - }) - }; - html! { - <div class="prompt-option"> - <label>{"died to"}</label> - <select onwheel={on_wheel} onchange={on_change_cb}> - {roles} - </select> - </div> - } - } - ActionResult::Insomniac(visits) => { - let dec_disabled = - (visits.len() <= 1).then_some(String::from("already have minimum visits")); - let dec = { - let current = visits.len(); - let send = send.clone(); - Callback::from(move |_| { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::Insomniac(Visits::new(super::identities( - current.saturating_sub(1).max(1), - ))), - )); - }) - }; - let inc_disabled = - (visits.len() + 1 > 0xFF).then_some(String::from("already at max visits")); - let inc = { - let current = visits.len(); - let send = send.clone(); - Callback::from(move |_| { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::Insomniac(Visits::new(super::identities( - current.saturating_add(1).max(1), - ))), - )); - }) - }; - html! { - <div class="result-number"> - <Button - on_click={dec} - disabled_reason={dec_disabled} - > - {"decrease"} - </Button> - <label>{visits.len()}{" visits"}</label> - <Button - on_click={inc} - disabled_reason={inc_disabled} - > - {"increase"} - </Button> - </div> - } - } - ActionResult::Empath { target, scapegoat } => { - let on_toggle = { - let set = !*scapegoat; - let send = send.clone(); - let target = target.clone(); - Callback::from(move |_| { - send.emit(ServerToHostMessage::ActionResult( - None, - ActionResult::Empath { - scapegoat: set, - target: target.clone(), - }, - )); - }) - }; - let text = if *scapegoat { - "make not scapegoat" - } else { - "make scapegoat" - }; - html! { - <div class="prompt-options"> - <Button on_click={on_toggle}>{text}</Button> - </div> - } - } - }; - html! { - <div class="result-test"> - <Button on_click={back.clone()} classes={classes!("close")}>{"close"}</Button> - <label>{result.title().to_string()}</label> - - <div class="result-options"> - {options} - </div> - </div> - } -}