From 105fd52694d7a39d8557fdab751dff48a5b72ccb Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Mon, 12 Oct 2026 16:20:14 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20ledger-gui=20=E2=80=94=20a=20read-only,?= =?UTF-8?q?=20live=20desktop=20view=20of=20the=20books?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit egui/wgpu app for owners and their accountant: Overview, Cash, Profit, Transactions (with rendered receipts and journal history), Reports (statements with interval columns, comparisons, drill-down), Accounts, Documents, Company, Journal; Ctrl+K palette; back/forward; light/dark. Follows the journal live (~30 ms from write to screen). --demo opens a deterministic demo company, also used for screenshot tests. Engine: ledger-store Snapshot (read-only, incremental, tolerant of a half-written tail); ledger-core analysis (intervals, balance series, P&L by interval, cash flows); ledger-config extracted from ledger-mcp with the full company profile and cash_accounts. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01MtYEaR6M6Ybdhm6X98BWNu --- Cargo.lock | 3574 ++++++++++++++++- Cargo.toml | 2 +- README.md | 15 +- crates/ledger-config/Cargo.toml | 17 + .../company.rs => ledger-config/src/lib.rs} | 45 + crates/ledger-core/src/analysis.rs | 245 ++ crates/ledger-core/src/lib.rs | 1 + crates/ledger-core/tests/analysis.rs | 81 + crates/ledger-gui/Cargo.toml | 35 + .../ledger-gui/assets/fonts/Inter-LICENSE.txt | 92 + .../ledger-gui/assets/fonts/InterTab-Bold.ttf | Bin 0 -> 418484 bytes .../assets/fonts/InterTab-Regular.ttf | Bin 0 -> 409696 bytes .../assets/fonts/InterTab-SemiBold.ttf | Bin 0 -> 417744 bytes crates/ledger-gui/src/app.rs | 442 ++ crates/ledger-gui/src/attention.rs | 265 ++ crates/ledger-gui/src/books.rs | 519 +++ crates/ledger-gui/src/charts.rs | 387 ++ crates/ledger-gui/src/data.rs | 158 + crates/ledger-gui/src/demo.rs | 796 ++++ crates/ledger-gui/src/fmt.rs | 184 + crates/ledger-gui/src/lib.rs | 21 + crates/ledger-gui/src/main.rs | 72 + crates/ledger-gui/src/nav.rs | 195 + crates/ledger-gui/src/pages/accounts.rs | 350 ++ crates/ledger-gui/src/pages/cash.rs | 457 +++ crates/ledger-gui/src/pages/company.rs | 493 +++ crates/ledger-gui/src/pages/documents.rs | 302 ++ crates/ledger-gui/src/pages/entry.rs | 398 ++ crates/ledger-gui/src/pages/journal.rs | 482 +++ crates/ledger-gui/src/pages/mod.rs | 156 + crates/ledger-gui/src/pages/overview.rs | 481 +++ crates/ledger-gui/src/pages/profit.rs | 377 ++ crates/ledger-gui/src/pages/reports.rs | 1526 +++++++ crates/ledger-gui/src/pages/transactions.rs | 279 ++ crates/ledger-gui/src/palette.rs | 305 ++ crates/ledger-gui/src/receipts.rs | 177 + crates/ledger-gui/src/theme.rs | 228 ++ crates/ledger-gui/src/widgets.rs | 291 ++ crates/ledger-gui/tests/live.rs | 68 + crates/ledger-gui/tests/screens.rs | 88 + crates/ledger-mcp/Cargo.toml | 1 + crates/ledger-mcp/src/main.rs | 2 +- crates/ledger-mcp/src/server.rs | 2 +- crates/ledger-store/src/blob.rs | 8 + crates/ledger-store/src/lib.rs | 2 + crates/ledger-store/src/snapshot.rs | 175 + crates/ledger-store/src/store.rs | 80 +- crates/ledger-store/tests/snapshot.rs | 145 + docs/architecture.md | 11 +- plan/STATUS.md | 18 + plan/gui.md | 111 + plan/roadmap.md | 4 +- 52 files changed, 14050 insertions(+), 113 deletions(-) create mode 100644 crates/ledger-config/Cargo.toml rename crates/{ledger-mcp/src/company.rs => ledger-config/src/lib.rs} (88%) create mode 100644 crates/ledger-core/src/analysis.rs create mode 100644 crates/ledger-core/tests/analysis.rs create mode 100644 crates/ledger-gui/Cargo.toml create mode 100644 crates/ledger-gui/assets/fonts/Inter-LICENSE.txt create mode 100644 crates/ledger-gui/assets/fonts/InterTab-Bold.ttf create mode 100644 crates/ledger-gui/assets/fonts/InterTab-Regular.ttf create mode 100644 crates/ledger-gui/assets/fonts/InterTab-SemiBold.ttf create mode 100644 crates/ledger-gui/src/app.rs create mode 100644 crates/ledger-gui/src/attention.rs create mode 100644 crates/ledger-gui/src/books.rs create mode 100644 crates/ledger-gui/src/charts.rs create mode 100644 crates/ledger-gui/src/data.rs create mode 100644 crates/ledger-gui/src/demo.rs create mode 100644 crates/ledger-gui/src/fmt.rs create mode 100644 crates/ledger-gui/src/lib.rs create mode 100644 crates/ledger-gui/src/main.rs create mode 100644 crates/ledger-gui/src/nav.rs create mode 100644 crates/ledger-gui/src/pages/accounts.rs create mode 100644 crates/ledger-gui/src/pages/cash.rs create mode 100644 crates/ledger-gui/src/pages/company.rs create mode 100644 crates/ledger-gui/src/pages/documents.rs create mode 100644 crates/ledger-gui/src/pages/entry.rs create mode 100644 crates/ledger-gui/src/pages/journal.rs create mode 100644 crates/ledger-gui/src/pages/mod.rs create mode 100644 crates/ledger-gui/src/pages/overview.rs create mode 100644 crates/ledger-gui/src/pages/profit.rs create mode 100644 crates/ledger-gui/src/pages/reports.rs create mode 100644 crates/ledger-gui/src/pages/transactions.rs create mode 100644 crates/ledger-gui/src/palette.rs create mode 100644 crates/ledger-gui/src/receipts.rs create mode 100644 crates/ledger-gui/src/theme.rs create mode 100644 crates/ledger-gui/src/widgets.rs create mode 100644 crates/ledger-gui/tests/live.rs create mode 100644 crates/ledger-gui/tests/screens.rs create mode 100644 crates/ledger-store/src/snapshot.rs create mode 100644 crates/ledger-store/tests/snapshot.rs create mode 100644 plan/gui.md diff --git a/Cargo.lock b/Cargo.lock index 6873575..cb8a20d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,121 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "accesskit" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b7f7f85a7e5f68090000ed7622545829afd484d210358702ae4cb97dd0c320" +dependencies = [ + "enumn", + "serde", + "uuid", +] + +[[package]] +name = "accesskit_atspi_common" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8c61bee90b42a772d39d06a740207dc71a4e780004ace1db8d99fb1baaa954" +dependencies = [ + "accesskit", + "accesskit_consumer 0.36.0", + "atspi-common", + "phf 0.13.1", + "serde", + "zvariant", +] + +[[package]] +name = "accesskit_consumer" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53cf47daed85312e763fbf85ceca136e0d7abc68e0a7e12abe11f48172bc3b10" +dependencies = [ + "accesskit", + "hashbrown 0.16.1", +] + +[[package]] +name = "accesskit_consumer" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e0d7e25d06f4dc21d1774d67146e9e80d6789216cbd4d1e88185b0095dba60" +dependencies = [ + "accesskit", + "hashbrown 0.16.1", +] + +[[package]] +name = "accesskit_consumer" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d10a236f96f87d70732e44520046785431ef01d5bcd6b041317bfadd2f88245" +dependencies = [ + "accesskit", + "hashbrown 0.16.1", +] + +[[package]] +name = "accesskit_macos" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce02dc63b43f0c9296af9ac946312a2dc8814427d7a64d2d600971dac55b6076" +dependencies = [ + "accesskit", + "accesskit_consumer 0.38.0", + "hashbrown 0.16.1", + "objc2 0.5.3", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "accesskit_unix" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b016ca8db0ea0ea2ceff29a9d6240391492d960716aa471967c00e8cc8cb197c" +dependencies = [ + "accesskit", + "accesskit_atspi_common", + "async-channel", + "async-executor", + "async-task", + "atspi", + "futures-lite", + "futures-util", + "serde", + "zbus", +] + +[[package]] +name = "accesskit_windows" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff7009f1a532e917d66970a1e80c965140c6cfbbabbdde3d64e5431e6c78e21" +dependencies = [ + "accesskit", + "accesskit_consumer 0.35.0", + "hashbrown 0.16.1", + "static_assertions", + "windows", + "windows-core", +] + +[[package]] +name = "accesskit_winit" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fe9a94394896352cc4660ca2288bd4ef883d83238853c038b44070c8f134313" +dependencies = [ + "accesskit", + "accesskit_macos", + "accesskit_unix", + "accesskit_windows", + "raw-window-handle", + "winit", +] + [[package]] name = "adler2" version = "2.0.1" @@ -26,7 +141,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "getrandom 0.3.4", "once_cell", + "serde", "version_check", "zerocopy", ] @@ -40,6 +157,52 @@ 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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195" +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-activity" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" +dependencies = [ + "android-properties", + "bitflags 2.13.2", + "cc", + "jni", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror 2.0.21", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + [[package]] name = "android_system_properties" version = "0.1.6" @@ -49,6 +212,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + [[package]] name = "approx" version = "0.5.1" @@ -76,6 +245,26 @@ dependencies = [ "derive_arbitrary", ] +[[package]] +name = "arboard" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf" +dependencies = [ + "clipboard-win", + "image", + "log", + "objc2 0.6.5", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", + "parking_lot", + "percent-encoding", + "windows-sys 0.60.2", + "x11rb", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -88,6 +277,141 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 1.1.5", + "slab", + "windows-sys 0.61.2", +] + +[[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-process" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix 1.1.5", +] + +[[package]] +name = "async-recursion" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f8abc12baad266b1c8cec146854c195b5864b4221d4b2ca7296a7ae82d9e451" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.7", +] + +[[package]] +name = "async-signal" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 1.1.5", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + [[package]] name = "async-trait" version = "0.1.92" @@ -105,6 +429,43 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "atspi" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77886257be21c9cd89a4ae7e64860c6f0eefca799bb79127913052bd0eefb3d" +dependencies = [ + "atspi-common", + "atspi-proxies", +] + +[[package]] +name = "atspi-common" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20c5617155740c98003016429ad13fe43ce7a77b007479350a9f8bf95a29f63d" +dependencies = [ + "enumflags2", + "serde", + "static_assertions", + "zbus", + "zbus-lockstep", + "zbus-lockstep-macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "atspi-proxies" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2230e48787ed3eb4088996eab66a32ca20c0b67bbd4fd6cdfe79f04f1f04c9fc" +dependencies = [ + "atspi-common", + "serde", + "zbus", +] + [[package]] name = "autocfg" version = "1.5.1" @@ -213,6 +574,15 @@ dependencies = [ "bit-vec 0.8.0", ] +[[package]] +name = "bit-set" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2f926cc3060f09db9ebc5b52823d85268d24bb917e472c0c4bea35780a7d" +dependencies = [ + "bit-vec 0.9.1", +] + [[package]] name = "bit-set" version = "0.11.1" @@ -228,6 +598,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bit-vec" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" + [[package]] name = "bit-vec" version = "0.10.1" @@ -238,6 +614,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.13.2" @@ -266,6 +648,37 @@ dependencies = [ "zeroize", ] +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2 0.5.3", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2 0.6.5", +] + +[[package]] +name = "blocking" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + [[package]] name = "borsh" version = "1.8.1" @@ -290,6 +703,27 @@ dependencies = [ "syn 3.0.7", ] +[[package]] +name = "brotli" +version = "8.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.20.3" @@ -343,6 +777,56 @@ dependencies = [ "libbz2-rs-sys", ] +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.13.2", + "log", + "polling", + "rustix 0.38.44", + "slab", + "thiserror 1.0.69", +] + +[[package]] +name = "calloop" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b32313e937c8721c9d17ee9bf60699a6402b4b7c2cb6ac1bee0ffcaa4b4e5e" +dependencies = [ + "bitflags 2.13.2", + "polling", + "rustix 1.1.5", + "tracing", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop 0.13.0", + "rustix 0.38.44", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa" +dependencies = [ + "calloop 0.14.5", + "rustix 1.1.5", + "wayland-backend", + "wayland-client", +] + [[package]] name = "cc" version = "1.7.0" @@ -367,6 +851,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + [[package]] name = "chacha20" version = "0.10.2" @@ -458,6 +951,15 @@ dependencies = [ "serde_path_to_error", ] +[[package]] +name = "clipboard-win" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] + [[package]] name = "cmov" version = "0.5.4" @@ -470,7 +972,18 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror", + "thiserror 2.0.21", +] + +[[package]] +name = "codespan-reporting" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" +dependencies = [ + "serde", + "termcolor", + "unicode-width", ] [[package]] @@ -497,6 +1010,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + +[[package]] +name = "combine" +version = "4.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "comemo" version = "0.5.1" @@ -505,7 +1038,7 @@ checksum = "3c963350b2b08aa4b725d7802593245380ab53dacfedcaa971385fc33306c0d4" dependencies = [ "comemo-macros", "parking_lot", - "rustc-hash", + "rustc-hash 2.1.3", "siphasher", "slab", ] @@ -521,6 +1054,15 @@ dependencies = [ "syn 2.0.119", ] +[[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 = "const-oid" version = "0.10.2" @@ -536,12 +1078,46 @@ dependencies = [ "rustversion", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + [[package]] name = "core_detect" version = "1.0.0" @@ -670,6 +1246,12 @@ dependencies = [ "cmov", ] +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + [[package]] name = "darling" version = "0.24.1" @@ -716,6 +1298,37 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2" +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.21", +] + [[package]] name = "deranged" version = "0.5.8" @@ -733,6 +1346,19 @@ dependencies = [ "syn 3.0.7", ] +[[package]] +name = "dify" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ce0fb972943b4e88cd03b8f92953df0c71bb05e0bde8e5b684895d808013cc" +dependencies = [ + "anyhow", + "colored", + "getopts", + "image", + "rayon", +] + [[package]] name = "digest" version = "0.10.7" @@ -774,7 +1400,23 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dispatch2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.5", ] [[package]] @@ -788,12 +1430,53 @@ dependencies = [ "syn 3.0.7", ] +[[package]] +name = "dlib" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" +dependencies = [ + "libloading", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" + [[package]] name = "dyn-clone" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +[[package]] +name = "ecolor" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0656a7530b9e2841ee7a5f983965bdd9840c32f4012f759cfd44b912cced6b34" +dependencies = [ + "bytemuck", + "emath", + "serde", +] + [[package]] name = "ecow" version = "0.2.6" @@ -803,12 +1486,212 @@ dependencies = [ "serde", ] +[[package]] +name = "eframe" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ad41fac6e3149abb4866e93df37dbd33baa95db525c3368c944584e95a5dc2" +dependencies = [ + "ahash", + "bytemuck", + "document-features", + "egui", + "egui-wgpu", + "egui-winit", + "egui_glow", + "glutin", + "glutin-winit", + "image", + "js-sys", + "log", + "objc2 0.6.5", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", + "parking_lot", + "percent-encoding", + "pollster", + "profiling", + "raw-window-handle", + "ron", + "serde", + "static_assertions", + "wasm-bindgen", + "web-sys", + "web-time", + "wgpu", + "windows-sys 0.61.2", + "winit", +] + +[[package]] +name = "egui" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc938cc27cd911415e1e4d151bc56ff9df063d8db081374e87aeb805ea74b2ba" +dependencies = [ + "accesskit", + "ahash", + "bitflags 2.13.2", + "emath", + "epaint", + "itertools", + "log", + "nohash-hasher", + "profiling", + "ron", + "serde", + "smallvec", + "unicode-segmentation", + "web-sys", +] + +[[package]] +name = "egui-phosphor" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4299551488dddaa8f757727e1eb4ffdaf277ffe6e30b413403468f5ecf4634" +dependencies = [ + "egui", +] + +[[package]] +name = "egui-wgpu" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cef1f6d1bba40b09a4d0d62cb822b81030922cfbf65c5373398c3a3caafc5bd" +dependencies = [ + "ahash", + "bytemuck", + "document-features", + "egui", + "epaint", + "log", + "profiling", + "thiserror 2.0.21", + "type-map", + "web-time", + "wgpu", + "winit", +] + +[[package]] +name = "egui-winit" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98466000559d66ba4db786a30448b01483946add4188e7f10f522a27b4fb89cc" +dependencies = [ + "accesskit_winit", + "arboard", + "bytemuck", + "egui", + "log", + "objc2 0.6.5", + "objc2-foundation 0.3.2", + "objc2-ui-kit 0.3.2", + "profiling", + "raw-window-handle", + "serde", + "smithay-clipboard", + "web-time", + "winit", +] + +[[package]] +name = "egui_extras" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05cbdc785020861553f230f23d330ba1fb72613b9d8e0e457f3bdc8ba6db6dcf" +dependencies = [ + "ahash", + "egui", + "enum-map", + "image", + "itertools", + "jiff", + "log", + "mime_guess2", + "profiling", + "serde", +] + +[[package]] +name = "egui_glow" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "606ed4167daf341e5753d703285c4c1d562324b2c07aa8f405cd7d066fe58f3b" +dependencies = [ + "bytemuck", + "egui", + "glow", + "log", + "profiling", + "winit", +] + +[[package]] +name = "egui_kittest" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb3f3effb2726fee23449293e67acbf6cc6ce35525b1722bd5743bb348114d5" +dependencies = [ + "dify", + "eframe", + "egui", + "egui-wgpu", + "image", + "kittest", + "log", + "open", + "pollster", + "serde", + "tempfile", + "toml 1.1.8+spec-1.1.0", + "wgpu", +] + [[package]] name = "either" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be" +[[package]] +name = "emath" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c8d4141cf0f60fb2f7aefaf352d3ffa5171ef0ab09731c64391801e95e48f1" +dependencies = [ + "bytemuck", + "serde", +] + +[[package]] +name = "endi" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" + +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", + "serde", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "enum-ordinalize" version = "4.4.2" @@ -829,6 +1712,70 @@ dependencies = [ "syn 3.0.7", ] +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "enumn" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "epaint" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0ec0308dc23130fc1a7d4623a8534c2ed069c6dc84e258ee4f3de99615aa1a3" +dependencies = [ + "ahash", + "bytemuck", + "ecolor", + "emath", + "epaint_default_fonts", + "font-types 0.12.6", + "harfrust", + "log", + "nohash-hasher", + "parking_lot", + "profiling", + "self_cell", + "serde", + "skrifa 0.44.0", + "smallvec", + "unicode-general-category", + "unicode-segmentation", + "vello_cpu 0.1.0", +] + +[[package]] +name = "epaint_default_fonts" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773fa9c96dd0dbef887e39d0ed6177f141cce4d68e6041df77570aa3702dfa13" + [[package]] name = "equivalent" version = "1.0.2" @@ -842,9 +1789,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.61.2", ] +[[package]] +name = "error-code" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7" + [[package]] name = "euclid" version = "0.22.14" @@ -854,6 +1807,26 @@ dependencies = [ "num-traits", ] +[[package]] +name = "event-listener" +version = "5.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" +dependencies = [ + "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 = "fallible-iterator" version = "0.3.0" @@ -883,6 +1856,12 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" +[[package]] +name = "fax" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" + [[package]] name = "fdeflate" version = "0.3.7" @@ -898,6 +1877,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97b65636e5b9ef369943878ac74335ba1c55c1cb6adbf1e2c293c624248d693" +[[package]] +name = "fearless_simd" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4beca3cb2444e3304ac30843cc091f44ed58932353cd492ce740067bfce6b12" + [[package]] name = "fearless_simd" version = "1.1.0" @@ -951,6 +1936,16 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "font-types" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c92d9081c7ab3bd83ef1eecdfad090f3d966e3ce74106779664114cfe1a6274" +dependencies = [ + "bytemuck", + "serde", +] + [[package]] name = "fontconfig-parser" version = "0.5.8" @@ -974,6 +1969,33 @@ dependencies = [ "ttf-parser", ] +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.7", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -983,6 +2005,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + [[package]] name = "futures" version = "0.3.34" @@ -1031,6 +2062,19 @@ version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.34" @@ -1081,6 +2125,25 @@ dependencies = [ "version_check", ] +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix 1.1.5", + "windows-link", +] + +[[package]] +name = "getopts" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -1128,6 +2191,17 @@ dependencies = [ "weezl", ] +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + [[package]] name = "glidesort" version = "0.1.2" @@ -1146,11 +2220,136 @@ dependencies = [ "log", "peniko", "png", - "skrifa", + "skrifa 0.42.1", "smallvec", "vello_common 0.0.9", ] +[[package]] +name = "glifo" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed4a1bb24121291d27230c1b1b44e07d6a9b28cefdb32fe1581dfb84e14f940a" +dependencies = [ + "bytemuck", + "foldhash", + "hashbrown 0.17.1", + "log", + "peniko", + "skrifa 0.44.0", + "smallvec", + "vello_common 0.1.0", +] + +[[package]] +name = "glifo" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1218dedd5348c1b166ec3b8b3cbca49d2f527bd43b3fa072ea5123c523ed3f" +dependencies = [ + "bytemuck", + "foldhash", + "hashbrown 0.17.1", + "log", + "peniko", + "png", + "skrifa 0.44.0", + "smallvec", + "vello_common 0.3.0", +] + +[[package]] +name = "glow" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" +dependencies = [ + "bitflags 2.13.2", + "cfg_aliases", + "cgl", + "dispatch2", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2 0.6.5", + "objc2-app-kit 0.3.2", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-allocator" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" +dependencies = [ + "ash", + "hashbrown 0.16.1", + "log", + "presser", + "thiserror 2.0.21", + "windows", +] + [[package]] name = "guillotiere" version = "0.7.0" @@ -1168,9 +2367,22 @@ checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "num-traits", "zerocopy", ] +[[package]] +name = "harfrust" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03d949a14aa089bbb282f7dd76a498a7f684428e4257202efc119ec010376f9" +dependencies = [ + "bitflags 2.13.2", + "bytemuck", + "read-fonts 0.41.0", + "smallvec", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -1180,6 +2392,17 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + [[package]] name = "hashbrown" version = "0.17.1" @@ -1214,7 +2437,7 @@ dependencies = [ "roman-numerals-rs", "serde", "serde_yaml", - "thiserror", + "thiserror 2.0.21", "unic-langid", "unicode-segmentation", "unscanny", @@ -1228,11 +2451,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4caa128ab87fd48ffb7490617cf93f77f606820dffbc9fd9ef6ab0ed077f56d" dependencies = [ "bytemuck", - "hayro-interpret", + "hayro-interpret 0.7.0", "image", "kurbo", "pic-scale", - "vello_cpu", + "vello_cpu 0.0.8", +] + +[[package]] +name = "hayro" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4675ff5acd7ca41c0c34ccd2a3a154f5c86d8b5ec92bef0a114bfb194969e2af" +dependencies = [ + "bytemuck", + "fearless_simd 1.1.0", + "hayro-interpret 0.8.0", + "image", + "kurbo", + "pic-scale", + "rustc-hash 2.1.3", + "vello_cpu 0.3.0", ] [[package]] @@ -1253,6 +2492,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d285dc30731c8485de5fa732fbdf2b3affdf01e4da7c2135022ca6fa664bf6" dependencies = [ + "brotli", "hayro-postscript", ] @@ -1262,15 +2502,34 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2613d0406898995042d0794c4245b2f2fba1246490c8ac593769bba6551129d" dependencies = [ - "bitflags", + "bitflags 2.13.2", "hayro-cmap", - "hayro-syntax", + "hayro-syntax 0.7.2", "kurbo", "moxcms", - "phf", - "rustc-hash", + "phf 0.13.1", + "rustc-hash 2.1.3", "siphasher", - "skrifa", + "skrifa 0.42.1", + "smallvec", + "yoke", +] + +[[package]] +name = "hayro-interpret" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac9df074ff163a63864cec9b0bf640ccbff8abf4e44481df7369ce0ac172ffbe" +dependencies = [ + "bitflags 2.13.2", + "hayro-cmap", + "hayro-syntax 0.8.0", + "kurbo", + "moxcms", + "phf 0.13.1", + "rustc-hash 2.1.3", + "siphasher", + "skrifa 0.46.2", "smallvec", "yoke", ] @@ -1294,6 +2553,15 @@ dependencies = [ "fearless_simd 0.4.1", ] +[[package]] +name = "hayro-jpeg2000" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122c5f834c37a2260b9c851bb8be685cf539b2a8b94b704a931ef7d2525d5835" +dependencies = [ + "fearless_simd 1.1.0", +] + [[package]] name = "hayro-postscript" version = "0.1.0" @@ -1307,7 +2575,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7434c89e920d84e077214a29e69b462a6518754610f732f1124af3948410cb8c" dependencies = [ "base64 0.22.1", - "hayro-interpret", + "hayro-interpret 0.7.0", "image", "kurbo", "siphasher", @@ -1323,9 +2591,25 @@ dependencies = [ "flate2", "hayro-ccitt 0.3.0", "hayro-jbig2", - "hayro-jpeg2000", + "hayro-jpeg2000 0.3.5", "memchr", - "rustc-hash", + "rustc-hash 2.1.3", + "smallvec", + "zune-jpeg", +] + +[[package]] +name = "hayro-syntax" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cdc818d8d265dcb42081d488f7599df4f73fb79e9d347ecedcd3c23809d2026" +dependencies = [ + "flate2", + "hayro-ccitt 0.4.0", + "hayro-jbig2", + "hayro-jpeg2000 0.4.1", + "memchr", + "rustc-hash 2.1.3", "smallvec", "zune-jpeg", ] @@ -1337,7 +2621,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0b3db92c4917aad24ff30d61413a9a7509ae88b27aee1ae34eff881e1d2723a" dependencies = [ "flate2", - "hayro-syntax", + "hayro-syntax 0.7.2", "pdf-writer", ] @@ -1347,6 +2631,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" + [[package]] name = "hex" version = "0.4.3" @@ -1717,6 +3007,7 @@ dependencies = [ "moxcms", "num-traits", "png", + "tiff", "zune-core", "zune-jpeg", ] @@ -1756,6 +3047,26 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +[[package]] +name = "inotify" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cc00ea907cab49550b7da656f80ebb97be1b997d931fbcd28d39734e17ce592" +dependencies = [ + "bitflags 2.13.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c033f80b2c113cdf91ab7a33faa9cbc014726dcad99880c8609af2a370edf37d" +dependencies = [ + "libc", +] + [[package]] name = "inout" version = "0.2.2" @@ -1765,12 +3076,153 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[package]] +name = "itertools" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jiff" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "js-sys", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + +[[package]] +name = "jiff-static" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.21", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + [[package]] name = "jobserver" version = "0.1.35" @@ -1801,6 +3253,53 @@ dependencies = [ "mutate_once", ] +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "kittest" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ceaa75eb0036a32b6b9833962eb18137449e9817e2e586006471925b727fd5" +dependencies = [ + "accesskit", + "accesskit_consumer 0.35.0", +] + +[[package]] +name = "kqueue" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d763e5b24120b4ddf50de6c92308156765aabfbbccebf401da7cff2d70a41ea" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" +dependencies = [ + "bitflags 2.13.2", + "libc", +] + [[package]] name = "krilla" version = "0.8.2" @@ -1820,10 +3319,10 @@ dependencies = [ "pdf-writer", "png", "rayon", - "rustc-hash", + "rustc-hash 2.1.3", "rustybuzz", "siphasher", - "skrifa", + "skrifa 0.42.1", "smallvec", "subsetter", "tiny-skia-path", @@ -1842,7 +3341,7 @@ dependencies = [ "fontdb", "krilla", "resvg", - "skrifa", + "skrifa 0.42.1", "smallvec", "tiny-skia", "usvg", @@ -1860,6 +3359,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "lazy_static" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" + [[package]] name = "ledger-cli" version = "0.1.0" @@ -1868,6 +3373,17 @@ dependencies = [ "toml 1.1.8+spec-1.1.0", ] +[[package]] +name = "ledger-config" +version = "0.1.0" +dependencies = [ + "chrono", + "ledger-core", + "rust_decimal", + "serde", + "toml 1.1.8+spec-1.1.0", +] + [[package]] name = "ledger-core" version = "0.1.0" @@ -1877,7 +3393,29 @@ dependencies = [ "rust_decimal", "serde", "serde_json", - "thiserror", + "thiserror 2.0.21", +] + +[[package]] +name = "ledger-gui" +version = "0.1.0" +dependencies = [ + "chrono", + "eframe", + "egui", + "egui-phosphor", + "egui_extras", + "egui_kittest", + "hayro 0.8.0", + "image", + "jiff", + "ledger-config", + "ledger-core", + "ledger-store", + "notify", + "rust_decimal", + "serde", + "serde_json", ] [[package]] @@ -1891,7 +3429,7 @@ dependencies = [ "rust_xlsxwriter", "serde", "serde_json", - "thiserror", + "thiserror 2.0.21", "typst", "typst-as-lib", "typst-layout", @@ -1905,6 +3443,7 @@ dependencies = [ "axum", "base64 0.22.1", "chrono", + "ledger-config", "ledger-core", "ledger-import", "ledger-store", @@ -1914,7 +3453,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "thiserror", + "thiserror 2.0.21", "tokio", "toml 1.1.8+spec-1.1.0", "tower", @@ -1934,7 +3473,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "tempfile", - "thiserror", + "thiserror 2.0.21", ] [[package]] @@ -1949,6 +3488,16 @@ version = "0.2.190" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + [[package]] name = "libm" version = "0.2.16" @@ -1961,7 +3510,10 @@ version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" dependencies = [ + "bitflags 2.13.2", "libc", + "plain", + "redox_syscall 0.9.4", ] [[package]] @@ -1987,6 +3539,12 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -2012,6 +3570,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "litrs" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4744e383959f0db86ede514b809b1c53251889093803c05267acc7d4e7030d70" + [[package]] name = "lock_api" version = "0.4.14" @@ -2057,6 +3621,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -2073,6 +3646,18 @@ dependencies = [ "unicase", ] +[[package]] +name = "mime_guess2" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1706dc14a2e140dec0a7a07109d9a3d5890b81e85bd6c60b906b249a77adf0ca" +dependencies = [ + "mime", + "phf 0.11.3", + "phf_shared 0.11.3", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2100,8 +3685,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1788edb87fdc09c7e26304471e2f5be8cdefb1b6930d6e3985fc02ff53bf86ee" dependencies = [ "libc", + "log", "wasi", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -2120,18 +3706,119 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13d2233c9842d08cfe13f9eac96e207ca6a2ea10b80259ebe8ad0268be27d2af" +[[package]] +name = "naga" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a616d2fb8c89516ac2723a581f69d6c18576046bed761bd6b305e5618e6ae130" +dependencies = [ + "arrayvec", + "bit-set 0.10.0", + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases", + "codespan-reporting", + "half", + "hashbrown 0.17.1", + "indexmap", + "libm", + "log", + "naga-types", + "num-traits", + "once_cell", + "rustc-hash 1.1.0", + "spirv", + "thiserror 2.0.21", + "unicode-ident", +] + +[[package]] +name = "naga-types" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "590afbf58a6f4f62873cd5cff4468061844bafa1cdf399cc954537c22d768d49" +dependencies = [ + "hashbrown 0.17.1", + "indexmap", + "rustc-hash 1.1.0", + "thiserror 2.0.21", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.13.2", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys 0.3.1", +] + [[package]] name = "nix" version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags", + "bitflags 2.13.2", "cfg-if", "cfg_aliases", "libc", ] +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "notify" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" +dependencies = [ + "bitflags 2.13.2", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "notify-types", + "walkdir", + "windows-sys 0.60.2", +] + +[[package]] +name = "notify-types" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" +dependencies = [ + "bitflags 2.13.2", +] + [[package]] name = "num-bigint" version = "0.4.8" @@ -2164,6 +3851,339 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d5490aaf8f1d7cf7688dfa9b0ce07900e168852c45cd2c03f534dfd27cfd0b" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08849bbd4767dfae9457696856ae1c84fe4e0281bbe4a7abff2d0e06fb7981f8" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "libc", + "objc2 0.5.3", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation 0.2.2", + "objc2-quartz-core 0.2.2", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.3", + "objc2-core-location", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.3", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.3", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2 0.6.5", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.13.2", + "dispatch2", + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.3", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.3", + "objc2-contacts", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "dispatch", + "libc", + "objc2 0.5.3", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.13.2", + "block2 0.6.2", + "objc2 0.6.5", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.5", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.3", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.3", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-metal" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" +dependencies = [ + "bitflags 2.13.2", + "block2 0.6.2", + "objc2 0.6.5", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.3", + "objc2-foundation 0.2.2", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2 0.5.3", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.3", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation 0.2.2", + "objc2-link-presentation", + "objc2-quartz-core 0.2.2", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.13.2", + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.3", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.13.2", + "block2 0.5.1", + "objc2 0.5.3", + "objc2-core-location", + "objc2-foundation 0.2.2", ] [[package]] @@ -2181,12 +4201,51 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +[[package]] +name = "open" +version = "5.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa576c76302b7b808eecc68061e67336c47833ef9d22caa74dda10fa9675eebc" +dependencies = [ + "is-wsl", + "libc", +] + [[package]] name = "option-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "orbclient" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" +dependencies = [ + "libc", + "libredox", +] + +[[package]] +name = "ordered-float" +version = "5.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7c9e0d9b23589f26070720bac724174bfec1083e82f7854cdd0267518343c0" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + [[package]] name = "palette" version = "0.7.7" @@ -2220,6 +4279,12 @@ dependencies = [ "libm", ] +[[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" @@ -2238,7 +4303,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", "windows-link", ] @@ -2271,7 +4336,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5e456864a7a304047bff84977dc6fb162bd956475d40ba50b2dcecaada7f753" dependencies = [ - "bitflags", + "bitflags 2.13.2", "itoa", "memchr", "ryu", @@ -2296,17 +4361,37 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + [[package]] name = "phf" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "phf_macros", - "phf_shared", + "phf_macros 0.13.1", + "phf_shared 0.13.1", "serde", ] +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.8", +] + [[package]] name = "phf_generator" version = "0.13.1" @@ -2314,7 +4399,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ "fastrand", - "phf_shared", + "phf_shared 0.13.1", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.119", + "unicase", ] [[package]] @@ -2323,13 +4422,23 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.13.1", + "phf_shared 0.13.1", "proc-macro2", "quote", "syn 2.0.119", ] +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", + "unicase", +] + [[package]] name = "phf_shared" version = "0.13.1" @@ -2355,18 +4464,55 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "pin-project-lite" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "piper" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + [[package]] name = "pkg-config" version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "plist" version = "1.10.1" @@ -2386,13 +4532,33 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags", + "bitflags 2.13.2", "crc32fast", "fdeflate", "flate2", "miniz_oxide 0.8.9", ] +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 1.1.5", + "windows-sys 0.61.2", +] + +[[package]] +name = "pollster" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6355899e1c9462875b6757c79f3caa011a1fdae12bbb1a2e72dd1f234f8336" + [[package]] name = "polycool" version = "0.4.0" @@ -2408,6 +4574,15 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" +[[package]] +name = "portable-atomic-util" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" +dependencies = [ + "portable-atomic", +] + [[package]] name = "postcard" version = "1.1.3" @@ -2450,6 +4625,12 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -2474,6 +4655,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" + [[package]] name = "proptest" version = "1.12.0" @@ -2482,7 +4669,7 @@ checksum = "b8530004ccb15eae51c7e40009fbe317f341f804db54dc033eec1c50be28cfa0" dependencies = [ "bit-set 0.11.1", "bit-vec 0.10.1", - "bitflags", + "bitflags 2.13.2", "chacha20", "core_detect", "num-traits", @@ -2532,6 +4719,15 @@ dependencies = [ "serde", ] +[[package]] +name = "quick-xml" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" +dependencies = [ + "memchr", +] + [[package]] name = "quick-xml" version = "0.42.0" @@ -2647,6 +4843,30 @@ dependencies = [ "rand_core 0.10.1", ] +[[package]] +name = "range-alloc" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca45419789ae5a7899559e9512e58ca889e41f04f1f2445e9f4b290ceccd1d08" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "raw-window-metal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" +dependencies = [ + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", +] + [[package]] name = "rayon" version = "1.12.0" @@ -2674,7 +4894,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4ed38b89c2c77ff968c524145ad65fb010f38af5c7a224b53b81d47ac2daa81" dependencies = [ "bytemuck", - "font-types", + "font-types 0.11.3", +] + +[[package]] +name = "read-fonts" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046a7d674daf459825b32f5062056d6882db0d2f5a479fbd76ccfc870ac18709" +dependencies = [ + "bytemuck", + "font-types 0.12.6", + "once_cell", +] + +[[package]] +name = "read-fonts" +version = "0.43.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "005c8acf251756c478b0bf402885bfd88a1476020c4c7e6060edc1aa68da38ea" +dependencies = [ + "bytemuck", + "font-types 0.12.6", + "once_cell", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", ] [[package]] @@ -2683,7 +4934,16 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.13.2", +] + +[[package]] +name = "redox_syscall" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "737970939a87c6fa31e7acad13307bccbb017a073b695b6089a2c484f929e20e" +dependencies = [ + "bitflags 2.13.2", ] [[package]] @@ -2693,7 +4953,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60dc65c0ff1a7ae1294b0c67b9f14baf70b644404010370171787bfac1038fc0" dependencies = [ "libredox", - "thiserror", + "thiserror 2.0.21", ] [[package]] @@ -2745,6 +5005,12 @@ version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + [[package]] name = "resvg" version = "0.47.0" @@ -2794,7 +5060,7 @@ dependencies = [ "serde", "serde_json", "sse-stream", - "thiserror", + "thiserror 2.0.21", "tokio", "tokio-stream", "tokio-util", @@ -2822,6 +5088,20 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c85cd47a33a4510b1424fe796498e174c6a9cf94e606460ef022a19f3e4ff85e" +[[package]] +name = "ron" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" +dependencies = [ + "bitflags 2.13.2", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + [[package]] name = "roxmltree" version = "0.20.0" @@ -2843,7 +5123,7 @@ version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" dependencies = [ - "bitflags", + "bitflags 2.13.2", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -2877,23 +5157,51 @@ dependencies = [ "zip 4.6.1", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc-hash" version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + [[package]] name = "rustix" version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ - "bitflags", + "bitflags 2.13.2", "errno", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.12.1", + "windows-sys 0.61.2", ] [[package]] @@ -2920,7 +5228,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" dependencies = [ - "bitflags", + "bitflags 2.13.2", "bytemuck", "core_maths", "log", @@ -2973,12 +5281,24 @@ dependencies = [ "syn 3.0.7", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "self_cell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813" + [[package]] name = "semver" version = "1.0.28" @@ -3050,6 +5370,17 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_repr" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.7", +] + [[package]] name = "serde_spanned" version = "0.6.9" @@ -3132,12 +5463,38 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + [[package]] name = "simd-adler32" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "simplecss" version = "0.2.2" @@ -3160,7 +5517,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c34617370ae968efb7161bb2beb517d9084659aae19e24b89e3db25b46e4564" dependencies = [ "bytemuck", - "read-fonts", + "read-fonts 0.39.2", +] + +[[package]] +name = "skrifa" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819ab7d62b1d3e72d9d9dea5650bac30424f9111364bb94928dbf5ecad1baa68" +dependencies = [ + "bytemuck", + "read-fonts 0.41.0", +] + +[[package]] +name = "skrifa" +version = "0.46.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4febebda507fb889c545a37a135517769d1391941013561292897961d1887d6" +dependencies = [ + "bytemuck", + "read-fonts 0.43.3", ] [[package]] @@ -3183,6 +5560,81 @@ name = "smallvec" version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b3dc8af474f516a851ff4bd12db780f948b9250ad37211e4eec0bccea54e01b" +dependencies = [ + "serde", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.13.2", + "calloop 0.13.0", + "calloop-wayland-source 0.3.0", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 0.38.44", + "thiserror 1.0.69", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" +dependencies = [ + "bitflags 2.13.2", + "calloop 0.14.5", + "calloop-wayland-source 0.4.1", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix 1.1.5", + "thiserror 2.0.21", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-experimental", + "wayland-protocols-misc", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-clipboard" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71704c03f739f7745053bde45fa203a46c58d25bc5c4efba1d9a60e9dba81226" +dependencies = [ + "libc", + "smithay-client-toolkit 0.20.0", + "wayland-backend", +] + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -3191,7 +5643,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -3200,6 +5652,15 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" +[[package]] +name = "spirv" +version = "0.4.0+sdk-1.4.341.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9571ea910ebd84c86af4b3ed27f9dbdc6ad06f17c5f96146b2b671e2976744f" +dependencies = [ + "bitflags 2.13.2", +] + [[package]] name = "sse-stream" version = "0.2.6" @@ -3229,9 +5690,15 @@ dependencies = [ "cfg-if", "libc", "psm", - "windows-sys", + "windows-sys 0.61.2", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strict-num" version = "0.1.1" @@ -3275,8 +5742,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38803281d1c23166c5ebcb455439a5d2afe711cc909cf88af72448c297756ad6" dependencies = [ "kurbo", - "rustc-hash", - "skrifa", + "rustc-hash 2.1.3", + "skrifa 0.42.1", "write-fonts", ] @@ -3345,7 +5812,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "thiserror", + "thiserror 2.0.21", "walkdir", "yaml-rust", ] @@ -3359,8 +5826,17 @@ dependencies = [ "fastrand", "getrandom 0.4.3", "once_cell", - "rustix", - "windows-sys", + "rustix 1.1.5", + "windows-sys 0.61.2", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", ] [[package]] @@ -3369,13 +5845,33 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6a4b9ba8738cb4a4f399d37e266becfd475e75eb73425b87a05a2f2039ba63e" +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.21", +] + +[[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.119", ] [[package]] @@ -3389,6 +5885,20 @@ dependencies = [ "syn 3.0.7", ] +[[package]] +name = "tiff" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52" +dependencies = [ + "fax", + "flate2", + "half", + "quick-error 2.0.1", + "weezl", + "zune-jpeg", +] + [[package]] name = "time" version = "0.3.55" @@ -3475,7 +5985,7 @@ dependencies = [ "pin-project-lite", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -3686,6 +6196,15 @@ dependencies = [ "syntect", ] +[[package]] +name = "type-map" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" +dependencies = [ + "rustc-hash 2.1.3", +] + [[package]] name = "typed-arena" version = "2.0.2" @@ -3698,6 +6217,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e" +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.20.1" @@ -3713,7 +6238,7 @@ dependencies = [ "arrayvec", "comemo", "ecow", - "rustc-hash", + "rustc-hash 2.1.3", "typst-eval", "typst-html", "typst-layout", @@ -3735,7 +6260,7 @@ dependencies = [ "comemo", "dirs", "ecow", - "thiserror", + "thiserror 2.0.21", "typst", ] @@ -3745,7 +6270,7 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcee505dac6702dd1c5e65aa2e94a6179d19ee09e2e5637d7313db91765dc4e0" dependencies = [ - "bitflags", + "bitflags 2.13.2", ] [[package]] @@ -3757,7 +6282,7 @@ dependencies = [ "comemo", "ecow", "indexmap", - "rustc-hash", + "rustc-hash 2.1.3", "stacker", "toml 0.8.23", "typst-library", @@ -3779,7 +6304,7 @@ dependencies = [ "comemo", "ecow", "palette", - "rustc-hash", + "rustc-hash 2.1.3", "time", "typst-assets", "typst-library", @@ -3811,7 +6336,7 @@ dependencies = [ "kurbo", "libm", "memchr", - "rustc-hash", + "rustc-hash 2.1.3", "rustybuzz", "smallvec", "ttf-parser", @@ -3835,7 +6360,7 @@ checksum = "12becd02464849f1507f3c4ef3f401a4d28d5938cc74b6acc6f1d703458bf393" dependencies = [ "arrayvec", "az", - "bitflags", + "bitflags 2.13.2", "bumpalo", "ciborium", "codex", @@ -3847,7 +6372,7 @@ dependencies = [ "fontdb", "glidesort", "hayagriva", - "hayro-syntax", + "hayro-syntax 0.7.2", "icu_properties", "image", "indexmap", @@ -3859,14 +6384,14 @@ dependencies = [ "moxcms", "palette", "percent-encoding", - "phf", + "phf 0.13.1", "png", "rayon", "regex", "regex-syntax", "roxmltree 0.21.1", "rust_decimal", - "rustc-hash", + "rustc-hash 2.1.3", "rustybuzz", "serde", "serde_json", @@ -3923,7 +6448,7 @@ dependencies = [ "infer", "krilla", "krilla-svg", - "rustc-hash", + "rustc-hash 2.1.3", "serde", "smallvec", "typst-assets", @@ -3964,12 +6489,12 @@ dependencies = [ "comemo", "ecow", "flate2", - "hayro", + "hayro 0.7.1", "hayro-svg", "image", "indexmap", "itoa", - "rustc-hash", + "rustc-hash 2.1.3", "ryu", "ttf-parser", "typst-assets", @@ -3988,7 +6513,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92a20d79df5d10c7fb0b4f7c18e4b2671edfc21e5ed9ad9894e18cccefd1c70f" dependencies = [ "ecow", - "rustc-hash", + "rustc-hash 2.1.3", "serde", "toml 0.8.23", "typst-timing", @@ -4021,7 +6546,7 @@ dependencies = [ "once_cell", "portable-atomic", "rayon", - "rustc-hash", + "rustc-hash 2.1.3", "semver", "siphasher", "smallvec", @@ -4029,6 +6554,17 @@ dependencies = [ "unicode-math-class", ] +[[package]] +name = "uds_windows" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" +dependencies = [ + "memoffset", + "tempfile", + "windows-sys 0.61.2", +] + [[package]] name = "unarray" version = "0.1.4" @@ -4103,6 +6639,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e" +[[package]] +name = "unicode-general-category" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f" + [[package]] name = "unicode-ident" version = "1.0.26" @@ -4148,6 +6690,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -4221,6 +6769,7 @@ checksum = "7cc1186384beb7dd8eedea376413fd654937285ea6c9cfbb928dc3043ea4b606" dependencies = [ "getrandom 0.4.3", "js-sys", + "serde_core", "wasm-bindgen", ] @@ -4244,7 +6793,7 @@ dependencies = [ "peniko", "png", "smallvec", - "thiserror", + "thiserror 2.0.21", ] [[package]] @@ -4261,7 +6810,38 @@ dependencies = [ "peniko", "png", "smallvec", - "thiserror", + "thiserror 2.0.21", +] + +[[package]] +name = "vello_common" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e9aed918117e8152c9eddfd8362d73c465c23f26c44786aa331707b8a64fa2" +dependencies = [ + "bytemuck", + "fearless_simd 0.4.1", + "guillotiere", + "log", + "peniko", + "smallvec", + "thiserror 2.0.21", +] + +[[package]] +name = "vello_common" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c2fbe53548bcd25c8ff42f75a93770a8611a16b37bee56d7ef7b44e36027f1" +dependencies = [ + "bytemuck", + "fearless_simd 0.7.0", + "guillotiere", + "log", + "peniko", + "png", + "smallvec", + "thiserror 2.0.21", ] [[package]] @@ -4271,12 +6851,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d8ded630e8316bb94a55881256506d1f3b9947b5f66db8a7d32ca7ba02decd0" dependencies = [ "bytemuck", - "glifo", + "glifo 0.1.1", "hashbrown 0.17.1", "png", "vello_common 0.0.8", ] +[[package]] +name = "vello_cpu" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac7349e1f55f6b801c7c277958df4ea53e7f20f21e8014910ad888b2ecda93ea" +dependencies = [ + "bytemuck", + "glifo 0.2.0", + "hashbrown 0.17.1", + "vello_common 0.1.0", +] + +[[package]] +name = "vello_cpu" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed1fec424fbba6acf6cbc78bb526447eb77590d95f40419d598870fe37535212" +dependencies = [ + "bytemuck", + "glifo 0.4.0", + "hashbrown 0.17.1", + "png", + "vello_common 0.3.0", +] + [[package]] name = "version_check" version = "0.9.5" @@ -4331,6 +6936,17 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbab34de2d982e9b48e18d216d04c4a6f641066ff19ffb699980f591ee3610e" +dependencies = [ + "js-sys", + "tokio", + "wasm-bindgen", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.129" @@ -4406,7 +7022,162 @@ version = "0.239.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9d90bb93e764f6beabf1d02028c70a2156a6583e63ac4218dd07ef733368b0" dependencies = [ - "bitflags", + "bitflags 2.13.2", +] + +[[package]] +name = "wayland-backend" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38a91b4eaddff87b1cd1074985e3713da4af2c49742d1b356b2c01670a67a078" +dependencies = [ + "cc", + "downcast-rs", + "rustix 1.1.5", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073" +dependencies = [ + "bitflags 2.13.2", + "rustix 1.1.5", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.13.2", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" +dependencies = [ + "rustix 1.1.5", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6" +dependencies = [ + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-experimental" +version = "20250721.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" +dependencies = [ + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-misc" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" +dependencies = [ + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" +dependencies = [ + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" +dependencies = [ + "bitflags 2.13.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0" +dependencies = [ + "proc-macro2", + "quick-xml 0.41.0", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88261b9deccee56594c11a3460c462c41f58d148598fe70ad77070126a68aba4" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", ] [[package]] @@ -4415,13 +7186,217 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" +[[package]] +name = "wgpu" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527ccdf43dd5b2e8676eed9984ce00e2bbb0a1b85b70c1969dcb6cd2eb55ab9e" +dependencies = [ + "arrayvec", + "bitflags 2.13.2", + "bytemuck", + "cfg-if", + "cfg_aliases", + "document-features", + "hashbrown 0.17.1", + "js-sys", + "log", + "naga", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c018fce9b6270aa203c2fdd56f3cce996713534bd757e4ea58c8560b121f14" +dependencies = [ + "arrayvec", + "bit-set 0.10.0", + "bit-vec 0.9.1", + "bitflags 2.13.2", + "bytemuck", + "cfg_aliases", + "document-features", + "hashbrown 0.17.1", + "indexmap", + "log", + "naga", + "naga-types", + "once_cell", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 2.0.21", + "wgpu-core-deps-apple", + "wgpu-core-deps-emscripten", + "wgpu-core-deps-wasm", + "wgpu-core-deps-windows-linux-android", + "wgpu-hal", + "wgpu-naga-bridge", + "wgpu-types", +] + +[[package]] +name = "wgpu-core-deps-apple" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061f3d319a40d39d00b1ecc2c33b89fe21d4e6fe01859df3500a3a8ecccd6b68" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-emscripten" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98b86cf4abf524a902dd35f18ca6a3f08fc2ae9847c8f10b48e30491b1f0b86" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-wasm" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d260ca2ca8adc654f513a869bf3cac0b47f5b8d3f87803d6942015f8de597aae" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-windows-linux-android" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7586165fd5f6d881cb9ce4bb71f40d6caab2c0f1837e3fc1d9788a197fb6004f" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-hal" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b7fb58561a792bc237628ba0792e332de418fefe145f13b5ed8201e6d52f58" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set 0.10.0", + "bitflags 2.13.2", + "block2 0.6.2", + "bytemuck", + "cfg-if", + "cfg_aliases", + "glow", + "glutin_wgl_sys", + "gpu-allocator", + "hashbrown 0.17.1", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "naga", + "naga-types", + "ndk-sys", + "objc2 0.6.5", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", + "objc2-quartz-core 0.3.2", + "once_cell", + "ordered-float", + "parking_lot", + "portable-atomic", + "portable-atomic-util", + "profiling", + "range-alloc", + "raw-window-handle", + "raw-window-metal", + "renderdoc-sys", + "smallvec", + "static_assertions", + "thiserror 2.0.21", + "wasm-bindgen", + "wayland-sys", + "web-sys", + "wgpu-naga-bridge", + "wgpu-types", + "windows", + "windows-core", + "windows-result", +] + +[[package]] +name = "wgpu-naga-bridge" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f62e73117bb7a62bfd9c5a5841438a823f6566c6442a808ee269d2d055c081" +dependencies = [ + "naga", + "wgpu-types", +] + +[[package]] +name = "wgpu-types" +version = "30.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99dad6f1fbdbbdb4c278a6508b059d44688f5cebddf78d005a46a31340269286" +dependencies = [ + "bitflags 2.13.2", + "bytemuck", + "js-sys", + "log", + "naga-types", + "raw-window-handle", + "static_assertions", + "web-sys", +] + [[package]] name = "winapi-util" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core", ] [[package]] @@ -4437,6 +7412,17 @@ dependencies = [ "windows-strings", ] +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", +] + [[package]] name = "windows-implement" version = "0.60.2" @@ -4465,6 +7451,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core", + "windows-link", +] + [[package]] name = "windows-result" version = "0.4.1" @@ -4483,6 +7479,33 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -4492,6 +7515,195 @@ 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 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", +] + +[[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_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[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_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[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_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[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_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[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_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winit" +version = "0.30.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.13.2", + "block2 0.5.1", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases", + "concurrent-queue", + "core-foundation", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk", + "objc2 0.5.3", + "objc2-app-kit 0.2.2", + "objc2-foundation 0.2.2", + "objc2-ui-kit 0.2.2", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix 0.38.44", + "smithay-client-toolkit 0.19.2", + "smol_str", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + [[package]] name = "winnow" version = "0.7.15" @@ -4522,11 +7734,11 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb731d4c4d93eacc69a1ad2f270f905788a98e4a3438267bcafbe08d3431c8d8" dependencies = [ - "font-types", + "font-types 0.11.3", "indexmap", "kurbo", "log", - "read-fonts", + "read-fonts 0.39.2", ] [[package]] @@ -4541,6 +7753,69 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.1.5", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + +[[package]] +name = "xcursor" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "163b33ed8786455e2fa5d72f554057ce3f3182425434f756cd39c99839d88e23" + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.13.2", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xml-rs" +version = "0.8.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7" + [[package]] name = "xmlwriter" version = "0.1.0" @@ -4585,6 +7860,112 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zbus" +version = "5.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db4be7c075cb421e4b7ee645541604239bd243ba7c357511f4ff3a74b555907" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "libc", + "ordered-stream", + "rustix 1.1.5", + "serde", + "serde_repr", + "tracing", + "uds_windows", + "uuid", + "windows-sys 0.61.2", + "winnow 1.0.4", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus-lockstep" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6998de05217a084b7578728a9443d04ea4cd80f2a0839b8d78770b76ccd45863" +dependencies = [ + "zbus_xml", + "zvariant", +] + +[[package]] +name = "zbus-lockstep-macros" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10da05367f3a7b7553c8cdf8fa91aee6b64afebe32b51c95177957efc47ca3a0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", + "zbus-lockstep", + "zbus_xml", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2990635d09ade6df1868f72f8cac69a876a90981e8bd3c40b1be413f8dc88f40" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 3.0.7", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8bf88b4a3ff53e883001e0e0115b297a9d53c31b9c1edd2bfdd853e3428624e" +dependencies = [ + "serde", + "winnow 1.0.4", + "zvariant", +] + +[[package]] +name = "zbus_xml" +version = "5.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1586c021a01ca0a9216dcd874e546382e156a5cbab5fab6cb5f10087e22682a" +dependencies = [ + "serde", + "winnow 1.0.4", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zcheapstr" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1afec51604565183aeb5c54c20aeab286120d4e4460f7f76e3e8bb8c0d99473" +dependencies = [ + "serde", +] + [[package]] name = "zerocopy" version = "0.8.62" @@ -4777,3 +8158,44 @@ checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ "zune-core", ] + +[[package]] +name = "zvariant" +version = "5.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d34c27cc6cdd1f458427519dd6b8612f7b7e3f7b9a0b2355d041dda9869147" +dependencies = [ + "endi", + "enumflags2", + "serde", + "winnow 1.0.4", + "zcheapstr", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864155e69b4352db0c7f374917bf45d1e0c8d17659c8b3dbf9795f3673f8c497" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 3.0.7", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad0294361a320b694a328460dc73add56c306150f5cb6bfafc44446120008a3" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 3.0.7", + "winnow 1.0.4", +] diff --git a/Cargo.toml b/Cargo.toml index 2cd08c1..a2eb360 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["crates/ledger-core", "crates/ledger-store", "crates/ledger-mcp", "crates/ledger-import", "crates/ledger-cli"] +members = ["crates/ledger-core", "crates/ledger-store", "crates/ledger-config", "crates/ledger-mcp", "crates/ledger-import", "crates/ledger-cli", "crates/ledger-gui"] [workspace.package] edition = "2024" diff --git a/README.md b/README.md index dee91ee..c4db022 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,21 @@ through MCP. Self-hosted, no rent. append-only, hash-chained JSONL journal; SQLite is a disposable projection rebuilt from it; receipts live in a content-addressed blob store. Drafts are durable, corrupt projections self-heal. -- **`ledger-mcp`** — the AI-first interface. 27 MCP tools over stdio or +- **`ledger-mcp`** — the AI-first interface. 64 MCP tools over stdio or Streamable HTTP: draft → preview → post workflow, server-side receipt policy (>$25), anti-splitting detection, asset management, digest for human review, plus read-only resources for dashboards. - **`ledger-import`** — QuickBooks interop. Import bank/credit-card CSVs and chart-of-accounts CSVs; export IIF journal entries (for QuickBooks Desktop) and XLSX reports. +- **`ledger-config`** — the company settings in a books dir's + `wanderbooks.toml`. +- **`ledger-gui`** — the read-only desktop view for owners and their + accountant (egui). Answers first (cash, runway, profit, what needs + attention), then every number drills down to its lines, its entry, the + rendered receipt, and the journal history. Follows the journal live: + a change the agent makes appears in milliseconds. `--demo` opens a + realistic demo company. ## Verification @@ -51,6 +59,7 @@ See [`plan/STATUS.md`](plan/STATUS.md) for where things stand and cargo test # whole suite cargo run -p ledger-cli -- init ~/books/acme # scaffold a books dir: mise.toml + AGENT.md cargo run -p ledger-mcp -- --data-dir /tmp/books # MCP server over stdio +cargo run -p ledger-gui -- --demo # the desktop view, on a demo company ``` Then `cd ~/books/acme`: `mise trust && mise install`, `mise run build`, `mise run mcp-add`, and start `claude` — the agent onboards from AGENT.md. @@ -60,8 +69,10 @@ Then `cd ~/books/acme`: `mise trust && mise install`, `mise run build`, ``` crates/ledger-core/ # engine: money, accounts, journal, ledger, reports crates/ledger-store/ # journal + SQLite projection + blob store -crates/ledger-mcp/ # MCP server: 27 tools, resources, receipt policy +crates/ledger-mcp/ # MCP server: 64 tools, resources, receipt policy crates/ledger-import/ # QBO CSV import, IIF/XLSX export +crates/ledger-config/ # wanderbooks.toml company settings +crates/ledger-gui/ # read-only live desktop view (egui) docs/ # requirements, architecture, oracle, parity, glossary plan/ # STATUS.md, roadmap.md AGENTS.md # operating manual for agents working here diff --git a/crates/ledger-config/Cargo.toml b/crates/ledger-config/Cargo.toml new file mode 100644 index 0000000..c459de6 --- /dev/null +++ b/crates/ledger-config/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "ledger-config" +version = "0.1.0" +edition.workspace = true +license.workspace = true +repository.workspace = true +description = "Company settings for wanderbooks: the books dir's wanderbooks.toml." + +[dependencies] +ledger-core = { path = "../ledger-core" } +chrono = "0.4" +rust_decimal = "1" +serde = { version = "1", features = ["derive"] } +toml = { version = "1", features = ["preserve_order"] } + +[lints] +workspace = true diff --git a/crates/ledger-mcp/src/company.rs b/crates/ledger-config/src/lib.rs similarity index 88% rename from crates/ledger-mcp/src/company.rs rename to crates/ledger-config/src/lib.rs index edce28f..1817b85 100644 --- a/crates/ledger-mcp/src/company.rs +++ b/crates/ledger-config/src/lib.rs @@ -35,6 +35,9 @@ pub struct Company { /// `[books] close_sweep`: equity accounts (draws, dividends, /// distributions) a close zeroes into `close_into`. pub close_sweep: Vec, + /// Every simple `[company]` setting (name, EIN, formation date, ...), + /// in file order, as written: the full profile for display. + pub profile: Vec<(String, String)>, } /// One member of a multi-member LLC. @@ -61,6 +64,7 @@ impl Default for Company { tax_form: None, close_into: None, close_sweep: Vec::new(), + profile: Vec::new(), } } } @@ -89,6 +93,10 @@ pub struct BooksSettings { pub company: Company, /// `[books] receipt_threshold`, validated as a decimal string. pub receipt_threshold: Option, + /// `[books] cash_accounts`: account codes that hold cash (bank, + /// savings, cash on hand), for cash reports and dashboards. Empty: + /// callers decide (e.g. by account name). + pub cash_accounts: Vec, } #[derive(Deserialize)] @@ -124,6 +132,8 @@ struct BooksSection { close_into: Option, #[serde(default)] close_sweep: Vec, + #[serde(default)] + cash_accounts: Vec, } /// The return a federal tax classification files: "partnership" → 1065, @@ -238,9 +248,27 @@ pub fn parse(text: &str) -> Result { } None => None, }; + let table: toml::Table = toml::from_str(text).map_err(|e| e.to_string())?; + if let Some(toml::Value::Table(c)) = table.get("company") { + company.profile = c + .iter() + .filter_map(|(k, v)| { + let s = match v { + toml::Value::String(s) => s.clone(), + toml::Value::Integer(i) => i.to_string(), + toml::Value::Float(f) => f.to_string(), + toml::Value::Boolean(b) => b.to_string(), + toml::Value::Datetime(d) => d.to_string(), + _ => return None, + }; + Some((k.clone(), s)) + }) + .collect(); + } Ok(BooksSettings { company, receipt_threshold, + cash_accounts: raw.books.cash_accounts, }) } @@ -306,6 +334,23 @@ mod tests { ); } + #[test] + fn keeps_the_whole_profile_in_order() { + let s = parse( + "[company]\nname = \"Acme LLC\"\nein = \"12-3456789\"\nformed = \"2026-10-04\"\n[books]\ncash_accounts = [\"1000\", \"1010\"]\n", + ) + .unwrap(); + assert_eq!( + s.company.profile, + [ + ("name".to_string(), "Acme LLC".to_string()), + ("ein".to_string(), "12-3456789".to_string()), + ("formed".to_string(), "2026-10-04".to_string()), + ] + ); + assert_eq!(s.cash_accounts, ["1000", "1010"]); + } + #[test] fn reads_members_and_basis() { let s = parse( diff --git a/crates/ledger-core/src/analysis.rs b/crates/ledger-core/src/analysis.rs new file mode 100644 index 0000000..ba323b5 --- /dev/null +++ b/crates/ledger-core/src/analysis.rs @@ -0,0 +1,245 @@ +//! Time series over the books, for dashboards and interval-column reports. +//! +//! Statements answer "what was true for this range"; these answer "how did +//! it change": a range split into months, quarters, or years; balances of a +//! set of accounts on a series of dates; profit and loss per interval. They +//! are built from the same posted entries and statements as everything +//! else, so a number on a chart always ties to a number on a statement. + +use crate::reports::profit_and_loss_for_period; +use crate::{AccountId, AccountType, Ledger, LedgerError, Side}; +use chrono::{Datelike, Days, Months, NaiveDate}; +use rust_decimal::Decimal; +use std::collections::HashSet; + +/// How to split a date range into columns. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum Interval { + /// Calendar months. + Month, + /// Calendar quarters. + Quarter, + /// Calendar years. + Year, +} + +impl Interval { + fn months(self) -> u32 { + match self { + Interval::Month => 1, + Interval::Quarter => 3, + Interval::Year => 12, + } + } +} + +/// The first day of the calendar interval containing `d`. +pub fn interval_start(d: NaiveDate, interval: Interval) -> NaiveDate { + let month0 = (d.month0() / interval.months()) * interval.months(); + NaiveDate::from_ymd_opt(d.year(), month0 + 1, 1).expect("valid") +} + +/// `[start, end]` split on calendar interval boundaries, first and last +/// pieces clipped to the range. Empty when `end < start`. +pub fn intervals( + start: NaiveDate, + end: NaiveDate, + interval: Interval, +) -> Vec<(NaiveDate, NaiveDate)> { + let mut out = Vec::new(); + let mut from = interval_start(start, interval); + while from <= end { + let next = from + Months::new(interval.months()); + let to = (next - Days::new(1)).min(end); + out.push((from.max(start), to)); + from = next; + } + out +} + +/// The combined normal-side balance of `accounts` at the end of each date +/// in `dates` (which must be ascending). Assets and expenses count debits +/// as positive; liabilities, equity, and revenue count credits. Mixing +/// types is allowed but rarely meaningful. +pub fn balance_series( + ledger: &Ledger, + accounts: &[AccountId], + dates: &[NaiveDate], +) -> Vec { + let set: HashSet = accounts.iter().copied().collect(); + let mut postings: Vec<(NaiveDate, Decimal)> = Vec::new(); + for entry in ledger.posted_entries() { + for line in entry.lines() { + if !set.contains(&line.account) { + continue; + } + let Some(account) = ledger.chart().get(line.account) else { + continue; + }; + let signed = if line.side == account.account_type.normal_side() { + line.amount.amount + } else { + -line.amount.amount + }; + postings.push((entry.date(), signed)); + } + } + postings.sort_by_key(|(d, _)| *d); + let mut out = Vec::with_capacity(dates.len()); + let mut running = Decimal::ZERO; + let mut i = 0; + for date in dates { + while i < postings.len() && postings[i].0 <= *date { + running += postings[i].1; + i += 1; + } + out.push(running); + } + out +} + +/// Every date `accounts` moved, with the combined balance at the end of +/// that day: the exact shape of a balance-over-time chart. +pub fn balance_history(ledger: &Ledger, accounts: &[AccountId]) -> Vec<(NaiveDate, Decimal)> { + let set: HashSet = accounts.iter().copied().collect(); + let mut dates: Vec = ledger + .posted_entries() + .filter(|e| e.lines().iter().any(|l| set.contains(&l.account))) + .map(|e| e.date()) + .collect(); + dates.sort(); + dates.dedup(); + let balances = balance_series(ledger, accounts, &dates); + dates.into_iter().zip(balances).collect() +} + +/// One interval's profit and loss. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct IntervalPnl { + /// First day. + pub start: NaiveDate, + /// Last day. + pub end: NaiveDate, + /// Total revenue. + pub revenue: Decimal, + /// Total expenses. + pub expenses: Decimal, +} + +impl IntervalPnl { + /// Revenue minus expenses. + pub fn net(&self) -> Decimal { + self.revenue - self.expenses + } +} + +/// Profit and loss per interval across `[start, end]` (closing entries +/// excluded, as on every period statement). +pub fn pnl_by_interval( + ledger: &Ledger, + start: NaiveDate, + end: NaiveDate, + interval: Interval, +) -> Result, LedgerError> { + intervals(start, end, interval) + .into_iter() + .map(|(s, e)| { + let pl = profit_and_loss_for_period(ledger, s, e, None)?; + Ok(IntervalPnl { + start: s, + end: e, + revenue: pl.total_revenue, + expenses: pl.total_expenses, + }) + }) + .collect() +} + +/// Money in and out of `accounts` per interval: (inflows, outflows), each +/// positive. Each entry counts by its net debit (in) or credit (out) to the +/// accounts together: for cash, deposits and payments; a transfer between +/// two of them (checking to savings) is neither; with a credit card in the +/// set, a charge is money out and paying the card moves nothing. +pub fn flows_by_interval( + ledger: &Ledger, + accounts: &[AccountId], + start: NaiveDate, + end: NaiveDate, + interval: Interval, +) -> Vec<(NaiveDate, NaiveDate, Decimal, Decimal)> { + let set: HashSet = accounts.iter().copied().collect(); + let mut out: Vec<(NaiveDate, NaiveDate, Decimal, Decimal)> = intervals(start, end, interval) + .into_iter() + .map(|(s, e)| (s, e, Decimal::ZERO, Decimal::ZERO)) + .collect(); + for entry in ledger.posted_entries() { + let d = entry.date(); + let Some(slot) = out.iter_mut().find(|(s, e, _, _)| *s <= d && d <= *e) else { + continue; + }; + // Debits in, credits out, for every account in the set: cash + // received is a debit to cash, and a charge on a card in the set is + // a credit to the card. + let mut net = Decimal::ZERO; + for line in entry.lines().iter().filter(|l| set.contains(&l.account)) { + match line.side { + Side::Debit => net += line.amount.amount, + Side::Credit => net -= line.amount.amount, + } + } + if net > Decimal::ZERO { + slot.2 += net; + } else { + slot.3 -= net; + } + } + out +} + +/// Accounts of the given types, in chart order. +pub fn accounts_of_type(ledger: &Ledger, types: &[AccountType]) -> Vec { + ledger + .chart() + .all() + .filter(|a| types.contains(&a.account_type)) + .map(|a| a.id) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + fn d(y: i32, m: u32, day: u32) -> NaiveDate { + NaiveDate::from_ymd_opt(y, m, day).unwrap() + } + + #[test] + fn intervals_clip_to_the_range() { + assert_eq!( + intervals(d(2026, 1, 15), d(2026, 3, 10), Interval::Month), + [ + (d(2026, 1, 15), d(2026, 1, 31)), + (d(2026, 2, 1), d(2026, 2, 28)), + (d(2026, 3, 1), d(2026, 3, 10)), + ] + ); + assert_eq!( + intervals(d(2026, 2, 1), d(2026, 12, 31), Interval::Quarter), + [ + (d(2026, 2, 1), d(2026, 3, 31)), + (d(2026, 4, 1), d(2026, 6, 30)), + (d(2026, 7, 1), d(2026, 9, 30)), + (d(2026, 10, 1), d(2026, 12, 31)), + ] + ); + assert_eq!( + intervals(d(2025, 6, 1), d(2026, 2, 1), Interval::Year), + [ + (d(2025, 6, 1), d(2025, 12, 31)), + (d(2026, 1, 1), d(2026, 2, 1)), + ] + ); + assert!(intervals(d(2026, 2, 1), d(2026, 1, 1), Interval::Month).is_empty()); + } +} diff --git a/crates/ledger-core/src/lib.rs b/crates/ledger-core/src/lib.rs index eb7665a..92c2907 100644 --- a/crates/ledger-core/src/lib.rs +++ b/crates/ledger-core/src/lib.rs @@ -17,6 +17,7 @@ //! (`docs/oracle.md`) possible. pub mod account; +pub mod analysis; pub mod arap; pub mod assets; pub mod classes; diff --git a/crates/ledger-core/tests/analysis.rs b/crates/ledger-core/tests/analysis.rs new file mode 100644 index 0000000..ed7efcd --- /dev/null +++ b/crates/ledger-core/tests/analysis.rs @@ -0,0 +1,81 @@ +//! Time series. Numbers computed by hand. +//! +//! Cash 1000 and card 2100. Jan 5: owner puts in 5,000. Jan 20: 300 of +//! software on the card. Feb 3: 1,200 of sales into cash. Feb 10: pay the +//! card 300. Mar 15: 800 rent from cash. + +use chrono::NaiveDate; +use ledger_core::analysis::{ + Interval, balance_history, balance_series, flows_by_interval, pnl_by_interval, +}; +use ledger_core::{AccountType, Currency, Ledger, Money, Side}; +use rust_decimal::Decimal; + +fn d(m: u32, day: u32) -> NaiveDate { + NaiveDate::from_ymd_opt(2026, m, day).unwrap() +} + +fn dec(n: i64) -> Decimal { + Decimal::from(n) +} + +#[test] +fn balances_pnl_and_flows_over_time() { + let mut l = Ledger::new(Currency::USD); + let mut a = |c: &str, t| l.add_account(c, c, t, None, false).unwrap(); + let cash = a("1000", AccountType::Asset); + let card = a("2100", AccountType::Liability); + let equity = a("3000", AccountType::Equity); + let sales = a("4000", AccountType::Revenue); + let software = a("6300", AccountType::Expense); + let rent = a("6600", AccountType::Expense); + for (date, dr, cr, amt) in [ + (d(1, 5), cash, equity, 5000), + (d(1, 20), software, card, 300), + (d(2, 3), cash, sales, 1200), + (d(2, 10), card, cash, 300), + (d(3, 15), rent, cash, 800), + ] { + let e = l.create_entry(date, "x"); + let m = Money::new(dec(amt), Currency::USD); + l.add_line(e, dr, Side::Debit, m).unwrap(); + l.add_line(e, cr, Side::Credit, m).unwrap(); + l.post_entry(e).unwrap(); + } + assert_eq!( + balance_series(&l, &[cash], &[d(1, 1), d(1, 31), d(2, 28), d(3, 31)]), + [dec(0), dec(5000), dec(5900), dec(5100)] + ); + // The card is a liability: owed 300, then paid off. + assert_eq!( + balance_series(&l, &[card], &[d(1, 31), d(2, 28)]), + [dec(300), dec(0)] + ); + assert_eq!( + balance_history(&l, &[cash]), + [ + (d(1, 5), dec(5000)), + (d(2, 3), dec(6200)), + (d(2, 10), dec(5900)), + (d(3, 15), dec(5100)) + ] + ); + let pnl = pnl_by_interval(&l, d(1, 1), d(3, 31), Interval::Month).unwrap(); + let nets: Vec = pnl.iter().map(|p| p.net()).collect(); + assert_eq!(nets, [dec(-300), dec(1200), dec(-800)]); + let flows = flows_by_interval(&l, &[cash], d(1, 1), d(3, 31), Interval::Month); + let io: Vec<(Decimal, Decimal)> = flows.iter().map(|f| (f.2, f.3)).collect(); + assert_eq!( + io, + [ + (dec(5000), dec(0)), + (dec(1200), dec(300)), + (dec(0), dec(800)) + ] + ); + // Cash and card together: a card charge is money out when it's made, + // and paying the card moves nothing out of the pair. + let both = flows_by_interval(&l, &[cash, card], d(1, 1), d(2, 28), Interval::Month); + let io: Vec<(Decimal, Decimal)> = both.iter().map(|f| (f.2, f.3)).collect(); + assert_eq!(io, [(dec(5000), dec(300)), (dec(1200), dec(0))]); +} diff --git a/crates/ledger-gui/Cargo.toml b/crates/ledger-gui/Cargo.toml new file mode 100644 index 0000000..441da96 --- /dev/null +++ b/crates/ledger-gui/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "ledger-gui" +version = "0.1.0" +edition.workspace = true +license.workspace = true +repository.workspace = true +description = "Read-only, live desktop view of wanderbooks books." + +[[bin]] +name = "ledger-gui" +path = "src/main.rs" + +[dependencies] +ledger-core = { path = "../ledger-core" } +ledger-store = { path = "../ledger-store" } +ledger-config = { path = "../ledger-config" } +eframe = { version = "0.36", default-features = false, features = ["default_fonts", "wgpu", "wayland", "x11", "persistence"] } +egui = "0.36" +egui_extras = { version = "0.36", features = ["image", "datepicker", "serde"] } +egui-phosphor = "0.14" +hayro = { version = "0.8", features = ["embed-fonts"] } +image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp"] } +notify = "8" +jiff = "0.2" +chrono = "0.4" +rust_decimal = "1" +serde = { version = "1", features = ["derive"] } +serde_json = "1" + +[dev-dependencies] +chrono = "0.4" +egui_kittest = { version = "0.36", features = ["wgpu", "snapshot", "eframe"] } + +[lints] +workspace = true diff --git a/crates/ledger-gui/assets/fonts/Inter-LICENSE.txt b/crates/ledger-gui/assets/fonts/Inter-LICENSE.txt new file mode 100644 index 0000000..9b2ca37 --- /dev/null +++ b/crates/ledger-gui/assets/fonts/Inter-LICENSE.txt @@ -0,0 +1,92 @@ +Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION AND CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/crates/ledger-gui/assets/fonts/InterTab-Bold.ttf b/crates/ledger-gui/assets/fonts/InterTab-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..844aeb008bf8af024b463f685ad96b25d903148a GIT binary patch literal 418484 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

3C3ZF4pYGZWG7 z|DU!M^CeGc8^$vlgV>P9Q~lis|J0e}PsDi6z=a>~`%1ymlD7K-VH^s@UPG9MGfoB* zT`^7u-mm0=A1S%%m>WTgAhf^{QS<1NX;C1^ZaT#cq1R7+irio&=)L_dG&g23IqntW zZd@~CHOEkJcod|xnruC*dF|8RfBzKGQUm38uI<=y4QEd-+r@{TcyY&@>cgZ^n-Hq_xT?Y%-wfl;qWOw{8`r5JY`711dF(Nb|+a40?xf!D{sh(;)5d=_0Orb z_g&{fK>Hi{P&T2Reo}<=oHh?uG#|b@aBnjhU@#K=ml3>}Bfu(FQJEymC|4&wHo5_jX`6CB}fF%{x&aKMq)*%fvZkgSIDTZeD)BTRqg{+F`CZ;3>Ilx2|Z zq%?o_Us;q$^M|pS!Cz2Yq5cp$bA1r?CyWIr52A^-?O=#`!XbZ9@{;6iiefXJ96j36v&-Abdo4zjow+@(ZdKOA(L^ z@=0o4~;A>?_P`efypK_Nm0_MboG9OpUqX=|it= z?eO|$(FV#tKft+%JWS9bRSkjvrPxE2{4Yfg?+SYeyBaZ}K3=e9!GToULr&**r*X|7 z>{=Kx%95s;vmDm7KP(dphDjV`jW}*4;Lr(?%rBC{TGcmSiE9LUaeQp zVGp65`c-IWb$G!cD_lIbhA9fZZ*kGUA)qu5t}C60B%%i*;KN~1R74ViwJHP&unBG) zov08=^w=Xpv8O%ZaQk;WEh34MYE_H1h9T1+RO9fSt-Wk!mgTH^Re(^oiUuw5^ z{)VG1va^~s&B_R1^_Ux(Ab)sk^$SN@?(93`s0N60pX!c-`6e$bde%;ElX8z>o;Kh;-xxLR$8VRbtG1W_fkT9 zD4<(a8&)u7(Ns~n3dc$4M3^)U{-H>-rtgCV-xC`{_#k5*W2M*-i#b$FCr6NB6n7eE zrr{({3uqz2WC|Gs><-y|RD-`}^Rp=$?2bJ27k)zzSKnFvdcN`L^siPpP)a{^0ixdi{32?+6dJC@|slmT4!)dK@}r9Cva``vMQX*c>`+ z@6?m`JrA-Yo_*S+XIF)~ysJmgw2W-A*1*cD1Hg~bS_48*SZGL4AQCQndl;Dq6Nm~@ z4uno;Rz%n@t0<a{Hx!G@;g4A(wcSg zW`SXMUmM@8d-s<-*Z%#&mIrG+U)t^U&gMFq1zz?d@1m^aZSQ*TW*g=8!TV><*iW=Q z4DBmM`vNFJ4b4E4fC&OH5E$MDVrdgP2)x^oDodak0-{n!+GMDu{6$g&Vq<+pRxFa~ zlEKE}FVTF$H%fsbwA;`3StI`HSNsZ#<5!TT zGQNy9LHtxt>u$piIPrB~GtL;=ox~MZlSpalHd-fivTiaHfw06|^n?ikisjz!%xKIt z3O)mmGB-*BNZb3rJe!y1i(0EmHs5G7CY- zEMUin+oJIK03q^XN`OCzgC9l(zWhuf$}odS5|Euh)5~*$g-W5xzQF`I%luRQ4fI3% z9@b#w+`uj}q@W5)SYr%dPfld4cVjGba|Z&L>;s=RH4EI78+H#i3)FK6Gk3P%Scq6%kqK2CfV~7ZSWT%W zdE}e@kamFn?@0;q3|1(h0<8we(Ivd{BwJK!GDvYMe$_=(lVgn-)OHy>1~d9hJN{wx z)=`B^;>KjZH|l%-TI%J7vt;GXhU@FH_TPWAYjpgw!ckkJl?xlAZ84Es=1y%L_H&Eo z%-_BxDmpf1V;Kut@M}by>GQE}AeF0Gg2o~*vpWJN=-@)Ixq%Y#qFknSNV9KbjM-felt)7psI7tdTbYdxWNRuN$N0Y?Dj-m8 zTX#e7n+HtnO}?LdvcGyy4CGP@J5^;=FaA>_v^blZ z_TYR*K3W8=lg<Jsr=m0)Jk%@pGm z1&v*T)H|)0uLokYy>R?`G7t?<$>{EB93Xjn3-&&zok>f0Y4Jg}8(;yOnY(+gd;99u zLqjF0dP4Pt_!@D@R!Lqgkyada2za6eBBTL7BBp{=U~R+rsRn{sz~N!QFTD!+fPv4n zS^Wio5k#k`DF3e(;t%`dHdCvupU2p|XX5zZcaN|GjPa~Dx(^EG1K9dndydOzR!vyN zM!tGtRcLs4=&GYH^DRoZ5Nkx$3H+~mP1ti|$71fAKtGm=zFKIcVZ#vz93}4p{a~tu zBTgH4=K&0#LpsvT_`f@4;)27Cl@WSPlt3vX1B31Zo+GOOx=KI7FI>F}2NHmgtg!#2 zY~yA2UUJqMK1tpR%AH`pL_ZjEtUPdB2 z+tZ{%BAx0xu8Q-91ML2p}sU`4lJI=$~J3e!*Cv zRbxaB50Fp##{X5#I3w!Tsuc~LPOaox$?-L7RFA6`ZHuh$D8_G%|4_@ES-`#WdW&ZB= zuMS3*3>?9NhqJsoe#NzkcxGYp>B*PRiivQ$Me1=*l zvMRi{f`jmdz)CB`j2^<4M=QY}lkXpe;B)-7psT4mtIZmtIeRx_`tR6^ADP=H4K@s% z%J+`9|1p}sGHLL0^$}J0QYzR?b7+I`(9{rl<4Sp(z30jutM~@ikA7C|*s)_}(X~mF zJ}bm1%hG%i`touI;H6-lo&%U%#GKPkYli!+CK1+gGt2gM));6WU^}fI$dK3{Eur zNBYM2cp@btvufVvbd2fsR`5aaLWf^BgXxIic{BwlHYJ#L68m-a?R7#!2lwbTN@c00 zhur>W84C}dugO5 zI-}X!4d9JNX`qi6&Lj(jWkCTwaOSwkUVJ>fmFvVO$0x@D0K^&*S`{A^3}dCG6rd3s ze=H)R<3z=s{FS(3*gQ5IMmjJmDU|JlVQoR&VmRSrbw9Rj*^=+(7jeR$os2)gsq4&Y zu==Gne~pNVSgFXhMyMC7d57@`OI#4bW#xS}ssyXb{#83y@ha?F`oTZt2mpuRho7m_ zuzqIsl$`p(X~EzmV>&0+>|*0}>NRXYvT=S{s%{fxW0DiANo~?H2u-`1>IFe@;JfT-T01W zzhQd)u-DvA7xWnG!&@Ic%zxhKd6=D5KC#$8`;1$Bw$2cJYOY(YUjiN@5!$c?X#uqp zs>KTZWqb`VX;lLKVNN9Z#s_;Q&bi_dg$U{~3f!3in-femC~M_SmImF6#@5lZ>b$2v zij1!qmN+TS*XCzV_Ot<+WIB@mlju+H?LFrs&2tpAP>nq5BNmfQkj2G;HVSej=W8M%{%-C z&nO*M%Uf9=U;2)cIjEaq=r7aI>6aLZ34Kc zM;8a)4}(7%aMqu;G-y!ZSLa+C@)t+=SKD7?)gKj*uA;K1b;mg2MWkDU|N zzIFgh;wWqP-EG$XsK=qh9<#rGZtz_1(s=JVLuP&Zj2EqmkNx@8F9`ph@S!Gx&L&DT zHTV)sC@Fv9U}A{%Fu?)4=vjM4t9N;F177j@Zbt$G@ z4}iHADpi!{r5U3GVq>cd2xg{;gP>%45;+x)|Qudt+3>zHyVmS43Vn6%~M#C{O1f)?b~=%RGGulHV*w;*Ut zkJ#rv9dVF#{rP8>dua5v=VB+%ykBl$+V4PCnWV_d)+>L}JIkbHsyogyN<_ALMK9R9#1;w@fZ4cm~tzT>mm z_ENUE!|F~OvR8Km{JWk1g&~9Ax+x#~6j_v{45>358JDFk_VENBlLuUVjBe0W6)-oC z6z1t>Ws)bNx52f-KTz^O(I5zkil%~*OeUeBC}`*7E<?!s8Tx#wprJOH!~P| z7}{sHj*ezhuO8iUvfH)poY^_Od7}o=snMxPwW?PO4-J4n2s{YD{+YE%e4%IvgaU#b zpC~T?>10IUq7du#dL|Ux!Vcz&5rV5!a*{86MoB$kF#G8$n25keh&d)Z3ERB($m`EF zsoP{`^E$cDwq&76we76O{?+`?eRB^stGz)NR5`%t!B_Pr=dF3B$AwpF*47)wP8QKd ze`i;z7m?a*Y~y-n*P^h5KC#jP|^^M>)awU8{MMA2`^%S$a=C`th(NC7^Ln z=Jjp-rthXHrLTnSKkf)pS`Zl0q(O0ECa4%Rp=Go5+aUzhkQQs(!Lxc4PEIM%57d-w z3);28aqZYMR??`?gJKK-Te*<#Ww`#42Yo?11OW-LCnPPV;xjPHk!&Cy1S?zqoTe#5 za2qMgd@WIaQKTtj28RIw$Ey?TGewCKVQ;V=kS@@%hXPa84?0yJ*r0Gz0l!?>A~%om zFAz=Ip?7Ahf&3E|W2(MxP?J8fIXdaxppY)dp0hWVPZf3U*VCT4ncq|r%!N6<`r0$q z{P~T$g;%|RApu=n4dLnop|cL5Ow&XpYzQP`P#Qw$hrFi)Awj+MyEs)BiIN8e7V&MT{l4Eu_*$HH_L?yU+sG7#S<**NVwe|afE;ICb}#11$T`>phK}3 zI?@*mP;cWmla`@Pi*Uat`EB|Jrxfv+c>Js|OuX;%m07y4j@vygIsS5;`tcQtH! zzBBD)<=Kezwh4V?xOEmlSX@% z$nuiCP57~2XTMw<{>b;C_$Z;iNek;iRcC5m_AYPi@TF-iEFe1QOIoR=po18DDH>c@ zqSPy`d-XWk-Q)#adh``DFxLZTt!^Iq9GKjh33@)Gr)8wR247=b(*0pW13mpWE~ z6bF7hCORt8S|y@N1hUTsOTqD^7xB^)Yla1b-qzMU!eOrv_Sq;n6AR-TT!_K1nxk~u zrJT>>*p&&t|M|?AE^B%f-`W{FdDL`17Q)O97S^$U{!!pX9zA;X#W`E5c&pu>A3pBr zkfTZ_AEx&2)O{i!$yR^FCdzz?sc(liMVME`)nD>bt0gT@b2ov~L$_m+!IKFTKPWT7 zXpHo9lc{f`ps#W_nji&v;6%U>P<{iWQ7V9Qs3W~rJiQ^$6)))L{nPW1Ss>*mRIf&0 zNW_|$&G?T-2dWq6=m4tKUo%f?17sklQh&vP9gFePhtAJ{Yen?|#E-3FgYkDYAHvtc^=P=Ax&QtL^WeY!{yYBzTMN2o znPev6r>KYejo1OQ7dbfr+NsDIL`EY9T7bn8Bmc-Rxbv47^j?47Y0o=5f-pq(5BBoxr3uZZ`A@~tFU)*7otS9C|{c%=@LZBAcsxZT5dIljubYZ zDY8$$VYB-}690Ve56^D;VRo|@pSdBA`<&hHQ_{Wfm?^_nUKu;;%*@VP-dpme2`;fj zZ>T-U7XtsbrXVv0(`Y7_?a=mQ*$#()n*%HVfAMdJut3v9rXqok^928Pji>n6{_Uz< zvgP4Q8K{LT1`l7dde)*v!xoM&ELz?^``i3c6cdz1Qek0Dz?9y*kkDg<{ z9^O4?NdMgF?+hRLX7RKagG~O%7EeDtipE*$2YO2SUw7ED5uFWQ9+Qe~lZAc6C`AF; z-teT;c3?6gkDj;53op21bNISZ?uryhutKgirvmHMzn?sUO+R{+|3~iu?{nkN%GJ{N zKLCMm{6n5?U#R)G_kw)|84DnXXQs6Zgl!MTHSiB)PN6DiK&VuhUZFq%hu&8VBw5zP zKvu0n(zPQ@Ad*G8JwA-UcZ`AF#;RysGoDAJUGX#b7pttgx~O2}ijvVSCP(sn8Ol8S z_*l1U8+*^cJZbUYexuGz&mFdU-1v2MYt~Y{O8NY{t)_jkeC_SIbp8;o(;>7wnrz0w zaHe>)-3GMVpbT>1fn(q*t$?tqK|;smXnHh@CKMs~)mB^qqUjXtUb*qhpZRIA!s2vj z{PI;}nomLFYfn|H*vH$@`oei1Pg?RH^@9x?)-_KuLoVPM}HMhSwdg;pHBUUUKQ!sUMVd3N{ ze#73J*lXh;Z)5P`Nn;KU9C&cdq{G2R??D@TO?-3M&54D5rcdwFdy@Rz=)AlU!@K9f zF`Q)hyI2QzunrPv9hk_+#I^Y#{$dsD&{?P?$l=66#wx6XI9o)5H6bW~oSDEEx_atd z#=a@ASP?t|c@Dto!I?9UGB=@}H@Vez#5m($b60&K7d(GmKj6Eu;JPg}$0 zH_cnP`ibZ0J5x&^Haw;1>f0l3)oU&#N5a;R1UI`h%>c zzE%qvk%_wo6GnUC~@n=rlTre;|f((Gegbz`1*UUP| zsz9DAz*2TlCl^^Ia2|ra7L!UKhmX^ys1&h%{8?SW390g$7apwAu{ws81BNeIzI+So zU|*)(;yqSf9lr*r(6G~Ua*M_cEm(Y>wRbQ5k`Gl!o}RSm!%=9f^X%~^k7}}36D7iZ zXsN-_8Nk)!>~|bKPG=8?$CVWa5BV!ID-$jr+Ue6zPGqt6FWK`f;N(euLpyrvd$6s% zmpFeM^lvG~o%~9H0pgCl;-Xffe}gd#IRXYm!=S*n4gg$<=Je_1fw*p@!l;Nah}s?U z=A&?rlUDy;(yIt5L+bFU)~xCaFOFUG(}tmo77ZP;WQpH|8=J=7UB$TlJrBBs<7cU+SpI2 za`K~M4xy`(l-}f$;o3vU^Q2||)%a3KJN~b-1%fqY8LaM~%7?_8K8*PjQviN&2EM%q z{nP83`qDLWtEp$jb+b~sZjN%w{i4@3|AMYZp?sgXZsAAQJ#c+VJfCi->!o;plPGW1 zoUZdwep!@fJk*}Qi|6m)d#&w6!^+2(JkdeJ{LDW8M8g98J$yZVpF+bT%yk?jECTUp zPZ;kgKCST*HltCGClC9Zu}Pd zeG4)sbiK(qe9I{r&BKIRdkZ`#zX=Tz%lK0%67&pHfpO}BaXKN!t?kb=PUYjCCB}Uk z%J+)$b`exQ4dc95jB9&wU5}3i`rQp?(48wQdFZYA89wyZ{0#B@z_K6N+sIX}*L`_{ z-WS(u4Jnqc@z$4RClDQn+=A?|{4Kpj&qyz_x7BYX8dx3Z4l3YjIa8V&!cEd`RD2TFY-I`Nqs!pw2{+wA+9Hi>rG*_?%`r5pTKpD zl=nLH(=_&45JD9qpWxfUq+s+xU*VZe>d<@@3h4-}Dg;dd4Y=Y%c{l{5LVCI*bkgDG z0Bfws35;-j*rA~JfUf}*0Cb8APhDc74aB&BSxJ^pEdHpt^Pqr$L7j^~T0E&sWI@lK z1(97Q@jLZj-uLp5{y@@E`wxC)-^=yC?l<(a)B&A?0)n~>NWC_+KQsIOj)P-1R&Zp3aJbY3IZVZp3CtkRU zmZE(F%;93mSyI4QQ72N#nUMs?6rzvlL|`&$f2do9)PWv7r~`{WD(*Q}9@ne*BYx** z|Do5=^x%M?&I3|E8`A%4^zD@q{TTm+^&5$9))(~Riepany63IVIcp>4>;qpD*9>$N#20T`FMSBnRJ#T%& zdvY65-wO{PDPzspkIHxQ7w}GcO*)7{L|<4ld8G24(i`iR?#HQ7tvbsVhy8ElRUMQuj+rXphb-!ullApRlU4`r4#r1lL>YtA5Kg9PYOC{<) z)eqNyit@2+jCxS1kL$n0_22RmwHDD6y(v#??=I--s-y2el>H*D)%w2H*>`8zk7ef` zD?5z$s$%@_eKnollJ`w_&i8uBS$6-ivTbZC`k#yXek%J)TBp6aPOER5v`1a2v!U!~ zXBpe)C|e`l!8m=7vR}%+)ZTNIZ2%JD3S|(=etoQLq4YV%?=O`7_E^~l=_PfAE)HeC zJIfSjee0!n(LYa={eiYD)7rUAYv*JZhcVubvOn>j7&CdFW6Z_^A^D(k9%X-_tVA2n z679VW(l?m9A2IeGx9AK+`~psoTd)PiOARQ3f&6aG0S2TojR^}>RM`q^9a-rr--9em zxPJ6-RJpV!q;Qe405%|1l?t_gYpDrbG98{0u`IdTGY;VnAz4hSTPMCoM0iLQ08PUb zRFMs=EY%q(S|J$`3>GV(eJtQ(N$5>ZQh*dfghz{FXtCj|3F{^|>fHC>r15+5hxEvM z7-oH#+4w8|PLGb~C-dtbjhl|^J#2P|#HOuVH1CicFyf6dbN6-0+SzaLOMMGA_a3;r zc^dyJbynv3I~{mgzow0lbE$<}d|tz@edV|6hIdM?labXVsfac(_?gGf(rCRz;ywyt|bo@ zdLbG7s4VxA+d~qROh(mP=Zy#98xBRF1r9Tcfald5J3b6xEdmy|@6)G!`@VhIRpmjc zp8Myw&C1WuY754f_8jU`DHnXKj`(4Nu0%edwSljcJ=Afc4Un2}(xVZq57jM>xq>G* z0Ny(l8*n55@G@H*4d5%O0qQEMoEqV*U;hDk2xtB49Q9|TUBS3dnDLaM-J!1pM-Fir zwjGR9Ar=t$awx5!G*MOfsYW1@L4%GbrE-*Sb>TEAjw0uJFjN4sptGoAYuUW`oW?DB z4$jIPqw?$W>}#`Ed_Hx;fZUFAF?{XO3-*4{^i?^rH3nq1@0s6Y#hbl)ADA}%rN(uJ z3=QH@mB$tBcPkP7S|`SJojOVM7x(q^D%>xj`&Ik)$p2PaBJUsOlD@Wj^9#dUzxT1^C`3YH_r$em)W;(CVtp)lbrdEPE8o! zu1l}{UdxZ?7ag2B_fV6#Ryoc6dF?)#nSJQTId3-18}()EL2%+CXo02=Aw`%s$k*r( zo^(3pQ$GX-z35yIa>I;%{7Ec#ru1`lyg-i$^nXg<{Vh?cdMD+pG=)e^UwH~YX!x1x zWiUw+1xRlJzNGvz zwCLO~A$34&7LZlke9km}=S`#^b(^`CwPPJNOyr07GuvI}RBCD6+nkk?Set6>B@+N#Z2%nc9d})967HY7AiIw`J zt=X=&YO8Ai4sS(_yHbF*N{_ac?1&Hn`@j1xyTk9?(oMPb*KumA^IKY5HGM1kjS}){ z1?3Rm)WLp^1MAVYQtZ00P>L^~Iir1B&i+!)7N5sgmO$R1xwAoT3J?2#D>nsNZ4S9f zlP_Fy6Yz;B!m*Ovr1ThZaBfE4@Sva(-7@AL95Jg~bpOJ_{?XlL@jIbiw#+FPo#t%m z66%tjf+2u7Whac4QU`sB{r^UGLO`2u;D3>wGy%{lJ9)|dXXZusD=h36oi}s%>vJ-S zCd*TcGUi|*JEW(eK&SLX{VNxrsDD^=(0TDLhEuwCrN&Zg)?8!We507ViXa<(1B6U9 zWRjZ-R*!D#D&KVQdNrXel-%{I`ye=t2sLj`JNOL2=2HZNk_?WH+@g^o&}Qa`+UD^yMIdocJh81p1OUUbvTgUfqS zvEg}euC+F8!lahXo3w7)x?bI+S~cQgVX`KZ4C0C#v&Np#*|Lae+3W*o2e^BAa{1#Q;yPp|V$d?|8~51RaOlkB$q*Hgbu89RFF7~bVe zwgVsq;cWjeGjH>E55LHN-P9qsZLg^}*Oc6t-YT`fy;rSzhfbYhF_#je!(Vtrjp+$MVH&>`fN+ zwe~N*_-p>fO}<#pWl^+8=OaJdTJK}l(K43N!Fph{SIfXUba33k)w5MFJCsV{fWWj-WoIJ zt#RYu9zFVPzZQ+>EL+g_wY~$7WtA)|sn@t^{k6;1W*r&OXMdZ;%jP#pKR)*CDBcf)=>h1|^ap2TwTO9)IrbFcV5yd-3Ie#@}`kKx8uG{&Fs+w6vrvkX#X8e|82 zkM(gL`$~@7UR70ulOeM-sk14$Gr3xP0yhmHG~#EIy^a2^y`AicAF0#_`q*4*NyR?s z&<9q^BVd2IeqI09-)^GLCC~#UK@apV`T(yfCCT1h{^F;f@G7d1*pFBV|Mp!~D#gRj zcU#F;^_GH!P5(T0s8_x9ut@Q_f8SNF+rO{ZP5R4OFJw-%nchXd$=5|6wliNPMp*@E z7jr23lt;{DAxQ*MM<#*PdNXf@NUg)j>9FeR**D!*=H{;KmbWq|XC?DRdPVWCyl$&< zFu&#B4Uq_808F)Gi(vNiTssBe4M^!mr^s%Sc{RBv9ho;{m2>(xut zueAsDZ|T{b?l*VDxSnC3K?(BSzZ`2tZ$Bx&=N#)&=Ai^A>(L|qYZ#IwsSY=TK zWV`YzK$e_UVCM))5=cyDc>_1HKT!=&Ij~ddbnBhd-^j1pf0n()S~$TH6rECx#+pg7 zj6H;hd3dv4l$v^Fc3ZD+fb7&Q*>9Y&eZ7rOL*ZO)|1yHtkV>J&uzrv*VmHzDef2tcQtUKY%8s>Zr^NjZt%KaXzJCC*)bmtuy z`)HFQ@>J{I7x&+1p9r zo%i)2uKPBfxR3e(VCXD&Yx7t+o}+SlP7e!erFK2Fe{Xy+nOUew)W7ofP$Dmb?&@Rh zq5C%NK9!655dW{h5mNO3->xkzlKm}NY%^uBJkY+L>c%$|;peOSkEr`U4Cf5)kB2?* zp~EJ5=~0^``bfG~g{4CjuaXw%Jasg;H_f<9#|}Kkz%6MyRhHvW5?RXCK&S`bG4#N9 zV9OMJ{8HW{+VQ2Xn`j5=SzmFL!`4aV+Iz4Q){w<}SZR3sF&pSE>3vzzxyi7B;+tP+ zPbsG~8|W8Uj=~0dN?Vuo&HwRvjFIf`u$f|v#P@ywi_LVG90&!;2+$X5ZFOy5$kog1 zS3=OIFKFm>`v_gqf)1W$U{5ts=LtEH(UnJy0#NTS1o|H$%N;4L% zQwN0-=!o*t2=x;h3}50PV;BSb#qRPEY$d=*#<4{!*j09wSL4<26#2HTP^$bts0Z<5 zsHZJJp2x8!Y$YF2u^P+|`lE8x6AP>p+9$W!Ct@w2e)Yb%e@EQEL-*0H9kBbo0K1<7 z=f6Rw^FIad+WySELwRU#D<5Q6{sijWSNvN~cpKlqD|qJvymQv^4$vKvYB0P)uc>EC zb@J=>Hp)YGg*Sqn80-a45G!v$@5#s_S6@8<8zNy8fF~x*A`G}esBx3CKuq8N5Clp#l)tpwoDGgD+`L?u_ef5z1mC@JJlE1ne zc2bLUOGAr7XbrrjN8fHbS9L4cRJn0cw&hpxo zf3Frj_mAI0j3iY_VL!%smA;Ce^Szu%Ick3c_U`?#cavQ%L|WB$Ulp1X>@JWP^pkv4 zl|ravq24E>6x>+JnI7t|Bs>=;DR=;j1zu&27b-oK7WJeDpq?PF5%Dpd+7UB`jO}Fk z)1;LO_CF&90zgcQ(U+f9$dBeaw^R%Zd(gUHzt$Oj`)1JZR#5hz|K*nv%z3NyGuAgV zy>H+2%)aQalNL`iqSzJi(Y6gjYXa& z*=R6!azbe!zy~`=r_AtV$bscRlk+Q(PVtSjHW)8q?QwkuxE}_+ zo1y%37*qA}ufa>yz4FH}$zc>hR3*7ea_vL_LBvufT#6uyj`WR=^rB(X;FknqoGm#( zXdH#BZ=mwjl8t+pv>BV3*dnri6LyE~U)FL$hgx-`>ZP$eRL~}|xmNJ%@|F`jCZKnvC8+GmR@-f2GWCQD@`4>4mPvOf#x`-uq43Ycr z(5*ZG8}%=*OrO%BMuXUt=IoCCwI!L;+a}bFsnb$sYd-w6UPg?qQ|^bKHfkOh-M$Bi z#13hf`hu=Hc$FVecV(ZG4^Vbil>PWv*%A1a9MDyTPV%1gsLx4x+5N}LPQ&M9x0;Lk zNP$z?=j1eePIl{TD5C?dvV3_+x&hkyHOhWL*>X*WTn?5BeRu;tC;OE_DEsxX_g;d} z$r<%8l>PQt*&FaV*{>sc_IGEQ%je_>d`=GNJW=)s$}0PuY=qCrC7iVIIYC)vpOba) zIk}>oN7-K}tKf5jb#jG;s=XC2@MEnsb5t0@_CGxyS3$)CTBE!rd(p-{Kh42zqAM~VN$x1plsH?0vMRbVm$C4r5 zMk(nm`FEE5-AT`rN`gGoKAj!p2oMo{lb0wY8=J|4#Sz*Lev7zCFZ#HPbJtW4X2~op zxyUMSi-}1ML|$j8q@j$qu+J^`3V{GsR(Q{H()V6LSy{n7UwH|u`uxtRQ+Gels`6XU z@18n!=kr|HU=P8sX%GCG%%ll>LcM5PWp)#-bygl@(NX0(R2~zEq$x2Lxsfmbax4KC zj$>Be?|qqd96!m@#_}(HzhQmOoO^E5xwFW?vFY7&o1Qy&hHs?4t5PBBuKoc328$F0 zyqpHoAh8PbYY`4mmIsUtD!lFG85mwVRS@_g8Qt{8LD1i+IyYc0icOJ+U$Ru_jzdN2 z7#;2J$D{`J>Lf+ij;;;REd-Z_hWH`RhRH~&-^mO`^THwtK9bV3P)wK&%H2zPS5lvOeR5j!cRTI#HdUqsBAz5G~aAtvN2W&0OjVv4TV1Ji;d+1DP zHH!s1$BkB;(yXy_p{-GA|*`bsjHqI6k9T|b-p+25TUVwU& zJTM++PZ|){XhbPyQUU_6S({%QK`;m&)IW;+OalV~!HmN3L>{zh?tBbZn<+ef;P`np zYRAA^J^&_QU>&0T5#NO$=lqj+p6oAAWJB*9 zJ$lFPO>01YZ_ek`{^9)wju@^@KRS~$9Bs@;8~;EXeGx$(F7-+49d3|~Ztkk=Vf17= zcX0GNHOtH731~RjdFDZ#1tXQ4Q9_;u4|knME@+wtxaQ%Z>rL=D9VmfDSg56{#f2(} zk7I^>eGxpT2gVtYs8f~Xz|>^L5@j<)*`f@@fNA}RNw%>)H>ZDc==hq^qu0D~wq*MB zhc$23*_t-Cs@VdQc0Q# zN2j|%52!VQb_fxB%HW1fkfX8t+}w@Rh%z{OVFUnWo`7}GHX>#sI|O@5JP)s(fAxZ6 zO927Wfxqt=?iKE&F=9(qq%k@bA!$iCd!r)#{gRU?w_|zdujFU02lkN5ot#}M z+S0rCmZG8;diQ>zsA>1^P1Ex76n}<`K2*>L1@E&wx|`M%kutJWPhP6DhnyG&1fNM7 zR510CwdskokdVLO?H$+ z2Svqj6pa8VV|a}Sz|#3!ygWqy15aVlcDh0%l?lS$(JNs{2c?I*5?G^@6zFJ#FEA^b zxvSvWys>?kx61Ll8u?*K{@&qVxrNV)${89ku6laM_VUtcQ+p0gHn;~@QwP_rW*s)U z;nY6%_s2HM+}f>KH!okku})%QE#ik|sX6+;8~rD(S%vt;i4|})(C)`<@LH2egQYd| zk+@Ix$NW=+2cMch_njd_-kDq2r>Ll?Pak>du(xN!-3 zEVLs-zRi*h4X~@drEJab%^%L>AfM36m3!HfDWQt%eg%O+QyxQU`XtwTkV&P2nW)3n zp^2^1Yt?GiO1`ZGmEKl{woFV&Z<$!D1+@k0SKJ2oi<5isK{(SP9M?JP1YAbak%sr} z__y$)qjNNfv~8lir@#Yu{F_#VKi&do#MD8WaHTlZyoaJJ(d4;G^qqW6HHZd({9Ew6 zEcVI=#^5ns#w@+US~P6fPJM&dP=aPR%~~_p{(#+RkqM=(@T5^&f)08KKUpy9aHE<* zqe_b1iXqg<%@=DGezG`0%)~~E3ACD(jt6qKT`w-azKz+{+xE0cpUj_kc``*()A#3t zshc9cPo6jc69vB23@mP;Sw!H2z?m_}S~UbDA;So?0{{s}v5CL1(rq`2i*Ibp0lfU= z%k$=cGD$v(cgWZAvYG%pOI@iIMQOtoRaP4!ZjS^}odU0O719`S);Km9IBP_qFv%6n z*HZ<6cVa@6wQ3bV3$pRlWpybS1#T#|R3|rV1ELsdSv8j`(n=YevP7Ux1F+GOzUq|# z#KhH&1@A!HEFe&B^2XOy?cUvU+vRp?%KsiZeZf$W6#JW8~Fg^-U-;Nk&s|}?X z@X)OZVGt1qQnN%1OAxTMlq|S|N~EKcbc5i>j={^rFI9M4sxo|YGSVA0s9T4i+x&bz z+@%;6VtZF?V&Pi``r=#^z+=Rrhi5Q!HZf*8WR3x0!c%yk3gz&* zr(4AYd4!nL&(E2DVak*X)91dM9uw#lYHs%4{OK2`PQBQIjq1>3a8gLDmq(Jh#)z~I zqjXi+$PUd%R1c`(5uQ+MNLq)HY6CVTEjq-zs!y|F6VFeca(?3ArjemO;XaLrPCP$l z^7%=;X}e)52|@9`-gV7!4TiUEJG@af|0J)PHR9_I73*jVVqcFzrVj-TN5)k`=qED@ z!o;OG3=c3mHT^HN`>>X2dS0OR2<^R62x_8q3=d<7P6?|KULyd2r+QTiWua~~SV@7R z^BO%SaJvBELrO8Bz;lQthh`d!6hK?;zD{#LoRys(c)4dz)|gqrv<9;;sevHw3J`HRC?pFw-(+!=Y!2 zt>eGwx(MC|*>^z(q4$Pe3mRJNJ3=?@~9|-Pm;=5^-;>d|m$NnV;>uTiTz&drbNdFVkh9PUxD1t$<1M z@M*@h8fdpGjB0SW+oJ|BrQ)wHga60=CI64^(%$v798=1~TVl<+9?^Yt{ryblz9N{4L`+c`NY#jGjM4KyA80CO7| z*EQNFvCjMp@6_%R9~{ssYUWuUWiZ}xe@6Y`{56yN*NU#>p>pOjJ~{{V>n8f;MtUbu zZ;H{zV8MGyhBguHlC>TZy;NlCp_}9e1s;tdvuNtH6xp(jb-u^bOW(XB|H|vCyB;LS z>U}(`NJV8I>LS%;I6g9X(=2G#U{58|so*@rDIn+Jm&^*O z6&*vX#@VVyhep?o)4`c4Q1by5V!Y=5NeUy{rAVj+Zbu7XH-J?6>-V+a);K-y`H#jA zIND}g_Vy+jdCy-QH|Tg9Hlp)_PIY=O6n|(n-1(IJTQ|`3N>= z958>#^@~{hP-vgPT&w)n_B)Sk*J-oWctzlUbU2u2uYaow8EO?Y( ztIV#|8@yos*n-^DS_#ce7lU^$%wOOAQ$xe<^*RSql3EY3g)bv zJILSk&27EUko;D2x^$eqqeVtWi?oakWqk95Axa~DCb46~Wm85kYyNWkRvFpZ87*O= z!v5@{j8a0eCIV@H`un*UFykSxZ-%ZemKo+QTO@wx`<9HI(7_R$z zcK)@~r(aw4s_#d^{hDQEH5=@I(Ql73>fowX2PO_p7}B<5$L!%Xhffvb+6CiUzkFOx zSc&E*jVtX{G)Eg(5jIPU&M~gqHI3^NAFDL3r2B?5Yx%f38EFKPQ1lKs{?rQN%Eo5R z>DYC4tNbB8`rF@_{0FNT)3g??T47w5jh?csVaG()p!A&~3C&;b&@v;tL#tL~%a<{( z|A)6Pfsd+4{(s%?&5`>)I6{ue!F`1!kOUYA1d>2F1VVst$Sukdf+B|m5D^gM5)_X` z2%f95hzp{)Dk>g$v5VsE%IX3Nh$oQDoBy}E-%MsQ4|RXLpTD~h(p|5*y1Kf%y1Kfm zT5Suy#$W|T25C$)!B_H5*EqtadngtBHH4liiO}7U^nh~y!g_7<<*|_nOYk=p%Nu)p z|EsS)zVkIbLLJ_BQqr;H-3a#=6|r!UTK&iacm3t@`??h7<+K|*mTjz}ac-wB;l5D;9n_V7Apd$O{!0>o3lRSnDYBQUZC1tF+FQ)A^$eaaM3lqtjvI zsnNIG!TAJa~2r3#yOCuV6>Tq)&9tKS(F+4FfJ<=MC7YulWgn<=t zt#Y9C(6L1ruIHT|vAL>wOkTU1&i(p#>eRo#<+5w;=y7R}Ko$Mahdw!G#Tc_tWvCM& zL9tsy%`i5HXi$K0qbY^e6_JVQadI>2)&%*xe_f>$7D-YiVaT%(b!2JGqkTTh7B}y7 z*l}jj-N<#Zvf9H4V(&LLBox0@H@ZVnU z95{Z$fSL*VP*#)Gp+lB_2bSk;8;2|m)#mp;&MLZk4@HJsL>CUH-P_}FK#2?fMG^;@-Lh5g90OS3oj9XYaZ z?~x;W`}XVCw+OOc{nw2f|4M%z8C6<3e0XW;DDaZ>4ZcMkCHj~`ndlG+Pl?9ClOvH6 zV&!0xgZ=Wv3CSKR0)`D%5r)e*KWt_?mSZ75zHtyql|>e_#x*N`-q*pAGbaeGVNk`a zIO|G7bpQ#|mUJ2})rO)@`eSUfkM2Ng^%k{5?>xlQ7mOk{2;4hmr^m zrf6m|mRW3OdZaBFcL^|51T3n|hdQ;#X=~i|Bjq++H7hFUYyB=`55}4>s&ikt4-f6K zL~rl21xq>MCD5UwkdGw<^2-(4_-NCkTa;)p&cjJM#X*c|CG}k_hKLY&sE|_<_ufXI7lhWejqng{}(l<|@*|9BxC*h2f zVvA|HaT?`_YNy_SxT~w76JF~K#^o6ggUgb~P@arq6oqiA1*b~IOkj8nO=}zG;81dP zOQ!y=@_^B1;SYgTCn_crDUdM!SSet5gK~f%NaEe672=sg`ooHUFI}3N5Rz_fmsOU2 z?dpmO>*@`=^|R5D%&zVXjTn0!OW!TV_$IZFB?TI$Och70V(`$TAVl1dBU>uzDv(X~B5yz_MfTf)KWx7=#z>r+@!*bxgC6ki_V@ z7xfDyC;CU7C->+vr4!3?tpx72>Jr2by9}E+>;TOptWdwnDFodp8w`t_XSJo+(20pr zR+>P#bMkn`kWb{oQ zt-r26H@{WiG>0>JzT`LTnKW2!Gqj`Ks-OLNUUalQv_-w}f` zqHF<;^?dN>N3}Tvbeh(EO+b#bVw|ja(a1}1JbWxf`U!M=QS&q z2}A~>J;*P{VZa_lHydycX?W%1k6$_R@kg)J)$LKMKY!!RFTQ-^jn5CCJ$LRbx&*DE zksgZqH|BsR=8LpWex#1;q2HY_mQ9a4HyW+Z!T8Ym(Wdk`;0eF@M-?BkrKyJE<3J8f z-s4R0hwqX8!*9Oj)g?5>%C*3s3H%|-;Ab$&g-%DeP%*HOLlV@<1T_ieMel z3~&e50g9q3WCM{h)o7a2NdVd%6k!phe30;~ro%!j2_!EgOrYqpjIaOziwh6=$k9ev(galoaR*y;*1*R28TyK#`*&3u4Yqu7Yr@vS@QX-e|r42jOA;F zF&ysp;Ei=*dgpGPIxM~Oj(MFX-&oq+en9YaB4mCB`qf^!?U@YZZ}RBL9m&1PV%2Iv z71>y8aciTZ-xTlIHVJ1pbd>gNI^T)YfBS$B438G?hd$sU4S18-=j~bhAURbsecX8D zIY8=c=&ErRu*s{VS_XSQpdHmJtA{<@+Hn>}>=pwfB0!Fl4r4Unr=%3f!1V~kvBY)eNn zT2-@RXsG*hVFc8`8MrcF0pd8tGDh!uq#Bdq2g?u)$rKoYSA1~-j#7efA8?wt#NKN~ zBf}v9h&yW*ix)H3pIdk%0+$$zjKynZUtRy?baufyys%H%@WFFG(8uzF`WIDOMqd9k z7<1#`^wwQFw$ER;#CoW1pISJ(B4e=(`-_1D}$4P&=T|Rgm_fO{BoVOe2RK%72&c0p_cI z1J>#A0~1L#0x)7&$llU41aUS!aS)mmIyQw3`&fULDaRHs{z!J}hoCRNM8D9VT0`zq zlts=EpP2WO&6(br*Ch14G4miAa^}H^>z$&Qu?YU?`G97e0VX8KFGzk0OEIjOnR$M0 zb6FH5-)0=rpu_$!>yZiUYj#cdexoY;WtGGq>&$2B<;`tzHx5~`^F6h?sHP;VU9WCA zJyVkM*?~i^wJY3sFOtc6sFZ%{#kP2-DtBc2t(!0%4>?tqR zl>Ns8Y3ypAFZ|$;tRtxMFZg24(7fNsEyk=XdZS3dC z&)xjh!Rhx;u%8X?-?4JEz1dwAOLrW9tZ&7rqMlXQUe)T-XLi1Edf>tV$<3Bb?peBV z_L^N!IJNpwi?4r>K?q0c$Rdc!+CA zo}xHjB*!I-sM2I^lsCAvEt9h9S@--8u*a(&zrLW`#ZUCJ$>kZ#ADg&mM&FU6`Zy~p z)Oq zXwSHU06b=vG97yW8B3&hJMGq~q*5c<8m%{MD_gI3=0|jxJb113uZLW>pkFlpi!uHb zA1_y#^H)S_Y}{Z{0wU;_;t)*|Ygk|@6FBZcG-g5i8f-okY~K$6mcsUkz{nJYyvc2! zD}(C6j|pMQeTF^HG|0XmBYn@`?7MmUXD%5zaPoxR)27xY2jSp0tIxn{L@Air$2qm2aBAloX7zrcd)qcSIc?f@XI0th z8C|+$q-T3%V>af)tHykgA@)7zwn#wKJy_y)(Fb) zGao!VtUT@;vjYcKm``y)kQWH-AJfECDDF^MVG~o~^}SP`TlCe_y~iP@@u3-g zM~&*+yJD2}NP(CR`sb{7MC`4Lt5y$u3bVEkri7FBm390a53&9VzY&udaY$H3a*oE} z`UQt|9Pb>N>pBd{dAGErg|qv+f6+b~bM)DMx9g{F?zi@_nhU^J!q2fcfGxve#q&58xzCPyW`h`U2cHq4L zyni$foUk{Me{6Q#b~bwPVt!5wu5#!FWj&Yde)3GjHElwNZGUBvNMY>TC zSjS(ktH;9|rfgL|R6AL_LNCWV3gEGD+Iev-!4N}H;vzyD_m9v<#=smXcg9A^R$jPp z_`(JC!xMiwf&bHdVai?FPPLO|3|5lgjGIHJ2JEJ}+!(Kxi$)pL_Ub*KEF7i$MA%$FtAk{Zg_1GXH^< zt2S$vqSOzi_u~9u{ZQ|F@p<}D1mm%z9`CeG>PP4=sY&AdHlBLK`fmJw1itSfzHjTP z_rpIze_3rSzDHmO6a4Mq?_A9Lp#AoqdVl<`f2f7x`wpIZKm7CbV`?AKKAfE-e!uTg zkB4%jfxnZd-uHWVgX@%04~IGv`Uroqz~9AFZ-Srr*Y#@k+N*2`>am!b)2H?k{lis> zNj>pT_CLo{?@PZj&vi=0Gaum3HLV|k`W~V_&$J%><0Wh)zK7epN&92azE#lQ!?eDg zei-`ehxk6V(?e{mWp9uP9i2CBI*54rT4=}Bt0{nN1`hlK$zy3AWmw4*^=&wcl z56%n|hA@tP_BUQ(T+eb~cH>W6{8SWyo{-Bs`}7WiQ@mGyr7AFscF_Tw;q zLp=3<{TmPbP9B4L_%fKZzfSMTL-+vH5A)Rf^}j^#$=(q4!%geAqyB=Zzs9tFD(Vl5 z`Vpq}Tisb|C$<9Zk2I~n%l*CDNx^$jD=vLZ_;ZhYg4&K1puWOW-`IbJ>2tAn_J)s; zsvtfNcA!y6iD^XYLzya~!==K7N=L}2cN-MSekb;+e(qoS&nm@siBZ}iFoJQ)A#0vA zHX@;JfJG691K)5jFxf>q(xPJ7{d@NB-&42$={>cz%Y!~XcI?y7-a7X2BgomJ>pG|? zLR(ivTVzknc6Rm{6tCK9Q$wMDtH>Z?7z)w$19b-u)a^O&*N0X_yxgkjZ%G}O2YveH zTc3UY=9`~BgzzW@`o{DHY)-0PkMTo$kP`MOt~PDLZts&jkR13B*Od(S!X`)|1IS4i zHbM63TR{gOR$-9iTkkkPJ}Y=&hrixXdxC%1<)u*&rG6H_#+)xmI3jYs_}Kegi8H%| z4qTG-D4*WB^TT7iH5>t2V8ATrPl8v?l}bN*pRlfyy|1aEj-n|1h8+*p{${);Nei2p z@hVt)w+?+ebm;!_!z=ErOTBJ(KI^rC#daOo8b-YK^H;5zo>_V8v|hnNmn*}#egInA zDu}`;jd*|97za)>rHLi3Eo-iK&Vc-gBs5J;Ur06-VE4kf=j9-Ks*l}k5G!(Dd+kfMkf-MUiFa^) zxO?v0-OQ;U3k6C~dl58WrO}JXSOo>!n-GgMY?x&$#9MDaYgAqi!lcD{lx#=NApNy`z# z>_X>h&HNPd-V%9mmpFrCASsy)k1Ao3r{@Ro?<3<;=^Ybj?4J!KZgnX6lt;6=~w%e#4ov+99K%O46q7SbcFcu-KY zg#)Iq+`Bn%K>xgM15~XzD7E6j~7bHKL5h& zFg}s!HSYI=gewxAqkZj4(x61sAsW}OptfanOOR_*B3Wc(f(jUvRKt$$HGkn;%WfRJ ze)RNb4!_r_%MEM)yu6#!*$oz>;KIcdmp;H^_18j|-Ms4Fd;8~g@7FJ{JCrDrXv5&AQHbI^kiyJpdPtBNuG0%Mw_v{7=DBB#?Z z76IYaOhD*nySC(*+ND$5oOU@Gj#h1w+ra(<*Hq8)Mdq`n_8;-w;p+CEO%u0OT-&F6 z*^t{ujaV~maBk0Oqqk4U?b9#2TfaVe?F$P!bj&XZ>UCY8fi+>lVKaO6o|<1crC0A6 zVZos_C4H{zwW**}=fc9yoeJ2LymoDKbK14Vc|eTcPmtLXA+t9<1K$Tcf-T!ifun`_ zmSaaTOrd@T9l8LZNN*&rjaJ@3!;c5fPh8`W4^^y&UUBu_6?pAFdAY*)K!zVY`!EbY z%WEGFdn=@SdjCQ8=8O8zSo!Gs+{HKa8~4EY+yPu2&?9$1|IoW;ra4y5=~=R6-m=Fy zYc;Cw){U=DVSg#l&K@=>FOLE&V4mWyI&}biK9VS-pS1n>ntdQD$Y6&n6lAT7iDn97 zRwuJ{F}B4BLEVA()9v6TZi47_;i!byXKL37lE$>@GS2o5OU4%Oz-&CHSdK0sy99dWHxlhX;vyhA2wE#0MS2%Y)(_JxYi5?lXFUez_`T zL}5&6LE)f^QA?i^xHq^}c9&9*{z1b>Y-~afaBB7P;oT z!pRj8Q(_$((k8EBwll69Yhvnk*Uzv=_2cXL&z4Vc9$Aaew@G^xr=&{2f%+oUUlH}| zJoV~9pZcME8~fC99N*vJsYgb;#_xNh{te6DQNP}_egNObpA`5vnAVq}{SQR_omZ{@ zOtinzw0;oqe=q7cdFr_@eU0^-J@tO{&)|3Plj8d=ruD?XPX&EjJ@tP0`{DaK@%>$< z^*ulz@`i#x+dTDt?Gyel1pe)wdO!a6<7?6W7x?~ePkod2x1s&dP=AkUeYG0S_gjXc zeut;tul?)QPx+HtE$Z(zt-nbf&i7husK3us@7MnId>}hyrStmzo_at09Z1IUV0;5HkNfcmzZZ_^GV*Bjd{(cux;wdKR&Mkf04p0VIIt4 z*R!oE;(S`MDDwF{Y2JFAQ!S7KB}>i|DBWxLR7^36 zr*Xaj&iZmA9N+~U;5Q)hTOd4iSlhdZ1Dj>cU%;!-rvQJac3HyvjmJ>;uhuK3`0v!x zP4Eu@{-XlFoS%drmQ{iOq6s|FztR-{CKWR%pugDRZ7l?TIlrmD4FdlrL}?9#AL{zaAK?DQ_PQzkTaa-e5PuoqH=EM4MWZW$rsFjT@J9tba(yBGbP@D#5wF>V zecxw2B>rPP!g$H`lKKld06({yj_(Zc|6u_y*B`>)(tv-rDBxUHh{Mexm;|Q~I}SX7u*}J#wDN^^o`zC;Gcxebog2Q1?$);pg3^ z^n?FFxqxF>iO{If2&A{Jfo9Y+%{PL=>Sk5o% z(y4#n>}+j{_(#{S&BxqTSw7~jF=Mt>mRD}8R5N^j$3Gi>CL5>v@|e8x+^X?8<#}To zK56_nM#@HG6FkKjn;e`b2Ph+z$;wZ1e7eT4;7D8|25U26>j-0VghE0@PFKsg!Lgyy zDveQ;ErN$zd`BtwcfO2bHd}@Fdwgw-u`}QFLrTJ;P`fa(j2nEFk1=8e6{AW97UbvV zW{6Q6KW^0IipfLE2aYTm+1HsrpkP35kK7*J^E$RqN4Q|$5sWh(!PI~eG#^vEguUvR z{>BLNyJ&860;wmxAD^X0VP8F-&zzp5DA-#GG+6LX0OB6$eA)+-MK5bL@U z_s0vAl`LM$ME67%8i())q1KrcnmHy)rC8ypdBwsC`-M>Y$`d&ppAQhZRX z7Q>@$zLHV+yWhtnRa1oz7JCrRIMx zN2z`i7n*e4#xe-ftc_SVF5l}TNdJY1S$h?A=~&!1V3F~cHUHnt7oa~Nd5!W2eX*1K zJ6jd@namI;)+pMwVfV%E(nG6gScKh0Wd|D;k#-2!5$<|>7UH00TH7c;3fMFOTcCZ@ zaI4JN;QkS?f8qG(R{TSJ^Na00lW%ggtxdk+-fxQC-`f5TUxrNh9-I^Hj1ld$(f$gW zkQss>bf2SkJj9`$V)WyAlW%(b#y5{@-ysjQ13{3<0i7$4Y2T^G@H^QhGDMuB=2(i+ zv~a9cCcrI>f~@25hz6^+i0$ZzNoDxMKl$)cmh9Sld=?AUzGHd%8w}Ux#Ipy{Mqkm! zx8nB`_+7I)xHb3+{f_1Sl6ukFLa_#K#0M( zqX%>hYnDj&WXVa1j%JRSsL+J41bM~~u|9kp+%X}%=MCR~vz@(0kM7m0qJk}@f8ZJe z|EQ?wg}kGDpFkLShjJ1y<_Da4hu zTF;5!tF+T`p5X~)+g{g&Z79eu|3kv ziAR^U=WIb3CyHKFBu1(`JY5iO0mcP92!h3dGVQ3G*acrvj$}d?3QBNC(d z-u3zNiQk&a!k6kZi8nnfDtMXk52OmgIDZ5#jTj-hC4Pe5@AUC}Iy}s+!8-)~ee_|x zr4o_hcVfR|l|GRdZR5h=XB|Lx+X6QILBR7U2vj{UG`i+P&5DVPV!jq8% zL7{zs^9y35R;bm@8ccC0R5*Kni|< z79>N%D+Fd1)?Z8mMt_57^vKX3j~7fnQT&wau;t7PFMu7u z;gQQ&#S?W5hAs^cMDX+gVgx@tO}UmMPJ*TkX9!=1%QRdbSX2e?w8$7M2!&b#E3wTX zZav~DEw&HN-Yu#FfLvJ6+xf<6#lU1x5>JI}=DE30r z)qi!>g{I2Om z({_&^zk3?}(7$~6VRn4-@S@=pCk`*V=2|fi=exfPYK3?~nbrjG-=>tPuq9%?&IkYO zh)?G!U!y)D%E4F52Fr17Wzx2S^Rnf2+Yg*#1>pPO%Vg2S_v78)S&mu0;hC%th7}oD z*qbnI2GKUihl|nX%5KCeI;553e%+xsojp@qA>uIJIAD#!gD$9ecrcEkvEVAtg0%x0 zI+ikWn8rVpVJ%xA@w%g>!x7usVM7eej5vB#<_RlIN1)Uw5t@nN)g1!!WM*nThQBmp z?vbq{#@_ql)OG(}+i*62(~$8m>R%1o)RTA2yYsaf*}X^K`&P~Tw|0!aj%3Q z=BwAUqFm(POUZ#x6{g6W?gQ3c81h*1HHfrffyIp%2v$mC8G~C7&2|FBV>Hb4)HY-< zMwsdZiWP9v7?%Xpa`~*KycP4*X zx8Udt(ZM;(^G?flgAQ3H{*T%{vFD6z*ShiYT%UITu{*Hc{joKc$%q1!J4C zliuRRp3z%|elm5Jt2IBlNADMP=6nKseh@#&KisVsT|n>~;^ThsaWZ0;BL^`8pkket zYz$+#Ap-+xzrx6S@*CqCR~>?Ir?DEwS}+t%*b?wpg3*p!9aH~8`B2T-@Q6#c<^Fg1 zkkdMl$@aj%|4VyNYs}lTR$qFke5h^o<&A;uA^*bx>q(EC#D-%5MF(S|kp>ey#FYYQ z@<~#Ynk6`wg&;b45M#L0BbWtV^hBM+!{_6p&gw-E@ec>pvF9(a!@FH=Jb1xJW8A_hhAcvp zBSETUBhu#JMieQl{n<%@f=L~@Ew4YUj)kYk2ZMI&r-zjP z+btR+-t7nP{wHnOnmy#YywNs#X!)gwtkrJnmtR}T757h;$;c}fOFkVov>h3OIlu=Y zjDHD~Hin!6P1X{yBUXt`jnWWiDvx64%Y}s57z73DUDOqg>j#D$8PQ>agHM0VwZl=8 z5*jx~)6U0+B$uYSc09(XJ0^Chc&$W#2DrepFF`|zpaE~S!=WMu<9Rk{K*(uY$&}l` zU53|_^kAIa42DE?ic}E?ECT^cNKS3YP~#O?OUe1z(Bx8w>)yxswDbubM!q~m|Es2s zVPz$+Rdkr>aNUFQw9@2|SSZA38~a9ycAe}$`p!6Rxn=)LMgLbd9aP``Bi5Q{ia>y{ zoMQisvXs=jSm}_LM|PNyPQ9J#C`}HH)wKEs$pJp?G1onk1FVc_z-a?xKs2EL=sQ!w ziSyKdIAFq+2L$=0LO1#^!joV%&qHn=@3Ma7d|YTsi9H5~h9kHSEv_-qc;up#X2c^eL%?>D+_DG9)vE7);$0`0ck%FS zFmqgE`JTFia-r9z$tirW4zplv-9fpe)bEgs|G`9F$Ljz~n@)5v7LGdDG_K3aCt+l1OeyQ5>%h2*G z)^bdGeYe>6+_cCH8B$&je4qt9q;=+hOiS?iJ+4bzJ+#>7y7%ytKerDm99sU%i>9<- zAI9OZ1~G4Am3U`NY$Q&G$UOwJ&}V=PbLma@ztGNc|8^kY$|$3qAdWx*aw1doADUiy z)*4q^SNpot`O9)dJ2@+IPxEJ?H+l6Jbwfk7Pdnf(`jaTyNu-x3(cxi8B8!!Z{E~#i zjumYpy<>x79~T#w7>6+9Q5v~qQ1l7eEHZ8xv@odQ{4%sK&x{zm=RocX?7FV^E#>NR zKFsx$M?B?Z%iTS&$BKsilo1zwc3rl{*pe~Ftxv}&BDbBlk8%OEW%+Q|)4Dnv6Yn5+ z8WJs7iz$mqTlZ`aa2uJ=y4Ci0w$62#rna2KVroNk^h|9z;lq;p~E$9g{#%C+bH57caRNN#F+53kN;tadn<7|x)O3X0U^ zr_?qM&cvE6TWZFSzw7jEx1GMLVW*t4Lc#SYnp=JXO+LL9bSS(e##Tw{6X?gK4V?)ph+xc9MEvZQnwckP^;rwa(36`DPfPhstWmMD z?12WgYhaJ%xeYtFo>{f(%+?7L=5N_DU!9nViz_qM=v6gt}m}I^d+b5VJbqq`J_i zbx?xhpeqqAVP}wle%c=ZiF+!tPVJ-F4C+HIH@kGX&v~|A9d?d7Z1l7J8sWV zbsbShxA3pXx>sb~71T`@b-1YvsH;OA;f(gj3Hdv!Otjvuoy6(X`m{yG+>Q~c`i>rD zBl!8(8%p_tqxwF6_GrTpdikfm`B(q|nPG!}$MGZxW zJNuq!Q>n&*{99{Bz{WYFF>gp`7G@NVtqlQv5df!JJ*+-&?Rfb(;hy6zw!VqGZOY$` z)u1aW8rC;2@3D?Or0!DXIYZ0l&iUL68+?K;Jicq<~_Qrxgay_Il*{_h0+7A4)83bTw~dQY;gQIub} zdZR`(@{fIc0*lBpHAzM`I;QOP~Fv2PZ|{tR4$6)yUx!uTS(c&1^x=;f6%&EbNI zif6?V8AQc_Ha;JI^zMyWqF7PNGjrGR~dVi9e0vO024G`D z=m-Q|7FG=L?i=wzXw8CWt`Z(-JhEP;dH5jHmO@rV3R@a)N{(+vBU94+ zvKE1=7oiJm##~XA1Sk0iDBy)m5{8{5ilh%2J)>T<92YNfxDUKdY3s~_3_wgs8}y!n z@PHJ@APh6c3TTmR#XypQ*v~*zpP;%M7@<3(x`hmRXb6E-zL8h3#0wP@KcHj60t+QG z95)y7F`+HOTiDC>8W7USPWeX4nQ zc=Lu~_}eH_PM-;H-dGG$KyD)~afnQSm)KwlIaW`Hy_BBTBbA$=O1!W~5HSx`NzD`D zqoYFO!s8@m6bw9&GWaOQtEr?I5P?moYhdBws$0_NOCoZboNgYjM!ZfPxEhTfotz@z zgGO9hXvh!?Lp9N;DMJ$DnbNXFd~#wk)cR0!8d<7`bur@ZGL@Vkyc}d6+FBFOK&+QW zjwI58xoyImzwt)%a1x{I-HG-{>mhK|`ZO-Xy0!~a?U4=L8d|F-`RRtv>U%1dQxMh& zM_Gy^lrU#70+|NEn$9%(2qEY*g1GvoK1?6Ro>Je}N9)7clk5@sQ$40v=oRcyep-}1 zwn!hv9%D~lvFfAQBkajVvXs^--*)WJ5PGarK{hW75 zW#ILBS}QE@jwBweq$a~bz=D93;SAb@7}Fj=g#fhQ`V2}1>Fnsdvwd|mY18;IlFUq*DmclweQrigSytNt2(du3Nc3%GdiXNMYE>|#6d z&Dd>~mD_-z@(J;2ALm%tM=ZZaf2{@>YWM?$LVr#CHH>1ByH4!Fe+`G(A-x#hQ$Bq5 zNP~yhE1b((CADad?K8OSHxLt{hLG~nY8NnPN+_i9hve>a{)+&f=3~^ME zTv-dVg(BS-4S_u<$XeBa_!jDXU2{xEUa|J^WyeN z$sPMX(_g=$Unx3R+`eT}`$YcTm~-EbuFNkOJ#pgb!u-n7-<_|-t?R&cH!Wz}i}iQ8 ziqxXE3u=U&*oQ{z(_vEA3na+AdDDjI&d2CC?$Kag!#q3W{=v2j`cM$X)PS~A8f2$D z6p|6qF%&PKA*TSs<)^Y3t)uJXk6kBu-FwIRF4xB=kxjXV-^MoZ+gywEYS$w0wGm$o zS?nTUtt^d+4#iUuj`Sad7Q1N$DY<+Cgihf@qT{1u=s?)m3`j4(@hD}W|T=?+Mk4B3t7yj8Kn z1T7K*VCPAVdQg2;eNAuG(4E(+uQlYmYI!Z7(5FT`VM;e=7pz2TDK2A??~3$V?96!Y zS3%KqVS&|1^?*48$p>Tuw#EjsNR`QE-gbh1WIz9?M>jUN-?fY{XK+5yln3=?2JOM{ ziHuW*Im;tdZY?DfBqpvE&06qK$GCM1va3OuvYIBQtTq8xrgm+J4Qgwg$jwI<7F#g# zR@;dv=m|8eQK=05#*Zlcz&Qid<)rczda{QP>g%pFL7^T4N_9j(XUm8)`f}GT?7SYW z=CE3JPLHYo6~3fE{Gs~`>lw_c0_4XTri=rLvy_{iH-c4BEJ9NwW=1B2t6B`@2}3;h zXd7pgHXG^Xr^koJslnJjD#btG6=sh`;8|tZHNyuE=vl~=S=Y^+F?I5Us?no{kGp1E z`Je&A1`g}%EG+I>oR{0RbKBNg8Oce_5-Dp87NG)GkVvzaR(N4oKm>B*pTg}j+v{&h zW)b9elW&*ku?TK>9dY4YTvMjVEfdG?h}QK#L+JDm%x)+f?lsJ9bCa z=FRfw`1{5k8MkBncq$yfX_Ndpe#f{YY}~!$dyd>(Fk*!I2>vSAG_v8{&1^(ZDoEHw zC50pPMMsXLim$6)Vf6E!apUe8zj34d30$vK5$bWMLLng?QMeJF93vS1Q8;2_;RyBm zjfK}-BmFz@({<(*l4IDH_`8;eEnkZBusAzngTu*|&939K`J6gEhrhd<&vtFz&E61l z|0Wv?c$rTl)9DZicP%DIMXS{sWDQCnW!=C?8>JVkYnyh0jrCw=FP=Y7w75@O9_E*Q zXc1ejMXhsfc5SL-Z}H2!U7Pvr-FhBqQI%2=zwa!uPM5nKWTnn#|2dT zeH|ZA?e}$JK(*i3%>t@@zHUNQaO)y6o5;&O#QTEpr3LAnEJk`0i!vO8 z5Q5g)dO$S`4l+tD#u8cyr%#Xw%J>9l1o;IGTRZwf_6e~4a&I{ahQlVtpd=t)}sDD@;d{~>x3r$2`NKf>H7Zt%oS$VkV#?#>yV z{c_q!EfXs_G&94m+J>CiXi-9(Yu=7g=V zz}0;ot{O&HyArxzlQ=M`pi3@4c$FMCuFm|;Ij%?e=s9=$X1jsj1A_zIozN)~nciV8 zz(aRfqhOk7azTlwgR~D*(2S@k8?I^*%u4uTWZ;Bxh)?GW*(a_Yt~ES^A9M}W{&}%J z=>q<~NNc!%JJ3b2l42#N%vxk&M`kUol@pNHnXU|m!0leKhuG1a(V88tWgD&0VdfC~ zjNink=^3uu*}eSW1?|+u`eeEn;mT=j=!ejsmRN85Is2qAO>v|q!2*#+&zq4C3&B>o zS__R4rv~Uju=67h0r~#0NjPD!VTzL63SYN`?+hXJ7*xU2xzpejx?+*QkcWN%O+rPQvj<0XO{p*IcJm)p`&Lesk@S^5z{RaX# zR#S6~h3{DR^_ttiS$D_RYxL&;q<49Qy$fD3*#}!5&Y_4O4;>95{eUy2 zJ|1MpSdhjxh)2a=o$f64M?HdF+{)CKX9rS!%LlirQ`s4YOcU0d-_n2G)|BMcpRcp~ z(OKkl!npviC}5Kv1bwR%)REPvmc|*OXXR~*^soZ!;bMh=l+BTQB^+an%q!9!97bku@L2!h?V1~oFm)@vzFYah($(MG0Ty0B2YwLz+{Wz37TVY} zJwZ=ki|y+^U%l>|+t+-(PLPjApQHmQWJAM`II^KiB@@x&q35$Oh&|ooUCk~hQZ#9b zhIC~K?Su+ShB;<|B9g^2$lPvGH@jN$e_3W<`9*6{|Fy1JiXPN2>6dmgO>fwVv^4ey z^?FLyB}{m_;;v(=?y7@t$R6Fr)IDy{i1`>4eia&R>hIAQgjDkAp60O~G6tJ9OZ5^6 zSv_Q#&A)LquV1dUU@l#)|C%jmq;IF*z_gwECChQjCw7LpxzbSOL!es$$;2b_fwWx% zI>~oCM#*>P8M&0{2mu$G-{hpJg)@kIxX4ypk6lU9uGCxA+rYkG4f5b(DabP{pbb?` zm?v$bw<#yA*CN*??inbGyEr{DNTIL41*L`KL$K7qT7yIl$kU`CXF77=VbY{V-Nw)J z^H(x0A0Rua;!<3A7II&cULt+Lb z8q$Kt)~WnCntJLUy_zqspS@emv-RxD?;DC}?t9v>(+#t11Jt1nPB)X}07>Uiki!vW z5T{V!7j82GKTbj(?B~3w`Fn(!a32Hx<)B~Sh9Q;`B?)&(y7iQiKKxu0K)k?Br$0Jv zS*q&ioK+uY7kAS=h^sT3uO~>F729AdS^PjVtk@{S-XYg3;JxiCGz)Gci>V}8+kCEJ zEbl1Tv7x?N{ga1g#a8aYP4ogc_yOumi63wy0(KvF3WH|iHc%7I4V7oLP3$62&uf^Z zZD7?P8oY3ywoVefNO307eYJ^45^%}e=~URBF>=~XdLqJ$G`y{)vw4Z^2Q}>520I8i zq_}O5Ywttig312_VgZi;h!`jolEGJL*jZHY0W~ysh6kt3MrYgTC@k1;e4-JIOBHsy zHbO#HG~Cj#>07tp$eri)JJt6ZI^*Mj_QThtZohs|hg{(0OMCg{y%W5O1p&9{cbn;yF<&885TGHE&?di!lb3?hWd z&S5!Mk-H0)bBZgEomJIfPQXXF!Uq?{f6<}VWb*h(r5qq44+x@eAwVbnd61oDr}Yj0 z#DC|%#D7{#_JbaN=#x7>(Z6IV_<>~+w78FJ^KlN0SCD0m2v`O47X}XPp<%jY05x=< zB78n4fI3{LfC8i+G5!ky2^P2p8ttO*1}$-^e4QT8s;TkwLPR>j!*^}1W%tyj6KsiKPQMnxR}WW_Fh-09PL6#(1_lR#tNNJA%|J0G+Av1W-( z$#5igYSu}TXN7Y+OEV`gt803CbTnec@^pBZBk346-{@#WI{!VgPrt^dv9_NsT==Q} zfxhFl*Ytbz4?em1=1*8#HvRXzbW8wFd+jwgowcLS^b`6$K(d37$o@KAyMm9|JHnr- znNNSs?zkeu>5ePBS!6TZ(uCm+AN3cmd${AGL}*Aak6W&ss9Z-X@|woO+-4Iu-NB@MJuZsP${*yLP0L@^ z=9-nWU^UCMJc2`a4Q!V+!wP6tp3Y8~mbd3COw0T5MW*F9@k^%Vw;)u%S-Z6y#{?5P z*K-_HOv>-&r%cNq;jpfnz`t(JPxcmhKbgQE=Xj%JQht)}HZA|2|J$tG(vyE?THZ@V z{ER^SmfmWJX?Y(m-;gztTT5TQ*A%|UoS&Bd{1;RBVzsAf`2ha2Y5Bmb;3?t%FoiEw zVbe9~Z<+Z#vJB!+nZgfNo12!GU!{DDmSYOPT^(y${sjLuupDn$o>uoNE8#`N+1`~N zpC-St0L*v%fU-@($N(Wt`wN(JxDNY0nD6;XWjo>Fd$)_Wpv@a?VUOzsd-w?FFl?~m zP7`)7gvk%0)FgP&6vVAT(-GbPTT&%{aAgvAMMq z{U0`=7@?^^1I4SG|7t@TfGeQZS9ojJ$^UX|g3YeedEUwO{(0B?CcOXA!&hd`*K9i1 zgE25jh(JwO^KkiJ?BFWyg8wU~J@mSI-|PP^zq&lE4Sv{E-hbjBN*VO<%7mXkdtg+9 zpG{%#F1|VYJ`g|3TU@2QC2ti7k0<_i_L1=a!~FC51~!?0wlKE)cVW6Rw=zi1(Lq<4 z$F^*4#eI{Q>%%-S9=#%y^a`OzY!q}hE$_p>GA%FR{`!dr&j>E}fu?vS82doe@->K7 zOzUXV^7Z_7)AH?nwrTl;e2r=Ot5`=&@I$}AVKuN_7Qyc`EpMjgnwF=tW2WWpITTA1 z{CyA~&#e3=F6F8TAJ{E?hADilu|GG3U(aEgG->x<{;_HKBZmIi6wmAC{Dgin(G<^d zLmz31=Oo`@3jaO-+^ih>h1_qO;IZ^F_S>fAy$wCLX?Y+1wJH9-e7|XV5&y=tyuYER zG{s-6b~A+^z`rvsA9xi!CEQegET!t5rg+NC=OgqByc!4`cgtWk%Cx-vD&M&#+^Tq z@8Iu`{2l-O3_6u>pOa|s2hqNJ|Nr1LOCDclCt7$v()MlM7dP$7O=S~(_^D|hOkjTY z!1(OReljBVWO-I;THb=0m$#&dUV&|4Pkt|8zxBh3eLIZp_+6N;P*5(TNr;PH*CFc3ZogjZ2aVi}P*J;Q>>?eN;ey|4^a z=}4o8{HjkV8FuRaEwhK0PpyJOUg)IhZ0yQqr8sa1I0I z_^T9ENU%TB%@gZJ=pS4OO&%i?Wa!)ZP~uKYHIoL*_$mFYFb}cnpjm@HsOX@ z_kS$#R{{Sw#2ddDxCTSUT|EZw+kTkUss*iQmL*n|7?>sPKDd3j4$?_z#xWzlZXlD{ zp$9hmFjlSdGBmMlW^1y!diX^#{v6JflyJJ28RUq<^AlViqXGObT4taq7qlbJUfpUv_gt%~$+)_QsH@5@M zUv3RS2fi+P5n^p@F=B0G1#e~jSPi~9#r}>+D$x{MgVm6A*pIr#XzS#?NMOh|c)Fv=KctEFwG3XR{s86)MVGI!` z#ORBN6C$I+psm#~&Nm1=eGHfx0uQ<=`b&6L>qT0Fz~h0LC8EoCSV1rplVq#FgEd{W z^{v2z#i0=o`ZZI)VEq&@c>y$|Ez3;NmIr25*c_mN_( zJZ;jTdB%$RIa{=iZ;0=1UDD^n_ogtX*vP;>P}_n&i3c!(KD60LAKDr#+QRxS`dJo$ zhxqk?fWaOnVE!Ed19~j;1@pv@1kLO@A3UerR|4p{RWD)(1w9haDfh2U=^>eG z)FA|a_L;#n>JtJczbTBn0pnF*tAcJpI!6}f0ALWP=$v~T=!&MzON^U$g3CE!Jx_gL zxGf^Qd{aOlK%ezI^`Q}_Y1=fnESm)$=rw}AZ_MyC>OK-C0MB^v;uy(0!~7$8XT1!0 zKMz>*wMoPX5^c*l`;~IHXxn$45iqpQ5MH!>McE-?e8#gWo>RyME!Hcac`fK`j7J0> z6J7r648i=vx(jXfH+W$JLvfAl2fg&@EG~c^nxp>|{kqA(BiAd>`YhHf@I79@)EY2z z1864s^6Hj??`r~R7BE6~fJY(O0Sw8G@&WJ(zDwEhES8X+k?ynFY5RWkLC)(Rl*dKe zzH?T<2>Lv8f1!l&;ps@otyjkt^eqXH3jyQ7Bj^K+fF*q9vRww=goDV1+-lT z-h>L-_QC|Tz1sb)Wu(CKh`{reB6;lFPXR;g1(Ps8Db=zqANe94j}&cr@yNEg&w5I2 z`QZ7*3{Ml7OIL*v90hDeev!Q?zAoDcX{F029!!Y{h>)%@WTk_Id!#bFm(LDcXXaQpoeI z0eI$OE`2HRcwm+V;Az~Cah4T$0{3H_1k~H8E#<82mwQ$~zXXifBPGmF?i(bGkIXm4 zb4qzBfaX%YNWG0{HrfJA0L}f-uMBH4WUOB73tM4%k+ioGu)g}4gmoCOnZcWHG=&uB zqkdS!GOShu)@uLiJ)pIyv@UIj24H#Ayh#xRFA&zP$au_H==iFe>+be+AM9WQr7J>!;PD?)dmlKV> zB#nfd_(Zq`pCnG-{>4J}TG+5Ra?-Hyt+JNwBi##o#y(;c_%uu});5TCHyb<{LipW# zF-Mk=+|nHgzWqwy8X&jWP5od_xz7g3B#pxo!6%956dNV_?$M!$h9ziWub^R{==&)$ zt$>F8&@UxVsGMjJwjB2}RBoFB+GP1pI`$mG108Xn7f+@gc&OLzi~b`cU{ySj{k#!2 z_}-U^>-YlgzN3#f=sD^~&l7mPw?uqHfSF+8ixFN?Mh;N@&fu@ zi}6_sf4WTmrQq?~Y$d!F#rSY>0R}va(Wj>b|0K*Qx72}r_~-sfFXDNma}XXS3q1ym z&{s!bJk0m>T6Fhq(H9-xfJ=Ot;0wmf`nEO)xKK`X^T2fv-)f8LTWRZpOpfw=+h_w5 zeGVLJnm5~NPN?xjE6!o}%XZjc(>bwSv_r6%6TjdGctUexJFO`Kht+=Nl25r89<+Pr zGqovfZNMYwl5P3U6{72X%P8Q455v`9M7#aG?dmnM-CBJ-)+6EvG$pZ)Y?b`L_$G<+ z5wcv_CCZm#o%Y%UsV(>S0kR=rEN6g|zRi*_h;DYyM)?%Hqc8B4gRaiD*?^rc+PTPT zeaf9ixz+x|AXI~Y0$$K1;ZHH?w^0rrcx{q`2Q35W5-{FxK^FszfCUa;$}o@6FaD-2 z679p537D_+qb!(Upoat->rZSGm{Uj5oMYNVG*kB+F zP0LU5ULKs*Ck0MJkKzI6WTh?Efkgu6KSh7PLi2>vzZ~Pm+8H=UX@3#$-$?j#5qIMi5QLe&z=&^as)_2o|!4IV;yK=oPeX8Rb`keaeY1qMUG! zm+((u_=TSdtFC-XaxAU$L7>`=)moE!F;C2b4bP3P{YTcKOy$G8x z@R;pI*c%$}KBz6FO;etVz34iz7tto3C1HMhFLLk48gQRjC#3BQ`+UGUv7`yiDffkd zb%N;g-jN9U1~sJ*y5j{yX7__WjE!54fhZSqT9*F=^CyiN=`V|f9HAUIzjC`JPQP^m zIDNkT#q%w-~_*z}ai9y_EqO!7pzUg&+kb|Rel?3JWHYMmtvdp$sZ1Rm`e!B{-@rse@KpxLm8 zbvN1yJYP22o8}lW(r%^toOdfg^Ljy#v^9T)%LkJ)v877D^f2%kHdr4#wV)?Wz`!Sy znE83&DOu$7AcupG5DXQylQD7VeyoRV14Pr$>Vp=hl8>1&ll^%D&T|6 z(()BOUM9U>nUh2N6eksanfd%~C622DWFZM|7ye!Axa$SNxMespKWVxYd zk)AMx$}Q2doT}w|q74z{R#|@5TW!=X^|xvK1PxjS&ml?4X4_2I1uQXWo)~vOD5(t2M2tI0t zd(l=(nh`k*5xvz~L=r;mEbSJ8nS@rx4MwaE%LIC?j#S*q;9hcCa$0H%zH8-(Zfgg_ z7=?(Sm&GE+gDtfeH-bdaLt?}L!h@*WI*jUBH14`VCG$1?OTO}>l^Z`@x^Q~MF#R7O z?ajnxn@44~n_f~rZv5DdFH}w3f6KDRdv=?3eWIRg&`Uh$4t7PYl5&B4Ugo}Y7;?cC zgWn=9Ri@K{C-Mjc27f=5#9}JOnd9vm1xbyHN{fn4v4*s4#~dk9pbp_GvPoi6*_90a zGdA#{C2jSC81*AaF4j+fEnzd>e&$Qr1kWDwju*y>#!JY<2awr%ju8akK9CZjzNAD! zcK3b&66w65z9eY{Jgu?^fX8Zo`!Ib!2W`pU-;uvly_P|8aahQg`*47KiEji9zM&S) zU_i?Ot)3*yeOS`vKKvVW?PE_cun~LtJ*#w(vRdIQZC)OmY@{zTVzy^t6wctPgmw`kktR;)a zRZFz%ZOX}_U1nkWkM!pwO2q>HHfN|nyt+4>dEZZ;T=16&YZirV~2`)OZ3N1<3G$;G~qEL(ev<>+s*?JQLP3C*MZDcU#cI-3*kg+pnj zqOBC~S1|?}EgiLJ=vM4|cutDP)SlO*K|!#{ga+YxIX<&RN889@Dj^T?dK?V-4)Js5 zog0`%|Kc0G7`3xFt8MpgoBj=JZmakT=Nx5XtloLxPHhWq?N3rtXS~-oiLPh#-WXQ3(dNI3Y$;E?O1FZ;boZtY) zr@3{m`l!e&I}TRa#m#jva*>!}_aCrx}ejFNlK5`6%@_#|}{vJq%Ls zcO7Pn4d%4^)1O?QOSaHllVi6TV|OKx7RcGP)>UeT{c+U8$uf{u3|tU1>=TxEUwC2J8T>~wr0mwtsMBoyj6HIG z+1?b)@>J}GVq-*@YlMHJy;4)AVZN!8NP!(sGyZpA;7C{Lbo`&UQ)00o+ccw>>v_53 zoyqQ&+wPXN+1Znpt!34+PvEW5C#-w0gW>n_uDg8wa)To9=ElDq_koJdTfQ3bK7P3< z$9VvFP~PZABj87Q${T%CsGPP53E${DA>bbp$4!r?-Av-DEHo2+vI5A)Ui@7rWiP6nbT`+%00T?E4+u#**YT!_tmNfJm)GK`<)usX9r34Xbn# zMFHo!ob0$*$NH3swe_F7?wUJ4_G0}xLC0F?;Kzkd{?19F3%{%130)t*V=sNj@V{QG zj#VjMd1g>7(A$DyIqdcXZW8i|4Ntk( zt#d!s&``T(O)dN)UHb9rckj64gN2vanySjBXdXO3`@s~0FH?c6D>nAM<)|pfNLl_W z%Ll`r6LJ$&6ry)A=>5X-mY^4LTfimC(1!TfI9x-VMh&)7j5Z=2$wML{A`&9v)1sm> zQ*0qE+NGv?LnhJ#4;CeZ9cF7^xc>2!d+l2HQ@^?8T6Xd#mKKyJBqV;2c_IuMzP=UVv{2fE!S!l#H+H{thIE|v1t~>I1(|W z7|!WXGAAKe2{I6rGX=4OGg6aVwM4+ zjg2`ay5{DkhI77ckM7?5*zP6wF8lhPyDzTi`X_w-wG(ezbN$-2%eUS!`?`%9%jTQv zW9PlPY~6ElA&C#)QuD&x*{>|Cm^N$FnAxWmj2k;|>WJm9;k1jsPQw_qz!+Gy2y9|p z*g$uqkBPWJ>E$edlR5?UsKppqz;zk}Z4yimM!%5nMD`0YoSQ`>C^jNETa-kWXqUa> zIXSW)w$$8Q3W7l)FtnId5jBfnJfxrevlbNce%<0nQ}j1upJI^@zsd>@Jf^>Kx2voA z@&oIii`~wey>jS-f8TulmVeg%Re$8-clu+`^5Q!m*$Ilu^Z}O6pgn~&#~4^hV#6RJ zxN7DwBym!&=`47Q&>TTC%rlHxCLy))XAj*0eF;1kbdt|vPzp%01#eMK3vB=kkD+xUzX1A@Bl^ zHy!+?shBF{TZ@aeQA!uCS#r`9Sg5kB=Pt3sq2W6BmkH{+8}KCkQi#Lb`TFCA_Bb8lw(yku;`3N%Y=jr%+6RI#SK ziUJ!8=Dj`TcD#F0r0*-rHP8w8by#b9%W|AIkS&zG?z$vxhOSFwP?0!;B}{vX)7p&s zsLa&ITfYSl;*@k{b=h7DBp4OTEWA|`V&33Y1*{+HpcbM`^((8Cz%3z)e3BKzEbV!0 z5(KmgOQC$%l0qvogqDCX?84;d2U3ZrFAAcDHUkB5nVDj>rt_8!0n^0z=R_)$hbDv3 zGJ$m#J9qo30vhscX!~5B_tmgv_gIH4i-47obx->m&dGQ-{mgAT1u*URj z*pNHE;89li=|Wb{=8x{V+*LH=@4vQ5QE$$0eEXS{ZLA+Y{*fWo%2D^{l7H^cg+Ypw zPoDKg@Hhgi3Zi92K)P|rQ^*#DAl^_B$Z`tRd?I=YOJHPVWMX83BQrJHN)ITqVlX2S zcMl1GGzTmp_(jZB7V-JdJd6cDg-vv=TY1X$3hT;(m#$yGRNc0iz2y3N!3UeS|3B)! zJ1(kgZFjF-W++mIp-P<@V6dTdyQ4;Ih}cjpAc_SW77!H+8nMNi7+W+^jIqZOOA@2$ z(UcPtW1=RWB&L|A=~bD8w1R&z4qR#yzA}dlNnlT=SChkzjVSZ zyoYk?UsJ!wo<&NN^-b^!AOx3%WJEo}9bWjOQiGi3+M^JG$w?3v+Fc3Eu|Rp@j&N+2 z7`GcCf+KWa&2yL-(NSN441=-A25AP^Ken^6xhH2<9U+*JL%`Pr0Vr2D%RBbyi#30W=WAU7 zNB+<{x@OjZQou!+e30IY=0;y-_g5D*1pu0)LZM>9ab`^L%E3Y+r4u0Vx%)z%!$*=D zhT;wWVKxyH7DUhj5=v>LG)xBW_LMf1&a{zzob+IyqbzvK`+Nq!#@}J7tRV|YSx`El zDp5OU4U2q~e|$0ZBUJeLW&r=qSbAgASXOem<&Ccns8`bOu?;-dB<(00Gq!CdIaq**&wJou0_lNs9*hn zpPO5{u!4Wcnsi>9^U&8z_;Bszk}+8~;Q^gujT`^=DgoPLabADLxEi7Q0w`mw5pqSO zFG?56S;%z;ActwJqiKfC8WM<1rH$l9#F8*Q=e0de z)DsgVh|*`f*e}6-WuU$<&}E2=Z`5y)w?vjc)S<)apNI7AleeaJXUI-oyC$!1-@G5s zbZWD7Wk~7r71KgWmo8JDYd5Y_SKpu5n=edQpV<0P>86WQr(D=rcDPOA`Uxk`u%CRp zbsXQerlM?GdHM9xnOOG$pg)}iK0>y*hNSZX`vUYx>w7dTSf^I zRCY#v4=GX>c!ee<^2Z85&&Sk1EIG5Q z`fhP7Eg0W>;ps__+}O0`1pg`p6^Nm$z_^A3uOGp=HAogm6a)ptU*adX7l@T$yU|I{ zJrAvtg)s~Msl)hw{xshud$7*3r&@4x8>MFi{XBub-E^t! z{`=40xzaxJSUHtbe;~&~wI%XP# zTv_S_+xZt5R{*SLdKD!JNdk%K(j}yEAk9RZs0NHqcv*HJqB7)ejFSQpmIIlcKi^QN9CDLFAU!OoX4d%N7+b{z)*-kmw} z!JGaQmQ6f9x#YPLqx{OvklsCe_UhHMC(MD2cp7aqV8kvxq@PDqOf;%VA`Lw#6$)-4 zmo2!A+uFc0x-n`r^ry&&Cqp*T8AhBGFp-4@<({P9F?j9sz;h0lD>#WfOKW{N3Q0y+voSyWM*&l+#faPLdJ&6dV=X2Z0Yh5fpfvh1y2fBIz)d-k$Sg<5{glWXdEFjc(M<2@e92&x;sE812 zsMX&WMHCEDFbmctA{4l^L7E1I73NrxOBh9|TzU8bE58k$n-k>CFR;d5LA~bY&ptbQ z=DYtcn_V%zbk1CJyP?gVQS)DDn(wHrm0o_Mxm^h}d7E zsg$TXLo_o&kvM`G@#h{%Su?8WiGjJ*qerbwe>AL3gsp9lR;t!=*ufR64i0ax$hrB+ zk!{$e<5l&+QSrRxkjDNo zG5+wS0PK%|A9ph5WFZ-k^Z<~$E71;=IM+Rk0w@G9e`1mgWeC|QClnOm?}-y40WTSe z^}e; z-AWISUi0@R_UWd79v<`3!t9datGjY**OkMu?o0U+bsNSQDYcMB9z_WjAWQwA#zNDg zAP0RVtP0?D=i&&8VG6(@9IJEsmOHy)I!r36>#gGWc_uVUXzaF_l2mOM7*U@KkUb>` zw?)Yzii;ya6Kx&Q1~sPU0(&ZCRJ)C@%=&KEuJ0=*JU7iZEU{v$ZFl_0!ShBGcJz%f z^&j1gFS!=jwZ$yvwLNgBb7j>}TLPD!UmPIYCzr%2a^Rpx@}7GraLSfAgOaP$<{aSf zE|_-+FnDK&157eFX^<}Po*IalCPS~R-a05!q3alhA}v^GbSQKN{=VMekSSrN>v*_O z2+C;(0J%U0r-_*b%o&5^$PJ&hUz@hFOW6uvCk!F#l|4Vqs`{&&&+u`%dSpaAGd zvmb>Vr~=-KaXOm^ zEO~a)q-RTRj^5$%{~nbny13-;Y8A)9RW&EkhtA7eu3HQ;EYL48bwEFprTW{+Jco+$I z_#3s=1`%^9!=P{=6(yjTf)JFgJh1GE9PAgCzdZI5WNEqmExgZ)&S}F1r1=O zz^fo6E(N&QMuB1rmF$4Vwtz&T(==mHI$KtUfif&qDM)8gGsr6pELxmpt5U^}E!{Bb zg|do)1>LhMHP*1?!_BMCmA-kgxOg*p;j~rr_w%n~o*G}YuwQt1W}}Ssj(LN2O&qXc z)Z*&Kfi2sPdin<%cO`gy3wY@S@}&q3ftuJQFw`Rf5FLh-Cknd54|n=2Q#O&bsq+xm}f&sQ&L-l}_tHO6#IJCNwXPd3VCD)NQ`a8|m1ML$ zN2sV<;pZXh3DniD@FKT7k&E00Jr=22Y$j#bCw#)kN_YCL9dtg=9^<3r%$oJi=h)+X zgxnRlK*X{MzV~4P|DZu?^8c;O*q-Dm9Syo&1Kkqi3l;qa+oA>!&KaxlZ{^u%=k5P` z>fXKl1388DTb?^KdwJe~Ze@py*8H_`=t=%X5-QKbD;g`|9#^c?$jZe`6*ol5JU-!E<2xmBAlOk&|m`ynlIhO%bK?V@7_tSn8sKu$#$ zQZfg$Y|){pPvN@UNxKHNeju_9;Ka55urrX@X!IU0jd#B1(q+FVC=2!o^G?P&ji4%U zU>w9Tr37R^EkqiilO;n5=`yjWki+pC6;SL}bAr&unp`{?VG_IBav}f;IdIM$Ixywy zeT&YP%PdsMA3S6*Sm(jWX2mbG;Ge(v(8j+X9&>78uZe{#yFAo=Wj?Glw_wIK9x%yZ zy9idmGrI->Kyi-@XGKqGJflKG0)$Xyl)K+4WLY7K}Zqen(sJ(~wG8JRqw$kIi1!!?Ej?qr3Jm8*usuex}#ub``6K^+_97kB5yX9+vjFcCvGd zYmcY6_P7%GVK-<<1FBvq{2{Y2X2^od7$NlM2?Z)N?PzTvH87b1$kGcv9V+Nq82%U4 z67~&)GI~58%GUEo`GukUyqeEjvp1aQo$s=jxC76p^@^^&s*Tlt05_ViFH%5!OmGlf zk9?rJWyrk_g;u!Zjz;M4NFt{-C1-%4y`YI;!$}nZg9g50=b?NMO?gKfHfu!7$RafliQpfBpTSxP>Ctv1i}0xxCr8|Fd3LP zT=Hpny`J?uxoz>cdgeL2OxD;qNPR}{NK`O4Swe{60!fE?ub#Grlr3boT+AYr6^xJG ze5Qc0HMP>t2S4udiFJIZNz0a290CjWJ^u=4aXE2U0drp{S@qHM><6BYYdpVn(p+M@ zYEFYLLMGB40sIGnqg7kg5yHs$g*XRgKdHcCt0>!Xp>Bv#2v)3H$=21OYI#WK@Sd&K46L z(J-)aP-CjWESZ^^O#DpPzG?J!f%xsvWrk1{a$V8@FI}fQQ;z<_h8-JlYRjLaNB_Cy z)ByOP5Bulv`C+WbfXo8chUI7G_8fLzov@u>eret}kDNdM$T#y|VzJwQobvpnsT=03 zKXq!|+znGFJr6|X!uOa*44qG^Ob2BjYQ-q<7GgMtWKR~ld!dog$T%*@T&&(p*wF9W z4N3{SHNdW$(OpLUdWz_JstKYNBR~_z3>Y*hDr)ecf+656l-hUqd^xT3tDRNv&0@29 z3>dt+ueH~@5#=L3zP`40tM&1l505&6v!qBHd8yV1=PwYHC>D~skCiHw`x@cS4n)%P zU?QgFt)DuVNkt?GBnJ^VY33aX3zDIwHUnld07FE;3_>-YC^M6;IVS^Y2w-dDU+**f zxxd(-=lG?CXUpWDGIRSo|H#eE%#~w8Z!ljAo5EMc@Lz9+-sHc=@Hyq2%{CS09Rs1 za#(1G;N5AgG5^}5(VV`aDMl8h7$&I;Z%Feqdt=;m4n_eV%!9t633Q4dIT}*tRn+uS znldkAG&6XGGE~5V5ypURATA1wAc(g_3NIbu<@W+}Y=l2G4hW9DmzQA#5F%twO%rf8 zM5U>b+5%=M{Z@3vJzflMiFFUT_l=I`?t3s&p`xjG@4a3H<*a{7QerbxV0;|3o+f{9 z?`Selp`5%+bwjd-j$~Y_sCJ|-BC&}I)DR9bU=`D0qiw<>K0VPS%c|JZdgZZCPc+Jk zVWwtLy>k;E>QT8OW7{^lEB}h6I~v1K$bTDl;#F^tuRXhUz1jJ>SG|p2t6I;_@g|?p z!POIFzY8_b%2S-bbV~8Tnlp)F$6wMum#l<&8bXKP8`yqy`X7>O~}J2 zyJUGmUSRsd6ReUIb2G;Unmj=_h>^CD<|ZA~5;GAK(G^y38ld?G$$Q_|CIvL{Z&5I0 z`_WCCPCPTj5z;Iuv%Q*sCBpf~G=q92V&|iBpDUT0x0)_0YU37}Vw|gLe^eh+TjPB< zMM=%0sA>i*iTwnk!526NW`(;N^FSZGu*=O5X<|SH-%4=V9tI;cqVVBXJ%kBQfUnMP zyAhF&v+QoRoE)(!q~reG2?+m}??73{JH`Zd7)Ap)FS-Ut%)M(wDC_8G5NkEV*#_|| zo&-K|W*gAA#YoXsZc|8nTAUl7V})fi|1Ej9@{04H2;20`lkXRv+cWF470j-V?Kf;t zL0+dm>|GyL`oj;;nxmNV%HHCggC~}z6qXv$9SxNo;-Qf%Iao?@w1CbJ z=N&42aLc#cD6n=oF~f;{lCyn%eS>|2Y_Ylwo|A z&%d2Nv8G?=6c*;lJ&M>tzWx0EJs&CW@UHxm?2cXfh%vw~&QPk21uaREe$&~vc+d$2 zQWH+BVJd);a1hiK!bk!)^x?o4B<=$wsPJb}U2mgdDi*b_FJXteFVgKd5?7I2cOx@+ z!rAV>xf94i(cEJbH;Fwg=%v4m%pq8>dhepG4QEn9oYeyDm%p!G0UIox6vLvu-6{%Q zjI#)IQBOAkiB7eFafY_nrNAI#pd5Jc*rrXasT|lf=e?hU`Hw!s`}HX5lzoPE8TefYM+kM5n_@BOqHUy++cSvs1#xJhz^_|Zvvz*s5yQHS{jfjoj zUeOY;FcC7`H-}AeDi(z%fLZ>%Le~6cT&l`c_owJ)hCtJUNe%;$p+nLM`@K#AaRojKA-QYFl+`vYld>4cDtCefH~v=qNwHE>BX z|HU_DRl&lSi;G`cG-z=$YnrlTP}NIgZ_Kw1?Vni?9#PP_JYVh03Z{21h>R%6>^CG< zP7T~qySjbL5z`!9SJ&xQQmG8< z1(U2cgcK>zx8VG_`r-KBvs)fqPoxg*TBav8Z=8TJ*~I#K3t9CJNgyL7DJzCyRrMuzcD(P}^5L@Fvb}p%yLGH6ZT|qRsaSAS(L8_O z)g{`#08~2|>l;k^7f2N{RqKN(12%f%nS|B_ytqpTt;bKJbY83_7&h8EQw%_hd^=o7 z+#0l?^z4!k{#>__pPxKxNVk5~^5G??$6tAK{pp7M82e`8=)vROfqtkG@9vA74+ixr z@HwOJ+9xa8uRh{O+fpj>yl|JVG+(VP|LD3fwgfK=y}r7lrJa|-@P1Qh-cmv4P$4#()n#&-Bu^{%oRJD>bl{V&>K{vK<= zKVZ$A$5;=3Ozu&$j-O+RG)w2RqNN+n4JLm~@HgWkQCgF3YpjdLRQy$imZC3x3+ zc^Vf+7$YKN!CC^niO7AkRIgs5z-hYDT8sls4~6e&U26CT2l=`8-)D&jSu<_q zb2oF9^ZDyf@Foz(d(S>+~ zQ8a{^>nxz~-pF{(>r>X559oS&%Vf;{g{i^8{O51l<_>7raZsL`?;MvbpShXy;`T|$ zOW^3Ep!)9*Sv`AYXTu1JbrQPS|F30rCRJdsKf@f7DC0fxSga6!(7^6sHzdU+l`_d5 z9~av&R2bEgSP~i4Q01IBQr&|p2vP}fcTgbtYzWh%;8xS%wn0>tuF3nxPidTy-g);% zOImtb^6bmIcYjimoSK?ud2CPTRxO)O`?$-Pls;?L=5`v}?n{f^F|WF`?V_^o-OCoW zEv=sCuv@-tSKKjo?V3I*W4d7N$uGDG#vMi8oM1VR>bN|JqSr%Zy{>uxvX1Z>a+O_DL?9=U~Va)2c; zrek@_jWcImTDjulOvs%1|7Haxtm86G`5-X##G`!W0nEOnBOxx@BnXU*jS$)%;e3iQeCsdk{O{Gp?&Yx@7lx(*ZQN@L^XRZhgVcy8^*h`=Z1YVbNWBoyenP> z-2vvyFeak}zfIa|mlhhtRFCe$6(eR!DOE585?oEJj6b1V=UbJj*RIv9#AC2WR(x<= z^o-}nT|8XWwSV5cw81>c)Uii@3==%f?%L}z#UB{7N5uR;!i<+`&w-w{=y|XafW85# zW`!<||e3{ZEVT-Zz8e|t??BFGsVknI|uW{LA;HmFf0KUfzPZm#qZ|o5Pi_RMO zBhi3hb-)Me%07py3DL@~Cf)xMq$n^Dyo|8cFwi38<*+0rG1R1nv!BH*w`IH#VGzzj zmb#k1!_`9muFTcp{LNL`;hI?Ga!s7_$&GCMjfE2LQjHxWlBE)Pg)$npaMCTn>i|hY zz?Fgt5M{tA&W(Zv;X5&$aCn6T%>t81w_x%^avKZ~RvsS@AM7%jH$yT~6oI8#kc&NK zpYhd~A71nK;m+MpA+oDe$Mz1q(Dn<;I$unf-DT=lHuF?!Q#;(70KffMU-@N>B}^LS z2n07IF<>aF;VY}YU=_*O(j2>rTm-O3$j~#A0bUt}dxbi2KGcbhnALly0anc?99m&W2pP!WK!E7>ZAv3R?U$Hd)aY`H(S-OEir(Vm`;w-A17s`BOnax)ew9%mQV7>FSmIJ!9FSu3?U>S zItjI3RCTUkwJON)b+6010UDQ~Xpgm-@z3Cc^f}p|N%Z;42Q-C?cAqnXZ6GjjoRN zfh3bgvKg(sO{k+g1t!H{z4ymhN3~19LL0qlrT<;twhNvD8yq$2Y6N>7OMep-LGtKHx|m3T`1nc7NvrV6#Uc;-`gKNGw*)tfM=zV3U}EA*WK zBj6d7<83YK1sJ66;(Jf@7x;`JPZ+L4D~{Z4sKufZ>uy9X79`=(?Y(uiMDTX)sCec% zeXXDu$--J$h%SW#C$lVK@TC|5ZW>&mG%a4sj*T^2%{G(K2-_l7Oy{)e1D#v?E6}xW zD~Mmrk|vB8F^)BVYs5sBy!g8{B}dwIcy`j-Zx*r(%FPoE`!oay*`2vL2hU^7SyK;Fp&U&zcjz?&7rdEaq(|93q@6-eJ~_ zQ!j0fpEK|1%YbIF&!|rWJ|&Q1wCQ8QhUc(I23JVFZ{w)H#;xTC9_PRDv&yTiTac}Lf*4-SDW%h`A<{6l zb2X~5{y`CKpe)2XevND6yZXyCEE{6F)_JHh5^6art0 zi&L1)*pXmZ^udV9$vC`wqYt*KD=;4@`)~|bXLgDCwoZaL54a$?B zSh>;*uKi(NE*x&yCh)VV4&QzzaC$$1)2~VSI=*#h2qK)#bG<$Ru8LbXzpIr_S;zDMrUO01vNNPRF)@tphRHC;vY z33IW#^O}0ChBxSKc}>BGxM(e~4)XPo|3L`x$KaMFGQ}boaV*IjF(O5UMFZ+V&&W`m zXZ&~)rA1B(3p`m#2F$?6ApG3&UfRJX@V;!s_SE)~QI6E7*kEMyFGBUH^L*Xe)Qrf; zmT4dHC)gEv|8{x7jhs2{+Rn|n;hekO*^jmCU6heNsy9C)Lps4YA)rFf{;d=vJ>cjV zB}}m}uS2fZDv_p3H=;u77v~k^QPT_suq|5*@XSR;Qbf?W1h^O$<6(rh0v2$}C!mu- zi*7d-90TDeGgNg)$}a30aey^Fv7LGDGV`}h+hJu4VK191Hxc?9&S1Up$lIri0WFh}rk(syoHR4OQ!vEB~8 z?O|%K{fGLy+l72Ktv1tj?lN6x1S2x9c*)m+Zc z;D~kBtL_7-gusHyQKvp(ny2C(=6y|Z&!lh02rIoho0;lQh>SYfi*bE#=ns8RJoD^%&nPQukydTlk`sM|K**UCU`Vu1OSuX>uCKy-6)3X<>gTb zif<JYf0N4XZw$XXIb`Ov)QJ-z+bGe#XM0!KbcOeDW|)grX*K z^~D**rz-mv&nqKd1-5(WyYeAhg%L*{8f=CYj35LA6Yv3vR06L~xWZ5JGX(`{M(Ab~ zs5ygd(6reVpa=$UM?x8PyHS~1YL7S(*=QPaV{AwMpQoIIE$IRNsWDw+ENqZxtJaq< zw`t|ccdGd}t7R{r776h!e9l)bcJWNhFpdzs4RU@AFjrK#ENcj%0B(SH8~Pw9HrZgu%`>(&@58_BmoV0%e++&*NCXB_a@DvUV{JSidzj1XiD5NF6t0{>EYkr)K? zVXe;{M})h$y`Uh$9g}GqOGqjxIQrb;^@5;28F%g!e^;&G?;L%be_1>_kbf1CKZVWP z$lp8u!5I^~$<@F!XOADBHiTEOs{XT%%i~zGi~lsfF3!7+Vuzs-A`w*75YlU85Dz$rOvc>xI z!3R>^3WGZ3w(s%uo#>D>qvoVehiXpN@of3p33`V{IlJ&~xudujoF#Ih6MgzYw6A3^ zigxf{YHz?_yk-#Z?k*$95o5Y7hR*%n5DuBQ3jGXTtI70>cKx|%cRhEt^tWi&bF5Q4 ztpWOP(EC>sJ*2uVE_!&~m3v>b)AL0;`lCB(eMBuA&>cVM6h)o$dg6j$I_&TchEf8` z2tgN3{uB}v8iKS~!KPsN&H6DvVmv?@iSHo&mOEIQ5;iG13nG{9`m?I)&t3ZO;&NXe z=UcvzUGgg*GiG}58m8>q&(t+*c+LKO+_~o3y6Mx`v8PH`(;%@1VvIC)JwLqH>Ob{% zJwH6!wE#3=POs|il~{w`)L*PQ+P|-BM}GKl?1eWP>hi;5EuP1BB>lpDsI~APct-1g z%QL1B&xl|cdT zR}QwEn3gsv;~y%)`m_& z8gYjqK>;Q|A0inj7!+yr(9;IFB5mMMM(#oNbE(OfUf|cOO)NF!nR)vzeDrkX;XwX& z@Ie-^`!&}3*in8uaNREt&02c%*XvAPI&J-+twLjsX7Mx<{8>s(s2{kaKjr zBAr z%)g6aUT1dwQC0Ov@Y{z{1{c4$Zo|n@15@{(cH<=CB?u2uoHNCtcX4zAU#-buq2v+- zo(#!H;GY3&o32~I=*U*eRtb4I|aLS># z*{fOU=~?tcbGWspVh$#M%mLT~W-fgW;5BIu^;h_=Iow)leGakrUFqBA@IS5k^X@s^ zd-d6ix8?vD4)p&j@bo?LPm;htDR<%@XwF^ur&1a1d_!*Sd;{EubdA4s%^3<T;NB-1^3RjAu!0^;lD3MQXAvP$TBq>3l(_og;-F6$@vzwv_t`Gou+YO|x|F56# zhy&;#P|R3-j}hH^tnkc@LSl{N7EK$+S|jaI_K+ZdU!2Ma7U2bWXX(1*b&O<6^Cu;R z{*^@Mpmc=U=w{}$RLB4>1tXlY|94liLpd6jNS%Vn&aJ{evQ=R4w{t!jvfwJ~-vy za+uj{kBLokU<)v*+1P_mf%{{jNrl`JXN7#A27?5^^9c4dWaMFTC3tLcAY4QMH-ZKv zG`0oW1q6f`jO6VC4FFt6EkPpiAT5nzN%iv!CsNHsSrv^&L$LaRch_bMzkK-7EAvn+ zpfrEz#O3EoFCRYeufSAZIkXXCJz-94dBf~A;E@Z{D=sbn`RDO-D<<`gc;u5M(I+ln zIm5qKpx$p<*`{Oc@a6g(hQTJ|gYysw4hDD$o-oKOhmFz@)m!Q10X&2V1i+7)1YVAI zi%>bhCJ4%$AjCh#*(eeUw+9Bs#+tlAtr3fW)GQ!k#Jt$7vJ#(ROM|h+wLh4oZiRx> zYxG&>kbiooVo!_adn#W4mC2o!vxBiQL;7{gV{P)f^&1istLDGA_c*`8KPwqEs)U(Y z#4Cs1d#~{6{+o}iTy*i`qLoKB4|sYw&R{ugY+Hd}X-~wX9O&%~AM8HO? zz(-j3kqNGU2@_T#a6VLc5Q_`4>z-Q|D6WA(J`_u)FMz<%>Ig(ys%n~uZXq2ANgD3! zWPfW;cw8L;2%tWW7#uyI0O|ugkRe#X+qyuV;fu?0Qe13mP;9CZ7{ZdFK$yku>kdTl zA7Lp*SJpc{Ne5y*pyC;#SI@pG4Fu)n{VIiRzDBXi_1>w^!a@`Rc4nyd^} z`N-%wd|M%ZPJXP~xu!>ktbXL-F=l%nvpH81JXiBr^?9tJ1-{m>PlXc~BM|>0@?8M0 zCJfs8=+$hSwP|B(vMt$;bOa#S%m!{X9%nN(EiEZsF!Pk3j6eW>FCp+#p%CwMU8@KX z2v!IF$c9h;0gC;K?{@C`e%6Hd*T1qXV#AzO2eSFV{v(^Pgpq^hjchuS$7Zw$O=YXt z!boKAd762wUGmElQER@cTCnWl(1-!c`i~H@H8`X7IPplx|A*c3NWijA7 zgnV$p*+Odz2M0LpkdZn`c&Z5#63{V&i3?7oNVf*Q5ov0OA&UdX7e|t0TYLr^j^FS| z>(5g7zxH08R{Hf``ZRX9H!J1Ky@!1MOZ zxV#FL1RF(A!b>X`E<>y%@5}4PCwy^`Od)BOsSiyU}|9 z|3viHWgf`BqQ)q__W{>)sD2!^A8|b&(1`KeQ9sIXbrUWN+39D)VDa8}^!{=@{xWGR z4`5enmqG5!IAkb#z|j;mPcT;ujIUHlzfcf{7%Z~pO7Ir)COs&mJrzrP$RIrcwE@gP zIwBy43^r`UkWbAvV~{B{n+J@@JNb+SM|Q43m%&}{1Mf)_SEQlxEM=DAUGV$JV9eB> z2R(84;No9rs}dkOx1R7hUxcTa?$vGfUERX()$Q)5S?<;C?x&F_ON4uD5Qo7LA>z(W zPiK>xybX&4^${{kyQY9{IFEUC!ZX-MkVl}05Hn)cDGxI+Y^XUD&R57WA>4B6fK_;5 z;n*SL7}9~bg=ltt9P-W`8#nG)$)uy>3i~p?Zs<@pj^!2<43KAy|9I!3oga=K{UQE* zGVa96#j6&v_m(eO1Q>w4cAGs3-<7|}CPeln*a%;jI|x`oJK2z2?Xa&1 zjCI$I?2PL^vVFlOj%7I``r*6r5cQ+)biW1-Kki4n=g)QRcs{k$b&rkXRUbshca zI`#9?eK9aj4S(zX4d1x?dwu#J z`{RDGyk@>*l@VuJK=~8$VW8EfwRxa)ZWCy0HTBzAO6k)F<`lscXgaaNT3s zUDs*+xK8gkyr=g!yeRrtV&C@BKFXhq?=E={-+PGfIjF0;3~*zR2h`I0(O=Z6Hc+i< zoc~9_zx3C>h8+Qv7l;gs8R|o*v@U)dNfW@7kVXOV+jivLwzv`j1t1(vc$mHQl2e(eSp z_R2FgtNi#!-bok{KiSzYoa1F(?@_?sQ{P0|)zWKhn>x#LBbF!NFy=SeuvTyH|#q2$MQTL{u zyGIlqFD*Ter>)}sr&M?_Cn2D`AbLIeR$ggsKT08T`et!L*a{d$M z2Ku;NTA*i-rHH_}@Q(;z?{s9R@3x(GEEv#hwuY!k-ahOwsPse&7Cc zW)2wBXHDOtzU9;V6!l%xXH1_m=cJjrW9zq#?OVpW&l)hQ|H}R&`%a(UcO*WH>NkVs z^(*W>by`kQ&WheeeWp&yDeArAt`_!Lzrwy{WqpfsmgkJ>S6140R1U2tWDDm7g2^8Md>npPVY{X2kmW_{62%7Nmrb$Dv9Ev2`a}D9^{f~F1r@1Y;q4hxJmZeu zJXD!4m+5<{U@sXnqh67nDf9W8H{Ln4=UsWEY~&K3hCB-V+ewPpPbOukn++QbX7F37 zN8ygENZoaxVghBs>g2n#)JQB3qmv5hZGG~N#9IYC$H&^NDkO+l-Lh|Jv5_x7`6^$x zbY?$HBV)%itmEIA>gL}4`(=;nH>-2!S^e-};Hcelh^#0j2;2G;>_}s14Z#b@jY(^$ zUx#0|!n(jO8`sg_qW!A;Y=Dw=hFe<*5JPjR4S63S zD?0iE%24P9`Y*}blT@fMo~jzjp@4g1F`99v5J3PA2{{Gw$ZiERsA_#;_5Tt@R&YC{ zDu#m#myS5M_6uTY{m)E^!@xz{^mZGcCc-qK5g6e?c2`v zmk(^;w{QD4IXSB2`T#C)H!qXBs!ecW{iJR^4>kj*7zl+p)J7y}VIK>yY$A^xs>akc zV{Zj>jf(&&WDwU>Z%@@v^D`k4H?Wrt?r`jkfGd>bBqr9L5v-;pBTX|%z-ay+ zpI$a|G#m8yU#xiC*nB>WhioVx-D=3NjM0;y5OA@zwoq)G7*qE_= z!#{uW-D75yu_g8AXRKjcrxc~<4{lvFV@;iC_QW3=yo)591aE0fji&3{Ycw%q z#80uewI`G%I0eYv1Z6o;F33DoMi7@kIPe+b6qT2ugA6m9EzTygdoYB{QK(d%K0pvn zt#Mhq!{df-eRyS$teF|bna@t@yK(i>2Qp_WQ72jsZ=2IDwb84s`?t+$n@Rwa!Gm4< z4KD?Kzq`{WGbs;$1Uiu@zT?)0YcaPi(r9QfcjS*P=Ij3Yoj)~p<}|jrbnE0%>B9!L z8(q2?0L!E^l9&3M8i)D8e@dq@21V7W3yD97hJ}huP!ybGH~G~mhF%<2P>hT_DTeyn zjf1=PUuXMw9lUuHpRVD<4Yuvj_WeKqynp+l?+@;H`nTVn-f@s{(T_YvS!X;9d)+~d z$*3J<%LOd1V%L>4`QOlPJ)=;++rDGzO?r|Z{_tu2bKN>TRYorOPm~216U8XP0v2iZg8>fA z3D!fAV3@z1bw~(~H>q%>hZ6%szD|L*(o!=rn8h4I&LeJ38oN=&6#hl~q-BL8Rws5x zhIe(LpKJ>94GwN#QodyWa(XQ(N-E0FFKRk`lYE`0bm8T;W&y!5(IEkeV$ZNT>RGKl z#s#=A2Z&slUiy|XzdDMCu5e;Ot{w8hS2SasVl&5OXyPXY-<821u_itEN6#PmhF|Q; zn!n3G%w|nqIP^V(2`+(e*jKrazr=U z?(DnTC$T8$JrA}3W)v|#0wbmnwF@8}J1`-sBdJxOLNBp#i1hIYX`&%ihJ9DSf4DT1 z?_fiyM^5ce$`Z9F;1X3Zlkv<**I6UQkjR)S)N{fmqB#lX2>5g96!bGW2G4h2rNl@U zQO?*SqDclAaO5*4W){DZFIB`rS#ns)$T2>ADJ%8KA5ZSP`@WgRO0Vwa|N4Ad;rW4c zeqyWt+!(Rx&((M?#+P3^K|6pou#h$xi5eL)yb8Q2saRdeI1LuFwA0th({4AF@3d z35_y)TxV5@*;4a{>pP8F-3-ec>EaR}ZG zM_e<8Xv(RYUlc#y5+Pb=U~UdP&4SKv_VOa};Ewy??hpPwEiS_zhkFmO)5*!amEtFN z|8TvR*XHy5htv8!cg=y2rHkhT1_INGewc$Pux<_te8z|YmDg8$c|U%UMV*0_x&u3r zlES;lHLf{qls3s#az|jcKD0Kvfi@J|#bk0?sVny?kaO>FM+h#-5T@?DqT6b3#Te2m z!snH85T$Ko*B*V9tvGVzx8KD4=Q=ORn`)o^-|PpfgVKH|Ec49z5>Jnkb#FK?A-?Qd zd^`)}7Od$6<|of#rvY#=Vvk{ps2d_Kv)-^wx;7U{axD{N6B6H?epZZUqcj?8FabPh znz*+y6!oZiI}lt0a4$dwu5n1D0`#uQy>W*-1cRdS1hfQEc28RxM42@9^P`Wxx^}HR zVaKz(cR#yB;IZ9o4_t7+mF>h6LwXdvv%1|?$D2HX5IXp*x?QjWpg-B_02ZZvB^$ik ziu=>$>8!gt6JE@qTh4cMUdj26i&rAuYp(KU?d)6YN%#+ud;kju`oWkE8>pD;h7HZ_ zWzV)gy74A|>jXcuaK#Ew{w0fqn>W# zj#5P^ot?Sz9%ruB{J?=fo_-pOAl(H6l>UHp;TSOn?jExTV!Pbih7=BvrHsnlGb`U% zSK{GWB0vECeQ|O8d%Cd#aP>s(%k|D<99~c7QGUXCS&ro|HEP5h&P#_E9C>J@hsW?c z@2P(lwV(>tJ|Tg>BF8!}EgSCPG4i1!3$QNv&g=5n+84l`hfA#lv?SuqI2{V*aKOst z5hp6#2%w=Q?&~vOD`v?-Q5Y=Q$ZqACndRNOP4C)udbj4C zJ2!99sk8HX`{Is{u^l>$b#yFlU(q44X@?F?6FXq5057jfKg&h39h~J4lC?&4@zSae zAGrRudQG_w|37%VHKzV=;rliE?sYSU)?f@DqD-zW2MtUVGqS-O6rsK32>~nvu>uW{$q)lj;Xc}6Gj=#mo?XLMiXCuGzbi3ltopO7n+foj+8}~qZ-oWJ8w51KY z&*<8?QHv%X-DdS@+@v`M&!lQ~irfSGB2CJsck6k-LV%R-KtSlqfPP>}y#xP<3rM|- zr|F@9Zg7Et-WF8Nc73Z(VXK~@nDG0)3-g?U>$eF}`nx3Hx;rl1<6R6#AL^lH-?Clm zl*`X>U`{bNo+9_CJ$=XAaD_>eLBnMsv&qB7lydMsx(CPgjtlpApBeGCDM8gQealnW z+AGie5AUL}Psa3QWaGjgdY2@NcVRuN?z(WVcTpy0Q}wqm@sww-@Co#;O5RZ!Tzldc z&7k~}$P)@+x&3W8FZ8kyap|_#i7WS_85+<9qUBA@!SY^q#&>!9ZN7-js#{N`jabi| zTd)FW3oO`VnwTUH#2;B2j!zQ37nc|j_&cuLW0t^FSW~5qbIi;9ivw)!*EG*vh=qSm z+68>u>efcX?0tydp~{t#p{RD3l)rk98rWy>ds5|TKNpxXn@tmwXZ(9>FD+AN5wnGV(kt=Z>mYn=$#HL z4P+746z5Z{Hi>F7BeHng@gseyB~3oWKjdF%hi_!7FaL7K^O}n1S?Ez>om{7HIK3d} z9*@HblMgwMgEHcAKdG;x3wpZ8XOxn}^Wrggu*L%c0VFYlR$=at1r&*fcsqZhkI_9! z{lUsRKmGOp;JImF`7vCYz5d+4t}E~UKX@)>Zn*8aa^a8iNKAFAI$M6yZ~(lC;Thyf z0#9krfL;|!Rmjc1%zJF(+{Yf9y=lYTP3pXP>o-+y-Z*E|#!4~~ORV-XYb;MzxRQeDma{XD%gp?)722KmFnTSKsCD_8vVZ>qq(9%r~a?ZrhcHi)C5K z_i9U|<$zo$c)bbFVpntm0%HOx{lsx+blgMe5>b#luH1Io4Pl7-hAT0!?8={&hClPY z?26OLqjBe`+FI0;l&~_t=rKdcq(~;6sibq&P%a)BA^;j*8m)~g7lN$h_wr_5UP1)d z(>+omuNL}khRXlNeN@5YzqoJc?eB9W*1d`<_sH-yylbfS2T1mEKmcZFvr@%@Afz!i znHs<%0XEeH7)B{(p#gT;phDn$6+)hV;-7Y~X5YFm=Q1|$i**;diGS=jXz=I>j7=D= z^mo3`KIZY?eb2U|w)Fnx=gZ%IcWCb7F$cyz#Mr{`*M0vSpsGJ$Z;kpqYWPHv7L4kl z`jgg+P&Zi*WZ*&w$*x1-io+PF!8b52HeQtK(zShcydxBq;2Cw54}}!UA3ofESK++( zXU~3r-tb)=*7P3JxuoODQDdFwl#H4;Y8TUsUYuc2!hg6 zSbb$P`E|H8?^jgmY>hOde|dTT0p;b&JNPvKUnn$P*;U@3+WVK+{3)*Df+W{0RCn@4 zhA)Lr<4MBsM~TmMdlHjX6slh26h%=&qXd_A?0*Rkt_&wy;1MV{NM}tBi_Fjmu3n^1 zZ+iDl(!%@R<4DoF13lr`!zxh;LWlDY71jOk0+@NnT2YA#33EgqKfdYKlENF2h^>u3^HE ztiA=&S*=;mF{4IYY0*AB==0>5&}d5l?WJ5ZPp#%l4W9$oMM&KRRcw#sYckwKsC3dT zzYR#I|el3M*lNxZHZ85$~9$Jmq)NJWK;OhvfI5(1+I0lr|D)QC|{|Fp9{?c?K`U~S24D# za>4TD3)&|qb!eBGs#ZTftHG?TTW2*W-&P5gWyisTJ2vPDZk*LDQ+M$>hL1sa2MEZ9 z${*xVS8aysng`-zAX5?pKLYZYEcFcs$44n&^Uwi6%aDkPE~1yzH}AM9z-qQoeKH;5 zK$g>xX~p15xZ?b-^_bkTPq4n3;nhpkpSq4KXMOmA5y@=6^CHGmh4q<@^$C}D(s=aD z-U!H`@ZqU2t*ILEyF%8zMH@#zd#_?xJr7!Ow(NRuIwb#dcL%oG6_$)tLR8@Veow|( zLN%ta(BMEnA5k?9zV5fdq<)TUy8NuC)6YmT7@VsXEv%|4nY*r8V!KAn-aa9jtz%2o z>h05g%c?8#Z5aiveA^CdWE%|k7`bM)x`Qt^p2l88NRR2WkHdWYJR$W4ni1g*!;z@! zUB3ltddd(-9j!uC20hljw&1-_%mY;rg~uC$1HnGjbLt}Je&Q_v?O28}dN;97c-rk9QHpH}^lcX$tv2O=Z7 zq^BgQJJ=I5yyiaEl1112(8d}+pS69nb>0JBZWuhw=V0C@shv21$)xb|#V@kR5O@i> z5s(M<2H9l*b*kX@5i=8DGg~RUnSK@pX26N0eK6v$vr(%dx#OzsiJiiqFrMZgb)GgK z_S4pFGn(;Ah17F5FR6!XqX2I)?$bybCiwUPOOdx5zF~ce=_Atqz$Of7vNr%c$ZC$Y zka1VMmtKol5d5Z>0)E9+x#(LmnHa=L|YTWr|a zwQ2LlNfT%ApG!T5ZoWU)4OZ)_O6!N6uwe`}Emn_wcHtTXM!okP662km}QJuElnhuXJiy`AUr%td(SHaxRVuj&PF6*9$UfmI_Wb|C#l zraEGQ1W-Y<8W0fRmWU}Ah+?+cjW)C5Y&|${-xE9ck0{vx)KX{H_}5Q8#lo41 z#_#lTe#~=f7h$hlav)VKfGX~OTa^qzqCAJRU>YURG9p<%QV9c&cus_^Yvk4?*eRce z^S1aj{eeBzwi6TUbn`m+k$<%D@G>1rdqr_g0%sHQ3)cXmn95`@NnpYAh*wg8wiTuT zZ8sEGCFI|}>mu^eS!oBYBHOFj!xW;h_LN}kA$;ZukBgRcXWXN#NnEzPjV&76qDOdY zaq)v&7_2FcwDB=bvqp>v4@oZTZD|q;XHS zEO}7vNXpROoVaI2oeD*F1Nd5KN-?sppc;b*LNvUX2TTij_~RiJG9TOpT&A;9sdwEb zA>EB<9&RSr4I{jR?s2apO}|a9y!E>O;yw@p3zJ&6OiOK%*f;^f{ZXjU7X-T`=z>v` z?9A@#Mv|^L1HpKLLveFkVtWw`j-^c}sg>R0y5cjyl>rP4yl4LkTkw!x{YE`l*{yev zt&1j1?C`+ISqu1M0aFsXhGsXM%GV$(yFI#5dr!~pr&){S<}K9fPU($$5K|V_i%cVP%o>MVrh@OGlquMk53n!ourD!)5os+wCHBRa_N5gwqQ)gM%V1ZC zQ?0ivaD1R$0Ro~0F7|4G#0`=$kNzSyn|WisiNds~x3d4$Em%`4Ry89nsd*#2CDEFA z+nUC(7@vEuX&ndaTGKl@p?VB$Ja686x+Qo>7MR-knXGr#<5d$UcIYx{!HSiY?NU<9A=#&S}$uX#k7PL{gh1OEO`8v+y z&sfVyDM30dR?<5m63~rP=0QosNJW+iEQ-~eic~FtXjTbyV`L>Dx0II;BBNq73J%za zoMDR54cpD`zKboq|4oimy}wfFehqLnXcu{E-v2hhbc0yrdA1@@2GUcsj=(8XwH_(s zg5bKFK9bAA}~f2ey4@G7pgZFrVX z1c@hD+#m_Wkt76ydlH-=2?Pi(L5l>ZEmmsK;sr`wDRp=1N{tG2r*=w{J^R1c%-%_` zw{>$|T1^n^Wo_L^DG@<;C{re$J7k5*RP-pMO1(7JKpL3gP~AuB|CeH#L?Ya+ia zH~{Ql+VQ7eF7?O>T3#%UONdMMZlHFu_7FSIvcsDsBsjTyJ7@>>JCw(r)pTV8%o)q7FslKbYyj@??ked^rJ@k1wCuLgwo&(G>LtrUEjm%i5U z&MmaZH#-#cAzudQgMVU#MxsO(ii^|PE-tl!P8h+%Gz7uf#3sV4_cml{04Kht#MSh!CBp5 z;mAf16HSHA@uHz3(9Z@Dh&j@~@C*C`UQ=%iv0A??1(S&5gP{_>w~c+B0P+L(ETH0H zD}alQtifpgL*Y?{5s|>IiH~j5HnJ@O3BYNC>qH!~&R}I9N7zuEY`NJQBh$-+qBjAc zDVg@t)qAJSgU-!ep3t{NuXcr9BYLDxTeWIhX5R>(Ee9$R(wesE(Wz4|`!J>L#FnuI z*{xeek^PJOmhFj+>gf7@!4fj0MfiJ}Ba8erXR3LUO3ck|%7nILqdoGzI^z%`UlCjC z1Z^d0VNr|!n4@6Jra<^dA~wYIG-&S78#e2mtczmO)cj-FQH3E8fm=j`>#$U~yGV`P zT+e=^BW&RhGP~X4Fx%ZGR~vv3v*KE{Y%d|Z7XKc+$0t3#D1&tFmY(T9mo#s&njhIX zZN>C;PbEbTOq-Y4+s|j9P&1 z6432~0)y&VrGVVrOr?1xuraQj)?1D}`^m8_x%<>BR#EKXPpt<&%sI?jflulPnfnCz zefH0Gasnl*tK+_X>bbh_Y&zcpopYgSX|M&LOD|wwLE*D)0nn{w23T{giF-u)N;=eP zhY}dyNWAZLywBfjcQj#lv|H^khuEMYaDd^}=KDa~RN@hAgFspU@RK!z?^<~EvwK&~ zui5*ws3iMcw~}$z0a9iiq)@k!x?`y0X8Aefx)MEyj{0Mnd1dSn^sz0rLET_i1>Q{? z86z;m8VNqOKN`3^$UWx@*qU8zENr;?Hwf4pwm9j}j|hqC+c&mZt{}PKh_W`YXTgP2vZv zOpI!kguZwLw3b8v5$fgHF*Zh1Uq=~_VS;D^hFY5*Xt|cWim~LhU$wm>Il+(6z$j1y zw_T4O%Ix2MOwVD<3Uij;u)SB`xHhfRWo|{Q`0}A02ef<{a#dJXLPVskC)4uDL2I7; z%!oD4IJ>fD;^T2_WBBLUUd1q-IuisL0GSPT%_?+uA+7GvQh!22VWB?NP??@r zIsv5Gi4-tKWW10o@AJBX9}35Eyfhqb+15+Atvw)i)~&%#Ly+^1qLm* zO_%GZokTuK4PgVeWqj53lc+97(P}dC1Cm*AWT~`NWe9~vC)_OuP zgW^h?1HrvGmfCu&poSF*thd9$6r4@;c22ArRubVZ@|@+yzBQioTRF};iZxaSo^ucO zlosGQcRMpjAIr^si6l|2DU;zrP+aKrL;4nNe9Lo!M{0=|VKX?vVR8aRqx2_KupDr4 zV6N;mITH44oK}BR4Ci($WUh*hZkg07DJ%qG8(L@Eg0yISZacb4eNu;JrhANah{8_H z$b}}U{?sm5YtLDZHjM+=}(3IXedEGM8VpBV0q$K651C{03LnBf*R#gWD z|3KfFv(&Y(b#8Lk^y>E6aX{sQw0q_rfak0ex7)hnWFyz;X_Ok}FfH6-w`*S;(kfC! zwh}c+?ZA*ALGh3pfG4uxFrTnspPIntzRdI^ezvfI0bLK?FS1qZ$f_npG$V=&RTV)( zT9UBfkg%!%;uD0TK7QchwAuiNA1gDk|cVjac4 zqeQL$>I2--P!qwy;cM9YwhFoGWd?f{B&Y^GI4ppcRxYte!M!(Sp=YIVrV$suxsD zT2P&e`~C~af=Lq>R;T6Wrtp2$)s+7aOPY*bxM0$x>iPI3 zyM5iq3rKb4#Ok@anDu1o^y#HZ1qJ-K(yFS`q`dsv4@zdtC`s&E$WGMXDV{mKG_h+} z@@a8ZRdHf|exm+N%FCmldv544K4Vpo+2UC+h(6F81>wwWZNwOf#t3_i2gJt(!o?#Y zIx5J{38(b22)}0*3A_YDPiEU8j!nVVQ|~6J57@yG5y8O`ts{V^85|xAd^Bhzo$-jz z77(m*GlNKccCH|ax$(#&lNp9^AMM(h7$1hnpWGl-JJ`CJOyak`G%@gc5@YRZMuu5F zlPMY4t8P#4&HgKg`7fW?*Ok(nq)ldfcNQJ5B!`z)^w{K@KvF8K2kC%bn|zm&nn_Ks z>-ASKnb6d_9U$bS#M)OYyT3T8DH}=pbhqA_;Ov=+&_y&67PJQoot;c;gIZzBq|D>o zf~`|;L^z4@i1w>-fDc;Mm$5mDvx^kAz^}-`=V3R_`Vpx~VR>!N0U)I(DTA9TbCL(@`}Qa(>l#vySX5(%k~ErM~FRb!-J!y&Pr&W)1gZjyFXkN zq9u5e+1Q&R>{-whf*FFV@Z-WjqC9q|#OzEJW;MCx8H9DTeCmoDG`TqIs`2bx``H%u zv&}GHFuCl9gXEX6RzM=nibIdNz-c-%7O;L`>0S-1Bm{sXEleF?L2G1`id;u|HZ>P z2T0d*9|jfrsL^_#5eC;}YXk@h8_Ou0C|{HK;yW6kGlN2DTiEahAL)bYJ#PSbgpYm{ z5$MYB`I}eRJQqCsu(8A-qOy&~A`Oi80Fv6XHN;8m1(q5URcH3nn%|skSg^qNBx=^X z?w0AzHqIM=`8A{zJL6SXiS}8k$=8szQ|4}LI(@Hv|GkQunPdAGrH*UgEi1mV8vY5D zuzaFUx4SM{Q0s&YfbIInTHB2d{+~&#itOO8!;b!q`?Too_=}3(_5Q>|_(`OR%)r^_ z;n_6zgvnQh^~Y>}oMGKzNQ+Si(!xc@*zjDsHAsnS!#(07DkOM$lP1$9W~CxK?8%bC z&KqyO8RhY&|99{AT9rXP#DCkj!lT2&thH_3+P)^34rJ3PU-p1RWoJd}MPwsXl9AS* z#7xbunAU`!y!qyhoeQ^#Y5w?vuHfOA2p3mM@D-)QlKND)dP*t>Yd$_VRkAV zo5qIT)Zl05_ogPZQE%RD6I$PyAQZ|NRikgnL&ibJ693V~Hs^V|_IK7-rw1uh5E&L93>n&2Cyw`- z?2wWgEq3yCVOg)J$S8V<%`NLTs%K1rJV2|h+pq^zWMdDIThcpZCM{gmp+niC)z*;u z4dLI=uQdJ2FnyF+W%x+xGYScOCFqwvvN#mktn?Rqm z2S1iYH};r{Zsa}1y5F;$G_zI|j2KanKVk&!@3|0fkX+Z#!}9Wm4$aFO=KaJnL+q)C zHY79uQtvay1b&kBRz;XAQAWx|W{d7^*#2+;jnYZnWx2oU$E1?QNDPd=PD+SQiAibI zA|xs_>g?Wb^0%|4QA--PicURe-atOXyvZ&YIkEtMWVvo7E@VksT8D%=m!zeRn7ho{ zG(0bFc;i2GbQ1rbj6hsNgKiU@Z~I7kq5%;D)VP~R+`XJM#WT4$6W`|FQx04sASu}~ z6*od2ABS^O${+Q9g?{{#od(vcj#KxXDq5R{m}q7)+9o z02@VoIII|C*T$_U`|Ng(7=d;=4d#EMS$Y(8^XyO5VyxyrljDfTK|VWsg+rICE7zh& zIp!B?*7;g=jXEIPo=J`Rn>6`NdEY+ecaGV`zb@T8qU+G1T}Nz&oynNUZ>AgNZT1T8WcSAZd0fxJ0n7XKTRxz_ z{ROWF#X<4XUYM^L1=l-ap(J>8!7@M18>q$bTA`9*w=ohwc-<*jQ>tZaXGCuc`b$e3zBLzHwKJUm>Y`=z}Ea1v*YBOZORjuO!#IK_t zzP;CwZnLjihz|PR8b_yK=L<4CoRJRZh|*lW0XtGX?*_Lmt#{_gg@EjB5Co!i5ipT8 z7cB$S1w0XCz)%qv?RAR^@+zfbk=91pXqB;Sof>u1xyVD?w3{EB*=EJsgp1baw_!)sD@a%Q3Q(1w5_4qmTU2x@q zLehHhu)ZOQ0fq5%tm4^~y;h`##tqHx*Ti>MNE>_4E3)$0boUIVe6KW&GkqPo;7nhy zTu}Rxd!D-$e**h!q&+tfjSRxpq1AeBfc>%4DeAq4VNHMT8g_`@#Gm-IJaU(WJ}_u3N>ucDQ{b$;}{$E+j#E^>u6`_oTt8ET}f)cV%l9w*|6+Q-iH z(EUR1Khwh-UsrdX#jRuRM~pXXSSl8j_*8krSkx(d&^SR za$v`t7xRWD{2#=jxgPq8++?Xw?zUz*{r*1RVx5v*pxruVk6UPH5X4|RZ7Cgqm~z(7 zUQCX^XA1thOb_qj=HJx9e4GR3-EB@wb?VKM#j200A z&GcTb?az%)PuoVXZOn-_Qj)gg!|0;}5M5_lcL>f|k{uZtpMEFFpH`GQATDQNQdEcA z@}~12{LFdzv;8vDeEM9{KQeG`!3fr&oqwMt2u-j3l&`bCQGen@*T^$PcHeZwY3Kt+ z(^j)!Q?QLW@F3SQ4;pV(t2Y$^$`1}*60Rx|9JQaHssN|wr%FivZehU8|II zyFxB}+bX$Z!{lzm2Ijs-);xawAVl%zBVzcDaK4oj-;*t{0yvYS|amjBx zUlYvElM7;FlhGbhyT^6H-P64klAJAN->2hsYy++aZfv8O0R;b{g+k~vQ3(4?6cZ51 zBXkg+!!79F_0f3t&p>N{*(V^dKAe@rCc=mgU1XSoO41dy=iPVrTur{ZdiRMFyRWfA zT_@grb=$UA-`ozm>h`+cvnIOl!fa`6&znFU6a;Zz>3}I?VRPd3QAeW1?A)-BMAtJL z_MZB54`P=6H(l}Eb5~rBV$jcY;-9(us5cPXol<)l-RbPPbfW;WhTdNTVS|95MO?rK-n=7Dd)vD>M*GyZxdfFP-uhUknn!cu{s%G`n)pmdH#JD|z z7;)v>u@0x6eQyiy-EH6NR2Ssjt9{k=o)L+AiN2j`VcbIbT$euSP`{A_f8D+|ulO(Y zV>-1@aJ_LcDBH17c{7^lXg<*93;E49_jj4Y32M5)^S=w8AEKA<6~IL9xhbPY7UH5J*TqS}ngp15XhMfS+Z z$kEvoSCiNCGBOGZGBWb4!=1A-^6)Ls`gGWmgs7;5r9(>=#^V53Sdv`WwQWkbZYjxy z1?^G`3-x^2$M;y%~*P3(p%J!{w2`G=FwB9*%BvBR(wvwr)K3#*rgvSM4xl6g1pX;Qx++{~P3K z*C21ZYVYUA*}I|^yM+e@Nqd!`^I%^G+Alot(5sqj*1c*6ahB^|EzZc!$gJ;G+ik<2 zc^FgRMKhc!b;I|xyk+x5(t;F{JmNpHcy{x>O^>a=#CjjlY42Fp*nac*@w7Qhnumus zPw$vMf4;uxfSL&UdNTT2)>K|i$TC!^p32Jxrk#N$}AiGjz0Hh%!+pp9eI0s z+*_%4k(95$Bq?|D$G^cWpI^3e3@hfo#jx*wQ-8*mnx#wcCaQSDx!eTno@8|LphHi+|JO{h{k>Bp)AjCEE3SCm z-V<)(Cw-O7F>EXmep-LhTb)lalAqStA|}W8IE~B4Ph;$CY!Ukcd3T*V%yR)gd7lWN zr_?0Oih67-+pvjI{qJx-w4Rclay|0=veU=JtB*c{L$_fc1I=p8`7~=gQ>zbD?vv>pOZc%iycsv!$N-T0dvU@;fJ8 zOLPFEqc}2(*|GfyJ%-)09QPb;y^eoGhI^=Q?J{@+G}0|%!h-|rBh!@k)DMa! zsu9x{@0if-z0Wo6rTj_JmbiFMmw08ZCu z50kNj`j5t0-G9(nSMV5|*k%0&j^Sv8b-a6CX=z^P;^N);#X}0Z3?72@^MdOwtF!w) zBg4BtWrPFi14k9M5xs8^h#3Yc?vMtEO2^VF>@y=QxG4<@27;FTsojBc;iaK{JrZr# zB^Y}hGq0+9A$49xj}p?hW82g&srdh#khzzWzR^i70;7BOj|*uN<`>(&&5DSYT~b>` zHTOsIvnDNC01wT_4D>Je?VcJHE@2K*Oop`yZ-aD+0{P6E*=v6Z-|Oxr^Dr6YJ&=!p z(-|h>bHl7JCs^IAUn*{sdHd^j>?_x0YoFxDt=}+K_41wGAj0fs!ln*}RflcU2{z<=xJp+nAb>0;4PG-~hI zx@E5r-*FSj#7%E3tky5zz1upzOG6Z*j`vZ=w*PS*LAnkWov3Qx-$W|LRuG?8thbge zIja)#*J=K$;V=HePUQ7zzU8O>ty5B~9zaZJCHes9teut$uxiYdMSUF>r9Y4T)1#*lpoZ;IdtGQFt=6<+GUMuO7!jeO!6-%t zxwb$-KI(9m^~3Oa2du9T5-hU1g_h~w=za=(v`4=HzYe1b#j*?wMZgu@h%h7=`5FZE z>chsi4Z|m{{v3*l2jG%-8i-6NJv_p<7j^@oYl*I=w~kNg7LnL3Ke|=6|5~4M6&)v* zbr?K$Vg3&-nnguNCnt|wnUK&a6R!tNL-+#g2xQ7QV~_4*NADAfSQQ<04Ku$maV%;J zH9ifmVHL_BZQzcBXb3J(2W27%nO~$VylBxV6s$sDaYJ3C927ob#E5DGXZtXHit4#z z#F4mq_r;7{?D1MwawJ7;_u4EE|6{Lh1D>j`zdDk*c4?!#5K=LCKxtT$*x=5Ik;PM{ z_U$_~xLGX!satdkTaYrMaM;wr!?W6Sif%)ePZ?fXUfi!^ywe{8`3mc(T57}?-R(J- z8;KE*!up^Cnm2=%Sq~9*whOrrv}qL{3YW_m660myVZ8IY)8e?&N+9QKvO{6?n7K-e z7WY50Z1b`HOSksy*nM;P$gX+A`(@-Mwg~Sjwx>-lowxPyHS=~&$_rc)(z9mv*Z#E#KUG9J*h9)rD!fqC&nIsw|i1K6SCAXXrRmLO)^3yquz|wi#C12ib5>lp-j*B3b!%x?2W-=FXi&Ad zdrn+8eujf9W)MV6rySM^g=t(HT<0v?9soYQx zs(=a!ty{7`t90gq>KW<%TKF&RnAV|Vk5;Yu-7LiVwBz+Fd>8K}i7|QAWMrXl(dhhV z^3mo?5XZk(o`wH_2qT6(PTK3*<3@%VfMJ7&hrl5YCRf<_55kN8;K@aJF8)KbUV(a7 z^-v4{B>R|fEn2dMRGK|I9&nAdi3(v=1_}QatTlvx=|Djpl`#S%;X#@ViUqFcINr?{* zY2TOhjR_4;?T0+VCrLEsQ5yT&x(xFuz=$;R?AE2jq6?8X0A7jcPg~9h=Yo5hxuBYV zr=&P2utj)aWKd*0@}hd28nmmqBM#ZF+lea34jFTLJ2U%JN^c`b)`_wQO}2Z5q?T6Z&h%sMJR#bRn@T!u#T1WE`a)CcEN2$ne52`nyK2*loGySmYGO(t}52|$MRU^QeqI4;h74?zT< z_885zsdA+evS>n3LJ;u{ZCbKmd`NN-3uzIbB0tXZO#NQ2851TezC^~yVjV|fj?72Q zMTpVao+0i1Ku>d!0`LO(I@>H8aOpsl*Rx%ljaYF;Ku}Dum#u-E>47Q9$#q~Y&|j)9 za#hqmQW~G;f8bKT&Qk&dR`Rstxua~zl2)M_vm~zxLkkyMaQ!el}*2uQA(%D-!|(kk~-;RStTQudjVv`<5HN#8-zUYkOzT`HvfG|JBnv zM#ZiigHzL}_J8$wVZN@{^Q7?g6E!$Ed_6Eo|6IMc?FHs{0mfiDjAjlnQoV7>5pA$P zGz!(nsOQ)F?+{5csBO zBq5!_QiruPPCnr4b)^6|+ps;JjVKg!F)dQfs%_g=)ok8elb?~1-!(I9MrKlCR%TLC zru73!Piott1CUnF!X82dy$5@U_J~bAtDOb|_RkS(3EHRk(j;S+ZXIGJv9;qk)==v) zXeNdk$$kKMf+j+TVYgFD-}T5uu?>a5^IQa@NC&*f#o9nc^#SjC1JXMHwjg^0Xq=J* zvK(fBvXL-cUm(7+YA+em8vsVuO(Y{RIRgWmfz7W&Vml4|)Go0D|FM?`*eH|K00ZjY z#-obS)jG+#*Max*i0lm=ey_TY+|SWy>Gp>H5VT;C@`kIe2Zh=wqxeo&F6%nSr1%xNrJN zQ~To?eo`S+2(I?p)}KySgJj>El)dX6gPs=XTxE+tyYB zrZ+1#>khJ^QX6k!sm-g>(7pD(^_AUhIA7}{pVFEbBvA1ieo0JBqIKHLnb0LBCMni; z=(3ntIGv+!$MW6o8EP~7wq5P*h)Q*G#0>THEv;?lde_(r3}p!|h)2rzgA+DItQ%am=~qJwi&t3noJM=Zhijj?p7@iK4X36 zdiUD0vTKemJwl$h{y-p*uhmf>jdjWVZFfiY4#u@@VIrKFwbjg{vcM|!08nGv6Ro)b z#!)zQf$fM+JJHyL7Un8$^45e;J}rOK|M4bolz;q5`I}An+rOwo`s{h?Vi z53c=9>#q07b@Y^Z0yY(7kRa8%FX;WG+UbkNzx$25@b97>Jte+@*TE0AF8vYsDUO3r zn3UfJ>-Rr}@00BB-^Jhs27LTk2et{5$BWmBMf@*fv^D-=bO7t%>POoB^b_0Unuzw} zeQWT(WW29IFQSijTQ8y+4XsITK!814F9L5t4FVg$lCAYRe=#li$-0YevhKz!;ZJ#z zorc{(`%|_wYMkUn;RXky0d~_V3Q5FKJq(J3=uAeA^5Me2m+9OOZR#J@OQ+r~(|!+} zBXRt+3=h}Nnc*$N5!~O{MN?}VAhloEJyUyMpXZ`!tzCBdetxpC`>DPrOB-w+9$zY~ zfeZOkLAd7c(B7(zZIeLe2@RWxaCA_vO$?9*C@Tk#IgaX#Hud*$!g!fF6aiOGcdoM*CV~ob(pnV^!T}h z@&BVa1|Y2q%&}F+PA~hLIi{sw5x{cQ1bYs(G=M0IezrRqyvhu)6A zNN;O%9#Zr=ZpoJN^t(3h&GNb?dp}VdHE!hJuyI(^!HA@+bY@W-L>qwF1$Ha~5ui@w z#$?z&JaY+&#<6ZMUZ4#5_X=Cu;R)d(;bEa?JDY3nNh{m5n)mFm1Z|1j(p3i|MAL(8 z&e+1yJ!9Zh&Z@1WFi!GsGP82pt+*^RvwY=cWVXFz8}=j9_Ke?l6di}tz-dHF1ty1R z6AdTpd;}6;Gmd~A&UL~mXEj{3NSV$_72Ws+co5Iq4il`xej8^cdVdNH@%1qb$FIJ5 zQ=eepV5rWKw80lrw1z?pfoyWol|lZhS@D_cIoF2sR>!0rI}}{Dg>o%Dca7-y09nFL z+vn3Sm@xMF#2TGXp5M3Q{DL3+MSs`l8!$r7|J}RK!LQyvzZ%u2)&1wy=bb|+f7+f? z6QvK`sD81}iFD{5JzTa9o&tZVH%f1=g$sG!H{RAYUv0aZKx`ljm+suTbji-0OEQbP zXJvQmE`2snow9lJl&PE7cFjmHEKJYPxfM{GCoTYMtW9A{+|YrT_-MdkvE3<|z?iNEtcl8b6>Tl)9Nmtdd&Hm`N3b-h*WhX0uSwoaY7!{f7YhnJ77J!xIz4t8%d zS{TSH7J|bS43;ySK?CwS*x?HTvsn;i&V$1iT(*>K-A;J@<~`Afj*h^V)M`)8Daz{D zeICj0l+~kp#W3BU3oT!kxR!usHguzz5H2Siq*k7 z>7Igf{Hoel&-C&9-lzWe&Q?77cQ1Y~s(sM?x%0dGb8r9GMOz70t@{9G0Pwq;pnZ0p z1TamFt+KlP|JGj__}#?os~k<=f8083C6Hy-+Sgx4f77}U*q%R}}uf6A7A9TnTAFxlXbQzA!=Gk>4(PFGcmtfymrLq&E6G98^ zc!hpgUAE~_$17;+z}wk?e<2|*;fYoF=2>s7!gHwi>^Ld?-RjOxyDLEl=JA<+dR*c2 z?Rb>vd9xpUcXx;Hw%6esScmiNb@*Lf`uXb+u^hjV6DaRz6!gC{5Tg=mZzk|r#d7%9 zaU6Q^8^>@gxx23&!!d~_^WSPbF&wT#RvEIne2+DkR2Z-I5!z7+ntzP+I=enS^d4nx z7VuW^)_9HMrL}>%emiW>lC$-Q@;tn3yX9}?5uDtq7-l489z zq>%FC&@2&GjO!OG&;20m*l0&1OjPGAMiaC#i&mgXv?R`Hhj8Al^T%tIf-B}|coZ0i z)W|`zdRf1>j${iVL{Do(jwhyA3r?e^lz@d z@bNd@4`|>1x)0B6_3Q)Mx8MF9IhYpEQ|?Uc!#L-h`2v^!`uS43SGIG{Qh*SUs&=mm zbe>m%o_&JW?hzlmd#N4vS%F>!Cx>Ri?rih^STFX0fzCJ1%P$D|lxfHs{5@DVk{ziV zDHreDNuqY_&~yh`tz4(vw}9@vx@XQj=b`(#db)F5capyDdoa)M1l_=;(!N+{r1$r_ zg|0WP>)r3*_p9rI&Lr#Ku?~_wbd%bjt!v$D-B*C)>r|Kn+cpxU2&$lgJ|{i^oTv@$ z5(+CA@H!DnkNBN%5@v564(^bREE1-b6VC1(66|uVCoA)dHe6Y~v~S;~^RL>_Bd^A~ zc3DBeyp8?(ZJbw7u$1U=Ye$Y)pV4FJ+aGJ!)*W`*Py&$p{rkELjLj}< zjeEL#nmsnV+|!)r-P1g6q_w-ygT36h{cp!+IJ>!SxV7h@he)#rAH-1B-Ne5IPW#gr z@na5|v3Bk3HEXA>Su4%7Kr<_BdJd{Om>9wuX&f_Ogqzpr?%_qfN=ke77^Zz$ ztm8B?Z_wZ_c>@P(IwtWi+2yJPoNBOvtN{+&tdVY^4Xv3EHj%oE2*} zw=sjO90u2k1Z*sfkSat43hU!9txw2y&DiE63{>54gR;IPEmY5eIXMIMALf8DNseZh zo5&~Y7ln47qh~?4==i?F>M`_|&aw&o90S4Q&}1;U|HAMFO&hWt!1-bnJ^oM*=g zGX-cTJL>#AVecQx*z#WNKL#0JOzx}aIxrlKl?E4<1-;^Iy-(>1+7FETvXoun*#qsc{d0<|ApI_=X&IW8v=thj+j;%)U&F3-D(YAe^Z}U_cf~TXRYVEV13i=`hty0 zL>lPkIZo@)Cjdns_G27T$fN1BRcG7KPCUF^yTjP{fp#f<0$;osg0!MzfJS5oY1MZ~ zd}9ft5uqgG`a-|3O`9r4lDGzf=Y_26KB2umr*t1pw|RlqM(@HN-Z6oOq<%~kX9`EG z1WzC#hbqM?1e_NXEAjP#S{~C$!;kp1_H7NSe6j7+QyUAMuM%qx}g3GDH}qVH|!yeCL(&W4Gkl~ft|8^%{s=T6a3jH zskgqYLMI4XAR4^DlVOU_jK zde!7-Fc`>*h4zB?1g_lwSAnrI?438rBGU5BzEizfQgmXl6Y{ zuzz2qj1$%$ZiL52ht+30@f?PbGVQbx_0CLc=RMo+xsNPdaB9HFUWBBT6lQYq>$)9p z+!EP6>UQUbx7pV@Uz=G4;N~#DiF^y(T>A^E}DUSnqduRzYc6pOFK;sIDe`_tac* zRQ%d5f64d>zl@|bLE^(RN|_42o}G}`LPkNm%hi6w1@U2@5=xc2Si_;50F#He|T z+sDPEpncxhPO0T#)HT!fHA#Vd`|sN$oc7GNMv$BE3dCe1-dlm-N1d7F{!T=AN`{wU@Qe+7q~SFP-0Ik$nHBpHBN!&MYhI)c)zG zle?Cc<)u7L@|R%OXwQbSc*GAXXk3uZ-5;l^Hi&a$oi@(vco7}y3E(_VCupD6A&9ep zg~Cv9sgzJ6!Gj7R)Uhfz6CsRJw*SLT$cglC(#BjK7T2^%BpXUsxK=M(^iy6<_in4u zx8d$5H~=2dx1N}qutXAe>s37Ys;-sd+sStSC(&E!e^>&_{M|kc9f(dgoJ{5B$65HAV&7IGk)~;(Z*?*WmgtqwpWv3h>Gx7R}ajk}mK-ja8#*&#;EjKE_+% z1CfstTp+Y+*m&S2Z2LFT=z+Q=wjw^+7^F4rzL=Y~rX6^bK{4}J2x$02LkI!Db9!2mwM?{DHxb>xIb86}Rpvi5jsh?yV* zM)zLcBWHBK)+s|$Mi(s`kUOGxn^Lm7XW7`e*tXsCCyt4OkOwb$_Z$2gz6pKXXpTNq z#XhJ?E92wJY}(L~d@3J@l@MLnMlawP-D_+Dq$qT_o&X-l2((Y-D0*4z;tryh`d-SOQ+Si)YdbRKe;;TsE)_wbM2*-2kYAffN9t_bOOovjVjj6GVL;ORA?Y-nw=1 z(k<71aq`+fwq0q}-ZYOiTQg_&x=R=SL0Yf-cIVEoR%5zhCQ*OHDrucrN@21#9y0A^ zQ3g#GOnO?!I)V%Whjgw(MP^WRP-E@F1EGlCIWTDA#6g25P2#N9#dnRffjat+({pA6 zR(yYZA4LjgEx1Mv)V7uhs0I50HcK1)Hrkm8(V~BC9!aO=BtyJW+m64DQlPa#er{zVC^Ac&eN+Dw6E}FyJ%$1DF?Q;BSdQ)2e`!8c%=mzR%yy{?@TJ;! zXuRWfdtu+8oPXmR^f#_S0JPJlEwApQv06#{3o`{AzI*`GS#9+N{t8-uJClD5^fry$ zR{sY#gJA1>TXt};Rbk&=W3L$xjwrsbt^W?}PJCbI{jPB`@qK;$cVJTDJ7yWyoCo_6 z-#4D~{ZjjT2mTq{Kq83r-E98h(QN-=uf?-tzu^s6ANP$3=&S~~j$lDT7sDYqVA-$$ zuX|B0gjnq!^5(JA%Ns>|6XOv7jrN9}>mScu!lHvn^{XW8a#+UNTd!l?{Of16t^LsD zBsb+io7!I0a1X3L zV)OhE)(Sud?kF-a^k+k9bz88ne;&ylQi^E8=H23#TE+7#ix#Iej~|-lh0;RzxldWe ztcre(`Pr^8DI7IL*!0xbS?-|&&ildseg<+{>I!YYrvd@}6m81t;k&+FuzlqA+i%}K zYFOEo2e*&y86E1}^o#n@|5;+ls6D_a41r z%EH}~igLSW*0-&0m7wlCxfFb3FUN->%wEsn*RgoD;@TV7(GqMWraE@YbAD(X*Dm2r zm94?v>Q>Q*9v8>&ur|JccOY*1ee$6DcRC+?*WdD19)qjjUtiGq4?KYRwVrN;tWosO zd!Ck2w5+l9-g`k}-F{cCHNky5o>NBq!W3`~Pyirm&{k78J^|oKD7lcymw<;PA(`2A z`^jV0+t;{i$vxIU60>a^?4kQzb=GG04dB4i;9Fkd?E0<>ufC~nh0C%Qx*tWY4cdRK z0_;erx?cN_F7dFf+Up=20pUm)?>cI|KysgOSsU+OZxw1ACf>Eb{$1K7SjS3&nWNA@ zL6X%GI1H{Gjo+oy&*Q(ko1V~~QZ9=;zW(lwp!;iUek?QFxcQ3At~#)X$C0;b!nb4#0Uup4-hupHpgh6;0_#?W*J>Pqh);DwyM~u z*tku6?6%mzmIFtpmE>=W42l^ryu*O*cn98}LD#UIApY;qGOZ)TxMr{^bj?c;bkLJD zjSk{d@tj9y2!M5-4x(vakYQiw-^o*K2*0<{?*Sx$4IxhvlYC>HvFnb;oGM~_&=k!l zL($8%7cCyPF`crDRYWpnqZ^h#M*s@0KpzfJh}{g!6;8+aKHEO9vvQai(Qt&E{$sOK6G1>}h5+Q*0@ zcY3bKA!6UBSB2^TnFO*Wu9vwoQlJq>tI~p z@3{^!GQ^8U5pv|rF_vH?s<4|(HL8s$;JtJ((lH8A#!%d;#Ajb)7JjKjsVI!)JUlZE z-zM6nyBQ1cITiQj8S@*J9ExMQ0_Cgm>;hw^(H$jb7?TivmxlN28oHpyD*T>mbV8jO zxKn|*R-%l~e_MhKJ_GUBrO`W6>)+A^v!@a@RNJ#iKeZHpo$G6Bp!i%mqUzr<98YMP zt3cT-Q2OsEJNM1r_BGJfP$J402I`|g=Pb19?0&35&H5MJL-X)C3DnHQ=R9LN?#)KK zqHOABqFh@2RS8PWN4W*|)7|X%I<1&*w?dC#HAZwk`l3Dl)9rKKFca@@Z;z-`b1%ER z9`91SwrXRMUArD{r^F0=PQ+8Q@D4pHQK(h7!XN?elcBP5(J_?Lzf>sVRqtU^(751OHawUtRYieAje1{n*RsW)$1k)o6Vb?mKUlc_Ju?_|5BMKF)6nusc&9U`=Nmn6Js-5r1hx9^0$f+) zO3$?t{Oj~(lra}qv++wMN=F$9_?w9DGx47u>A!nRl#cvE*(j9Ly)xe(5j{?NE$CI6 zjP+fGtBH1h>0c(IjGklVxN=tXe2k!`LEm*o`Jc)}p$|3n`VEa+)%ZPUx2qfKcWRr3 zdi0f^;j{4B(07w@X8~wvxT8mCaij0E@LfMM03{dUa~^h%iFlu$ol*82Y?u$#xUa{z z6#vcyy?QQB#-Dc{Ux*^zf4Udu;BE7ZwG}%`MmKWvecE3Qs`5M!7F71 z8A(Qw(PRuMBV)-pGM-Ez<)ng4B$G%bnM|gTsicZbBh$$YGLy`LGH4E&OXd;eJ0lB> zWU`PfB8!c-WC;SuE;0Tj%gA!Ff~+JpWEHFtYsgx%j;tpe$VPH0xy)z>AC66AGucA6 zLW6t-*-ow`SCOm9HRM{dgX|>Nk?YAWvYYH7d&xespBx}Jkb~q9IZSRON61a&W^xO; zmE2~eklT${$Q|TP*bZJbUNT-LcawX_y|BUkMeZZV$o=F2@*sJLJWL)TkCMm8BfpbB$bZP6 z9dQwhxG}*#gDHv{9iaV(FFUwkg}5Rg?D>=(J(-Cwe9YsgeF|>@1HFD@UKuXjapVJAn zoL10@bP}zklj#&X)ySn)bQ+ybXV95+7M)G!(7ALTolmQcj&yOt;XjMkl(BUSV{m+v%0` zDta}&hF)uQp*!eKdL6x3#GVy`MfnAJnG~eTY6xAEA%Z$LQnq31d2al0HSB zrq9r4>2t;m`aFGszDSQ7)96d|W%>$)38&d`UCxu{zQMKr|B>BSNa?Mo&G`p zL;s{_jGpu_T1)Gwi(1qTyIU`ajRZTQ1;aWnfc}Hr+D31fa1=9{5A$Vy%%3%3O<6P6 z93c0BEC@LgLX1Afd=`qcZjLdJg|ToJ!CJ7EtQBj`+OS9#1=~*yLbl>qJWF7SED3S6 zZCN{(!ctipYmX@1bfYiJV3{n7WwRWX%Q~`7tTXFk^kaD}pA{HqSXWlay0Pw%1beWa zMt|0e^=5roU)GQHX9L(kHi!*oLs&5@VWqI$4r9aN@HD`9myI+Qu~BR^8^g-jSeypc z#zHoZjb{^BIjdk3*(6rUCbKDQDyw4C*mO37&1AFKY-1ps!{)MiY(A@I3m~x!VvE>f zwuCKZm#}4QIS^|G8>iSxR>M}Y)ocx0%hs{=Yy;cKE@hXo%h@KjnQdWP**10s+s>|J zSFx+vHSAip19J3r#t?Qr+r@UXJ!~%|pkiY&+s_WL8`wd1h#h7(vLoy!b~C$$-O6rb zx3fFI)hsiX8~fRv;6Iiam$19o-RvHAFFVTaW5?M2>;d*5dx$*@DfUtJ7<-&O!JcGK zv8UNH>{<34d!D_(US!AFOYCL#3VW5k#$IP{us7LT>}~cAdzYPH@3HrdyVwWpL!*>^ z#7?r0*(dB%V<`KKoic{8&)FC3OZFA}ntj8*W#6&y*$?bT_7nS=oo2tVU)gW$cVjsF zgZ+p7$<9E+{DS?(YFQm~F^jovKeS8XQU`qq=WxlAP@9r?$4X>ro0(%&I5QL z58}Z*gopAl9?m0p3*M5qGDaG!cx&EF&*pRZTt1J_=hb`xU&t5n#e4~0$}i!|VAER8SMZg* zhOgqQjj#9`zLu{ue&Fl*2ELJB$}i)W^G$p+-@>=@ZTt$ponOhX;#b4|dM)3`M>5AYlKL4JrI<~Q;q{3d=gzlGn*Z{xS~JNTXaE`B$^hu_PO^85HP zem{SJKgb{A5A#R(qx>=cIDdja$)Dm+^Jn<8{5k$Se}TWqkMo!K%lsAoDu2!RmcP#5 z;BWG`_}ly){w_bk-{bG|5BP`tBYu*9%s=6u^3V7w{yG1Gf62e%U-NJHxBNT)J^z9K z$baHL^V9qn{wx2D|IYv5|KWckOVnSyme+9?x40WV0R$lROmHD|W!4E5?cOVuC0a6=I^8Br3&ZF-1%j zRbrZ$E@p_CVwRXK=7_mso|rGH#R9QVEE0>w60uZVB9@8eVue^KYQ!qBTC5Rk#X7NG zY!Dm8rQ$Mix!5E&i!EZS*e0$J+r^dQDsi>A1`5Qr#x)3FIxMagJH$?Low#1?61&A7 zu~+O9`^5oqgE%M-iNoSXaYWoCZWgzQTg7eScH=+d4sj>^kb{j7ahDMat6{jf+lYW3 zsU`Fp_lSGNQE{I*ChivxhzG?(;$iWKcvL(l9v4rDC&g3ZY4MDBRy-%37cYnx#c}bH zcv-w6UKOv2*Toy+P4Sj^Tf8IQ6(_`d;(hUf_)vTVWaE#;C*o7_nK&gr7hi}k#aH5M z@s0Rad?&saKZqa2PvU2BTKpn@6~Bq!#UJ87;!kk~sGUAQ*yf_nxIws#7-0#waX=by z8TNyxYXOvgg+N9a2V-)qbmM#vVjrECQs$oq_Ah@BJ0y~a`F8RKc$Mn=jg87*UEtc;WK zGC?NFB-qRYj9X-~(OR~Z?Tj|YQ!+)Sg3o^pcJ-U#+Z1hFWn2yEVk>MAKN&w8_ZwFl zHzJZEO}3XEWV+0dnKDae%N&_2JIYS7vvClblhwwPkTjYgJIQ6n?#Xo zH`yKN6T6K)vPkwYHp-rW&fae9Fm@W(8M}-_vX}9I>@EAqzOtX}F9*nha*!M>hsa`C zB1`2^IZO_hBjiXqN{*IeWSJZ*$I0<>f-IL6a-y6hE9GQ4MNXAfa+;hjXULgymYgl; z$hmT!oG+{80=ZBwl8faMxl~>vm&xUFg`L=vVzAI12_vHKX1LHUOq5MdmG=4Y! zkRQuWU+lf#s~5@<3r;k<5T&&ankri{vrP(|CDFsU$R!#NteN-CEc(b5JeS(C z)nqkAO;uHDnwqX=sF`Y(nyu!jxoV!8ud3AowNNcmi`5dfR9&K$spV>gTB&N(Dz#dz zQESyYwO(yd8`Y)iGIhDyq&BN9YOC6&u29?6mFg;WwYo-Kt9GcJ>N<73+NE}@J!-Go zr}nD@>IQXC9a4wYjp~THN!_e&QManw)a~jHb*H*Z-L39X_o}1nK6OmpuO3hjs)y9W z>Jjy*dQ3g8o={J!r_|Hx8TG7sPCc()P%oLvBEdPTjeUQ@5DH`JTzE%ml~N4={~ zsQ1+S>I3zm`beErAFEH)r|L6xN`0=rP+zLA)Ys}8^{x6&eXo8{KdPV9&+4@LMg6LN zQ@^V})PK~U>WunJ)dINLr7Y#v3U!m3fTJ)4GU+PQ1lG2%>1X*;iOfr+rwq`ps#Y{ER%=Tsn zGu_NEGtDeB+srX@&5mX#v$NU7%ro=N0<)`GXm&HZn?+_1v!~h1>}~cj`)6Kv^mBsGsl|a%<<*~v)rsOCz_MYN^`O~#hhwZ znbXYa<_vSDIm?`F&N1hj^UV2XwYk7tXf84rn@h~4<|XDbbGf;~Txr&rtIXBr8gs3= z&RlP9FgKc)nwOcEo14td<`#3Sxy`)7+-_cJUS(cwUSnQs?l5d&SL<8#YxHaN>-6jO@9Q_{KhU@7Kh$s3f27}}->h%fZ_#(?Kh}5Zx9Yp} zpXj&gKh<~Zx9fN4cj|ZPckB1)Khy8k@6+$sAJ8Avf382I|3ZIQe?)&&|E2zz{ww`) zeUJWx{-pkt{%ied{WtnE`fv4T_222w>Cfvg=)c!r)c>Hrr2kQWS^ty%ivDN)RsA*n zb^R~;8~R`MH}${iZ|QIA@92Nm-_`%2zo-9Ge_#JV|4{#zjsr&>in2H;@-Q#+F+WrJ zhm)BO?F)mM(7?!N1#BEEWaHTcb^x2m4rG(qWHyBz#13X(U{l#4>`?YaHjPbZMXZ>W zuu@jW%9YnxkX5h{3$qBTWKmYdVl2)QEXgcZ&1zUJt7G-7fgQ$Xu*2C*b_6?;HL@nw z%u+1PY<3iz#b&cP>}WQZ9mD3a`D_6@mMvt*u|@27wwRs3mar4qQg#wMnSF^ZW6RkJ z*1}p@8*67BY$aR8I$0N6&DOAPwwCpVf}1?4YDD&j-ATZvkhz``yX~1`!YM7 zeT8jeUu9>oGuc_}YwT?Hb#@N>20NF1lWk_-V&}2{W#_YRvkTaT>>_qCyM$fJwy^K8 z%h=`Y3ie%gCHo$`ie1gNvTNA2>^gQm`#!sY{eW#_KV&zuAF-R*&1^fnh3#NJW;@xf zY!~|pyN&&n?Pj;LJJ_A;?9F_9FWOdx`y#z0Cf^USWS`ud>(J>+CP= z4fa>|Ci@$Ei@nX>VSi`uvVXAm*gx6(>;v{8`xpC&{hRG&8K~ZS46orc{Dx|1c$dCz zFvBoRBhSb;3XE|^p)uZ=U>smfG!8T-8Iz4E#zDrx#utpK#v#U`#utrg#&n~|C^kxr zQlrc$H-bim5i-I?#Hci)MwJmW;zq(q8kSLQ)EKo!ol$Qz7>5}%jKhtY#u3JmMx)VW zG#e=+ZP><9#w=sDF~>OCm}?wk%roX23yfopg~oBlBI9^tv2lX2#5mDdYMf-8Y<$UB zW-K>W7%fJt(Pp$89mYyymCM1Y__A@j@fBl}@m1pt<4of$<7>v*#@CH=jBgm{8s9WF8{aa{Gyc~&-}tt1fpMX6 zk#VtciE*j1#rTeKnQ^&sh4EeEO5=ORRmRoER^uAuTH`w7dgJ@X4aN_QZN?9c8;u_s zHyJk@+l^a{9mbE1oyM)kF5@T0ZN^WH-Nx<49mbu;UB=zUJ;u+BdyV^y`;7;T2aTT_ z4;jBO9yT5^9yNYxJZAjLc-+`yJYhU(JZ1dac-r`l@r?0X<5}Z(#&gE=#tX*pjTenS z7%v%rG+s9TWV~Yh*?84>&3N7Ti}8l>SL03NZ^m23+r~S_-;H;Te;Dr>|1{n=J}^Es z{$+e*{M*=TWS|$~F}?U2sozxb71V&Ko6Iy!)66sT%>r|rS!j+oCzuDA6U_t7N#6nmOGpGK zn>A*wS!dRp4d!9y4D)bvrg?;Uq}gaTnayU(Oq;fOlsU_sZO$=|Hs_khnDfl}<^uCr zbD?>hxyU@;Tx_0TE-_CumzpP;C!1d~mzm4W6=sXsYPOl}W{0`bTxE8eUFK?YjoEFk zHG9lnv(G%m>^BF@L37AlXP#=VH#e9Y&Hph^Grw$}ZhpnwWPa5=!#vYy?CXhL?3gX%n<#%1@5dmEuk~wJT2Tq7hBYkpxOP;e=w%gksGE z(q<~R*#T*dnjReL?+K*)2D-X?d-BM3Astn1$7#^xvI%ya2A!H>$7#@;2}znIWUY9$ z94(?ID@LQ2l1+%$3qL@LT@l_C|4{&}$P%wlnn$_D^r##x1^y%w+EF=J#%=0bBIY|P z8rOI+(Kr(+>yy!VzN@HcTt7;TPc)vFE7eJzNbq=3vJ+%m(gmE2MXAAwI&)U8b)vQs_Cm84FkD1VCbrwAx1 z0v?gA6|42lj>gT|PVHG_NjnHsUz-hU26oL})!(wNgF6KO19r~Np%M=kkU|!M6%QhW zMTfvF>Eq!VT*>nYYw=3<+&VQ4ldCIBs!by4>a zM)k(+RJOcSw!BofycCrevtl)}6u1Byb55@Nl9DWm0Lfa35EdasJV|ULEr%wZBo3D( zic1QLi&=7Vj#(0qfrfSJ(Jg&_EtrA0a3Cs)C!4gnSq>6U%d%lRWfSsAG{NK{&;$a5 z6ED#vZBZL6(FPE5%6rU^s3B>KA~2;kYx7(cTh-dUY{j5-D$pW!VG+BKK!~TUMs;3i zZ|@pkx@VOr*OFWrz>`g~BzKNkm{U2&v(f|xIYq~kwKd*(vPtpgCUt&iFL?fZqQm(D zv-0P64ncD2A6nbpGBhaRlcEVOEqehB65$CsErL2FjVB}%iX|lTflcAg;8>E*(iQ=% zngCW!gVs#(%@i*Mk9ayo@s4C5=M01syoestDatP;xOiGhaIh2R{DJP4fldkf`D?ql z5ST}{i>nf#ZHoxqB0{%_`%wpMix`C*uvn7j9Gk=lOY(n!zs5g5%jYGkB9PFjnnt-= zqOv8$q*%Ps@-6J_1O@d<^6+v(6xmw#Hp^)7UmEqL6TY`PJpT=z*IX`5n!qX zU=#7U?OnKDj-l189VZGlj~hvQj+?OW6`q#n<4SUX-$ zDaR8kA1_c@J)SQD@{b>e(8s%{nG}hVDQbC2PQ`J_=woqW@Chl0p(oViT7pC^L88_P zC%D&A$0Ydy0V&?$Rt^eCLP9)s+?E|rI1Hec08^VbPsojqc7m8Tv=hX*u@ju>Mxabu zinQ@GN$F{l&eKvVk6Ch=5wq-OUvp=dfMvWXX`YxXpWsVnj(BBLmxu%s zpy}gDcqCiU)j0ADYolFF^i@rCRZa9%O%pD`$xc%`f|s3c3Yk@8ijY{*oc*?_O(E!Xc0l&;RqK55}M%wl&mYBbwQXG zk^n#>U6>Ie3FNorFv&^LNGUkDvSHaW8yyJ&K%3k^Vvgc2f-HAQ;K_nHbitDZP$5s{;Os>6*61xHjQLv~mL9L8L8~St!QctV zNlu96rsO9Hk{sf7b!J-*I!4MW<{GtqL+`3ie|s;<6$z_0&_TSkL*Rtbk!x!Qkzhx* zZh%*kN5bhbtxM8!*@vMaw5R1`nwE`eT6d&rFCs1X9zbqHR!u~f&D4ixf^ajDpR;&M z%K9xSQpBukNnTc}R_)+)k+;0BrGGHGayg$!d@G}I{JT{Aogt0`wX~HTJ*%Q|6)WIX z1LlCR2K#&0bQB184gzA3}AJ9)c0bM2B1 zjuT)L1ki-j8X72CNT%y$ZB|p$ICQ7GV_=|b`1;P)y5!_5fRae@DI3eYRJ5&aZJ)o3 z(@GbiQkOs_Ij1LVks#2O<6@X^Y5pTZNH`cRm&A}en`G(DO)|3pS+dq#O-*wMGhx+> zT43iAT8^Mqjf;J&{apa`xYZB@2L=XPy1GR=Bj-0)kAN8V(FEj@L_U@jvcU8N$H&rw z>?Dl~OC2Oovc>Z@bS{tNU4T*B3|Ffy4QBKOGtLRiCzjvSan$bZgf-Y&hhVf zvRUiSViXoEGZ$?ZuAj{vOIZ2Qqnf&H;WZCqU|2v?Zx9Rt|JYnOyU%knhX zqrf$62=+*b`Lgtwtk!$FR|;AXg~#jDT8|5IR*lw^g&bC1G;3Q#1>k?OXeV6KV7$56 z--9Nqy<+9mOL*NY@H)SDn4l?!RjynxHBtVwU~6EPj_pVVGCm=i;7D6U zwUWKX)6T>r_pU)86fY-!tdI!jq<{-Q^^0~g(o(=hII&wPr9dDh(591SuWRMhODiX` z-76<4ciA*1_~MfQpe;9Ru_-4dWt#wO*V3AyHtFwmsMeDEE?6Pes=XZ!CRnwSt}MBI zjMV^*QMF@Bdb8y6JC?wb{}dviem5amDYaklNny&Ey#AG41D%{t;ygegN}@Kc_Y=Bl z{Vt5DuGRW;7=tyGOfDx?j09l{iL_}FY17rVzn^ynvfDat54f9@w6y_Ig*h;S+a#Qc zvW7;YhDNf6dM&wsJY7T3khe}~^sjB{X>aWwfG{KHy+JYWi5ABpnGVWE6jEf{ zP=9wWL4x*H5{-50AP1O#&>5k4O;Q_l13{oI8sXT4Mm2cj@qA9$JR`85k8lhSzoG_!7fRv{A zG{rmfgya#RJpy8yfM~~kLjcr}Kokd1bL*&_$ADQr&X59RR4fnP0&%Dlx8s)wAV zST>)tRhO=Hq-FFq8%rC0=r?WEp@k?%9~vfTr%_2jz~8Ahot5hC>|mv{gPP6`Y8rz& zZrE^8)c`Da$*J6Q>4?WHtiSL#BOZ4%Nn=o#MO4HYLweCwp^1VUT&+{w05@}<@SqBdjPiGtkbrIT!|a+d;qv5r?6<-$dcPe*n}ooI$n!S=(Y|00%VpvQo(ky04Vl| z1xCdzxygiWH5y_msmCmNm;~FA%q5mta%TY>JWe=Gv2?s^NnslKDBM|J(5|f|C4R(9 z{$`O7ZppJ3gbS#{CZr-6#iA`1OP+V5z0@8#3TO|NM|{+xb9GB@o*{igZ4u|(!gR?L zbii)QEfmP#Bva5T+opqIn^xPlJcdC!Ni(+GM#Qc<$tLo^7=9{8uHNAn4Tddg&ZZqS zn@HZK1A3dbglsyfw`pt0rUQFh0zPgx)%sgO0_rMG7HWG(Hx8#eXm5;c(aU`Dv~~9m zbl}RHOcFO82Sk$bF1JiJ&K1Jt7QuaNI*_($sc+Lpuuam5O$W&~EywNJgnuKN=)+&f z-v#sp0V^S=ZoDI1)$u%qs}6ETOI*+hPy0+=i z$R?g_%fln=lTh2}K**-`l}+2dHl0t{ByHPtPGQsegq^CzYK>oX@UHLj^=J3=3EiX| zfZZNRAIau~Iw08PV9QWoNFu{TvWN9;+=#$D^1DWnPF8GMC)jktV$*uTrn3i|WN2G1 zjj<)+kPdN7Izh2%Jz&doC7eqL9s|49*Voyl(IJ9O@~lmV z2{y^KHXSP1B;VR}xL}iOO^dHAUxa(f(1ot7PRK5NMnGo&MCFHg?kr}jJIksNMpYEgc9LWOixzdRa* zpV}$e1K>gROT>kr@{^oz$^Ak|JOno>gku9qz!`SRpC0NLr)uzs%&_aUzK#Jf5zZFi z6?t*jK(qyRy}!Gw--#3hk3<4r5Geoze$Gc7h5aDzEGv z!lDx)`asuu;b1*oP9l+UaHYm`!5TcZ7nUxw4z3J{yxi`>%>=~r5)eOt`*JF!v`o0Ts-{nW_3RxIH=oG9UOq6)ZgO$W9#MZR(5 zb)v`T3Z*(HxJss=@wwuiM6Nn0=m2*`6gF{KZ4}5lH}rK1AQzB}A_9Ed6@4?nWLpM1 z`gxyuP{%1lE#2^pqj1NsI}Wp_chGSM`nrdBA^O^`9^o+84s{Q9^>uGRAZzbh*VQf{ z%ab`t3UF1TzjwV;M1BjlDdcW1@|Z0HXiL|?8n{JsoWXILu6NMb$?ihtlaP^LY3bS3L0DYhj_=FCN-TGK# zjGVY6S_h{jeyfpntZ&22k1ZGqA%-KlD6abvnM}ZLI8CHPqkHjw=(g1MzC3x38n8 zb*Q_$W03lkEEw$XYUx?k-7zefIGJSViR#8i(}m0?HgQp?sBB!W65%&H)@I{OS)@#t zt6BK@#x+2g6rKZyx51sD+3mq`1o|hkqDjJ&f65T3gWm)0hxlD6d>An&K<(@ATH9gD zyKKTO`z>dB9C+30A{6NhT#2|BZR+dpaAJA3Sb`?ZL{noPIIcLaXld{0HzX4iz~}wK z<{N9_sNdbuC1xJn*-0}&|Dpp92jHH9;dC{A6j2#Dipn2GPAp4HMvjp3hf$H~BB6re z^iw#Jc*c#O9PkO^47{1zP#o(KIq}8iW*IK3#C+(ZfGDnC>F7EV)npxwT357ZXl=jN zBP_zWCcR^A-{1z!*jh_;08+2kDy=qYwMz?=A&*-rEu5`!U#GNi>cf4jrL{&{ICbEG zYo&z^e(uBM%B?Aok$vGPV3*@w)i{LXjPbZ}SIP!%!;3P2QoG!|j zvpRQ@qySfelo_1lF7CtAxw#Mb592;OU^w>?MGLg!E=SbS7r@ll1vM->(yRaksfVR3N6;-df}On5$GJvsQa_w=rnSkGN9_;9a)j|_L70Gf=J_^Zk z!~L}qr#J_cFyk&4%(z#;Oolr!<355JcM{C9X(Y_JSHjE{!C}U|0%qJHV3tilFynrL z8FxyUahHTyHo1hENG)L|oDyatc@AdW>xLQkJ1`TuBw$3coYM_69>x7)frujxnrP%c zJ^XUr7MBZ0_~ptgE_XcOck)S*EG`$O2$w6fcy)|{B@068%o9W^-2*0HAdwr(5v-2L zBPTVv^MZ0{1t>QXaFb9jF5_~u5;r%gJ+W9pOM5#mtq*`^R(G@ws$%m5lB~SR9u;-x zW7in6VON_xadslJ`z$fMSeS`@djPAIi30`h5;91Vc9N4Zi;43R9-~7PY3=ClJrxTq zEWU)ZjWR&Kl`}8R-Z27hOzzA==%p32+?jE|Mr^yYz2Vb4x_ zWWh9Qkeu4Wk4fPA7c2;Zt~7PH zdxtXXUadry@;tdA#U$WUK9^;vF=;F4`)fyg74w?cH};w8E(WZwgZ_gRFEcRDaKOPz=w zC!%v}1tCk<+BG6_;s{`fzzI%)qcY)E4wqj=JnyFPQh~L?lWok%Xeqmkv;b!=BX0J) zJ+cN$CfjJV_pEAN-qzXCwkA(FTU)xjdk5F!G`y>272qfAp*}Id)liud{(gxk)pCO= zQ7t#f64mlT8vJrdYZ_xFKjOn;2$y8mko(lmu0iNAgJL_{TYJ~blI7MORz{LDG|9dC zL{mJO*WT5#wwIsWqXGpOWe2xdCoSO1_X-Yt z@KgO#WdeSxU+xFPPxZ^2(+Nv%zr&Vrv*h+W{L~IY5le2rBU}y--Z(A$SyMMbE?Kx- z8;U6eN^iN%=oQX zvja7qpzMB`pul$8jgp?+Zj|&p+f34D$U?aYD>|AWR-LG?E09sns#rufChH_09O`rG zCQb#G?1YTtoEEIv@yisFtIAp>XC$^rK{@W^$NM!diA%A`@uDWWA?r$Oxk|zEBNqdC(Cv}U5bec$$LZB+FD6gn!R8@9FX7<@xdRa= z8TLp)`G_0uY;8(-B4mOSB3Y0qKm=t|j1%5mw9Mh`jf!Fq%oajhs3PD?L#1LOW^;8l6Rr@XGN?ftevrcoMSnPOexs1_}^jh$$v!iI{P@ zR{*$EifhkKN?EgPMzd^FL3&s-#^n_FU8OV$6rfV#vW??hisVk4aUI^>Q;CU`Eg_p( zkW(6V<)R{83ck6>W_K5o?w(6*rt+cKo6BRlp=G)ASh5)s1`Z=DHMx^XilUmT-A%2|6%C=zU0RJBmRw(gFay_6-SyPCORI60ChxV^ z792miNAZ-PM`}=Qt~^|S6vQcF;1R^>cm$82JZU!|ZFlQx-EF9qP$;3B`2yK z@4`xV0^p_eN?d~KSZ;uz{UvZIdsinL2apP8B|!=;xoiwpCGPT|$CWEDCLupAr%2_F z%#9IPgRGfoT$WzYF${9!aw<-)QkrtZ4lO3x#&J2#9#_g?ZBDqGnUKxo+ti$rx`tIN zn*?>3T(_X!B0QuUBRqU_n-CqhG~JC#%Br$z8ia^)N^(5z43-<7I7f5J#Ujd$$(DNz z2>T0qN3|V-gpyfVGSZ{l8}1iZNd zO_d?Cy<9oKRUp?XaC@`O&y930UW|3l8yC0Zv$+xL@Hru&@e$7@7Gs|C${X|9ykgwl zvHViIh!wLcUXA1Sw0Z^ChVK=*QIf*+m zyrZJbB;NOu^SDGm?8W7f6rLRF;5{RM&`*L4~?oP7ejdtcG@P@aoiP+73JiT zshzwcSDPe~gU5&>z#JqFr-o(PcMR1eaEjLWVzLqoei!oLjX`15>T>@2%6klukROEPad;~?hN})BrEQQwijz=~_@Y(DdpXh^@jAN{)>#_@a zXFZ(@aTf4(qnG$~IF1t+i*Vl&L{K+kiBCD)OZ>Vqm-ynS4zJ1+#}`nYjpLPh{k<*X ztO3DIdRnq#vC|BFKe2O-2(cp_i_;Ba%!zzQ6@FP>BHrwsJx2yL*ZSvzP{`Bhoj=>Z z$k9}a*ID{vT(%v+>8tm|h5FjImOkg00F4pb)sRBP!6j_j$b?i&h2Si<*)ai&QwiAO z7yx!!YL3-obrZmCCS2ee#QjEL^U_&sOX~)4FI;aM7{tLuTPG8W9X!$xwy;h#HsQPw zqOQj180hTo?d{7((T!)E`^cnHAp)ww5-tg;7y)ItoVSJ_z4mlNskEz&NtFf! ztKIyq5h6pp5sJe6-oI2*k%d%STrr><@6G5jh0ZMiN=n?&(v>3>mzS;4ZE=7BG!Y|& zcyR!M5fld$(3c}Lk-F^|Ng7$wx=%RoTOr-9G`*lMO)sWP%ZvJewx|cTJRku&IqDOl zp@DUB&}FZhY<~;alfyNmHa{+{wE00gZ9Fa!g93}3%H#gNuD*@{Hvle!Y{J*ZTH7`j zaxB3Gr;dJ6Y<0TY5IV;q$Pl2(#ai^54ojZ6VG~b6!XkvR=&f6pe1ik@u_UfrQey{x z2^ovt%4Lyi9~}Y3=;#NwI5LAxJM`vo5HDm z^8F&{Kb0pj9`KR%CkeiE@(Mj9nJ-E3Oxm`(hQBILl$va6_Vx@(r&MId#Z=kgWG!W+ zh9>dO6|Vp0RO8q+nkX*rhb9z-(JN4F(i68yh1w<+YMWH3ZF-G?EnfuyE-$(YQB!~d ze$fJG-bqwQ()+hkO}5^Tmo)T1n3E1j(1r*RvLO>renv?y%qcP*4r63GaR?-x;si)0 z+G;u13O3!;WCdJLP+yGhR_E{PK10%>6j;(#p%AGRPW*z(*sF2@dj0Xf(L zaVn%nd-nv8{4wpOnTe|s#w`QE%0|B464Rlfi&4~eC6~9wm;Buo# zkt88c^J58l+7DZjY=X4C67;^ggfsWkd*>4L$^opmWI3d7oFM(=QSeE`{GFZ zJ3%jwN;q$LB379oR*;~nB;klj#2ON$u$&-mwgjmpCWs{@h$SS5g(Omzd|MF~`E5Pq z#El!riTgH=6PI!vCob!VyCl$;m7Fz^O3USCeRb}ZcO2JX#N{z@>!0q-@QY{zy=$|# zQDXEiq$H`6C21~867NpZoR%aWo}{@gNxVEsb6k>mdXnb4B=Pnn&3Q@EEKkwva#O^J zQuHRu6unm^MH-(edLw0u-mj9PH&dqQJu4}CLuHEIx00eaRi@~@D=E^qOp(52iu5g0 z#OPA=LctWhLn1|bm??UfM9P^9xuW1Txv;GXM{^B%cA#RTT<1zu|`Tuu_Q@X zN$2$~^cpT(N@>uV6m$tKTw=V`ADiBeXH&mydLNBV{j=%a7T6=;2#)-Mp25fky`x+z zk7NYw7)Y9<*NP?OMZ;K1o zjtryAa2I_5qSxZ}uKZ9zUgl}*8H+cx^^EFWmW_$2IhLSz$tIk4G}4Amf>hEIG-W4f zS)XW5>kh`TENV&4NGsn2E!Prsi4}a6URTz*oL?~`k9>9aB>Ao~@xDfg_zppQVeH`L z{T=HE4;T^0DIuT2HuUqCK2i-(s=(60NiICg(Tf*^X?>8J>lKAhCM zd^px~`S4a>mk%e6E+4)$;PT-F(B;FMy@Zb@$r=!hWOmNrq*pN}s2 z3wgYNKLzCT0315XW1m7nbR5B`R@12l6PldcaD0IN3%$Sryr*su5e3U7t@3w}LTs4m zCRYCXnhpexcM4kW6#qG4hMB`{C&wZmNH8-lssw-M%PzAwZ4itiGbTYSicuR0?a z|4Oss!55l!nD|H;%shV{%nAN7m_dICCcdr=Gv-gitnt^wJj_2A<~;vAm<#-iU@rFe z!aT))3d{ljAk20CQ(RRKMG6&UTocYyO@7OI6X@g-oG2da}{9;6-$vs^8Q8BrrJqiP&xQbjxQmESs; z4eH@Ak5C(7&Q@o`JX$>(=6rQN%wyGsFi%uZgn5#B5=?x%7bd>i3-f#GR+u-aKTtgU zJFzf}wPKj%_#&%EOKV5LJWfO3@paV|Fk7_&nCrClF!5bfnD`T@SPZi_@C}&w zf+oxh0~f-)IB+q{8w0=%{&h>3djh}>eAV(vn6C%khxtL^1I34LP_9%w_<|$q!q*L7 zfccXCXN145zXA8#`rC>JUo0$uIgX7}eEeI4aN}EqFsHF1m?iiIp@)Bg5N47A&ispm zFb`*dGrl!=Busp55N4XCVa{f=VIISdfjOT6=J?v+u`rKg$H6>-odEMB2FT+}g8eYR z%)ScqO!jq{-(ct|z7F_9m^&G;1>fug=CeKQDVV=yzlHfc`xDI93}7$5V7E^3;p=mo zV4iRM3FZd|dTnG3U^u?K7J&Ih^NTQpW)Nn`1kT_KX-6nNd?gJn=ifwwxxieYc=1Iv zv=CoKTZGtU<}#T078<8$(5`}S5G(k~FnrqIU>?Z787sdR%fA*m;+uBc@m0Dz@dddL zP}(x2R`7M;27GDQP!`}DzSrX`=PQ&>rB7L}Y*Nlw{3(0xBBdWwRJXDYn_g>_b&xE3 zlzSAlt#6=DIb%&ne~)sWFz;B~(!WO8vUbhdHOe`nWDmYx%-iSjOjZ2cR&FAD2id#G z-c9yh$`eS}hrfpJC42C7TaUuv@+#Z$?P3Kscfad-1#VuRG#M-(!hIq{MOiBH2k_n8 zU5c-{anUqo*D>?w!dy827??<{QEJKqzQ|$eDOrG=g@A~sxTy;CU%Ye%u)J6creNlU zc*vAuV1MznqW54bm2+WgHK)P6An`8DdyWD}L)pp)OQn5kP*G4i?>(=}k2Iad;1tD| z6gR+}BVqzYZ@Qms4v)-Hah6CmSh}cWYw7tVQ%V-$IkaR&>2qbN(tfxOEm>L8M9)%T zFD<*H7V)cX~%421({7FLjd_hC zxn9O+W@f70DKm33_q+X+YD?y*;h~v5j(<44Wp2+r>ckAU5hJKhKj-;h|Ij)?Y zxjW~UE{98GE_C>8X7k=x@&9KorF+yRH9GysEJU3{nb&e@-7b!MRDM1W=WcgdJZ$d^ z+#LSPaLk#N3(Nc_=a#OKrHqXKe10+NWoQG9+vwTAUBBDC|Mfa`xN~L%{p3PMk6JEn zq$_h*=B|-p`|HnPT;|ElZ)E>C{pP|)mgvMtOvwC-$7jwQnF?VmMu&|K0oQwe?>=x! zrv9vR!sxn&h3sRFb5qr@^q=GzUfvfzDf!s(4s6Gc{qKj4rbgZdhhu(ndoq9eGIGWS8&u4Qvha{3uDYK8PZ`(eRQoNIn%SV!KhnI!5Ty{>$rX3aH#7Hdstn{B5pDV|4jkQj4;{Ka< z=C|(JGJkaY{*ThMp2pG;nX~Q4}oXMTs}s&{S3;CvGS8exYwRMB=e2^ zE81BBW!~Jse4|rmewq38r&((_^q2V?FC!z?&Z8*}F=BsYbUnjEg5oO1a?iv`hD`gd^XpY9M@=^{L~}p6!E$3%#)u~MCNMrdf2|_ z$Q&7d!t|MbIcR47`k4xFWpbYYxPte?xo=oxZUGE1i~qNNe7))XGK(eFIrJ~NniK2T z`@mQydOvM38>pz)wS$QwCi9kL-WXY!ko2aF3?1&5Tv&#QHP<+lHB71=o_@5CuevjD zji#B=DV-2Eq{bS(kvj`cKDUiMb?{!k>zswZOG3-M$kXx}QS1_L;=a*8Ik)nbkCJV0 zS}K2;^BmWwvoqIGJ~69)(w=0Fx<;K2PU7Wcp8a&S?mJcH#(l?qx|qxzpDx|LQf0oo zubAQCIap-F50IopIn02K9km8vRl`%r@5k*W@Nj-}Nl|fk=^`Z{?mgux`3+Au zyxMS8!}Sd}Hayp`qv557+Zyh|bAJPFnJEGFdG!VL_kj=fU+RzPxN){$_n;0$?eF7% z0sfem8m`12H$)mR$2Q=+Q`oq5AzJQgy{qL)1LS}P%o~7@(tz_Q_`SGo>BapeMKP62 za2x4r$(4%1=Fp=Nrm%xMz8d=VZ@yo;N*%p0_+7dhYUl;QN>77k=hn)c)BfU%?`!K)2T1u|9hMr`m_r&yR{25|IoHTa`I`n zA^lJB-;LdB6)jt!ZOi-;q1PewI)q-QXsG*k^s6Ib#7)8O1=gqZ$?U63+%mJVd~A9o7Lx0-wXKvJ~M>6wgf)R z4C%kb|1tdc08R`wY*HUVipOC83ii_(-kVK}+=21B8TI@C^=w8x zKR`X3l>+r~^kNVG&u8vKefOch`}l~X{QGoY<{I6P|1aTw4F5fu`&eP-8a5u7HO_Bl zcA(BK)y97Z{tpAfk7W)ERHLqX{AY+dm!ZzXP~TxjFtfv`$m}qW1U?iZ$0p>k)kiU= zzZBzYtFHjwI^fRm&(A!8zCNLihkHBP18hS{HcGN}i$KGgGWK!fpaAnqjB$KMMa@_|L|F4&sl7Js0uwU|)wawj=M3%rf;( z*bl@17+PXrR89N~;GPV7DlqC0C5;=m4+K0)I&e5(JQM#T;64)nM*N%bZ^obZU>WRx zBR-S4*<7fk!3E|hvz6n(36|q-qzO*&Bc)ooS-D?n@~rc$QPt>WhMB* z_mv*pwO*v0;$7+ensS==O7GRm72@9YRk(M(UAfvf3-_zHi96Ll6nCn3<2LmL%ANj% zKcVdLFTyS8C;Wf)|5bTXJy<_Aq_9-r~vEPt(uz6zbRL z*LkMsH|sZhzM%hD|FLJPe!G6V=Meo){Z7xJOk5_dbm1MZC2B&tzp8Jle^cL5-&WsM z-&6mo{!9Hx{kOVT^JqTJuW4F9)6qFYGqpS|Un|fGwei|yZK`&Nc8vB7?GoJQ{=RmD zcC&Vy_ET-Q_BgH==LL!bC4uTdePBl5@W9N#5rHEEje({>b6{EE!@$1-djlC=(I1tw zr4ckLjHF@V=J7&LeRa*qC;1LS&i^b=@_po*k=$$fEyF6T?zSdbQ>$lWOIlw&?6Hb+ zek)k5SW(Ne8muGnQjfXT!s@dSwtiITdTU8Fh-s|HT2?(_%;$>gF&^u~&+}B5R9_+= ztKD(A>=o6g@B6VmfR(&o)&V}m=@W<8o zA4dGK0dmp%KIr)$uBqZVk87%UF7QqA9p$;mcbxAy z&x5`TeV2HC4lR@?J&!;O<$Z6!_mS@-@4;O2#QOz*t-sbg)t~mKy@zlu5$~Z~1H>Cs z4^R*A#yM~GCb&L^HwjIQa&I-~q23y;N~`kLa^QIDw8ON+y!F}<+7aFc=w>YO9>)2p zcZRk?Tj4!iTdA$|&eXcKZtoFVpVsF+lJiz?V?YgPUYl!KcxOS&qSrf{b6D@3z^Q># zy+;SW9Qd+#Zs03{uXv9MoEbRNJ1_9{z}LO=p?7hkcLC?Q-eUu|25$8(4BQ^L-FsZ% z&cL1CMS-6Me&#(s@Ic@J?_y|Q7~T^&=knYv#4(W6B z3`Ax;=LW38ztU5xVDD(PR^sfcSGZ% z*Lx4Ugk9?W8T$_Vj`u#cm2LIj&v~@>0nVen53>8%{oaSz&)Ltt53`rp%ic%WYwR`e zW9$v~hWA(OP4=euarQQQ+q;MTo&DYW1p9z};C+&P#6I#q#rCqj-d`IKyS+~vKEvnz z4cD^pK4TtZ9^?HjaPJ)aX8`{im07^Ug?O5kMas!a3N!YPlw&YgKcHNp{2aLWW6wCx zMCCnbO082q;uz^U$+O9GF64Mo>g>-fwx&_s;iT;JwCs9G~sI9hmKRAa1Ak=iXB|27AB8G1&VJ zu4{!H(6#bj23@P8ytnv{_AT-Li|bnX7?%rt2XMK-SH!ife5G8=%6B-&Z{N8bzkT23 zx>mj`xvrJ(Dvs;E?{h6H-wn{Is`cIJZ}d0%?&f&!yT?D1e2Q~!0>^~h8a*qE@P{oh@-wNCuxYhr^fu96! z_g?~fc+h`2*GBSR2TI8E@6-$QkpB)nqA&LU78t)$^+Pl17IlKYQ{SbY#Bo|(#&KG0 z;W(|fa-3G%I8Lh_!09*CPOht@u4V_bgVhaOOG(|x^^?@oxFn)(;<&DUmE*d4Cf7q! z&*J(<>eslwk$N_;{}lD>>}%|6>bdOe?Ca_`*~RQqbu*^~^?%vr>~i&d_FeW}_1o+! zc9nVoXyaP-Lbi+TQZL~YqF%}=MBTzEM7<0Y@{oE3*Gy8cFL zS9fxnQE%lmqwWH|T!jD0f@l9oIZ5abZUa@E?wKIyVS}KDv$z(a=K?_qk8>?T&s(5@ z72cWNRy@ah+kwT41>T=7@cs;e_ZM;PLhr=_<8Kuh|5JhSw+oDaSYZ4gIL7IST4Y|7Ot7q5kcHW^U#BhW=fGW_EK;L;vku)6jo6*EICs%QX%C z_i;@_|NUIk(Ek9}H1z+RYa03=64dnzu1n~DgzFOe|14cN~= z)h}|*L3J9}98?eEnuF@$Tys#J$u$SnBe>?EdJ@+hRKLVE2i0YqR@LQPXHf0oI)m!t zTxU>Aa&1A);TtiTs&B|DrHkVVNb_}OLZ62pUZ2{K`)Q;s^f!cAL z8ns278nxp&HEN5w_MdhF*Z$K^;@W@O3h4cPTkF6I;!+ zLP4jzioMb`MttP6{6f)4B(x-Ch3*eEpe8#sH?%OcBwNzi5j>$~+}!sQx(sRBL#so5 zp>?6tLT7}|37seMUBqMX)P3?3x+-*i=*G~F&~2f+(3XdJj?m+wr$x?0HMl2!o+q3aSv>X=4k7%G@PzP`@S!|KxI}~;9Qj;NI7azX zk}o^VZMCZ56n!jp<@mrrs?BG)l zGlq{gjf!h5B$V8Eylo6Mdl!UfuO;&k*XCwo{py+6lrmY-hsVWfRzC~_?0Px%ef9@`9WLy9Nx zzbUw&d}sOY@_T}1urt^b91L#c@xe_z zBs_EUQ}Q`~!Oc`a4fNqZ^Ak?-CwPIhv%2(-j=!{Pf?I-HgjPP+%>PVJBpSRnJf~zv z@Ji_J;|X3{G9x@E{Osr_xGlKN-Ji%+Zl81)73}K?F94 zyd#Wu?E49C3*H-iDEL_LsqnVpPsxnPMUjhw&jz36cH|;=8zT$dKIsm=xDVJ4hxF(4 zg%<~32``pU@QvUbB{kvg;<+Py2f3u*F?WUc`2^nyzK>jY1ov`t#B*RAG#U+@}o*w?@thx8msxcUBZ~(|IBd^o-zv!#Se#RZNPU7Va7KY^+#PF%?g+ zB3fZpG*lc}VOPwpSXfasDr8B-2yd)d7MU8ERMB3sI#L+k8=1TRPeos3;r>0J22PPB z`}b6=<4^c~JlRpt2iSP3}0FNYQ;I>vWoLC>+Y?%h|l;HmsMOm`bSl!_cBo zEL0Pk5tKeRq{dg!dsxuNqzmxQjstXCG^7}{Er7rG(z zUg(L?P53_%+8Np%x~D`F?vFwbh8`6z9`j5|9>QM;y&QTyJTdeZ^1TQ9qjGGdho^-n z;?cteB@={;`wlLdf^aTVToCEQOt=Me5a(OqPoSnU(k|yCF%OCPN6agm9r?jMrErc8oq8sqfi#>b)p4mI%zzTu9O?(jR1 zgbE>hY>Z5bObu^}L`#|?RxX|3-5)y=$Tunc5K8GQ2?4r$F-A{CqL^P^48Ib717q?& zC~-CZ9B#`ZMx>C}1V|R4reGw>YvgsJ7f0efGfgG2hz+`32p2dL=w=zlay3S89XQ1q zk#i#FVcuv0>@F)R(0&@8Hhtyvns9-5rU7fFO`_e_6q`lD60d@An&_6Qs+nmGN5aANv1(m(wLm$Z`L z?&&X2e|`GvA{74VZ-r+T6-z)uRYj|!MKkfFV9&vS0S}Q+(aFVAi&~31i+YL%i#8T*DmuGpanZ?D(UGA@9W2^h z^dig)@P9}=TZ$eldI-KNh40#`Af9&kpDlW^Xj{pYqV2`Em3J5ID!QZSUZi-e=&7P- z5&L5J#o`9w47ZE;Q}jx4u(&AvV$mDI_YRLKdcSCIvA@_TE-aoDT3xXk0-h}y0>_4@mygqEPph*x2mCdNmT=X!Y6aHcv*2f?779Oi~FkPI#1;l#p{Ys zgLxXBGb*oeo+_*OJUr)=oK<{YmBmBD8;hSSzEMcfV$LeQ2$Z*x|GBI9G9FWWm59&s zn&Rt=ug~Q`JkQT_JYBq___pG^itjIexcG6A^J#=WCtS}JzXTk6wfN28*&M@)KMZe- z&MZ;*ACFd&7o8d24Bv#3DV1CKYK)usmsD=$54TG~(Nr{562rfSyI{`V$ zlAU-i!P}$GE!i2J1ONHLd=Oz*;7w3Bl-z{)-6i*wJQ$r*c~8j`C6D6&MCCos1Mcxk z_?42EVZLATOvww54bIl&i<#6JM+bDls zSv&r#%lcrRR(4v|)XE$9Q+7t#88FY`e>~@vT~v8PWF2B|;!oLSWtVXi|EnkjcG>l1 zH&*Vf+*!7Ro5FP)*>_d$cAm2PrK{}W>9MlM%ie_fblI!od9Li$=`sE|Hg}c1B*Pq& zr$jjNafp?@%b_NrH)*>AJ8ttZX>u2bb=il}XJrZr`N&08OUgCOuh*C7iM^&Nd_O93 zedPM+`+Qd_`hMho>@VF9a|YjUDvxoO@Yjg2CLUWpuY3{qjGjRF9^Wi%_{i8x|D8GsC-$bXC--G>|2ct8=&liU`R$W&91pd!NPv%cm zLo|hbniu#^4S3tMsw2za3T`ZaFPf?<{4@{W*>Rin^a9Y@uFBVgiz~Nczh_#owek`!-$YY@F{B;rwe$pgqBHrP zOYm&i*mDVP4qkv=iz|cIVn1Pfa98jSXC=?q?7e~Eg}=h6D6E)-)t$4N zbFc80R4n7`xQafkgs|$tb56y16&E?{99rXGeM768vDY_zRU_6ou(_MBahmw*Cb}2W z-A1f&&c$;&Ryya4wGLn3$o0-y2ss~XmecXSM7X)1hsssZ%b~YIS3m~40qdKa;O48J zk6^zLx<{;ic>G(TXZY#|Vcg9h9{M`|?}a|X+DGSd8JA8fuZYg9+$#CvWX@}D0*BZw zWZH>n=fU`Iibk;3iB#F)MC3!PMrLB2@f21UklHGhs$h6=Rgjm2)j@03+;Askl%C2% zAwxj27tf|JMku_wa%=bk{ts`7rueFA_=CB88((2nP7!OYhoW=Bk3m{}s&WRTFDcP; znVzpoxm53mWbVlGMVO|_O68%IC6%GdSY=J+jLN3US(Wo9ZL3^VxwLXc z<;u$L%6|CP3knrwRGwaWR^_>s=YRZo37O@=%10}osC=gK1@NA!l`mH`VAthlf7ep6>v$aM$qxfEHbYpZA zQk)&#ENGhZ_A8^;Mz?`Jw?}tH?}*-8wIupb^s(qu(Pt-Z=QCvVmFOGMcR*UQ!iC7RU+zT>i3jN z^=kEMC8=JcUaweqJMs-mow`lkrqru9<6d_I?%)1cnSndFcPca0yVbju6u*Vb?|G|x zl%sG1_i1H5ZsGo3S)l$w{eyCx`m*|pvPgYZ{flw}ZsfkNoTUCsQv8XPva*riy;c54Yt$AfU)GM-7AxP<`n5Ba|JBaMTb8fJEs67#?`z-IE>LdJF4itl zwrN|m?^kz2o;JEs>TRaDN%7t z{17otg<_m)FitZtDu?4O)(7GK^GuBB5g556F>;N{WVH$7_eG4Kt<vf(s41;OpG)WBh4_zUxQ}KIqEsUn{(A~!u>6bx=)Py z6pZ?1N{M>8dbu*?|FQQTa8eX$+<$ebp6(6gB`1|dR1`!E2q-AKW=?|XJl7l+&-3)e zGk~rU!{{ogtca+G;u;56F|DGfo}!qzQw$hRMGh6SD5prj-{+Yfc4h-X@b2FC|DXB% zo_VIaQdiYe^*q(xPuuBsI{c0HM$^X5urnApH!&vK=$L5Bn3xHFtG$)*+w5&7-_Bx` zL^?_$9VI-;VN+&T?$e&lxzyMi6Eaq6DeE!&nAwthwjYO=5#uppUf?N;`F1`dl{>h3 z4&!C}G9j6-h#zoV4z?GNxj*;PE1!9n%+A5c;5UTq&&VF2BfFT9{b!!`IRjtf-GeiOv*6DT&W4{5On{#lOf*A- zbAofspx|6&z(oeQo09v|FJ(d%uj8Fn9)_zt^h6%6HG{cl{W`M~Qc=ax>yeHADjV%o zHhQaU^i|m?l6%>CzKOfpp&}ch%0`H641wp~c9YND?YkRa<;3Ui_8(0m@l#@@vE1kW zvuVM-?yF2eB2L7n1^2w;FI%N34=H-l6v`d&CK0|8zG`g9GdA%52>)R^hOZ-C7U^nj z@}f3T8`Cms8?`lCMD3z>@I_G(e0yZCrOKW~_WGE7?xWwr_$q;EKi;8AU@MhC9|^o( zCD7x}&SOnWmBZ~+4ihSeeN_%ysvLScQ-&&gp30u5vR9X_N3G zht^KElTCk>#&#-=-BlXfsWf(1Ic#lZR&K4b*IH#SR7o4ElIE$TZE5dkZg!Bj$H-G8 zZ7ZFj9hEn`4)T_tC2tY(wwUL=KDKyZ&yu&UDsSCX-ny#1byInB?Kk#YVv5vRyWB2^ z7uj>|3TFMZ1iCg3@G-7(XahHJ;YAwVzy|mLSD9?9GTBOH(yC1MQke`@CVQz&wpE#I zr83z=WztjM{R31o^Hef7Q_0*_WwMLPWS+|85S2;pTSF%Eg3-Zf(;*m(m;VkblfFu0 zXO%-=<#4dd;f^YYzRIDma=5L^Vf!E%T!GA2@(zG4R2n-4*96xvYlut^QkmQ#m>Ntq z+o&|QQEA*%rLkYa;mId2QJCP_!bGb?YvZakCR7>|Dvb%1#!#ivOB|Fq$P84O^i(Dz zmC0a@GMS$xlab0~pfVY$OtuSO3whR5B{K-$2;VS)%4fdHXR*rX<|?1XDxaIHeD+rP z40LTwsAO7Q8xty-Embn{9RKshw1ngQp8HuHN4(%UKVOjGjRQZQm-vtnc_!X*iZ%Q? z<@1#n?>{^hE7ZM9-pJrQ#SHJb9&@$hY%U|k=^Ze4IdACE2kR*B2yi+|DyO}KxD(Mc zgmxihp~hM0RaQ z^-fS)A=Lg&s4Gw2JKn#v-0g&ScybonRYDkJ@QJN8fNjSiAvimeNS@p3YGq>A*Y$SS}W>r7HiF4l-iobLYYO$hgno8nle;J zk<&xdmMA?|>269V3Uzo!nVOs?G{9R3slHX-7n(R(=`~8v((nhA@-#N({y}=*ex*lG zRXSCv=A4)&yw&)YXRj%xg-~y2rN0sC^Sn0n1EtR?U9435%NL(tyz@nLfH1Uwcx2LgX)N6QuCyj!>RD8B6%x!uu06ypK?uo@a(@oL)+I5bEEe^jW3pRL|?tB|_bF zucamKdyUgt!~djw8=A+-)p^M~UU=_Zp)Q^R;BQizmLQFf{X;nK0TQ~mQ2#ik=Lq$-QL1U(8sXi0 z_2~9WHNH)c?RO-^>KS2INIu(X$TLFSIZ9tus#5If%-}DQkU;xAI7N8uAEBQ{A-+Jdw_XkI@`X66*KU5Y5x?uOTHu(GrEesZ_^+)wA<|&=5Ue zucz=xGSt0VsHfw>)qZ!!XtfS>5(?ZQs4Zln20HyCMeOah`wDNP6PnYt5hTJLh zhVy~aCzQ5V`sB~(woa|^?hP99meP4b&C;K-BHgEjnxz_km(l@B-&gvwQ1@u%=PIAh z{{i9sm$Xd=$?RmW72ZEksJ&8YwbDD4-mLT*rIkvrh<_&LWy+tXRObPIr1EDd)v?FU zjpR8|X_ZnPUG_rF;X(;hTX?hInD023f5T}EN@2>n`l>SLWw0*on<+Xj>(^nlp z4OMa-oekXI>Cp*7yjuC3}+%UtcAqpRdkiF4t9Ox&cj zN@(~dbY()u?T_J;8h#k%4i~+Gn3eFog!gt3>ffUDS*3R?eO{=yM5rB-AT4yNPziBs z^=O*}WqEBR-2GldKGdUS8d4@l-3gKwn&zd36ScMzw1#JDs-K103Z=Jc$WuyJ3MDPI zbx&3PR4wr;J=#L~7E+eiLQ7ex<*wASR_ZwpmYDu-N+&3tA~Y~cietGS6i46&c*peb6cvp zEtTB7n>6hMLhYtX_fXnb>E1&9bA&oeHRq+0v$u_ecr)t4rBAQa*0@qa+_!}H+vw45 zn(Acb#|iZw)|e01wIOHc6>3PKw%)f|^KUhzNXshHdKPK?BI!G?y_^Nlev+H7HM9>2 zZ{Ja>J!s$8quUAfisan!sQ~X*O3qN)({HPBhH3az4WFtlJXLElUBfkJ_a;4hlZNYA zyLW5I-CC<|8uJSsEnjH;ztDWX&^TX8ZM~Kn=Vz^XZwdE%OMIw|&u{A}A?`BezmS;l z66Y;R8=R;#t)I`-+?Hwn%e0lwmk^%blXJXFbGS>7?jMAN?3dVA=`ljZ#)NJqR4vev zVu8Act3>Z7cBMB(!o4YCU3ybAe3IsKk>+zzLh`vtVnQXii!`^3G`EY@o=vygkHLE! zZLRcJJ$kIhKUU)(r{x~2xgD$a?0xJ{I?imR2P>VG<`WAEzfY)py5?}Y+QO%&>+j2G zKU?bQw3f4mioCSe9!Xol9kf>MrCjW2>g-&s=k>=l)jWTrIjH11Dzi?yopszg?ImY# zro{1PY0J#gR1=lr1%^7Dru8{Z&+ar0KTXf>G}%LP)7EsY*1T4a)@tb&D&0y;e_oC{ z&ucxO*Eqv9{&3~D*EomU6Nqz?@*@(w>WOZ|_Ra8LWfJ4TMe%NR)a+GwrAXwCUV<$tgFoTz!8sHL1JN4+frRuFfd z%ECPDg*`O>9ukvhx*4TjT0*zgahsm~?ib#^sdTQ=MS66F@+v`IPvPCyHT>!{ulc{A zA*CAfn9_L~qPrR1a^bxTHT-R*pJ+&=`~zcG8gBh59-g-TgJ>G~1QZH`B82RCTUvH)zbal+F|Cwp9LgrDaO1 zg_`97JG;)?8uGGGcbxKbmA`hc^S)YiF$qb~~YoT~g2$`5mS zpP{orc=Mji>|_?Zhe&OOcW=-*Zz-K8)NQH!>q^U%Rtq)Doj1tmZ4G%@s5?&ixk}$t zdcV?@lC$%s(#1-bD811eLih}&=P12O>13rhYA>YMxXHp>4YzaB@%5LRrL2pUUZPazI(v@tX9-15W3Gdqsq`$N5{||t ze3{Y-8fQY9*Hot}zfx1J6dtWZXg6J<9u}UpUTBfdrA298(^d-aPOYOdpWmeX-AcdE zJim~bteDgaN_@Y!ru|mqEYmp4l)p4R6>6YR8y7x zPgX18TPv@#pL?vvKUU)(EAd&0M5a#HJ=@k&E^CdH(ppMk-XLez2+4n<($lou)0D3j z$_%em=a%8hkC6RxW^z_QW^dW!JxL` zxff}iizJ*ig0_W9S?#r~30nV6wDmp_>X#}%Rq3}v=`X1Jw$gb@7ijo}LTO<+dW_a{ zyq48o>1j%bD?LG|x0CX(YbuT7?5wrAO(+s1XY@x6IapfQYa#9F6>8tzq;31Wp4V`p z&Inxx+Y5E?(m2;DeIiYDd_JlC7ry8!=@q|9bEwjmxk`E64|n(0JpZWie;8g@amM{*Ao=l*T>pX^2Deq@IuQ$K@`zjgZH(a@N75;c}xEcxvi zAEAu!&t^FJm3KPHd+PLevAo4nQ)fpp@(#RocwCV=5aVAl!#DoLgZC%tci^RurQd|t zXMJ5PD9MO{9!BeM=4ys&?n<5699me%-L zQ~jDw7$@VZ9Ix`dn~v8^Xtzu_eo34B)W0zy(~3<-O9$5VOm2+q)@*77WZs)9sp{V4 zSzYfbJ(m5v)kl=OR|6#MWpF2uy`m<(KQ~pH#+1G4oKLO?{ifamS{Hpl`nSG*4a=3c z$Wo{7>GyHPZ{khWFtSte;ql(o$I@FL)EAwpVO$pfQ$l$!sO&ngewVC-5&DI^Qqezq;6_V}{|^ z#>>+Gcq4%9P8zc{X}=aw;(O_1P@CrJ+Op;9k-x=iZgo`B&XxBR)TLGT^II&}lnuW#~ooy*@`-;A^4%Ny|0t(G1!*~fkbzKL^+ zlN-65iFNsn+{pPhmt7O*loPcl^A@8MsqGUl)+0SL$C=INn5gbweWKzR7tnk4@_h%yye) zW{Y%MnUl0^>dU8Yjz}MCKnLhtd7p%GP8H1R-Lqq4G?VNwVscKB|2ls*YZxtYg z^6eSVj;rIt;qdG%=~m5JD%M~b{3DWOmVcmIxW5hO(k{Vu*7sy(Y`-zWOCD*g+J`yj!n04(kUAtIsnrMY| zUbWP0a%Lrt`$+~uolTX~wT}?iv3PoBZp!=;CfCa9KACrG&?l7I+-KEinIq|b%+4Wm zWX-<~-({4o$wR-xvedU zne&d$WYSnij&CK#-!)!?b!P4Do5^)eznPg~O>vq!mTkS(kC4o49S^RrUH#EaKDr{M zXQzrx*#FvZwmp%lTm3r=o3x-a(Tq8)snqp{o92GWTNHD1s;^&e_?rIZuFY$Rxkml# z*ORB_>nD35O@A88Skv*=7TSCXYfHK21Yt~2JLEii)=l$AE?iSRituLWI zZ0%f532Tp@6GP^N%)BONo|z*gQhbzYiT+b(32TVX3-uZ3$YO6IlSBQHdM-Q1`cUC= z=bonYfw)h0>2;~o`d)*Y|~O%<>Sa^D#=clwZFHSQTr(S=(_RE)w_OwZyoYki^S4KIU`Y4-t_)m z!}G>M6-lYemht*^IJYL59l+es^uO%2o%~cUPRm%Xr0H8J|52BQUx^v-AOEY-JLOcK zIF@6}HC6Hkgk|<2uxS1xpSp8eTUqHHON~{~IBrujQdX>ztkhY-|6NwcpK7G^==gM9 z;*nU^XEdx=X52E%*L~{75+gYK6OYin)4}97TEelL`DE_{=>H0#@`;a%XU2!dBhvrU zAxeFrt3*EP>L>rxpT-t-=1AS~92t`^%2*xNSc-ntv7B4Ajry;-8H+;NY}A6*KQk?V z4fWF;<0l(t96wvXXVzGraz;W) ze=_4YlS6LAhX2-{s?j_yS*+0xkO=W>O4*;R*BW(~ksa80q3*Lvgt|}N{$qaTzu5wA zfz&O%x}|sQ;=5KKhlyW{f1CYZcy=}yLDyr2$%=cJsV~1SW8QSQPM@q?8pc1UVZeX* zzm~s-`emw<*$*zt1T^?F9D z4r|^fT(7*lW#=h;_O;L4W9h3Ix@YoJgCp$wHvTkK4^6H8DAzR_rm4GL(lD6+P36@@ zv}S^upUb(9`e^*JT$RmO7VH?+&0-?!Nb`4@OtbU=wMaBqxmJ1-ISiIqTmz`c#LoQ6 z9TW{eSejh#k@IhMMy3R6_Go?StMh0=-^*Q1;tO~~`@Oo8E>EZMS@l^)Z-_4^-wF*> z!ja5OrP5b-jMU_iKBtaZ=UtbO5)$=!#4idT*RFa6x~6mL9=}M<{#BoHHP`5zxCW4O z{Ug1j8}r0TykvE%Iwo`9M#J!i|24Iq?W*^hIHxZg#+U!=xb`)bbZucWXZ6%bCp3!s zC?ON;LM2|>rbvgf&SpMNmgZR()~F>jao6zM(C(8GdS=D1uipuEwUU}}r6?;-!+$x4 zS4*kNpb4Qjf~ zx*2EzDVw=Bhjf;sA2d$SO!rR-t-Cj;L4?dZ)tkFQw0ibzkgoCH_{`j}+%@UfZuMU~ z|EzQSB{NV~awAVIWA-ybqT|GU3+dkVEu!%Xj@5$Gz~bgk?60-BgDDjKD!pNAVA zTEBoy?be(s{+rlMx+B87)#3Ea)|94k3{9D|eAetnGQxO$5&Cx+_f zjcbt;hdr_#Sd<45ZGrnyWij*1mu_lf7mkJP7?60-iiBaz}yGI7(tS^2C!5EC=L z8!VHcreb8G#-C@n+~4@6^#Az5^zW*fad9R_?vA&F$}!zhXs}nANs;~)ZMpvLVs@f( zwCCKo4gb}bUYA#0{p#a2jFEMug0hm_5md;v8Ikis>hY(>vsuHChW|4;#yQqWI<(C|hVb=R$wb&pjya}Ul=u?}~!XGhQBSN%P`>z^ICZeuMw#fI@|%{TkbZsh6R z4a@WYhSW{&@HVJ;+Rkq{8)PEY-!GO4k>CHqsJt+{{0-ta-=NgZBwpLyJ=$XJByru2 z_p8|&ul4I$bS8Q+cgn4Q9$hlY z|0}=i)KCAFn*H)Z*V+f^anX3C{G~;1yqtb%4c0B)y3FP4meYSS)_;1X|8>ueC&4C4 z3GCue6i%P$)R5-NO~aAeSxxs!`Qz@Db%ao+KWbJ0_|25XJF2Buk^Ua=r z8}HYr_XcxQ{4e}V?_kugYPnYP#=Fn*f8ku$yAD&=JH>`2DEZ~d8(+n2Ca(=BqnRB4 zhl1mO=TxQ>{{+9rr}f%1&AMBypmFTR_vYlp`G2~fa?Z5*KWpy07R@KjI?^qRUk7$A zy|NBD{QpsYQ42I7Ar14%USZS6xG$o~dp;Vb{NMdwe@+=LE=}L>DRs`?8%!S;{ZKgW z-AJzetTK77J!U3Gb31}-%jv(?58GsF{-6JCd?l&A4)N;sAs$p8`s;IR>!)A82LI_2 z{%2?Gjj%rHz2(d0ic0-8A>p#0ENyznvFTo@zc$nK@&80ne{1-&_G|DOL-&d6ve}_gb{!gq zG`7wg##qyTN!`>vOKVE=UpjW&f2rJcE%sNhUs{{_e``%_PD5MQM*lVAWv&r!m=CmH zvxaNUTkP)UY;U=zEOTF3Zk(q7W#2=V&Q(&UCCaXCd2WY_STpcu<=;#=F8pR>%H;v&dn*Kx#Wg!_`mp;4bS6$ zA%}I4&Go3}T6Ne~rr&yGw?R?Y^i0<;$+)R|bACxa8<1v=zEqpdckRAZn@uVQnwojn zm>~DyT4(m$=o|mv+I83slY!j!$^Ex6&L)08Cl`5od7WnFoO|J$d*<1g&YF8V$Hw_~ z=85s<(`wRR=6^5eoc?Qn@FBxG6tk;WKXdUsf9~2u?HYz;{m*$yv8g#ia?k!`rOgh` z;>9a+{Lid_b!GdkYs7Vp*LXBH4q4Z{)-B%pYVm8*VAtm|dl#)*|Z->ml&KdZe} znR-sEwf1>#gKMAJBiZ1L)+K{@MNX`iIsY2{srTlc<;OewT?P$Oq`i041=h`b_4i2e zr06=?PYp8t)&Azp<-b}fzbxbCoy2yVp2AzqJae6S!F+1wI(g1(=6z?Odw_GNdl26( z-9z|p2`^=x=&+wM{xA?QX&;4rue(zg?Z^&zJJNsp} ztL^R|Z8x`@^PaGNc3b~=JJ1gF$Jw3iPX38@u-(P~y&Z0c`+u~hb}#=FyN}(+A8+@w zBmL9uI6KZi!~Wj>-apg+!T!NN%bsFS@z1vB+bjGDcB-A~Ut*`(oBT`dE%p|_($2KA z{HtuWt@f|6ciKDsYi-KT_OG)w_I|(0K5QTNr`ad$6aLNiY5NTCZGFKm@MqeEcAJ4-)%pzANVP|*e>yB+okq1|9<<0UEx1ue+sPsR1gL&{Fj1OL2LiDphM8jUl{ZW zw)Wo*`UM00kAm%ko&0|VI|sx3&w|~95&k#9e!+hJcfqJ&l)pR}6O8e{4-N<>_&)^a z1{c^K!NtKPwpTDam~A&tgoy&%C($#}%Wj?6KC!(WkQkI0WVcHUN$hS1CJss*%o}9O z5@mLm#HWc*?XHPsi4}HO;>Xa~{X#F?(~b>ChBw)1;Vt29c3GGTYwXwI1K}LIJgg0C z?GNGH@F}|@d?tL}{v6H^7X)7TkMQ*%FZ?WA78FLj93W^JxlxOtRn#it%%ZMQ*PuA+ z8TAZ$M_WW&1e-@YL^}k1qG8dnV2h|EDhalX_K5Zfwu(kaV}riYq0ym1zo;xK3;IVV zM}G{qjZTeD4YrFWMi&JGqe)RR7#dYZmBH@O)zQ_#h-gYQH7JR$kER8CM>j?@f_--zZ9ENX(;bu?X!?%|i!&{lg8r}iMTba&=UT7|bUdFepxty7qR z=aAHz`tf*hhJ#kf?ve9gIR1ohA!pnm{0h2U=ENs9p*VL%$80| zryYEeQ)F5??Vau6cW`zvU7a1BVerFw|G4k`*_jA`j&m-2g+r~J%bd$ik&|?i@K-q3 zo3_q0XBzws&P?*T&AA;~?L229XP)zd>E_IL7MM+)zw@racFvp564S!@%vlEg()kkl zmGh(N?EK_*HVLOSwjK>Ydcd_rDyU*zaZ?o05mxUX>Z@9yi+g)Z+|WZrxi`kwoq>EXWb@@7i+WA|gy zF5xZJj{BASE&O-xO88Z7Y&_3+jtM>2i{SHkgLYRh-)jfo-rL)_-ag*G@cViD@eZ(& z-v02TywQY@;r-N}cZhe03B2EW$G{)&jW-3}>E54-$y`kMMDG&lrQT#hrg+y;%2aQv zDf6nl`{5t(9w60g-fJe$d)<58SZ|^C2K<}eTV@mH?tel*@D`gM-pAe#gs<>c5NDo7EU6Cg zPd2XqNB@t;^H1?lF^Bl4`lp&9{-69mnF9Yb|1{HG)*<-Q{R;T={PRq?f4+Y`@mZNn zds&&FtW3~q|8D3#{yk=QKjo)P;LrB&C*}kG1LQf!pF>#>`VSKRkUx*`=lvH5neWdx zNBA%LADKdbvA@{l`5*fqo8S0L{H4VC#Q%i&pZcGgt^CjYWu}M!x&Jw-zVN^0=y(2i z99{1Jz|j>xW66pen7}&LF|Kv3XL?xQ`h@c_p$%+cM%jc7O~OVtpYQ@(K>R{mXjH$JHpQ~~!Vk7XphN9Yv$NgB?qW)1B{qB6-Ry2=DDU$wA-vRkJG553knPcooJJOWc6YYs+b9<6K33{?U8OoY%TCrwdWZLk~ z&Pni>*h@?&-r{*F{AKoX!jm=$e}%n*@X2RJ->>bd%>|M~5O_^iuY&)B?uCX;{ zq`lwXPq`1<$0+x4`?%R(^aDcB4+wd|zF-E}`F6h9+P-LCGTYdf?aPF`VqYQTRlC4! zA=(2x+Joth_ORIWv>)4#$zh3ILj0w6sTpQJ;r)ff?Wgur_|NQT@L$-kIqPqDr*bR% zo&AoomfPj<-`gJuUtw3k|72Ie$AK}e0w-`xr@#$dcrWlx8-`2(9|n=xDahj;#@h!4 zK>=|JgF>@M&?0DIiqTYB!M6@t6Q@JafjAv`V`BfHYtYq{1l@vehIbP3R>I$*$MiA% zf-QK9VV|IH(AOLkY#nS3zfG_W;e5?+gZ@E(b6Bu#Fo2Nlf`MjRG@k8=vqP{0{Eoqn z@H+)N!4C=snIqAJb~eWaLxLe@?_g*!)Epn|66|752zCv2C1lTFFSBbfIv8yR2V;Y= z&;x=4&4}Qj;2?8Aa7b{9$q!Bq{%kr1X9j1PU4jY01o(4;bIj4AKf$9vK`#w1H3y3p zWyU6)gky>lg}fQGRiag*wP_=|l<6h96m&>p2y|#-7gLCX@bs|p0WIyM?=( zcHxMy)U*iq2=_Fd(E`VqL^w7)fV2mOzcX%lSa_J}8OJ8D3>J39k+(n;zkm@LEEy3#XbcVO4k|X=j8p$p5DBHu6k`Dd_BQHfMTYcpv9j z6V_1w2f_ykpA*g@1Z|a6bHllm_(b?5{8Qmm@Xv(LnD*h{!e`;13+KTUgs+;O;ev1h{6E5fm_gxd;cKQ<_@4+8G3Sbva!)0BidZ_ zWf2s%e4FeLZoeMbpUV#^^?l&WL8fqkltZMYmIj>ZqDJ+!5Uc ze@}D|^xo)RNC8@)^TCz15U=h0Wx`RnLw_-~@`s0li~aYUy#Jw>NCy+o%s zokXWMy+o%s+lfwZLUj7krYL_*{up#@*WCooehAC$Q1ttR>i0$H_oI00*J!>zn*JF0 zvF3O1hnX_d-W-nJpFr!s1bQjD{y=p7>$n$dD&G#~E_1gD%sqSy&Aog*)&9E~(fhlp z#@|hK{cfu3cT+9Do9g!=`h7>!(dp!DYI-=EIh&!84@0w$(CkN`&6hYO=1`~984rIt zx_&}+{jJdT&mrVoH2z}M_&cb^zn5zK9nkoz(BrR1?=Molza4u2?WPcozuJV(9nKx* zcg~&8U*Vr}o;BM#&tVCKY6)zqmcSNR03xIKj^kt1)jT`%Lta;3scPA#G&R0_el3>(_XCtM|LkvFLp03hbG-5 z`CQ>%VfIj~U=OT7PY zAnzb@IM_Rw5V0#$|4d_pnCVv%{2!4lUM5|2k`=&@VKJI%`DikS(!8`kEqtYkwPJ ziZ!yUS|eT68rcPFWT5HjZ;wqR`R}55($dsa8jkS{=u!)p4X+9j(;faMZf!qSi$hwJy4-bg@_g?TSCBUC~XA~|Mve4|D*pS{7?Q*@GJe50mn$(h+N9Ypjt@r0r}w6CyTAzS<;5sZBCWZIY9)N&1=N zZGSA2{bY9#Em`c7KdODQkJ=}Ds(sR1?UNF&VQafZjwL=D}9nudwGJWQ1BH!_^w;sn*CrYK?5K*2qC>jf_xhWVl)*gVh@8t=7ozu|u{n zI|N$>TbhxDn}_X@pD4hJ=$Y6QezQa`c(F$M zt2NSJt&#p}jcl*hNN?HYHG8Wy(p#;OO|eFnnU0Ci6Q7$Ni7&BCI;dsR4$I_g(;3U; zJL4vnW1r-yebNg1WCiw#SSJ0{GTBBglObxE3{uNvh*~Ct)H2yF%Q7ia%cMJ&NlUcw zR$*JLh;~>h1Jz2|RPB>)Az#xm>>l<&*UwlfTbZrGzSt@q)K+Pywn`zk%3v&nA>k0S zZ8#LWB~-g*OSN0JP`jn8+ARfYw``_%i;LZIAeO)(*e#CQExpuk*+lIYSM8Qa?UugS zEyrUEWh|C*EFZC0Tr8F|NP8w0OP*RRt+Ff@Pc4>wwOIP7#j?3tEct4&v{#G8Q;Q|S zV!6rm3TI-s1ZuY=)NbjPWw&(AvRE9oSX{MOobaz$EUsECU9v2eE{!afoz-ILrxwdL zYO(ZFi=|X8mNsg!Y{L%yXPl{6EPJTMvMCmeYdWH0u!|J2U1U0__0kUOC1E;az2u=) z=VQaR)Cx>zsUMQx%sW~kaQ2S@FqcJN}!92~WeI>3uPZbZ*+uP{?rP5zsy$PnmQ2?yOQx$@GF`cn zfX#_LQ%#-ki0-6K?!unwtoDqPWzXcRJ>#f7lc)Afe)MScsM(rp4v&#aY#T>y8&_=` zCwdm!##P&9bG2<8Y?~L%z-T@ePDizH^5yCTWi5+7r{-Tr--PEcsTPdTG4s8q7~_H$H$6RbbL&{nUKc6`KLDZ zEttE0-*(S76~Ay*6W>6?(zL1LtHbiAt;@GC*kj(v^9zIg9qM~Me}a75maa?sHN`17 zz3w}=;PiISwsI;{VH2qEIli#bp1=5_< zt9@CfcI}SH@6|*<(aJ@Ai~6pq9X9+}!Rgs~YD9Q(p*DY&^2>T>-JkW&bDb{ zysaKjYdrQ8bM{k(PvzI-ekH8n^iDg=Z*$**)8z=`?bh_TtEc@JcfGjayZmtz`b5R``zoV;60GzXjXm zeV9k;ymy-Vw!XDsSpJjEeOpXsh3l2+vo2-y&pNcD#HY;l{I+~1-TTr4lzFj?cKPbR zUP1*jT7+x;1#Pk_%@@qgTbj2NIg)bW@kInmz-vap- zo+jV?{%P8;#byKZe$4wZpNlf!s&t(EPdA?+anfJPBewD<6#h0J6x>~KH}n$yepv8f zal8Do{96UvFOz)ROiq`QDW}b{gDxcfRrzh|zMr;p3r7DM-%PpkTkxHHDfKE^VD-1K zy46vPGUgN+cZDNF#yAhoLe6aU*=6Z5X-y(WV;~R7CH-x%vc4?iyy2Qw_)dDol9ejG z4#~=snVq!vwI?M<=|TB2|1v80GDl`+Nf{&QQtOV*&BV_9rpJ?<72~GyxUG}&v^9~q-hN_>$V`OWly!6mfzhiE5FwJl>MzdPS|+PPcr z$=Dph8C*$Dy@VEykk*oKVKrsFoWEt!WG!`C{+6mqG7oT+HN7xs@vzhgN*?mn`drLE zW-kq6Cd#U5x(%hy)9AZu;?%WV;X8b_?v%;q?fP?QjCY|N7$!$S90ygaV@DTxIgH& zIOWVDSIK2Gxk$YJ#2X>`Id8>P?gGxhBbU;;@bTO(a$8(MstW2^%hmY0@~NHtBh2zX z3;RCL0(hCcwC0|9-t6OkZU#i1%|6C=ALI;Z4eoR)v76v?*XMYN9OoR0iBn>H`$9b4 zz8sHF{0w4h=li@zI;+H##;G7q1#v2fQ$d{8@wNWYcoApu&u9y3 zFk0J0;%F`t1riMv9cWs-xbKi$6JJMRxKJ_h<4lQOQgXSJ8qJ}P#`^=}S2?G0 zc1~N9rmkkTH)pvluF)C>w3zhQVYJ~)LdP>&s)8Px+l`Ee%$RsTF6U@1XI{oVQ2BAn z>qvZQ``hTbkK+_a%Sl_2j=@>xoDWBJG)v3rxkb_j_FeLLkF@X02#;$MKgKh|m%z(F zMkrTH%p__!iBUC)ex1Y}Rg>tqN!%$lDLfh+VGal`$)Mo+pN1{S6t_uCQDryB< z)2ETP!6|VvryX{o?e+$l_K0e59PdguY%oL&rjMWX;;t!w2#TBUM1RcGL{|( zbF~$9Oi{NIYVZ;DE1`ZRIk9DQW@4+1NNkalCSzykeVUBdb&kEdCe7yEuqLA#92D7tK1Zt%gjjb0UXJdtC8+J@Cx`lU17n zyEaC$2R4%H%_B8cl2l1jB}tVeRgzRmQYA^1Bvq1BNm3(e<@_-Q=bYMiaY&3S?rGL{iTcdHz`PFiMwVYoq=T~c5NopA(Iir7l za%fEpO_4c(^PR%^PT_o~aK2MG-zl8$6wY@F=Q~B_2hMql%p9Ee6wZ5!%&?sM6yCym z0OP8RE4*idJHfqXDz^koBG;+TPGBh51zc{Xx{oq$>edx^K`bp>!ks2lO&cU)rawKd z^=E)vz+V9GP4;gE$hAKURD(Ofo!~BTx6A_O^6(kjPflJiV* zo=MI#$$2I@&m`xWIFfg7;?lZ}KCb`el+*9P9BKH)zr^r1; z?kRFlk$Z~VQ{Bp>ed(I9g~NEi{f68b=F_qlMD?!tMOl=?s)Ij+PonOO2zY z#!<>RT523EHI9}VM@x;PrN;g8b3vM=x7YDpbnfcR{B?X><#hlZ!8L&1@}|c9JnHTJ zE3Wlode#9hNW}O0A($4Ip>HJp*{hbTF38iQ$n|LZA*=VtaT)Sm#+sMpTngd>N}B4n zjrVXn$A5PBWyU!O{1zMujsYhCq{pp|AJo~jdz|#fko$qGu~#!|qh*q7mHij|vbdl9 z4*j4`FNuaxN>|k{HiB$q<|WlWvgHK*D@RtkNj)3s1*gO(*o(m=a4ATF`@s|7W3ZHS z_!KMy-|+uiupF!aaeP8xfD0@L;u8{upap0dpAfzlpJ2K-TH{WM=TPDtN}NN9b0~2R zCC;J5IStmnIg~hu5_yUOtN?L5hZ5&d;v7nxLy2=T>mnu3q2xJ~Jcp9!aK}%>)%BEk z1|`p+Ptn-6;||Y(AWL)O9>4+Ip*Mg#?FN`l zHrC8d4>hlmW%YlPGyG;w9;*)e7QK;j3PB6zt__`8-etZ@TO2ZPHP$UlM z>8(wyLNlP|O^%_hHu{?PE^FR_Fwwq7e&8MwKCw^j%S;<&> zDIU$38Xdj@|Ei9y(c$a-z7ePLn1{GmQLKxNu|hXBB4h_gR_)BFs9(KhM3k-5h+u`! z9tqm>Ikk4*i*IgLxA=f#AA*m-Vj#N4s`y^?jeC9Gxq{AdFFMD)z6X3@K>(W2LHy6+ zoBd_+&DI4T$edmMS*_Md!mHz(!^z;f_}*}8d~Y-_zB#w8e?hH9ORA;TwbZ(nTGvwR zT54TOt!t@uEw!#ibE@^TG^bx!>so4EtF_)HXBN7QnIPBp8`a46`=v9{bId~XvSy@L zR?kYKuu?~1rH;Z%9fgHDN@gi6)W$Q_@#)zLi**$Kk+Ln;%dp3CYhJQJHGj&SmNSn& zhaEUi?ZNbX`U-sAoJ#FWsC@~wFQN8gD@yIvBF>p-k5{{K6tyog{TtMNUD|#9tk|b% z&umM!zWvprWrrZMDm2ypC0XrXZ}q0zzeL-A+jX8>R$&c@1%NmI)mDH9?*j`0!2TLz zTXrEETLtSjLnd=(#_N~`r-HT3kUMfuwc(Cxqx-y%@LRXn>plkLh$n3f&!d=-yhHNlxf8>)7$({c><$hEW#Cj$4IU!X zov}8@V{MMd+8mFyIUZ|sJl5uTtj+PxE#NO;Cb$jE0=EP9U!3Q`3*b%uzXjd~i@-bJ zUGN@wAN&)106qjCfyLlsumpSt*#E`i9?!nec-iZ15*!vR+t{4x9=8;{3|9gh_| zKHNpu-SJrG|>m0fw{*n=kmCBk@!J4wxk;}|oq3ip; z^luscTSotu(Z6N%ZyEhtM*o)4zh(4q8U0&E|CZ6eW%O?u{hOkHQ}l1jK_7D1-E>|9 zuY-l)4e%y=N?7modlmg&MZZ_k?^X1B75!dCzgN-kRrGrm{a!`CSJCfP^m`TkUPZrG z(eG9C`yBc`#eVusy>>7Neh4x?9E<>C_&+u-qyNk3|1$bN74F8)((ZtLEXF|<~>Ae+{@6us6g$My*!`t_Rb=4S*d^??%8br*{*$8L->wvD@jf+v(j3 zB=1?^cEFCO$Bw7Rj;D7QV8_$D2iyzLtG(IaK2QVDrdIEp{6byEqA{#df4LATy9l7; zhm*i106jmv3|tP-_cOXp{=P`pD8|`(@9QznrZdi_GtQv?vDe{!0@&~H7*if&%KIFA0T^4}SKw>#4fqy(2bP2H!4F_1 z_*utbiZM8yxo0|KuYRv_4FB10%v`V7AZRfoC(eXXM>609B?kE0Ox`8 z!36+`@sJn~iSdva4~g+lVQeA2T$>&5f5Pu~NFBY&_4`_jWoui4PM|aB0#1n+VO1}} zs$OJCk7d0G%X*Q$0)8^MAO2x}skeO;)Pl#r6NEp_?=#?I_@(@Q3S{N^hX3CJDSJ7; zD?l7C!t!1eFsosGFT(m>g!R2BpkCNoi?F&EVRbJ`{D737065Q(^9(sp?5{-;mU*-r z*c}`S%D}0h8ax!&=4}TCGAo?aU_4jWjps_{)5@&*w37L>lKHff`LvSxw37L>lKHff z`LvSxw37L>lKHff`LvSxw37L>lKHff`LvSxw37L>lKHff`LvSxw37L>lKHff`LvSx zw37L>lKHff`LvSxw37L>lKHff`LvSxv{L8OrpNQfu@!AxN$)n^GeK+F=oa#YaV2wi zC3ANrb9W_kcO`RoC3ANrb9W_kcV$ESRIF;T_K=TCbBb}<@AiNXEC_(?w1*%9c_1GY zfI`p$v;?g{YtRO?1?>P=z)XA40dxeNKxfbebOqf2d-0|R=m|Cfn}W?iFHj76gUvx7 zAonl zuz(%F0(Jlk*a0kH2T-mpta*>*b*?33u4Jr$Z|Z6W?d3ORyEL(T5HRPklT(|Z?g{Ff zpq?T95Yi7J{SeX*A^i~257Eisa=?|6JlZFZ_Q{v)72{cv*ZbNdD{=)Zas?}L1uJrj z6*}Gr*l2Xn*Cb?6s`ywXE#59=mz8Vy(9baNW*hH`{v;ybt~fn4wwuYgHd-hGXTg zW#zAB<*#MsuVv-0W#zAB<*#MsuVv-0W#zAB<*#MsuVv-0W#zAB<*#MsuVv-0Mf)sg z<*)Duf$Zz9WBAXtS62L5R{YwaBiHgf0d~rQE@+^2*JRNED$oE@XaFfRfD{^OIT~p> z8fiJ&Ky7#>s03GmDc~A_-iT(9zLtwlk7kfWOD#uBEk{GBMMJ1XL#RbVs6|7lKtrfN zL#RMQs1W~X?Al=)BbzB?6W=UA?&iWaMmAH(W(wI%A)6^=GlguXkj)gbnL;*G$Yu)J zOd*>oWHW_qa@`bghR9|L*-RmuDP%K+Y^IRS6tbB@HdDxE3fW8{n<->7g>0sf%@nek zLN-&#W(wI%A)6^=lifwI4d@5@gKfb8z_nXsGlguXkj)gbnL;*G$Yu)JOd*>oWHW_q zrjX4PvYA3QQ%&v8|H4sT#VD_0lvg?E|IXLo8}Kdo4lD=XgC78Qb2$G7Ke9*hI^e%g z`!aHpjGQV)j$Bu-zhXaz|BM`4gRb}jzb}JVW5eAEhF$S~?Bw=iC$}H6okF%#$hKV1 zmc5C7+;^5t#K^T58}3%X%?%@p{zc|f$b1T!Pa*T!qpvF5ga3Pim*Rfm%V0s=k2@O- zcQzOuWhbL|a@~_TB85#P*Z5_wNHMai7+F<}tSUxU6>~?5xg*8gkuue87oOg}57dDB z!9(C-@F-yCohu5(Tu~_Iib6406pH0aC3{K5TvaIMszNbW6^gm4Q0%S(F;77AY%}hm ziaj4#5CD1ZI|LEP2L+%I;D^O)30i^HpbcmX+JSw*zF;Ky4cH&(bKm?P01gDd1&4y) zfx|!+7uzDx9#Aiyoh;_b$zpaai@7pX%$1?y@FegDa5A7Bd6uv^ zJQJJ+&IU68=fm@T#UXXa8%Z%wZ^9)&W^g39`eTuW02WyxIYnTUXmHb*&;#@Yn}AKhW}p`+2ED=N zpbyvrYzejkeZkgX8_*B*2it-HU^_4nY!7w-JA$3SAh0tS42FQAU>C3}7#7zs=lzmB zopR>9a^}2pR`zmM_HtJCa#r?oR`zmM_HtJCa`t^!mos)-ZS0Fn88u?IV@5a+kAmm$P!0v!|3~ zPbtX?Udjqy$_ie}+*-lhTEX6u+PNB6T4V^?rq$WvWj1>?6A+2#4bvDF1!bPfF0}w zAOS)Ufqa0a=3#|-Sdku9q}K|x25mrF&<^Ya_5~xsZ@~Uw3>XUz00)BK0xUT1ci=F9 zCFdOujsQo3qrlPN7%+vpT?1G_u+x&*X-Vv~Bz9U7J1vQwmc&j=Vy7js(~{U}N$j*F zc3KiUEs33$#7;|MrzNq|lGtfU?6f3yS`s@giJg|jPD^5^C9%_z*l9`Zv?O*~5<4x4 zotE^_kNiIZtWh6p)V~m5b^BP|K32DX3AhxnPvx^u2=L)VrSFqbKhuwx5_LKNcb{uBd&-g{s*>za^eL#u0UvOr8 zEtbx;>^iKz7bx)^md|p%=07;`6L;dTL;}6I0F9_1JPG~z58!0LI0(-GX9BFH@N94) z5{$Nk?VH5*O=9~dv3--+zDaD~B(`rdq_0ByC!}9O`XziG%m**UgVCS{hp$lHt6%{< z_a$+?yn^fH6%lP5(Z*<31!z|V(P((;5X}O&gFC>T;4W|vU>ro06VdO{>tG?fA|2ui zY;2yKF!+4J>yp9KQkfZS&f+@?UrI?lE{Vs~1G(GmMKi%Hz+X}Y{!!mH7n*m>N5oiy zXVj~W_(Z+NiSUYat@=Y+fG4DL9PwycO(@=soDTRgdd=yF-{j8DQ1MRWoR43k1D%WT zkbH>q2wsSeacaf?kn=b3KjeIj|DmL_RD6&+pNfYeXBobQZgW1zlh8}fa`mL#1+PCJ zxxMi5^M%__{Q9_q)T{DPyeb>FL_GSqd#Z2c{qW+`&i#$}?{N*u`u_{%A9V|;bC_9F4m=@sG;r@z-i{NH$O@WwgVYo~shJF8#jF5=I| z>x~balfBLHSaYg30^gYDd8Pg|f0{Q|eKa2+zG}P!)kpI|>ZAEE_0e1|{${-E{m-rA zO~>y`?U>-?^(O0-O_tbe6)D;@XNA` z_q_OG@#c#c7Vkyzx#GPnK3BX~#OI3ls`y;-7T|5=Qt$8hR=L7kXs@Oe0sc!8exCR&@p&i;FV8LTP14nG8T1Hx`0ell@@KzDJb(Dxi_Z^#NAdaL z?<77y{GsCQ!yhJoKK$Lq!-rog9zOg%#CNm5r}*>m_s5gR7yc;xb}aYDikA-m5b@pY zABrE2JpU+sZ?yEsiN6j1B=HC6{{c^cTluHpOJlHqKK?WI^e@Ll#$oho1kbczpIh!wbdp{#W89&;K586ASzw@GbGW zzf!zP_^a?F!9{8OM&w&pyhPZ9c!{u4)G6v@^P?_NS6dMEj(Xb`;tj&K6h9EQmH2_M zt;O%NZ6jVEY>{|;w(Z5!gY76DpKT}c_-r>7&keQ@J{zXmEyUNe-CBG-+kWDq!EP(Q zp6vkf^=t=;XE{3Rc!#rxi8lp%xIEKpj}&hT_9*eDV2>7$&-NJZ036O;2)lvZ!3ZE z$Q>33f`h=p;1KXza47g4I1H45!@&{YNWfk4hUZkwG2mFh-SUPzAIu4$9E<}eg5QIa zz#qWL;E&)Ga4Pr{I1P*kr-MI(Gr*bPY;YmC2wV&%flI)p;Bs&a_zRc`ZUwi2S>Se1 z4ekJUg1f-o;2v-I!Fg$%@ zcvi>o6oKI>0>e`T<|*(rcn16pJPUYc4G-BRh9?S``%9SnOAOCV;3vC;6`;ht0p0{} zfu-P6Q{uD)tw3wg2DAn3Kzq;ubOfD1XV3+71>Hb*&;#@Yn}AKhW}p`+2ED=Npbyvr zYzejkeZkgX8_*B*2it-HU^_4nY!7w>JApx9XD}EH0o>WbGa@Cd>bSed^Gsc=s-GE(7$dlLXVa%Vsw)0+fJKum{)^>;*{U z5+6@{CHUDZ!OLC=p0`Wf8Q>;xGhlqUe*ugSyy}(UfxE=526uov!Cl~Pz_@T37cS$% zWn8caQi6ZH5|@5*=_B`Tun4>Z-UaW2e}WIdhumB95xikM{CtFK-sO9nfwb?dH*L z9_{AQZXWIC(QY2?hEKf`JnEHrHQ;_z;zuA4v;cj<)_`$^H@gyi*_HT=DSt2+2Iyye z*OmD6vrj+cyRO9F8|(`>e`~?!fHamgcy2Diix^&f_0Fr31YFrfNue99_E7rKppY@R1&rVtw9^m7PJHHK?l$gbOBuf<%Zos56}~A z0yYJkfvo`N8*;vQhAIiif&;+e;0SOeC`Gc-PtpQAk{0yT|6h(g;yKAz`9C}Q@P+{D?J?(d9Anodi4% zOa`U^Qvq7N8?ESd(>0INNH43{rvuLsKLeNvya34B0r7a81ZayY&(4bVjBBE29=8HLHBKK6-U0z6ajfJ%MwnJgohMQ5_;OctHVqBB`^CX3Ew(U~kdlSOB;=u8%!$)Yn^bS8_=WYL){ zIujm@s*I7#GICk;CX3!=(VHxKlSOZ`=uH;A$)Yz|^d^hmWYL=}dXq(Ovgl0~y~(0C zS@b50-el36EP9hgZ?fo37QM-$H(B&1i{50>n=E>hMQ^g`O_sIvqC3f&3d_i4(VZ;1 zlSOy3=uQ^h$)Y=1bSI1MWYL{0x|2nBvgl40-N~XmS#&3>uLFhv*8_Z8&9~KjTXZLj z?qt!OEV`3Lce3bC7Tw7*a+NW1l`(RaF>;kLa+NW1l`(RaF>;kLa+NW1l`(RaF>;le zT{y4kczXAiKmlk4oCvfAP68+geaoV6S@bQ7zGcz3Ec%v3-?Hdi7JbX2Z&~y$i@s&i zwPf_Nj9!+}%QAXdMlZ|gWf{FJqnF)c#Xd4@arD~y>V4{w+bd(s(JS7q;uUD;0rP=Z zfd#;yfH#16^eV{S1=Uw@FnU>ZJd2KJ(eW%go<+yA=y(<#&!Xd5^BJ%h_#F5G_zL(t z@HMamr~;M(%Yfy;3ScF$2KWy69{2%R3;YPI1J(l@fS=&`CY8sgp2w!1$EKdgrk=;9 zp2w!1$EKdgrkU*wypc)$`cZ^Vrq%*wypc)$`cZ^Vrq%*wypc)$`cZ^NflX z+j<_`dLG+)9@~1}>jazzbOyQtX98ydoRWcUJ&$cY?{x#t0lEV{fS$lW@}iESe_HfU zi~ecRKP~#FMgO$upBDYoqJLWSPm3)+&j@SL|1A2SMgOyz0|43w`kzJrv*>>|Lwm>^ z#mZ>f0P9c77-20VtYw5PV}!Mguohj=q6=DdL5nVE8DYyZ{m6d^a6K>-xB<8k;6$#> z%>buyVdu|d=g(v3&tvD$W9QFf=g(v3&tvD$W9QFf=g(v3&tvD$W9QFj?gH)x?g5?z zo&vD@V&~6e=g(v3&tvD$W9QFjUI1PMUIJzTvw=Cl%fMXVkH9OyJYYWXDzE_f3ivzl zHLwC$39JIX0agRw0&9UEfpx%oU<0rbpuS+|&->I9pL*fv0P2O4IH(7HJz#ra2Y|i{ z3B)3SSoCF!zHG7m=h2yy6-ySq*`hbw@Hhb8hwwf;o%NdKT&d6K&KBL-qB}Ex3#6n9onKpTXblP z4sFq)EjqMChqma@79HB6LtAuciwUv9owQ~TYMn$_(0_GfymGNc)|It*#X;x~~;54ZSE*VEdCaG{4MhMTjcS#$m4I3$KN84zeOH@i#+}odGvOR-fr=`$m4gBM}N2I z?-u>tqQ6`8cZ>dR(cLY&yYy$syuUhYd=maeZGg5wJK$vC6rerO0kA+vfOQ}LpPXU7 z6}d$8{M&i{;lLe01uz1r1V#d*fI9(J@+j7zAzA(3oRNN==VCNOvijF%qqoO@26@agu#@9|$hc$IrQ-?KmSW|~Jby!n}HFa21hc$IrQ-^gY z;548!a5~ThI0NVkoC%x-lmX?y*+4ho9H2YU1Lz5y3-kic1I`C70D1!#0)2psfW82} ze!3rU3D6(76c_+p1`Gr)N4mTMxDvPuxEdG)Fq5aR;r_M2VDRgJApkRaNRC^dbst7N zv%;(``-gTn(i17;F<=t#I4~KQ0!#&-0Gmi zU=}bNm;<~F%mw}kyaLPv<^!(+3-FzK4S0Q1InwLDWA5d@w-h|3N|}2p#j~=M`Ib`V zTS}R4DP_K;l=+rY=2=RaXDMZ#r4+BqQY6$;B-BzQ)Okp#^N>(WkxomQTbYM+IuGe| z9_x$evA%fTe|l~O>9l}!iZ1}*0n8{PofeQz3rMF0q|*Y@sjP#Zhjdy%IxQfb7LZO0 zNT&s)(*n|I0qL}WbXq_9l}!`j1;j&@%8=FUMQG9B=hKy1F!+uh~FA~an_Go_!q;E zOkL+^d?dbaA8UPTtIp*AUzk5o(o9N1*GQ!(sKdnxq$RsKzc49Jr|Ik3rNoeq~`+Ca{=kO zfb?8IdM+S67m%I{NY4eN=K|7m0qMDb^jtuCE+9P@ke&-j&jqCC0@8B<>A8UPTtIp* zWaa^AbV$zyq~`)&{N;FEO+bn+AVn9Dq6?WSG=ddeR|2bmZ-CXnx4?JY`yTiKSj+Dp zfpx%oU<0rbpq?XD7m%t8NYw?T>H<==%;S~%b=ljJI*eppK(a0%Sr=GEP##v{>%ENm zy5#_6BOz~TU0TEM?*Ph7txUD??WQjLqNQnj?vwvNWNpHCKiU^)2s8rl{f_nnngIKg z7j-SQL>+?1)Sdpy*=K{Te^VGbb z&G}tKd3}M40qPo3b^$57fRtT8$}X^yqMX$e<*c44XZ1umQg`WpJ4eVE;;dVY9Z25= zr0)XKcLC|Ufb?BJ`i?DM3SW4`Jf8>fEq`YH;=3Y&$5t>|wb2~>Xf@BxCw2s<|3L!Z zx;1QQ(f6MA@iVK~2>eNr2eZh6&L^MxpS=(K5w4E{j{%c_$AKxpG}6xio(HJ!NazJ5 z^v#yFcZvUi-yZ@?fGS`qKz+jxwH!axa{N%s@k1?7t!}3x*J-6xP7lruR;FdEcAZq6 zKIaVRtF}|@E}%Fe_k`m*m8$bkZr`p{z1Xq+$)&okQkyoZhTPT4C{N)WqyiPHNM%({ zm8e>(wyL8zPgHT5sH&&xs|IQ(a@&O+)OJ(5t36by+LN;a_g4Gh$K6mhQjJ}XjsAfg zxBoZfxx>F9&mDh5p8K71PM-m4Z4W}NdYp6Vxw=-59vAh~+w~aO>>#}t;la8&;UT&W z;i0;m@OQdDVRL;W;bD3VVGBK#@Nhl1$H0S{=?@7H(p7{9>z@b@G30j8p{8NaJ{O#4 zj_BF<;)~4jz51Wi!?f;magRQxmkay2uz%mnF6wWtxVV4MzUG>K{4h6O%CnhamtN4f zm#Mt;(q;#ly9p0A4-y_?CKDcNrW5|o%pq)UUMD=vEF^4UKDqR=?w6XcFTJearDnwd z$!*P5=k~vt`7Acda9^AaF4TdlnL0!r>V7vR45(L9tE5hqaMh|E)h*&q@+Wa86PHaQ zxJuk9#N}$lwI{BmMqCHt*iR$<6Ix4L?KCFNuOo5nxsm=!x>Jc`503Ot;yMvW%Situ z?lj`IO=IHxIuo~Djkwc^t5+kg3vu;p#IdIcbJW%UjB2iqAVSm56z#4)Ew%w|ZCBb^ zDQ#>Y+E-)MMCDx?c@Ir03FX~2?Nh$OvFPja>u49A;KFSkH(N@y!wO*9VXeT7!%hVA z9M&2vgOdZY`*>s6~`T=;t|AJhGXxdyp>$*_{Qc3r&dPrEhP zV{K{u(nI&I|>*GG{b6W7rw9 z&RE^Gd)J{|=L%bZh~3kN=@WtmQ5Z#0E($mwj8lv8PUKXuXxnJJs2(SS)#pU8lcF7? z26!rRYB8RQyK**Go2YHnE;>1y$r)js4;Gb1dq#Ujdj~s3`$kQo#+(+mA14~;qXVL* zx-x1O9VDlP$ys5X6m~?^JZcdg9vz0K(V5X%oE~;Rr)8CKa#*+M9Q-9Y=Q!%c zd0|UA*|>LfVbmuYkI&?ToEO$Nx;W|=^^Y!(F5}#=ft+)EWpq_^wbwVgCc2i>!~PHr z_O6eHMAzeQ`B3yQr-2QPZi#M)Zi;S>ZjA84j&6${i5`t6Mvq04qQ|4j(UfQ^XN(Px z?uaU)N=_IX8I6kWl+(rV!<-+@^UoBYS^xL`asKiC37oIqiZcx5?85svO>lz$5I(RE zaAx46_`E)j_v>Sv4LI9hhR^B>f2F_5|3*&e<9xpF~ZBXL>=&$2kz776H|0g+_ zk8}BqoX3YZYpvj$V0ExDdatBo^u9kC&)f^~$h{cf+>87<{>%Pc@tpPN`Sbl({RRGO z{w170wlI3bAM9V}5Am<}hx#|j8Ht>bc#E8j=;ON^eH~RrOQKJr<^FL04!;7A*FD3% zW->_lWC~O?=7akNg4G#>Pg-yc!!+dx^G$&dS{Wbbq^l9{2v^e@a`Xc%=`YQT+ zv?f{?t&KKD-$y@0>!a_YAETAgs_2_&b@XlYQ?x1CKm$F&jmX=m?HO%LY1JptAD)hl zv4`rVF2UA!o2pb}vD-a@&F)pT0881Q)e^N-EmPmC_4tj~)4S>2bwk}qAFL1I%-!R4 zXMKh~Tldsg>KpY<`et3BN9s{}w7yH$mkg`d$4# zzUPbdC;C&pT7RcEaSVHjsby-LI;Iil;vQlSHNP{>O)GPv>0r(>W#&B7*Ia1^!44HFL~7^R8KB{%)3Tp7CDvUh-yn zv%NXq%idh?RqrkD&)#3WPrSc*i@ndizkAEQRhdjC#2rekcDl zzq5b3--Y_w(?8em<)7!D?_c2RjMNvYH~sMB?(bjf5AZMZ2l|)$SNK=@SNT`_gZw}E z*Z9}|TD^&Di$4;d@4LjaoBAzvTk7~U|5<-J{@l;|Gkx}c;N;6$)cC*oUvggMuhs2E z!C!;VgRg>>aV^IKI~(TYyhYA_uM=(~XTOKrh4sSv;r8JU;f`U0aHs6NT>ad^xm$C$ z<%Z=dawBq2?F5l&TD2X^cZ;z7Fl07-^W8acyjNWnY zsJ%g0vgcCM-eMiY$Ldp7FDz4Q)H==Bplj*vbOY*JW8F+Q*GEy?TI*AECw-Rgu6yf# zobWtI524Ntr^bz;wmqUJ>!+z}v-B&}u|@i8y~ZeNRRdNeG&4t;<4tRGis@v!n)A&- z>e8*$q|s)qd5{$hQ>jZcsY~KxjtFZ-`@LQ|_Cg>R)LfUhKU4lc2TZ47L3wm*)=T6)^FKAA9esCD!1wjk$e}~>; zg5JU5;NNF!fnOLL0saHKf|+nFHU$&(363PZC^(9+Z*Vl>#lbOz{es^UUJ@Lue9rQm z5ZoFZ=eGwR5Ih_V3r_GmfDa5F4Tc8=--2HrObqS_TKOHpuM8#yBZAicso+-!lY@~# z8^06ypkPWcDroDU27XQOL@+uy+3yT~EoXq<6`bOq4n8<|D!4mn?{`tg|7-LY!cU@) z2tSKHCR`jXBK#uyFBJqsg6YA1{v(0)d-Ci0;JIL&|7g(BKNr3Z^(O|W`sah);6E00 z@;T*%*3*mdaUU+zVmSFS+{9^)1`%_6@Qs}EXu_YeoID+6IQP*+UbZfw&h9{HIP1|5 zo)5}x<4qfL z8f$)T;vDgDoDKdqXL&vXJIeoWb4mZ zck|O$N8_{oZvHubcfW@lm1RVhk@*=}W5NoPx8<~5|2_YGR+xOk`jW-0F8P%aIv5Y1 zmvDxCB4LTtS(jhhyArG@b?Ix6Y@6W4QhVn~tbf|-ztb;_s>ORgg~<9GGp(UJ{oJD; zn4<#5m3f?Z@|t;#(=z_VoN5Msyv<1?@0xcx1!N&JsA6k0O{gy%22L21M1;AL9AVv(Z3*j_Y){C^ zMuhagg!`84OW3HSDPgmcg9v|L@_WKgC7eKCazV)jgqM_DA{<5Y5`M=2qK73sH|P(w z%+qE@$;q4!Ki|9#{;GKgc(sI6g&a?xgO@TkzXtE#hGz@S2XHCQk*BOX6#3&;`tZTj zyvh0#Q`dZGKIJ6$cHTSQ$Be7TWV&P?^eb7*G~fRS4)+Ttg;#_RhSS2Y!nH`pgR-5o z-B=+rEITW^DmMup&dRMVIhZvnQ#tvms#d;M^I9D^?P);mYdBYFX6+4iTGhFEn>O1F z*yhG<=4|s`-F)5hy8Y^2g(TDh4X3s0fE?6Kov->K2Mxx@X&AE5-D;eANKL{!X*wQ9 zTaHsZDlbryzzZ|-lywIWzfo%M1fxH3LK z%}Mv9rB}~Y!XpDcV@R$-G>F`tXt}0jZ!}#)div?yD6}+_yB9gm1S`?$4EgRsnkLMw zn4Fx&VS;67Z-%--kChvN=4VP8@MSX0!AOpxq195-hgYF#NxmLs)gj&SEffOko@)L164&5$cB`sTqmfG=#EWbyo?$c99Q@Q`?sG(m#oWo*%ckTv1-c9MFp{ytjm;gDqV_^0{@z;qxgEQ`4XMbn!E8n z2@e;*l?qDu6SPaQ)=Ft_x}0Bi`MgEU3dJZz`HW6H`FQWe5F3rmGL`Q#@73Vo3~OI=flzW@FM&~eW9xKnXU#_>9gE*sVmG-YYQZrX@?Zj{T0ezbLU8OtAHCLfe=SmIMUEH-ww{lN=B4L$o%`;bu zHphEOd#%tXfiKr>z(?t}gzGhJ7v9m*crRKSPe5zsJ4kE2SJO^|Wx50SCVeX52&uc8 zc0kRj{spDoRB359OSQC{(VBKcsnTv%#=Qs@V@ZQFLM~DA?UNdbtyu03AzXsJSe{@g z_%gf=rR*Dp3Xem1%3Fl{^iMlbcciB&em`c4I_Nv$LKP`T!>y5Ahr3+wfVxsw5RTEb zDoT(RHd2ptxze`Cl~%>LSF^5-bE(HV%KIG6{f=h5qj|v9g9lwbXuxwELAz?h%ImJG zJ3T{RdY`L)d5qA{7QgUxcdgRT$(5&?;eIdGv*ZiIliBiR`F4{ibE$ruuu4znDJu08 z!V1>82&bPQT&|xaW|V%4@J{_S;d=cH;k|kecUS6{!AI+9gd_Fy#4OV@!8d6nzLKnd zk#HCNl6#x#-*zr3tMnfUm+Dts4)efQ==p@nw|&jU(8h_`VjR%)B0MR*2-MPlROz>g zsnG8bj?nKq3OCB=_g&0Fx$C~}=3em#M&4Gco&MO-QzmcpUxbw!Ii9@!M*LF!spO?U zBWAQ-48B7Dm2kQKgqRUEp6VO!RO!`nM}JE=Qm-Mb)Ze*0zJ~|(+=x%VAoU7A>$85# zHx>QV)FqFldV`c;GLoy29&3e>ey_spKzOIwkrMVY^@v}tHxe_-)F-^x)FEc2*%o}X z@kz742?_J47pCL@lO=4be9*^(8JU;zwj5ilRyVUe{n&rQKqje@nXVzO+UhshCYb5x(a->xf*2H(9V6y@`R}JRv;|Pj#21Fn2>c z(A)z)(u|?3DswO4@}E&Y<|yd_NJkF9;oSdjWS=c(fbR)+Stn4+$mX zMFLmwBN1v^WU$hsC6&~}n?y>JasQv_9lTv!uDcRedApH!rAJGoe0qdjg||ESa&Hgt zQ6B9vx89@0=EiwViC^g*2tL|tM)~`D2NCAIg9#7t4k2vn(TaKMy$J91_96W;Z(s0D zUPHn)UL(>R&Y|K z+v>M+E!}f1-J^}?#&~^Qeiym?E_QkJb9vBmOB#8!+>+9t*DdzUm-4T7wAZ{Mp6S=*K)-FYhC* zcd19~B`?}G@Ae7d2=8w~<9!OwyUO_DEq3vrOB%FOC-WzA9}<((L_AtM`D`G~y`Hr5 z3Xc{}DLfCQta5pNL(FJzHTVi|8R2qoIWZ%=6@+(gIl^aX^+8o8Blj~t;m8c_JXe_s zC8taTPiV*TbQxL$DWx@3NZt2O0vqSBGm6;pq^yly^Eh_d>BM@fTh#690X0wO^fr1Y zy^qdg<7lbbg@9R#+uhzdkLd;aPx?LmkzU1oS$(rdwK=ofi?e1j7xHKGsafgf%-G?E zS&g>LnVrXc*+_5n=Gn4LW9G}4H7(9s@n+0owM5%ij1$bdgnc*9m(aq+p2&NIeD~^i z{58D6V6@~>%vMZf1=WjcK3d$zXd^4sT5Xs|-$9q^Ci+l)3^V8*nLqEv?DnLlElWWM|r z^Ok!e>NQU!&qm!YV${VVMtv+|)X5@7y)0skNJZ?~6k~iU#xcSbu^B1$e2Ou?74N=~ zVlSrHODQ%h#b&42oD_RG#pb5iA5-j=6q}b~^Hc2A6kCvDucg@QDfXundn3i(OtH68 z?ClhLC&k`PvG-E!{S;f6VjrX!ZM?`A+IbQCD8*>g#W=?7B1X$EVzmAuMh{TLX#Yiw zKA?zwmSXe*#W?zgBKB2^(dLVB^b7>LR&ME6NmGlr|sz$J<7~;&WxfOH!2 zr`Vtr`$LLdlVaDV*x(eqF2#nV*!3wkG{tU6u^UtDrWCt5#coNlTT|?|6dRUex2M?f z6uTqEDpG7jidClA$P{A~cHch}GCCEp(J6LUirt-J_oNu3d6DAY6dRjj_odjl6uUpg z#;4c=DK;U+9!jwXQ*2_2J(gk*r`RJY_GpStN-;)$_oTl*X31V}$%vJXS6j8soaDE` za^229**^t)@?HKE{|PKJVt-kc_(lY`U=6Mv?i}tC?iwB(9zqKftALC}fs9zn(-qj& zuj5w|pCf)d=5T0>dMEQKS80*P{}LaBo%p4gv#b{9QYdD|({{VLU9&3E(P5$abZhrz zrcm-tb9P=g%pTRlX0QvE$%nB*PQ>Ck8SCN`SQ4MYF8CZaq#0P+o(ZtKsCwop&)+I{ z#EV3%QjQnt`x$c-vQAyVFawUg!+%1`=T}57*i!IDIf1a?wwLr|MV}W zDE6H-Xsc7YzV&DKIR>gmoV@4e^0s!Dqor!lRHyj)y`r>}(o|3Ft66 zM@>jtiYNEXuGHPmF5Qkb?igiEV||pnx6_vQ^jFHmx1p9Ub$55Ead!c;xhvd%{BFC| zxIa<(`mOk1Ep|EVQ6t5TI6qBJ{?#0pX3rXFx~mZXi}W8GjlAvNHBud=B0M&#{bQGv zbomp^NEmN{eKZo7A#y{SSl6F5r9o*vZxG$KYw*3wLz~*lvevg{n z4dlBiwLf9K;1)a_hT+X{2c8Qf@lqI#N5b8~7%cH)gZqMU!Ts2!U#wPUOUm3Dg`^!% z>ajvw?X5I+3(d^3X0BOEJ%DiA-_R$KYOC)?&qn_yJ>87pd6#2S2W#_72j8S|hEfkL z>9~a#(PTUzw&v5e_}6@hev9`SttKZsRnk1~^Y5oEJm5coW;VfpSow@Q)9FEH__I_k z*=JJKV;owm>Iay$)t-z&J7MQaM~H13(#!0ihO6QF3jLw}ki9YoF>_O;)~KI!gy+z% z_^CD1N8tUlm&xNxb}YUPolH5tKmE-hb0fY#W6VSN{md|P@%h2_jL**+G`7gw&fC>% z=r!|>@LGDO;O*0$(QP38aXa0~8;rkLg?G0%9<98;o*CArS6@!K{na3B#uaJ|_Ts7R zRxwwPr`Mi_FVX_E#YOrn^u={1gMZsU_&nH_7OF)&Rb8)vSL!upmgozwMaWnQzn<}z z7qMw6Hob^VOYcs@D=bbo4d1XBo1WgCp5C4A?$*IeMe>!a(8*P(>bN)EA4~WgY<>%| zc73f@s}1;R)n&ZeM>o|i@X%_9M_@O`tpP|NH)Gi!i&xf@dM2aSTje zonmuRY;F+~Ud9x{%LGekr_oxHxP*2Z{-AN3a5}*fTH$mOm(Wh9#U*hG?d+6xc3ST2 zl$QNkixkpYW7^qixpPw5IVtU&ly*)^J13=`lhV#jY3HW2b5q*6Dec^pcCMps=<3e8 zP_FW>a+Nogt30b*ks&Q}>~!4Pqu^7(Rew^+S46m@9tkXHslh zicK$Ke9sh1?$S1jaeT29OYZW;T%6Q|_^x2_UBQyONzPJFlDkRH()towT3s=}Bxk87 z@m;~G04MYrkXm*aWcAFtXQ{R(zRe#oE72s77zgI$e3^{epx{waup?Sfr{hC#F7h@fR~ z3Vxd1@p~K?3}yr$#dtk2csh77m>;|od>nj%<#ugo@QdAn@vcdDXn0K6I_wyp74{1I zg;#|`!{OoGcqvT|r-yUG*TaS3C*jxOYCP@&JpFgZYriR;`N!kg-x+WE-q8R&<8Q{Z zeJp=3-3MrX%o zC$Y=#tn7m9d)YvEY~9o93+uZCA2$$zCN*@S-}Ru!MGcN=uKL-c4xfQHyc(s414v(xawv2`xQpF^(QJ#S&V2)HE)krAJNU z5?XrHVjMkciY2u4sA*h6OONW};8c-Tu$We`m{zcuRu!I)8m`lQEt|@K8XNgN_ z6F$eim2g+Eq+ID!lDMSYgwK*LDL3J>jExB`BUh0&;j`RL%1!vplcdkg$W^3B_$+sm zauYsFTvBerXBmGJT1Kv7E(xFIZc=W-XX$HWUI`Y{3Kr7}7MCknOe2MEO7~K!e^1q6552%5|_{> ze3rO`HsLdQq_hd2B`%>&_$+Y=ZNg_tEz$}W^I5Q%Re3rO`HsLexn9?SEmbipA;j_dgvfNX%jw6 zTtb`hS>h7fgwH%@N}KRm;u6|~&k~o=CVb}2Qrd*i5|_{>e3rO`HsLe8NNE#3OI$*m z@LA##THf7#Be<8+CVZB-gf`)`#LW%&EK0HQbz1TF^x}1P@j9n?jnfNfCB5)9zQ*Z= zr}6JNz3@|h3pe9yoL)E?|BllO7vtY?df}k_7XHQ8IKA*L{vD?mzR7RlT6~Su3&-N$ zaeCoa{5wuBoRZ(dr}!GD7aqmG5{JG5WMAS9v6Hh5McA5X9n{&!w zP1~JWi#AGTAdTw9{)1YTg2%rH;sGOm#cr09S*Y^#&QbUg#q(kZ71Oq1wk(c07#bt> zee*1hn+dK%y!Mw7X2M8PZ1w(+JO@_$uvAjGuv$K>=aAW+cB&Vv!CL7Kx~uNve5rO8 z-)9}DX1W&hLm8P{XRZRDe0QzouB*Zwu$t5kcOOt>iUdpIl5`unzb?!d zpCP`+za@qImizk@-yyzkbic{Bc--rv@i3~l2X=)760*F(tiJ9e8>u!^dFBv?RRx|ge&*CGCKqvT$u}s6q(={`FCYb zFUI*nllb42`Cu_N2fg=>Ax#;fV(4QPLMMFMgAgJ=ISCvhE-quyD~p5 z#`*M5?%$R9Mlm+<$0z@;%;X6}R#2z^uFP?cLdv|KGBta%auN~To<+R;W?tU^nn{bN zX~A*KBw{{Po*8e(W3!0kMiVy|JpO|6-LX>mPeMP`r7-?@R#a$0jjyQCc&x)6j^B_b z)TXSbGx}+UC0{fr&S+TtUjkISYS+A9o=LhLGuzMT z4tOZ7)qT8;nMjYwoaXPW?~`+@Ob^;&V0v=8Q5|z`_ONVUb5Zt@>}%%X?AzI|DA`%F zGJ~*Ybx64gKQq0R$@JDTqDWheQ*~BergNsVrrlJFJyvBnhl_t!h*XbntbAsH+`rn8 z-qB*Y%E;)#wU~>hH`1Q;Vy_66#?oHBFDQE||I&8jCo%Nwd{2)WBiA%mW}me;om?E2 z#-GnTzs9f6qi1n=@s7ucA#<488%i!*)A;7B%AqcZPh*UwcXnlUP($vp4g}2M?w%3r zjBJMi1!E!hSA|t~G(9_>Y4~`(s+Oqd>2GgQiIie)QJs*D~2m zC;f)Mn~(KFMsL$x&ImJIu<(yHXUNH4rUx@#yPBTNYrSO74Q2b8Xl@>||~ZPY=&F!(=T$vyUdq0neG92V+7Z??b3ShobA=HHThnALK(qbVRLFYI#cDhM$H2$R#%W=y zlzFv-*a3+4rN`;GcTa3_QhPG7y%8&c=4&Lmde}4j#sAVGmGphdR|v346#t!d?bvGf z!s_-$WFn0fF`<+m9|37;gwIKaJg50-w8a27v z|IeR>ev7AhNS=l#8Ny03%^JnzdEpIQk$>7CcQ?oT@Ff1H?_u@Y<~so#N&ee#k9}_l zMV*P$wbJ6vWD(>cqY6R4$v}@1BDZZ5#yu@ zR##~mZ-{F_sOgU-e9GM)0FDP25KF_`v#R)M^9-wspGWR_f&Tdw*22DO7O)=nb$aMG zk%fw@VjcaV(8rWgBD|IJ4jE*w6F+5_f>wk_XZ&>zCvIC-YE#RZdGDqIbFMj;RmwM+ zn_2b2IgP3g_RSHhE`F$gRoj`ru{Zcmc%XJx&AqN(Pj$G~qxq%(;ES$~m3g;kY_F&h9bJ-=~JoZMo zfZY%-WbXeW_Byy2Y3dU8HW+{<;BxjXxSIV5u3;~N!R#z>eK0h*0V(XpK2o!6Ct+?8DGJI4o!p9FCpg$l$2pXr!;-2ge4-1t$cB zpjFU1XcM#zPR0V!KCnT@;MAZ~aC&fBAig2{|HA70Pm4ar@v8jT!}!-%Sl;dEl3KS{eL{`}17u-yZL@!qbT_#_xGL@$B-PXIFsVTw9)0{1{4HuTw{O zqqd>Pdz|#l3aK3#<7TS{&hKj{C;RWh?gn3|-TY;Yce~RM)lw~F#}#!%urb)k`rXZM zyaQU-N&XqZ@xi6RZNWp~$nah6iicTyYD|A@Qxn2l!dL0PL{i8xZb^%ic9QfX$AQz6 z==Ev;(YV-u9OwA`vp16T`Z#X~u1TG)gJ#ko*hzrcjNI4jNs%e0i1jRK=b4Ze?Cl^P zZb*Rg9K}5JFizySi*f26^s;-Ax9>w|yB~S0%Iz$)T&++m)hhLkTCKjtd*eIy8u~%4 zRX;MWu1DJ2sD4tLBuhNmJ$&PQJPtxUJhI3dd!u3QiyuKF)7b2XHFAGEJr2OD;6V0! zImjHG?jv*o(DhuRpuLPl;7h2@f|x|{2+S>nRRBp zclp+OJ8v301HJ3b^QL=$^q%#e_ullLW6y#=d2f3&*eU2Gw`0%?-W%*4^gb5N_poTr z#jZKuTj0Isz0O&$n>{YOQrpk+%lvZejwc2u1?_?k!DZ;ZR|S6vt_yBQ|E&z}4DJaY z2_6d`52glBqyOF+jt=j_#`s?NKGww#!VlRytW9z6uKV3SToc^hT0h@MYbIa)XmvZX zq(YLMN1b_5DH{qv?;Y zRCmeAvFdJmG5BZQq3*>;YlIq$?RJ#94=*itali}oVRb*2+=*&Da|)Bx z19*c@Q4it``jnaw-WuMj9twwrx2uQ4JHk8EqhV!OsV0UC!UgIvthj$tlfpN{H`V0u zo$wtsh5g#LS5w)mZ71~vJE(P3PqI5&nR-U{LQ~V&+iaMcjy3m5HFt9>V4Z7e>S>#N z_2io;Up)EV$=6Q4b@5A+TdCXW49`-x&(vvt7dLLSg+nq%4T2Zqp*D)Q7N6HC!Bg^9 zyi=vT1@G`qwI}M0Ui~k&!Cz}T(tEjH%TULpzA0DVw5xC1xw=&9>e4>0F74~;(gE~u zN2{ic1?|;=^l!JQX5p*!atBp=?qk(%VO6-46M&b8E5eoGDoz1j9ex|G3BL=!m$QJw zO_2&WhCf9aP6O7F3D~F)~Hf8K+!+thf*_Y-EeD=27 zb;jVQ)b!uUJ=$vc+qqVaJEPQz;l=nOToU#VFAWETmxTkv%h@^QO1u-U4hMyQU>5D# zaBz5CI3&Cte}x;u8^fEzo8k4X;cc$A45z+Sgd?akBdhf{_k?4@d&9B(-xrPx?+?d^ z4}=rKhid$KFq{}Z7Csz45+ljo*udT8ASNzqPZ$_%G=CAI26gQ^3_f_{^ zFJ-2*x(B=H|E-x(oDxnAp9r4}p9-H2pJ9iYXYt;6E}RiQAI=P42wx0e3TK70@#lCs zoE!czd?lR69OSF?4zIaZ^#<+gt?+I7hIcpj%Hf~GkHWu%AM^iT;iB-b_<{T_{488t zzIw`Avc}L5viFV6+ z$*z{!jO=S!eOJq@AMb0K4gOd6wd|hmY_&i~9lm(gGF3i>!&6#ZB9Ui3abLYzDvy&e5IdPnw{3?2+#NcNJ< zZWAqcdqjTl&+Zb5Jm#?$+&Qw$JIC!E*|*x>k=GaZj*PY7e|`7J&6wQiJ2Wl{R=S-Rcl;;!UQFe3>}e7HW!q=B%htLhOZZnB`=MprT!mxV&4n^ literal 0 HcmV?d00001 diff --git a/crates/ledger-gui/assets/fonts/InterTab-Regular.ttf b/crates/ledger-gui/assets/fonts/InterTab-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..40a1209336ed25c3020caefbb7cf48390e9992c4 GIT binary patch literal 409696 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∈;=FPja0RO-y6!RcRtkpKbDGh!C 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�wQJyp7g3gHp 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 literal 0 HcmV?d00001 diff --git a/crates/ledger-gui/assets/fonts/InterTab-SemiBold.ttf b/crates/ledger-gui/assets/fonts/InterTab-SemiBold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6863b2f1b72abcd94baa3b88e6cb6e00eb1d5dcf GIT binary patch literal 417744 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�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

KS(65=Snr?ddVRav{ zQ8Y*KQ+s6lU?2r(4y}BJl)bEeCm*p4eqHn5SqAy&2lCeU_&tN}g)MX^)+{BovAtQV-)sHlOb8)Y(Q* zj-0znmHP;M&G*aAu$^59&!e`dMw{7@>YNR+nf#UYQ?E%Y?Yy+#Qcrsg{`c(_YqeK1 znFz(e|5C~4XdA+Pa12|3`xCM#DDr;XKpmkwk?&Bb>73wHAhc?^LFI0CHaU>|D3Hn@)|Y$ZqB$4o0?FT0PqmdFF##{$QQ(^7ST1wD}u zbsy_mE568mY~XmO``AYd;cAUh*ZXQg{Bid&$U6C}?qh!~jep`kZlOg9&%3}PCX(If z1GNm{t|LKIkC^X1AFL&d?e60coPWT59IAx~cN-FLhzfU~VlU1Ve`>vuCuWv*8H|zj zSal|AbG2A4Q|qL4Mz6(c)i^T&pXKP=xj34Q<3ad$CSq46XydG_dusFWIT`0>YjeD= ztj3mJhwJC!-g$^)h(%VK3HYqnigE2UZM-%Z-zVX>X}EH>)<3cmS!lvsq)sNEHhBH zfA{vLcCc&bsoVMQZ@My88-kL?qAW8|gXV2nj}oX~R4dKK=XjKAIzDG>Q*mx4${uT# zayqWdXgnH>E9T(3dDh)Mt>@acnPb&P_2OLg>KxR!BmPtMw4X2?&+lmUs{Q6t>w4Aa zRo2_)Y74Blt3J1{n1;`BxN8QUp?V+|Z&mfM$Aap2b!`=D*bkor@m6(htk(48e$Aec zhTqO@`_8DF`m@K|h2HBaO)XH3wRoNyF?IM?y?X(^t8&=wSgQ5ZDy`$WsC_KX+ihXD z#2nN`jr3VKt6Eg`|1^B6u{#MZGZ5wO_dmL)slU%1_veoKrZyUnx7#Cqj#h%>IjGfi z)JvV6hvT_8QloP){iHxA#Y<3BYf{_ZKUh(eu#Yh!VpYQH&F z->Du|Gegbkc32JSaWu|qS@p{}T%$%~EspH@KL>rS%An5L`6mkYhV&%k$ePd{9_0H3q5o{You)Hsf{ zMr+f^nTzvkBvj$w=_s!n^%L>u8Sxh?k!nBH3bXLEIhfgV>?;2J?%Cr7w-lyGWA2t8iPdQzQmWc6tJFa+6JE4t( zx(mMtVDl1LE)1m8^Cf=7ACTDq5=eqbFbM&xU>Ks>BS<6^xn7joNd?HF`jY|3PBaL!;{~+kv)c2pq7Eii zq?!x?#9|m3PHM;qGLnoUmyppgAdMxpq>hXuajcX`F#3?Lbp$Z^U~ia+Bqe^-pSGX@ zG>`^CyAPqEG>nGR2pUPFXiM6Pwx(?$D@@YvfDOH^_J;PV_8N_*F*KIO(Ri9b6KN7G z?F3qD|X+ABW-Dr1ONPEyC+LIR3UbKYv zrlquu_MzppuXd-FMJs4O+Mf=f1K}y_LMydwI+#|`YC41trNiiOT0=+Bk#rQjM9ZP0 z5#i9FouOlCEv=*D=y*DTPNb9QWG$E0(q@Vn zS8DlmJKaHd(yQn$x?3xtd+1)ek6umpYu)Gp?HhVfdx%~`uce3RVR{`sLa(Pc&>QJZ z^e8-Yx6oVZZS;0}2fdTtrFExw(|fefDfD%EKh)<3=!5jQ+H>eb^kMo4eUv^%AE*D( zrqU2vgX`hqrvzDQr9FVk1(tJ)0u8hxFQ z`YZj7{!ag(f6}vBZ~7N)pbqM!CUt4wYo)N360CH7fu(m9k#jsfTec};lmdKJ= zGD~5ptQ~95I)`@l2%2_7MVqI7^%VD`Jk9B4FtU&9_y0Px8P(y|dR>XR; zV%Ce5u-;k)D`jP@4=ZPVSq1CI`m+ISARELg*?lk8`ws6IorfGvn^~Z+s3Y7 zSF-JF2iwW6V!POGwukLy`?NvqYPO#pU{>`*3)vxdm|e$?u_&DIJIZcm zx3F8;ZR~b-2V|Nh+EVQhyA#sKW!hqP7rUF?!|rAGvHRIE_5gd39cK@*huI_SQT7;n zoc)JA!JcGKv8UNH>;!w3J;$DBFR&NcOYCL#3VW5k#$IP{us7LT>}__Ey~EyRr?k7+ zd&pW*#XevkvX9uu?6g+RK4G6~L)aPi8T*`l!M|6F7`=0&4eq=wfpV=?$ zSN5AWl>N^BV1Kf+nnU}H{lyxXgE<)j3M{kTaG>_r2+H%BWui$Y!o+t1`p2U-R3Qy(j zczfP~r}1>2!8`I!yfe?_S-cC+<~cl<=kcyQpBM0MygM)CJ$MoC$%}a}Uc!6xQeMXU z@N(XlSMYxDSq|U>`5<1&2lFak&4=)zd>9`NJZTLd!AEK%_$Yn}AI-<`vAmYo@p0Nn zKAunD6JawM1%%UNV8XuTQ}|RqjZfz@_)I>FU&?3mIeadk$LI3}d?CM#FXD^&673Sc zlrQ7U`3k<0uhPEYtN9wfR{M^x?tf#1k);z#+-{1$#Izm4C{@8EaxyZGJw9)2&s zkKfOa@dx;W{5XGzKg=KDkMhU(gEdPr)a0hpCle>TiARxGBAcPVs0iiI2kMI?K z!e6uy0U}TYiC_^TLPeMe7ZD;-M2VK7m1r&6h_)hH#E4iCC*nndNEAsTS)_MQ2h3F^xivePw7$hpiU{NKi#Sk%63=_jejTj+Dic#VcF6=J1WC02_y zVy##w){6~dqqtmb5}U;qu~lpnSBNXccCkb36jzB|FmSGcS9Ps+gV-(hh`nN;xLWKN z2gE^fjks1E5{Jcg;)u9j+#qfgH;JR-W^s$SRoo_S*ZvT9h&zFc4%5QLU0MX($x-5N zttIT^tziSXN8Bs!6ZeZ_;sNoXI4&L%4~s{{qvA2~xcHBFLOdy+5>Ja~#0l}NcuqVo zUJx&em&D8B74fQgO}sAN5O0dN#M|Pect^Y|PKo!#`{Dzz9)Bc07N^B0;!|-(d?r2@ zUx+WoSK@2&jrdl4C%zXyh#$pI;%D)T_*MKSeiwg;KgC()_Y)0p&N{T~gcBAWQ@FIl zQUi3{52)Zm7!!-Yk}w*MJEr-?-rMBe3$U(w=~x(Lxr$F1Sf{lijt=vQYMr zMY5+X)>dl=w1cvjEYUW|-ayW7*Y;?8wSC%t?Rr_NJt)g$A6YK@$_m*}_Ll?XKsiWO z%E7WqR?8uBs2nDT%NjXCj+CS1C33VJBge{GStrNI@p6KkC@0CuvR+P+Q{^-{UCxj* zVc`KEkJzAaD6cjUYBlzdP7RlYAjkRNKl zX}`;l@QpR_I7M_MoWv$j?K zqP?TNtDVx`lfP>3YaeK*do|S*e2I-JajY(6w;Efn-#EFuMfl!Fq@us)r%hbc7zMN9ir~R(fl_jowy|)?@ToJx-6;6ZAwq zNl(^O^i;i_-d^vZr|Ic>hTc){q<7Xc^(?)Mo~`HTxq6=7RnON8^lo~0y-@F=7wJ9q zV!fAMqW9KI^)kJWUat4mEA)PPe|>;HP#>gM>Vx$vy;>il57me1!}S_{gg#OqrC*|t z*2m~$^;*47AE%GkC+HLPN%~~HUZ0{*)u-vx^%?q1eU^TyK3kuo&(-JY^YsP#Lj5v* zk-k`8qA%5#>C5#M`bvG3zFJ?SuhrM->-7!#M*VVqlfGHsqHoo==~w7i>f7}l`cC~S zeV4vl-=pu<_vu&b`}G6*LH!#2TK$lISiep`qF=Aypx>z9q#xC9)^E{o)o;^p*YD8p z)bG;o*6-2p)$h~q*N^EB=nv}0^@sF_^+)ta^~dzb_5bKk=uhfT=}+s==qL1N_2=~G z^%wLP^_TRQ^;h&)_1E;*^*8i4^|$o5^^^KL`n&om{XPAC{R90&{UiNj{j~mx{;7UO z|4jc}|3d##|4RQ_|3?2-|4#p2|3Uvz|4IK@|3&{*|4sj0|3m*%Kdb+xH|P%Cshhe> z8S4#dfbzl+$a8OcV9k!rLv+8Z5=G$Y-}FghBYjLt@;k!5r-vW*-g*T^%v8u>?6dFB@BBQ5KZ1gfpjNV46QD*cp%8kB8h0)LGZwxR78iR~VW3W+WR2xH#p~f&{ zxKU$_Fh&}qj7yBs#u#I)QESv0RvT-KwZ=MQy|KaAXk2b=GBz7qjIG8t z;|k+SW4p1#*lAp4>@s#6dyKutKI3X*zj44gXk24lYaB8T8`l{}jO&dXj2n%cjHAZQ z#x2IJ#%;#!#vR6;#$CqU#y!Tp#(l>9#xdgo<3Z!N@sRPb@rd!L@tE`d|-TN zd}MrVoHjl&J~hr5pBbMUUl?B+Um0H;-x%K--x=Q^VC#J3B}36(F#?Gffggh#^1-m}IXc zn{0NMJwialh=_=h9|A%|L=1<32oWJ7XGBDP5F;QWA|N6nAR;0nAZGsGSM_?P_u$sw zf9lh9pReAldUd=Sv9I{J*iY;)4iKLZGsP@XE-FN&s1ntpMtea-M6HO5n23uykr4GF zDN-UWGQt)OqER%7X3-*Mivz_$;$SgH93l=Ct)fk|i>$~AM;s>Rig{wbI9x0cM~H>u zNU=zKQY;oni6!D_af~=tEEUIzW#V{og7}nJE>?(@qC<3wF3~M|#452`tP#Cptym}e z#Cp*$2E?E^Q4EP;F(O9A262+uC{7lqh);`C#b?B6;*OEA91eusyI)aFD?*Y6Bmk$#1`>&ak2P@xI}zYTq?dLE)(AtTgBz# z3UQ^lN_4M6|acDiC4wn#cSdp z;&t&)@rHO)ye0l6-WLBByG7o_&1TbY2F#$Tn}!)O!=^Az(=toUQnSpQVoo)unbXZZ z%stJInKR72%)QNh%ze#|oBNsjn+KSmFlU;x%yP5BtTe04YO}_Sn6+lqjG1w>&PdASC}i!4zttjGP}(lbCtQ; zTx0f{Yt40LpSj-bHwVl?^F(vV95zSHQFDWNlDW}5**wMkw0Wxe8S^yrv*srAbLQ#h z=gl+BFPLYVUo_7$zhs_me%ah?e#Jb;{2%jN^Q-20=K1CY=GV*%&5O(}=GV=O&2N~O znBO!nHNRzEW`5h;YF=($VP0uoWq!xJ+PucR*8Hw{o%ucUdh-TzoB4h7M)L>eP3Fz! zcJqhkE#{BRTg}_d+s!-7JI%Yy9p;bCyUm}N_n1F5?=^pB-e>-=dB6F9xzqf)xy$^8 z`Jnlb`LOv*^AYn`=A-7X&Bx5&n2(#kHJ>n_G@mkmXFhHI-h9UVgZZraNAo%JPv-OH z3+9XFpUs!dznCwZe>Gn*|7N~w{@r}d{D=9v`A_o=^G)+D^IzuM=D*F|W*+h&KFg1P z6b)KB{th8zg)L#3mSvS#rB<0W#hPkOv!+{nSbJI@vu0R(S$kXiSo>NZxAwF4w+^sA zVa>E=S>;xRRcTdO)mDuav1+ZT6|>@2ot3cat)!K*(pJW@tp=;nYOyy@E>nLl9b+mPib*#12 zI?h^V9dDgreac#Ht*};F9ag8+Wp!IU)+%eYwZ`hT)>`YVK5MeKc&FpSvvz<*@PAb>N>DxGc8>eq;)LZ)o*L0Xt9~tN$7?ug0q{`4qwy;}e>?GUR ztqO3GvOy^)sS0wEjtXz%^lhBJO{Pz#Gn`MG%qMB5RKxA8YpM!5&78iO(>HUvW-h;( z%WvlLo4NdExBPZvLC5;e?hdL>GL=h*T640iq}$GN`;!chr0bUOOs4IOO4poH@$q(b zTh9n**4$*Zcl8c+jjmtS*R#=V?;aTG=<4d}AECJDGg);sRW&iytn$n_vMI?_bE}c< z>Hvmtbk(w4lDmu{nNyHSoA5iKVX&CC_+kyAKlXxRWOS%M zlp7rG?HlMXVbgr_-h^cWTnQ|Hfxsi@AK2LWrhB#^Njx={in!6*-G??b@NHYzlnFiZA ze!C(B+wHa%?zR@rw}s=iaK0^^Zwu$!!uhti`L>7WCAtSjJNtU5RRENXkW976R>IwG z%p2+L>+T87V-lIC#^QNn#$uTr2trl|rm9Acu`1Wz8k`5p7Ni|E)YG$0+9Z5R$gjJ% zXQ*emmj}!YH!8!8atAs!3Z$G2H!8!8%5bAH+^8(4hg2c8$;mQMvJ5;XTRYhln3qUd z^W4%4$dYprsHLgk*ADEOw|b~!Ll0Tx_y_EqS41W9mXJach81}+!lJ=)N(1W7D-eWR zOuNH20I*Sg^T%PR8|fGA$hHWQw6}1wT}qhzUT;7Hr%+_;I-aQ6ax$n~$5`Pyn! z2JlpsY&AM3ZOo}O;@LR{gPNj~nWjenLRFzP8 zOz1Wfy3L~>H^8xZpimu_%f~Tz%)p}rc)`$zj&kS zL%ZELN@i>wHJkdN#_^fP`v_Pqp$;ujYniI@M|{k(HIRFr4nx z*~ryv8rPEm2uN znic`2M~^}1qrKBimRZRx*F3AH;*=WblPMnH(~1v6OSr{N42dR&M3d{!aBt#Ra{4ggIIn5LX{Y_WHYW977A94q@x9P3Uu5@m9VrA_6SOV2TP zo>N?T(pJlir0ui^+Sl|-Sf<)C)^WxB8NS@c=A3byEKgZv0 zO<~8FIywzZUkyxG4NOlBJmE5&oE*nvcsaSY&~eN@FO!WomlftdRlOF*)fTROi|io` zMRsr*C^5KW-;gPOC!2bTSj_P*@!5D57dA*V1Zs6xX!U>J3h&^bX0v z%VA#)xJjD_ZrjE495U}I4kLE9A@KnYGU5rT*sNkoHaCU>KHsKCt#)6&hke+JhPHSK!LFY-xsgV%NO*Nk2 zEnZ1espe*@s|X#lYaH^b1wEz{iM&bMPKCO?LtX<9PfW_`bjs*1%mOG)QB#iB{W)Im z=TeMfDOFprX|gtHM!8gbquzb;!0I)@?g8d2(som*hsV+$i4$f|v93K#f<1+@0bWHO zX}86^F3G87AG(Ioo|lg~UN+`<-I3$Hh@9Gc0J$+)wJ}+?a~s+j!tG3c?&2w<%C{9u zk+d5WdD+<}y@%+cWW`{|&`4s{3Ytg)s}d=Ey*fU(i&H=?V^vT8>O@M%3V8LfH7t#h zp@DThWzt@Rfb8Uy6QuYGmW|2aYM_O++S9$O$0SIm(ivlQ5o9Tcn~+WgS0{$MOrqR$ zV-i+{L<)pxiW*65#U&w%9C=|fHncS8Yp98q)cYi}U`ji&4e8(-s@Ixgy;Ox$4A?XS zH0{=gJBk;QxfWHL-PSe*&FSkI9_}5xzH^LTHTg=Qq_Z?-W0{vtbakyC4E7SO^fD^- zN>oyFdfJf@LcPUN4D&6|e@qBz7o*jZ7<^}&%Duf!C6*w|G+Ar8YA#`>?G{-I%wj~_ zWwaV_v2Sg#7l59!7L4HV@JL5*pNwY~-PYQ15W_y2gj|Nn$5u=h20c0AV`;%=hWmvl zuUv*vH^Y$5H0bN7zl?Q?tD#1uT3SWl`rd8@$v!X9E9MBR4m;R~W*U9P@jI1iH~I<~ zg#`=u9j|k9yuQt4vPNHGcsQB1`Xn1H?W!9v@KHcnq3~i@y0Kk41Qjc7mMXg#1r^`` zS&KpdRmJOQ@jBYPj;wS@z}oFj5Y?2}pG-HU^!1W(rQY2$j7_|5MHsv+&tZ6!xP}eE zeg&~WfgUpr;r_l=k``p#t}q)!rWLM-}w} zxpEp{ydIEvT{;JHkYvmJS(RGUOBPpT{$Vf z%i%t8)EXF@ajF6ibF>Zv*lFT5LsKR=;8Lxv_Fb?-YSIUKTuiW=6kXYB`xvVM?xP0R zRP<)6<##fTCI5*`Ktoe7kx$qF9n=$0Un1&`} zsE9FGL#gO$QbkWNrZ7vJW0p48-~@-LDd62UkU8wFQpPccWf9i!xX~u^gxK&QE6bzF{ykYTg@>^PZvvaHb=w5>q*_Yjmiu7$MDj zE9ur|eS`oO9C3Rn)tE6xyg-m>i%PgAqfsNHVG~!rr719?CR$X`uEZpU@9GzRH~24Md9dJS{*Y9 zsU<_o-I-Rq449ncq7J5F=F+^QopxCpJg+Oqj3(}(CZ;uozo}dk11ZPhISzN{2{lH5 z_85pc2BMP+i~>-j5>Z@0HG^jks}{L{&0=%9bhL;^E+m_nRmSoaY`8V*F2xGz+^xD? zlgllmt%XqD@I$+Ks}40pKHkpr(b<9qi{}9qZS3$Yy0)Y<9|;e8^fQT3w3 z`$Y~9H;&q6O*wqx>bOOM#kW%b6=Iv(?T5Hh5fro?`iU*H+9l(y_n0zTjP3TXFmdSL2(_Ot`Ji zUf?gG1(T7Ac@&$sSZsCPjrwwZR4<@DoF9*)HlM58YV!>7(|U(I=a#yMr{Dv2M{S{i z|5kfC4zIEuJ{Wd*we6^57{pUF^yOo!Kt4&R1wcwfumEm4Oz;v60>9Nv&~c-U|h)`0P5pex#dn>&w> zsvTbNJA7pAs3Yr?)83?y&_EOH#qczZGjj6;9vtSO9kn#ZmV`?> zJYw<*io@#xN1ZF-Ttbd9Fq;B{YkI@@R?{hL0JYW!XjC_)?x_(UA~?*?I((SmFkkEN zp@PHwt;2^44)eJVZ-qO2+s0A*rx?STnAK($+zee_B{+Nw$Km~1NA0bp9JPvv$?z|%ZI5G6=Vb?<&)Vw54DoodS0`t1bNyZRNOd}XVm@UD+-XS+oc03|Ud_kZD5Zvj~t^w>6VhuIa)8BP6XCb4YL%}TYko2T>)4J72+JPd}8woy`{ku{(~u*$0jMzQFG zPk6X@qqK+NWLh$NaWetolmo(tabK>VEIqxe*Nngt zk~xm7D&_oCT`ZNWEYsxbAaV)kD*Y{$rL>oDF47V18o-Q+=wh&EsCS^7ij%;FML{{y zh3#9)Z@33r5d?Q~U~9LhzprN%RjX7whPaX?omj&6xIxn429=R(T@SW2Wx6Tsbc3fA zGvzX;dva#4X~pc_NS-p-YY%Th?6>Eb(%4h1IeBo61acYMI3PsZu4tQyLAGP0XNcNN zUOgv{cJ#q9h5cQ3*tJ;w10$|IG}t#vnS|H(_DhSkezb3-cd+kdc#7`c4ZYnGvJ}mY zQiiJ%LjxP#EJ{1DO`&#sk;dv6MqPS`*TF8U<93c)9oIdrSXa0CV=By^rK%WqO)XTN zJxXN#-MFfTZrnmk*rSY_!_H~NHnGnh-iEQ?bWiKpYigm1>=7Ow1U{j`a<@L&nq(_3 zi8jNkh~I7%JsZ0)^J5E!eR#l8qbRQXF`27TJDp24OH5*HTyf%PZ(rYZFN!FyvavWh zWgJ3I9gk>krV6L22@>fQJ&;o(J^GL+n%todWtyvcSC0<$bmPi|YCx*N92o5B?;P#x z>lxuTWy(f|dOP}8_w|hN=8;Sd=;?;mR?CCT7B+E_sVr!A-0^{(%+)Lk}d zSM63aJr2B@!qOM<%RG_Di8>AT^|+ywEScsBGu_r&f)Q7qS9Emu44G;Wlfb8TVe?IN z5bF2!^vanBcXo0@(!XqgI|7iSY%E<(n?O`%k)le+kdr9Tl366A(lJzIc}S>iEd5L! zPdrn`Q4Yol9vP^b#%K!b5jF9p)Mgnjsw4wwql74~Uxm?hL~1NpT8-XB|LFQ5qhA_~ zac$wA^@AfPW5zZ*62stnjZS5BDWh8%m<%awl`?R)My@r=z^M87C?OvnqKGD+8w@M5tCCg5;mID(GBxcN184@Pc!~>vrBt#5ZUj@!=`w#ctCN*E z1=z|I&)`P)j6M|4JNl4&%;-ZNV@DsEwM09zG1^J1LQ=BIUhP!93WItT2K6coY6=YM zRT$K(FsN5yP_M$EUWGxu3WItT2K6co>Qxv7P8igyFsN5yP_M$EUWGxu3WItT2K6co z>Qxxjt1zfnVNkDj4!gbDS?JYHa@^=jvYUPad2t0+$mCX|kc zo+5m@`v=x5tS6fXKID|}QT{G`$i-MsR)$X@j)D(471nzK2tMSLSWgxSpF#wN54jmW zWL5AXn}Savx@w(_ty(9o3TI{X;+#xQFZ{@DF()fiDfU)ID_W@+GE>I7n-osb2&iC2 zHV@3mDPgAkU6_%JVMbPlSs{*s895cqJOKnVa!QzyMZ&BQfni2&h8bBE%*du-R*0@( zCSxm@NvndHj9!EpIlV9=w+l0wN&!YjD_XrUqabq21tN|(c%o7J^l+3ey zuGCHEjis8CQk$DN(`95+hevR?sOoeMj3`FC$!RK-@9}KK-87UxI;f&|51gc0*pkX9 zpV7f?ZnN4L!6n<)GMPp$ZzbzU>?N8jdEY(8wpsd3a~m)|NwW-|B7=)-1<6Y{IgK)K z&vC$zp3~h7CnUnH9O7SPI5kr`Im0IDC{$*Au;SfiT!6Ef5I6h14pjn2Q*|`E`&W0a z=vvd$wXQ^3J3IRN21YjGG`zQCHQ*=B(Lve44G@`itG0%*Mu)zNQDXr;t_ct>SK(8fzMP>}hkyAaxQA zsioFE22pg+z^dMUBHQ5+Y)Gq|GwRSKo#8w%hRD1#>To5UQRe~aj5;)d$&||*aJ+Mc zc*-B+luED84RAwJjoX>_Tp2DHP>-Mj?nx%@1@JJg&SKzJBTtIA;~*O$vrDN>^>j*! z0Kin)wy9%_bb~rCO}8m=HQdADy*`f5hi7S^nGy>t8=B^!I^EJ-rh?p6u?%j_G^=rNbkHrEM=A`-uFn)2X)!dr zZWTj~s;X2qGV-vDY!_cx=OcI=1BsHm6`a%(Yn% zjdbl|ZoxLMV4GjC9bT|4DANxFqYAbq1>4aD+c5>(u?5@G zg6+71ZJBE;QD~_eEq9+80G3>3DgRPlT`8B^jOJ)1a-Z8xBe9dy@amXdlDR7ss*qL% zc?pB_DG~;I6bOUe9>Q>w6bQqOQX~xaaS6jsQ6LQV@Dhfbg!kUqsR)A|1;SuA6NVdA zt?Ib-ys%TQsjIMaE-8}ZPIYO-g^#=c>XsxYdXNmeJtX7Ca7kuN3`sKV<0To_%R@5k zHI`)9lehrfzD~jA2kHY45U{f#uVu+2CEeA-l)v>V}(q33sw5=A$^A-c-2Q&?Z;N2;6q@?rC8aF zCgp&T7wXYe*6J>5q*L`z7K0hWq$8~w@1{x?LLdMkyO=|gwhWn4d;-85Q(k*^W2%x> zHQH63%5r0>F{LQL@5!Z2q5$WTQgxi-5hQo(jO*~;mMTo-WNB5+vZBziClzPu5%4Vr zwtJh9@wQxHGv^P%-eMZt3oYB5##Yr(Fi;rE89_ zl;n-3D2hvJ@K&{Z*GlVSdzR1V+O9Fddq3_=GN%VP2Fp6Dm!{&i&9xhk6fXq zVt%;(D2Y>sz#)m#b;vP-)8xE>biB1|^46hAL7}W5yys~~v$uiG-exp=;n1w|D?4sN zGjLnc3uL@nKrot8l$G-o)}q=t&4adbq-mO3#7N~qBN55-tC6T_ng=Vr5rCJ?T}(pb(~U^?D51LQ|Gj|nrT%{+NLH->K#+8suILuip_#}i*> zjC9cEHX}N2X?iP_QAHKRG#C-pl;k?R32ZMsagOHZi$#{#jm-m3h_{?Z z#?s%}Qn7SDQT!1)s9QEoDzwv$y8B z2wqIp?1fOX%CGF?30;Qq!3%!u2~iePiZ^{dS>nwU3RJ{Ta-be333E#4)FMF_!zD?3 zoJ7<`rzC6TBu0s3yQBz~CwmgfQ_g|}l60#03cq>uk~!ez3RG43sQQv{fG0zeDeyWA z)i3sRF!mM=tBH|9M~x)JYj(xrCkl(Q9e zoegxa1@rymdS@XJQ2N9pPelt9BNlY zDqO@W;yD~e)P}>GhH;OJE#h(#cdTWhW3F~epYeAhrRP34KBSk6TwIqs;)Pn{J(A*7 z4o4BDxWecS@s3fr+$b|BE1btmr+Yd-l6-(Qxs_eqeDd|+3`nZ|m zx+pTcrWLEnKGQv!v6t+aG~>hccY>~`O94<1@8Pt2a5;lJGSpC+X9n-R6dfMc4|{S& zB!#1hI(TP9Wl-wYL*{_n7c8J4oqH4ldC`v&y>gxs)MMp&Wx7)LAVj*RVQZ^!NkjVV zh5cCC6YU+AxJ73t(tkRlVaFDyHU+Oe$3qj!DTZ*Gecie#aU5?!lLfh{RBSh`Ox2}`WZy}G7%=KWe-Z_Lzk~qa{d^uUk1-}RR@M4hc1{E<=#HwV?Y zu?Y7aK?Kd?miU~)yTosvbcrvI>hM&aJhp)7Yzj~24Gnb2vj%v#g>z~smOIUm_mex< z2#`C{$rRrp#+*nys&K3P(y4a;y!pzjy(zc=gu;$i|B>^8OI%5%RI?pE2A6Gzar){% zZgF^hSI3}xOn}PB?P_qL^57Dts$^P;rGjym+w5SxgeHf7j0iS7Ooe(%3 z=YzU*Nta+?L&hcR=;*b-4??BAT|$X8z+3O5S0iMCR4W99>E6E* zQc;;S*d!Rxhj%mjEh%#gfU*!bq;yqJrPO6>G+Q2E08L~MAzU6npaUov}HLk)d306$rYcF6%B1rovvEd<^(%PP7c?M zx`Md0(iH^hbWvD32>}*0m8XJ(y@Nd=(f}@#O~%*OCdV-s6PDnDQ_qmhwjtMGN||Hn zWlGQ#Lv4Ph!&WD5*u+ziuo+=&es#-MFE~IROX0e$BzE9dkg@qyE}KRB_y{P;M?Wy- zkr_M$Eu@)cs+st4fabn3_sA_MGJM`937 zPy+-XeZeh{w1~--Py&C;Ca2?9$806B0k|lPupJIpCy}^Y%jwk355!ZLW;21=j6t@N z(1s|2+fJ^JIs!wxIh`wEt)vj)uQ1hCQip&8r&IF25Lr+JY%@mMjN!Jr`wuv9e7@7q zM}la-+g?uZzAmVaD2csR@W3NJG;rE1KV&QUVPdk`pX;aI7eV_uKZWstk19XI@a2 ziv9Qr6o=)+9TuT>ScKYP5o(8@F>qLv+F?;@M}Y#PzN`Tx?-VLz`2DSHn-dm_F!zIB5+|BSAdj#c987mub97Z~QoU3{D;@TCv*mCl&xT9aoGst# zO7g9)WJ5z4u5pj_c6HEvg<&|X4!%~bC{>nzdZVLbT`9T%N5@?Q=m(6|az^(Iz0K(o z94_|^b@b7Mw{D8p0S2Gy20CekD*SssY8{1RoB-&M)7#AlXYq|EaBDp`J+ zGRyC*Wch{4EWfvs<(De6{O(GYJsV8=kw96u|TQ5Ox98Rmg9>IM_s zt);}Sc61JG=%H1nO2wR1hF|K)uw;FPCFL_L37=t!_Y4bbW|-H^un=U1@ioK3ju{qq z%&?GShJ_q6Ec}>ZVa5y#GiF$rF~g6OWz;B^%(z(0oJxj;8#DZtONJk;%J92y8Gdmp z!%K+_FC{YkLRf}5nGAC_8Ga-pqpocxGwKo$OrC!E5)d|AWN&2oG7|P&$W7ZV>@O!H zY;mgI%Cc;BmSwZE{1{u7WwW#D@)F{^=_MAzE%SxxmZy3<%UF|TY{{}*b(ZC-vn*Gg z<=2a{ZoT+f$Sl8{lI7<#vy5d~#ABKK=}JE;WI zCO?4E*Yz>pv63D5-7)-cH+O-DpT&T(0 z(OAq-GlOGHAUh!5(A&M*6I!Y~ICx4I7_y;`&ffm+QOau?T?tcvEl`L-S1`ar zpb&~N6&mgttMwjvV9#{?wju2_7AspS0Ym#X6um^cIP+M9HAbB`4m3$C7*n!n5 z#dkfhB{4KW9u_@!!0Ai+z^4*lL;+J=2g9@A=E$WAWn32qQpG39QVK3kyazp^M0H-% z(YK0|;0|#AYS}*?Pm4S`0`91EtcC<3J4+-I;L$rOK{?!rMJ|oPu*v3O+Q=uo5fCTK z6ony$omNZYGT;mRF4{-CN~jt#E&@Cb;OAtUjgxqec1>6Hm46^YWh1At#dq~X59V~2XWdxmWY4O5f6(XuwG6sAw87~C-oi|j`ch)yz1+5;iS>y!aogoTsQ&rxbU)#X)hVL=xkK_N|eZGJB z=W0IxeE;Rpuk>FD{c8M2xX=H9e;4!z{SQHZ)c-8>=lpL&-yJ}F{3rHO=*I`Tp|1{% zLf;rT1^TIh&p`id;6mtI0!W2_bw(=smuAg}e`pRv$DfozFA0`FpB}7+9tlRF0)0d9Bt(l1?Ybcz5@N#;H%JI(*ZsFD=_MV{{b$AK2@Iz9sdLj{bTxG z(D%^~fL^25K#%Kj=m|XqJ)@(Z_?O>i=(F{Mp&z2RLZ7G4gMPSvIP@d+BcXp%Ukv>? z{W$2y>&HXKfA>PizxG1^mcAAG)%rD>kNzhXdWBH|y$1it>N9f2VbG5<(02U0>PqOH z#xV2^#zyG)UsUM$M^xzN80SLAf1N`AjzPKIVeEi@w{bUg{C_F*2aE@x|HAkM^j{jk zhW@1SB=i@ISF}LLA2Kvw=$Ozk&<8?af{uUCgnoYLeCS^beGU3`A>ao6yCw98Lck6D ztK~1DzZiN0`kSFQwE+Hua+T)8KRBW+{JY^((4Pta3H~pJUxNK_;lF7<{9|Dm^eJMB z7NGwkgdP7y2z{m~hhB;QAoS5c5JJxgz?uGW5cn*S&KA3{t*o|#J{2~LFjU8IduFN8c{T8SHpi0 zYxtL8xQxF-{}}yetopxL`nSk&|7o`k|4MfU{z2|dEtqu{EYXHAMfGVLu<5l<+W^k8U)!PSU4z4e+Ue_hhWfR0q<;JQ zj-hqhmi6n_uhY(wIs5SM#Z*6^Z$B+arglA>H?p~%&0E>LQ+pWk2JspAzhoc&-PWfG z*!8o6Xlv4o_UqxFz=)YpwLBR3~Ba($)5+$F#D}enKGs|CxuGKAoZZw_> z{k-&R(03e$5e<23ZvrRD-0+5`A$Mv$l@&ysH5C{sDlV*;4Sl{036;O>RfQBjm7?|x z8Ed3!N#)k6b1V0*Tmp4K<;tojsBeC82oKmn+o+`h}>fM!5s579JA@ve`fj{TPW)=TZU6jw^pvy{72nREk1hb(#N%S?NGqZ z^UL4nacKGLy{^gZ`4`9g=Klr=UpC$sem(j7$NT1YPVm{{^~rDcy57G%KRPjP{_=@_ zllkPgP3Ak+&)bsxm&S&XYxipt{qiS}U;deiAzq)c@b`v%5PSZHiLpOI&ihQv?S1G+LIr&{|J3__t==*!@|6QwW!}}{Df0K%rKM-wrA4w)1YaBNr<)VH?o9i>y zRO1dopD;l6!aLz?-X5ElT={<#{qi>!?XE4q!?n3)p{Kv%j5{Trm=B$KQ-1(uKaR*3yc2w-xlr4=B?5Au#fJR zy$*zOeHt?43wX66aM0X+SO_P`OQ}oH-S+u{GE&r4JPu?redxaMl zKLHN6y;DjzL}3E;J7S+bF?N3CM8AnX`FZ)@?|uiIQn5emoG`JhF+T4w#}PO4p?+iY ztNKuRybIJnTz(%l)kJEf9P`BUzpr2Z<@Xis14nxQHF&SA^SxtZxY#|`_rL3+d0NfL zR8Iaclb812so6&x(I&6y2lXXBhdGk>$+M3yA^)hyr`)yYA9HOV)SMjeKWHv!)r8g3 zd*zXT?!9767M_26GT#sG_n*WDm&bVbTI7HJ?&1Hv(Dz!I{r5^9pYvGC&fh&g-0RL? zlfO&3z5Jgy#(&@b|F7g?+wy-e+TY#w?)^L#_V1q42MaBZ=O}0*Q!~QSL{1e{N@=tnQ|0R3le=y%^ z|G~T_$tpiEmYVbTj*pc8#(19(?#@rL@>99&eq(HI`7exhzn9Bh0e!f6)0=z#q5L1- z&sw9fivBC5R^!lQbd{%l_xJp%y^{BemjCQ~#h4hLe|4gt$7hzZ=dp88fWHHIF zxMPujWn7#YGW;X2PV?Uxm+uF5y1V=zI3Xv;LJ^oJ2 zEPuyDzoJiZzVz~R`Adp1Tw8wo#JzMk?ElW3Y-XNVdj746e*Y<-cdr4R-WBJm4_&7D zp;NwRLNyA#XSDxfg#Xqq@&~E%`{UE!SB}2fxS@wTO&3GgWNubchE>>Fo4Gy9g=cS7AW z8@J4~kp86pl>WQWTj8IFcZG4|>;v6{`WQ-o1K)Z0FfYx%6yFv2up*g#Et|M?A!|K( z&9&L!17>610DQFB*b{}@kK2}h++Wf(OS=%ak-n|{RJ%a?nf8MABcJK}lJ*4dSzhit z!FQ$aW#5SJ72jLFI|FY9{^k4Mpa?GU?bNe+*1tFIz#0C1#NMLOKNC07uJj)w?iaiK zYj7LzC5&x8BZRr!7djU6sZakZDAQ-0Pj{z`FKJ2AF~|D!YVt?uCaK>hQ;|LG(x1p>pC~FIFsXhM^%6ds(kl%!yFGtRs z5z{e3yKmEkenb8S{YjMf6u#f(M^V<6&|CS@@Xzt>!uJs1Bv8U8{Q<<-1@jj$AI(#1 zHidS>%;z_SaW<`$AfH{xXBYC>WtjOl4GUi>AT|}>UimkX?=IxK3;6=8G4_^9Sl^hx z1o>Zs{5K>2YmonD42g=()J&yc$ zgai4@!$EvMhkX~mhw?kb)coaQ8Zc{0(8}*bnZ3G$??!z01H!xV2ZkC@Rtvs^WSPrR z=7A{hKr@oxY1Za*nMu^j4T{fJHmZ9KOTw z&BZql-+Y804s!v*7s9*}d2B=48}rNcJ7C@q_b$}LM6X)-%3$9M=6=Aa{k0r!-2OD= z({iDM0pmIN4uSnpe69G}@U`Qk7A%MPZ-nRbH&~0c97cip+C1$jj07uiH`2mL@I9?T zyFt50Yx8aJZP1qbzJeRq$Kl5HR&5o=gYRhlxNE&cJJG+&{{`(-|E2zKYnRA-*O%em z^)~I>fw{O}eXYDx{atyd`c~YgK2N(Nm=313hk{FR3;N;UUxI(peyQ)P@2fqc?~nV* zzmoTpf2}8RGx;%jGx>3OGx@hhtx>BzVZ@A>_N0+8653Nni!odKow3YVrv2VH!8k#C z##mvj(EeboHP&g*%3HzD;U=(O`*Y~T(23ehq2bW5_LtCx&<5@0(C0#@Ykv)0AG%)q zTWDKooAzqxrqE5=-$QqWc4)7KUJ1RTy&ifUH-Y~dE)ADzZ-u9Z_t5?oo)O+#%ZKa3 zw$C3vCVY%996m05f=`53ggbnt;Zwt(_e~979=_7Icld_z4Ze?ue-QqGZ@=(u;oE%s zhwljA;X6PW!ti}Ul!!9lOxy~t^;OUvU|*#;LwvzkCC(RL^VNuNiEsI$;%2ek7ZbON zTYYun4soY1A$Euzz9il0^`*qa;t`)MUKg+XnoPqqe7IArjRYvQyW zJ*PYRT-@Y7LO)&qyncrM1^q1jZ2imnSM;yyU(>JDx9KaXa3(_hnH*Z-;iOMhGcx4zr(837|`7)Hnl zqj9ET86`%kQD#gvrWtz~`x*NiM;Ko+F2sHA?-*AbHyF1VKQeAL9>n$Hl2ApcGSm=i z2^|zVI5a18Na)Z|Yp5;M9$FrHEA;Qs?od9gg?Fmi(u|n3X2!H}^LVkZrJ-`X%Dmc8 zX}|noRKrI5<%VSDjfQAucf&z;uwiAxX${FjPS4n5mFaQMu=lge?TDSQZF{zTC?58h zYR^FUc;9F21@>$2pcXe6ld5wYCQ#A zYz5VTfntJcM6330D6wB_XtM`pZyEN6hPn2s_UZOn_Bjm;?F;OS?aS<|?Cb0sp>DD7 zwC}O+Z&+eK*s!c&nf+)(pZ!F`P{R;%IKzGm`4{_F^$0^$LhoD`F5I3%OH?gY?ae=LKd24)a|QI4W?I@7}=qfeU>b-X_CkAXCR4D z<8Pob)Zb{-8}tjLhj-^{~{W5{htio9J<-RICNX+HvdtfJ3@E(mxO*C`mz7$&`(1@ z^&bQ23)6orjlBL(h4%^X=kEwthNJ$Ta6|ZDe_uEocKoB^`QfAd8)+2wpC0ZEukxQ6 zJ~4cf|I6Vs!khi)h0hOv&Hs(?mhh$iOT$-%xB0IO-yFW#zb*Wu@NNF@hwlpC<-aL> zcld7q&EcPh@AYpF|8MvK|1IG^hyU!q4U!v`{@Y1f!+!^j(f+$2aWUZEAubdb`F||F zF23&niP$Q(`tPAJ+W%7;qy6`apNM<>_lcj0pZV_>&xmLJ4~Q4U3;tc=CGnE~7vg2{ zvj0KxH}N>j>)z z|8IbMXW=^t_}8k<1s*PjYS)%%CumvB*x%ERz+C-P?Go*0z{MZMUWcUA2JLOa zNZ;|kO}?|i$3tq$x0>c~-zetr$9$h5*(u-mC3Zdp?40ZS2hHmKj}wmitNk5NHU2KB z2=MjG{#yT6{O9_Q^q=Ry+M;NJ1BVBe`u|0;RslhLL0}K!3j*aNWfiC*DXYN2gx`U)3BLp1Bw4G#r6g+=xQuW; z@Eww}3S14Ds;0ml!Pa1F;4Z@Zz>eU&;Jm<(gNFwX58O>sR)L=cKNK0zV~L ztH8aGui6lJnk1_Nzb85gyh+kjK`Z!=;O<}rWTyhbI-;Clf@G(H^+Z3xB+*YWMZ8Hc zO}t6aCfTWA17xS_gN?+Y1e+l>bx^Q{Xe@XTXzbA79FlMfE`@~CiNTIgAY=qjBsvL> zf=&j58$v^&lY$#VCx<>0JPj0bR`Bznith!#61pLDbMSvcKMdU#yb$zoZ}1x=jTF2R zlu#19DO?tg25%3?!^Z@F1B_p#2O*jCeSLcPrto(Cc*1FYIpMV4K{%~<5>D$~gwuKt zaQY>E4aq9$YsJ1|U;Si~QqoT$`6T^R;zaaKgzNg}2-o$`lN^$M2FV-gUm$rS{Y+s0 ziTW4C7sMCzv&9$17xgcTuZfHF%|r?M|A=phZ|LWWZ;Ef~Ulo^$%k=X=8&~M(i|t~& zej!naei2cKzJ(}6zZev9pMD8RCh3=wWRkuWl1WeMmy6$t-|1I?a{j1aNtB~sBmN@( zqF*as6|d^w75@Be`N3;J6{q>8OL{n2(!&`fMd&+EQo@5IMd*74G_cY?$KMHcw7(lze2m2V z(8Q&&KGqw_?8JC07-ZZWt8Z)jT8Z)j1jfIWxl5C)H1IYs#+ejYJ_&(8_aTC#- zaWlyP8rwu#lp=b6^g)?29siH1=v&c8qfbPii9R2FIrf6^q7?iIv2r$M%jLKrv#K-i#h!{i8+$SK zO6>L6+i`z9?2awcbV=W(_py{Wkv0^zyA5^YCqnUmCwc|6%mu zkE*c9EUB4Zvvb6U+A zHD}kH8+)l{RZU;?sqwzir&Ou25oJ!U$2w83o%k-Sxuj-m&DAy6*W6TdYt0T>-+L*f zye!uI-m2!|n#XFMs(H5N#hO=YUaxtZQbhcbuuM5W=27v;SQVLB@dSMAu`0It9aK8z zRTS&K|D1}x7%7W9Qdtt&vqp`%zRZ z8{dyq^hK|Vmlsv+?#WeTe(df@I?^1OQ}GPNh-Aqp`pP8g_2@@Zkwq$f?7WYnqHjy} zm@*+*KZ%N+7da+!OzgRjrXrm&e`PXq0%Z81BAu1Vm_K&uBx+l1TYRcVE%(@6|E2MF zP_b|<>oQLadTY))(r$~?iVA|o-bkE+#pJ=Pf;iJTJI6i>i5MpY)`3*rkRXGYE> z6Uwa_ndTUm42f)>46^@ezgSu1yjYo1ku8xevGY(DsK}*}OOeZN1)v@V zgQB2f_eEZ%ksz{*Mz89(B9BL&jyxB6DRSQgpI2!-i@XtgJoZRrcWp4XD|UMvOZ5+` zYGuET?XCB4c`@*v>@(sYNYzdy726)$F5mv3_dgB*EMKafQM+GdW$c)W=WENO57$O8 z>)u|Qpc%i`uANF+U!`Ot=Vh z5XOsGCvegP<@Co!T&_r(Xg_f}MXn^4ReXiZ8^n;0nv3P^J9cJOGoL%pVOEu- zL}ik~h;qEMQhX^vO)5EVOr+^p9DL9&@E-TY9s%t%$DTvoUn<6vV>fYk@7NRIEKiAT zDlbD%oeAjPj`Fvl^_Rx3h+P}o2E5%4N-T#zW@VIhA4)?>@Oc{Tt|T~7`(rPm4R4_S zjcCDcP_0?nC~GkTIqwI!N6^D|e0KcMxP#fE5wKevUuyiQe(kL2%-5p#lB!=zYSsZ{ zQ?BT}GvAt}vA;2^gly4!$(%KP*4`@4tmLf5SqIH(n>BaV!dXjZEkpPLGM`ErH#$CC zhV{)_IcwD{aHq3|2-9Y5oOK$R^(LuVXG5Jqdc7Gt0X|b_ojdEoS(nsLRjTf^x)54}yZj>Cmq`Qg>K!0ia z$X0PNg;ZQ7!wXz}#Z?v86;mLb(o?Gbid!n~thlG*ep+M682yw#*-*+8b+1=EQ}KMo z%N4J|_Es!ix2#g556Y-4saqDy)-8)@laB9zx|O7qnJ7z?RaWAQk_~1u zl2$h2$tvec)rj|=4yv51xHQ+4p>1ByO~r@45Z{u-8)Y+BSSDsdRbz;xNo|R`v{Z{y$TX|vSC3p?$YJ}cYd23?Ny3;D}t=xg{ zUQh@tj2>6SuBdzp`u575l@CkTW6}q+W9*75Km4DinNr4hvGNsZCpT2(>y>X)NR_|- z(5i5?S$}BV*7#ZRv#Mss&#K#6RaUj9bnQz%bz3Q{sv7=rWrrJxjF*C(oWSM4TyWG1=1O8M6(;ukC5s+X!>t$n8I4N9YY+>rW1>kq9CLYdW5>kmyl zSA8edSE{FLo=rT5wfD2tGhDyA>+9{r71a{b1aUyVoZwC$*{UPd2h|C;Z}ctlGi1pn7rjWr?Q~Pow`=k*Z!=y%hR#`k=b2*Ve6y+X(3+RXtce zNIJd^>;tpr-s)59hU$i@PbXd4&SLYNx{a=?zChWkFWzgv8QZF_+iO3R+$q(iiO#+D zBjuW8tG-J4xjMx}8l)qLRo_TZW9U8Q!j4SxQ##oQ*44Mvyr^O*$j28{-&1`*=GW!b z4^}@~{e)D{#FxjHCvLBPzWU|F?eSAbImH_OD>79jvqAe>y4b zWYKO`lH4)bXX86JQBA7m!pI!#^I)eZad)Du?!|hu=IXlFYpzd}&3yU&DB2q;#!Eb&c)Vsu z&Am1ElFg%l2_Hle)$CPH^fg`)jdAE>*k6K@y)ve!RG&!v=l)5&^a0fg2`KDay^osp<_X?`+DX7O>l{h7Fdtx)GNEoUtvS(sfWZ%RIptVhP*GFd7t&CLHuZ_g( z<`RFCD2t?t+lkDRA<+#b1Gt>X%-x|braM&7{c?X22ht%(&7Ry(!jwUOEcRyVx9DXea~$E|B7 zUD;qo^E|I@o|pE*$_6~a+E^Ovo1ti1^m?pv4wCDfWiZ{fP8;kCvEtc^7+CdSm7~77 zFy~@5voN{@ek-x6S%o!CpIqx)0^3HcU{1q2=4#mGnn&8Mj$Q(jK3er$AH9iII+8B~ zcLJVbS=~xCE+(Fnnq~vV`nDzjBTzv4Z9gHgZtVdd3xgNx5u{OyFGR{xOnF0V^3p_l03ZP-s=w7tDM#` z?pPnk*dE6y9^bD{!`NG{##-X);_vH*W?buzYp$vIeT+ig@wM^6_=fnY zbq8TA!CW3cr*3Qfg1W7HmDjaVY4MBWm&LEbXj% zpNKybe?IymYibqCe8y?cL2p5=_X zv+K^SyRhyOj6+-Nu1;*OyT0zGx?3?r-&?n{?qN{eQ;AcEXO~?4D|N3EJ=MJpZpohr zlb!e@@XY%rW@2QEC(?=L#GFJnF&{A&C5|DAmb1c|M1Nug^m$5RQ{qfXyW0}yCAK6k zov{tRS0t`YY)fnhRo{&~?@rv8*ahERiAQF>jPXp)=Wx?3`x44}Be5IYFxDyHg!ij2 zua5wZcKvM3%ufA+`o;B2>zCJeV}@TlV|)D|ZiHlU7wXHJ7Pu&Ik>hy2x-_|nv<@!~cjn|Q{)|&Ne^=q{jo$htd#{JtL zXb0gA?j713{Vx43Elam>>7KX#kaieu;6ADyiCeh8(-!H!*MF}ar9Z1br!CQ+*Z-^? ziyOIbXvgdSGIVVfZr_$^C(^B3Z6og8?xmeVcW<>%8?DA7?K8&F#xdGgj3MLm+W#15 z;+5rZp32y8z*B*dmi>B=i2f{(^m$=fF7#X67rV#{<5E@%6@7@KOKZ#IT){4?}Pi#bI_xQpyv)n z&$ViM>22u0PoV!Ctw}#jKMX#&8;zLr_4()_+&_WO0(}AE9HAe9URj8qPRX7YvZsaY zX@Nfe0whz;($50k;5IevUqP=2WUudyUcXqY)W4yBL)%-wM85>~Z|dLFrt6pLmjZ9T z1)P{JabgeP#O1JGpZIjanGEavRFJ zUB6w6>URKd0uo~az?l0XMe%_C05BCdxFLtJOWy^bU+BMp&x61xQ{odOI)G0hiBCH4 z=~+$3{qE-w|9Sm+tz3UWe?hCzU({cO{m;O&3g8)Dy2icl*HG5$`afa+m%bZPIZ%+9 z!ToR8ar;}FLHED4X}AGi0{>E@REyvyc$sDaFQ>vj4cIwDV&^nqCth5}?eP6I8#vmg z8AiL21v{2Aa$1|=;I(kWm}|__W*PI1!(m@wEYRlQF8LAKY~%m2_a1Ok6zTteb*P^1 z4a8kw$tYp~1r<~T6opyCsdogkt{%p{Q#k`BMAth5>gp*5R%G!Ib6^lW)0$2_;~KbA zygM;x!JIe){eM5t?Ci|$&ccGI_x-*8Gq2Ax&s10Hs(PxPr@H&;J%V2o@*76>7CN#w zU}T@f(>^ETOT2e*N^mOt)L<(7X~Ajm(}HPcRB(E5x)~mvfeg6F0C!VzU;24Wnc{W4 zyUN23Di3{;hs(_f?peRWY=czPaP&%KV~EN|iOR+Rm5o6v8>MnDJI^<9H#<~hBUIT4 zk&Th?+}mynxx0Og@l{TI?r#6qBof~xzBiWp+3m6cr#v z^`=o!^Ox|0=fF9=@!0-bXlaUqbZ0wMV(ChsB_fWY#fzDCGe$DDSQ`X zuf58iMfNr_g$1Z4##aeU`|%D{0z0S#`bglFDuEt%b{=Nhs~m2ra+pv#9HesCUggl! znKD$_^HlacmAz7xy}l}Y+o|krq_WqI=Mj>oR3&hjO5mpIWxiA;u&+wsMk;~bR06kE z3GAaYtD{oq+H)+v&Q*juHsM5VE}%3((< zvvNn3y^bn-p-S2)l{8N!Z4!tGM+RyD5#1yHs_AC1pyvUwwS1{|RCD65TfRAyNLmRk(3op{> z1~$M4xXNT_mB|h&lU8N2zsh8>C2cva`x$2bIY_DwCf2?%zTsvp^+teU;4ZRVI6= zOctn2j#QcCzBOdBAQ&HvH(i5?c=_+DGU=-{c2_y{RSrj}9B!?0=&Kz1DumncrOM-DqA zIvQ7{F`?3!P-#r4G=?gTUSjXW-e#!Eq^B|&sZ0i|l*z&znT%8>1C_~0WwIoEA>>(8 zmCPV~DSXKUDxZZapBt!rZm9CPfy(EGDxU*XJ_B7F6DpZj*T#fOW_y)PJjefVIW6Hh zyKz4&@4OKD!&M31IPk+2i8l!;Nr&jsZc60|X6J`L3k6VjMu0zm=Q&G!*AK|k=_(`3 z=_2oIa30sA*Edi(+Cx$~MH1p3&q#y@oe6nF<2>TypWmG!)Ok*MPx-D&yC{8J>Getv zQrc6fxkBgo%Ue9Cvf2 zrz*Wz>0F`SN})crhawSB-pxSxuaxp01#%PLaE{9}wS>Q{Wo@K6g7nBdQTiP{S5j%4C&p?_J@her9RNR6%j5eVg3k}Xusx65|EFnBq%~A2P<5=(7a4MbCGPvs_k@OHl^&*aH>HON4IUDj&^+y-t|cEmi{MGk;c=ybQ18D&ZGWNW zd>LuJjzfQ@b35nwf{wj&+>MF3qdOb=7k?yY@rH~yubq$VJLSp`_U|HOQ{mlhl)fQ- z>a~l1CvlV?%#-cJ5#HTKXyPj=H*vc&T=P7J(ob?9<-C5a;ZuYL+QQ)oJ-cCgUd!Z+ zurN3p?xZn~(wIdWvW3PRq%q&rnC&Fo?jgLdyuYVY3NQENJMNo8{Ye_)xvTr%K;Z`k7FBkkTVGWQI_8 zd!c>@rTZ$a5^7&jx>Bj;V82&>6QQn3ihH&2-VZ{V$Ans?=`-3@kM1Yb9imig?p14e ztx*44p;qHtSNSpx*M9W(7T(pGdnao6K#g;c(!c4^l+q`ZULn-~yU<{a(jA0)$7%Q+ zq3$@LSc*{Rw@UXBYW}g3HuMyS_Q`Td2uI(v8>mB)iQA$ur2 zSg1c)XmGz!ua8h?7p3(go6hG-uMz2U(yPNm%HN~3SZSR*lXJh@{R?!dgt(Vz_;X4h z7HVE~uOa+?q2^T$pQm&qr7tRdM5tS#{6gh#Qa(+u5$Sf)E73#B-=nlxY26R+N$JA7 zmuSdyN*@+#Uj5;7DP5>}Rm0~g-AL(+N*@vGRw%zv`J0qi>Zj#m8<|P0ju3W7Xe(b= z0js@?O-qQqRH=?_dr`cS5FM*l``u2_qbi%ewliA2q&h)qjZ&3ItMdakxg0%5>Dijw zpM-a{uicB4|4!-WLj6+ZuT(lpsmisJo-v}8ThN9@GU{9%rS85Ghqr|Z)zaN*%11(- zr9$1r%Ap($m0zs%Hl=A<*h_e4XARNS(78-Qey<^E`O+3}kB|_rK*O~i-1C$_VdZZq zWwh|lB^shF<87||bxO4+UWxL{l)fM|*g*N0l5H`-zjt;l0Ehr56ef|E2UL z=(6rkX6ey4T#PRspH&wX==>32}NuhPj%tAw(v zBXp(Gca(mwbQ7i93gxL_sB^T^UUC*rPstxD=XJ5hnJd)OeEdGb`+?G48vZM#`wJx% ztpt_!(Ym>(HiUDI&MTV#Qq6y<+P_JNdy(dRk(QVq2_I|P z!Fp8RN#|aw?SHApNon{jO*KnHu2cRx<#mj?pKF~z*ZP01X+PIEU+6i8n!|@$&r%8Z zOC>&3M*iy!lo0o2nPVlypRM6@G>18Qv|KDo zcMSTwP?Cs6Vf0D*OM01{`c}~(iC#fZS6FZZRbEDGnO0Q1y ziKhv_NvL~_=5vf%!N+LMyGhNRNX{B65)^5Vbky)-tyPhfi|s6y^(h*zJ?{KLYrBh3 zCoS)n%Te!2$sa0hb)3@4TIb1H;$%IG$?0%Ci^+NxlkMlkUnDuWDXn2jV(n(;f*uL}Lz1tPejdfqhJ^gf9}_O=-@@Yw0IwedcS(aT;>GhU}#w z`w8#uuf4gCguu%g?XTsQH&E%v1C&2d(;lGpIY7_x08QJEg~V}h*Rg%Ow(2O2KT31c z@#zne*7HXRWrt7by-M%a@b{E{Bh>3D)O}JzD$~5?snY8A(~!HA-mY1)o;Dbny74L?po=uO(eJx;I@z)x;OT7aUZZtLOXao7>k8t|RQ@cX&SETAG*Y4N0CwiE@pYeP zit_g;zfHhSr1PZkW=U{|=!C)d&{u?aFVQ&9DScR|Ym|RR>0V0b3N_2vQI`_ookxVa zhbX^L>GMi&R{DwL?EFLNQl+nISp%G_3IDs3gicZZ9_6=jhY|9m@MekYOATGD2J?#W z?j;)MIi(K^b&c}RDBVlxT%l%}^H1_wtRasGbq`T~q0;A--mLT!$=Ugb(xpmYReFWD zHQ_Z%rzyQe>7`1w{hbk{WGf40);O3zWMYpy*-`9CR5YclWY{Qq8p`2;jErP=j7sIwfPFi6sq9{| z?g+oW@{=_FB#l2w<4=qA*s8^u8N}{W)gY%%C<8YzQFkSVE zgt~JyrplE2fbtLMNPbZH*L~T8ovLZiQhHIEYFnM7{4q*L3w0)Gs$DeXSfSqL%1_fg zRVv-Plvmkgjbl{1Un{*((_W`kEd|pZFf?dRH{4b&UaeFOO+m?;RiSH%ucSZW$gLONSmyy*a)Qu3-$UaU#|JT zpmjS#`4O7K#meuXbehuRG(4>}rB~z+G}Y@`+wMZWjvAtE=*`z~U)TK!n!|QNkr86L z>6Nj!$eMShhW}kPoOz-VIrBt&bRH2M2`VA!l~J_9#Fnd)7ZH&#DZ?ir>rfJh?8s)Pxi4g^~-m>MFI)HL!mLU8(=bTG>Qkt2g`r? zWPK0ozn2MNHzj@%ydnOXHMPdf5P7FvIy|mw412F-yv#9)8-I{~r(HTsN+9(8Y>Y~{qiT| zEs`}&-fOT~{&=l~_R55}<_kId282v2W>Vz&ZRnY%M{-*;-w4Ppx#8WM^W%pydBk(m zT-K*`_MMyYYm5+f3Da+K&CRDFjg0C%pO$a+Z1ygeg?SRCgZia^vh_>XAR9k^LqmFt ze`&aX$=i71&lm}l;@vrWe5~erG|sd~e0cgT1-$3;B$7408#bM9{H44jmV7GlSI?Vb z;bcdz@m;Z*Gf%%MR*&$uSl%!*IGtWY4p(}zl&kQCVeCI%X}Kg1p$8M-2iy_ zFVF~sNc#y`PKmOUnEo(Z%BSJ&0v#Gh{sxU)Izl?uBX|{V_~d>2Kph_4DQ8um=K1El zdF4POS5NZHOsmRo4UfrA@Xz^aIoIbceeK`AC)r8r^f-_a_mh9}oKsxAj!QkgA-|#P zIN#Q?%X3amqW0zO0Iao0?FJ2RE$Ev$&TPKO6gT|KhKgLuwIpNu0?|4K>AY73$D4df z^{UyxG|WwsbIbP+X#D#n{%Ss|1rSHBKy1($w^zFS+`eh@c8VaaH!$0+m-~JW8B2U+ zjs|>W|G%|QKbM;`bpL_}BtqBcz=R4doY`x||IkTSln9ljcTg40F z`7zf);$*svl?$Yfe7eWS$Is`!SC}K|Gi*qo(R-Np=f`pthPOTCmXwYbZ`BYz=O>=B zQnah`Ob&9WX`5=uf_(3OFyr)C%5<0Ce4qGWM$1F2MT6tt$$BEC#FbnhB}IHLsEhxr z>0T8oHBP@{g>~m6cc z6E%O^OSXjEd@{9@uuT0{{jS8^)S7Bh^N=?GFU!QtUHLO%Yy8_d$Hns8nVIup&91M{WM9?s9L&07(h=9H~p)9_XOYq~bCBIYXfub)nyTCZR0 zZ?$eIW2-o?RUB%)gjFPJ!=cvemwoSN{B>?d@e{fKn)6L`xV*as*%a9lvSF*|nv}5m z=uKkCoRFE<^nrNO+|nCT zr}aIZp_=BG`!83s$;{1brW@tv_EYki+O4{b7H{@S?@Eve-FC*R)3)tsixMPnUB#OA zQ`>UO#%gtrXknFP(@=6&-&@Z-n0ut{d~5a2?(elBuhmE_HEl8yW#2fxf7krHu~6A# zV=pY%QfNg>$m{^-t6#I7={qG(TE?16nyfdO_khZ8Ow4%C`29>+W8NxHnLHXp*DbR{ zLw5VF+iY9St>K(nJ>GC2ex@--*vK_9xjoewm}QbVsk5QKFsI{BHBx#sZMTaKyJIZ( zQa1Ty#%+9LCb(h$mJyu$iI3F1(-Gu1Uc#}P`Q+{c=>ICA@`?A0=f(SHb0tJeSow_{ zT`BU>P(S&f{=_?GxctAFx@M13Mx)$iwb{(^rjn2e{ons>ZN{SJMZa+Ewft4oPpj8- zZjzw*sqDL{Tgp?Dk&tYe`p2JhlMzK>(}&f`d@aGH9eZMJ~chi^q=TPjpMZG zp;iA|eX6`?wn{rdN{pXVS{Ed(4+&JJw+eDhJ(u&67nSf@$ziakC`}d42yH2>(jjh!k*Q@7RlYa3JO>4wHD{I2)$9&UN>AZ5oZ2aeR+IVcHEUr+9G_T0ynchd%e`=9vuA33(ByvD!fLlMV(&ITK-y5#6 zH2V^p^XJW=`9G9E&F;;X-WV;9zSndt#OL$I^@Z`_=@KN}$}cl|gPdh<9XXPjsZ{zJ zj?L$a^}>d8>egKUA&2v0udzN2=MdNN{LiY-sdv1Dn&sF8jd`>6)dZXX|%lL#?DHTq#N)ZlF#7H8~`Ive$B2 z9QvOKSeyD~W{P|#kSk^Rj{ovu>HBJ$)+6T4$W23j&VOQ+#gBsr)~wXDoxiGkbI1?P zD&KB+vwL%z6&yEQMQrT~R^#m1EM3dL@ySiYn$9dgb*ul>`RAP5+RQ*X$;~D?f3kZh zyX1uakFxO{Qn7SPXL=WnU_|TH&0by4Gh0-(NSB?5TO3-mfK2UHohp7HUd;KFgMZ6e zt$qx(jG?J@&5esPdou39Ip`rh5C9h>cnR`6)C68av7n%u+f5=<~&RD(iBk5yJuJYcWiQn39CKbmw z$i|5uiSN%|fshh%{-tf3*R!#O%gLwlfUYvEPwA^Q`C??E#vf$3roWl78{d}>UpX%x zn2FJHUr3JWU3<;;Dl;k4zws5snw$xXACv!W{bWl|r^wVVo4$FBoFi57({VL-1a;=x zjL3Os>Tz_-*{pd;^Z%I~<0jTgI<)z0)mqw29u28lx!#bCl{*VGq^XkM^w?{v4`%K` zNyl3=x>D!ArfD+vSkus-?q7ONY)y-4Te-QZbNO`Y)z7+ZE2ZtR8fNYhxhZn)SI!M? z6Tk8w>0STa$ZZ>IxhZ}epI#Aj@9btgzWU?x{J)U8#g)1|m2S}TYw{c-D0{zH?(tt> zRIb6yn_JU7eB-K+=h#{Yt!`z|7AukLGxu7o$+JSORqMz1L*9L(<~tX8i{~k(b!I)} z)8^Ok+#2uE%v;&j2bQ5Dt$7|fdeG{NSm!a?)KBZY)SouP)%HPpT(n#%*S1>gE~mAv zLEF-`WiD@9PCsX?pL?bMY0oV_IX+WLi0_Qg6fQmsXh>`2W{zsi>G@(cwac6DXXQ(g zKP*#{9BrEC>gw2#U$eWZa_8UX`H|z2{I&R{L(|urvv)!MRQFl_(&xEW<^PX9dzbHA zT3*G>7mG06n`-6Q|M}piqgS6{>-ZC$RJYaVn{&5X*fMrrO)?wp|LK0pp5`jKRrg)d zD$`~TvJpM3X3uSxpT4$n?A;U5v|za&C~v`{?DFMhKtM7_j^i> zbN2?*$3;IBj(az_Z)0_zOrEQYmp$Ivj^OHY`o;QTvuxdeZm#8(q-+hcd)4u-+0dV! zTU|f>^fmaoOZcCivDd-+r1zG8C0A6kS8;^PeX?{-o^s1xoB6qWDO+BAwpbf0S7bvt zpQCdB{omu`+J-uhZ1`UYF(}Ev@tBF;?|oQs=v8X;o={p<@-lP`Pa__9w4jTATTQYfWrTLu+fJ z|CI4E*9d={544}MhO5n6?C#cV?{ORx$fs$X{Qq+AAxo!_)ake<;N|L*#@q;&=QWyq z4m2%SkxV)JHj9}KPuH#KRgNbAekw^=SG(40UcbEeQhuIkoz?8IG-;bmnqTm@U%G7W zR?GDBkE~4GhFz*3S;YUjyT0f<{Pk^-^y-i2rx7!r0AyW3quk>>;t4kX{sWH;K zD>fZFXSe^Ewq3)`c{Xfy1*-o*X0y!N-gtd-^>ak-ZbvJ{tX5+4%^-R1W?O@2BwMM; zPZiuS2mDmoH_f+gV9zV836ll5s8)oR*4P5-STS(^_v+XpQrVaCVjD)UJDplFC9sq%l) znq)f1micxwg{Jkin&aB}-^*W_pF0#EGOR=K`k?WCZoJDhU7M&>^N^hXO`c24H%G)9 zHa)AHv`r5*{*yH;e!cN;+nJ5p9<^;TTaMD5}Q27ess z!-eUe>{A%r)zxUzI$T@7nm$!2SHp5(gIu<8{x z=Vlc1lzgmqHQRxkMK_NHuO&Mrh40W)4V&p z5#9^lzrEwVm%SB)e(#6gOuxWy=UwY}@H==n`2+nS-p&3N{s?b@Kgu8F-RqC`clGN0 z-Tghh$NcgB@!k{u6n~2Mp+DQ7?Je`?_;bAF{#^fh?<4<4f06fv|5yKQFZSQHCH`RB z#dh~AY){+UKg4cmH}ns;gYD-25q78@>i^DeW4G~tZ%5ee{G;p+b_f3tw%qRGA8UVQ zf8|fHyW2hd6YcNp?|9SdQT8bR6nl(4#y`~_YmfD(+CSP0{nPABJJX-eJNT~l&$Dyw zT>sB@p1t0`*xqPw^e?kF+nfE%ZOSh2udoa4BEQDoZSVJI*$3@|{$K1P_ECSXeabHO z=h-E8iGK_4Fn!Ix)xKfh@Kg3}`>wyhzHgWLi|ogCg@2d*F0lT?K^V02p9wky9sL)A zu0bz=~Tqe-oS${K@tS&IzX5{=tG^f!#0>CW`DviN1;ccGJYL#4x)>Vt8V>-7+yUF~$x} z?48)hj!aY}D(rTN4-+5S?GwurE9~gRx1q7ShhDg|ofz&BUTtTEbHnTG@-P)Hw4a4{ zgnzYPg>_+_{U&@MeAuoC9}SADcUI*7>$o627{vgqy2-y zQAJb{42dR3e+V{@j*E^9wv47lX9q*0bEE2DRP^WQ&%v1JlIW6PY;H-4Wdp>=WG?-5cy1-4{I&R78J^o(_H+Eshok zM@37bCBf0r2ho?oG0}=>MR00C*MhFW)Pju)HV#fJ*s@?~aC+hB!qGuh;jV?d24@!T zR=8X6$HMW26L@E!>--nV9BnKfPIl%keY=iz3zSR_qz`e{-FCe_=nwx&HnBq?jwXe z>OMxu@@7?lbVuxzBO*AMT6LCGJa<^>6nT=&SClrjPrY z`!@VL?mMJ?*Zl8^BR<9Wt&Oz62@1Yf`#v3q)jUI}~`Z&%}bzv9i* zp0~TVJ8uHp!}|^VIBz`R6TH3P_x1KQfw!M`DEtxL6jS7#=$%AN=3>I9dDEfic{2#P z)VqRGW_mMCg;(P(g1^JNgH$hgFPH-FMejvpy(QjD@c;7uZTc~HzYcxFd)xH!-toR6 ze1*4yINy6ez_0W})5DMa0^X2U=ogy)evw~fe7~LFju2*f_)dN&vm0~$K-0?~JRaUm=b3HEzIuzmOi7=-^$;L@U8u=Nwtl?4I#t*;iTHu-{5||V2$|qd zAm@qxL{ja^`|e%;5B?vF=O61IYxebz^N%wl{p0=PO_6_se}d^P>k#~jeii(g{+XuI z|D%5;@mZNn7g?F0tW3}w{ac~8`L~%de#%doz+d1mBIX_b9pw2}|F4vFr++8mcll2c z{-pmDAy4~Hn}hv&|1DGOzwN(m3jBBccg(N-cm4N?^MU^X@jvuGGz0x*{&LgD|H%J{ zR3H0aaP&+6OOAf!f5XugK4Zx;)tJCK)-kSit!MgJ-};2}F`*4?V8+>m4NbyEwvg~5 zTSWX~TWmVocD6ly2iw66v>k0nj&`!0$fvXI3}0ePOpz_MUEsU&UOLy7*&f92$$MK1 zY%kl(jJLgQZ?mPW!KPH!V6%a&zVIXLNa!d#%4}=5v)h?+S&7Xqc1OFT8D*0;NqD&} zH;leup%Dvm(N4fXg`^|4eKOhACfRLx`Q)UbMw0+uaYU}MYW;6S&eU^~t z>~n-XZx@@5MSFlpdoTmg9^N*6?K}1za(LIiOZ@lk`)0KLzZ#pq#0{Ae9 z%r-$mP-un)ML`j9ii2XaQ_wDGXEs1n=>Xp`=t!KdL095*3woF#LC>J4Nd~=wUZyly zKUm)!fF84v860dJ3^W@BgMvY3?_kqlQ~1q-%?Rgf_6vptL(GA}=D`+(Y#9tSo1^gz zBhFUAR`6Q~Tf=V?Yy&?$7;b)xCbX?NJQx{_G`j|)f>Gv(V7p*Db7Zi6ustC=2fLW< zgYm(5Ga{H6OoZ+k>}AFVdk1@)J%fFNV@+XjTyT=<7Mv2CYPJhb3r>SSJviMQBKi|N z`V;iL;5@UBXi;Wj!bv!$G*O&rZ#pD8Bs!W-qDz_nqDw(XCPqR>CAKpgB(_hCA?DtR zz0E6`c=@q^hSu`;pJY?_D@vDqRtT!7sa&CE9&hc+xQHY^N_j1v}z#l{cYg{=Ew zX;=#1CFEU_VOiMSbPaoi>%;dCHz9mrxEcK5a0}Bp+%g<$+K0o!Q6>tv3%4`9!tKKy z%zELD;TTgAjt$FAyKtv)XVV=maDqvM6T>}8yH|LCal-?{1I?hYBCLQvDEuwqlfp@+ zV|Yk-s98TeEIb_ki0}y0Gdwap(ga~;cocDt4w-wyW5bh3b#gcr{hL=9OohCsHe3)c z;7o51Z|58rh6}0x9pN2>|26z8A!w_ldLVp&5+4j7f`2%C82-`lQPU;-d-xdqm}p`&kq|Uyj-oL`Cr6Ww zjs6hP=At(fGA%ltIA=zGf}RzfMLo}s&Zd-eqjOD3G(AG&iq4PDhh7j}K-%gEZ7{kh zLhlj{+w_WNL^DWrS#%ln^5}BXUJ=bS?a;ZeB+jg87WvdhwH%!j&4EY%hF%}tKpk$3 zZln%3MYq7;7TpG&AI+x}G;&jbMt&z}cUN>5aqf=pA>{t(0Yd&3(NobQ(cj@8j~<7A zB6`B~iJpv}B;=`x_t}f?PW%_6B^-SvdWG;0BI%2dqED&wXVGWypGRL(6Lfmxh)!?% zicW9(i%xIKM5j0XMW;7gicW7rbo%k8v~WV<1axfI?T2PRlI3<3`h7z6`%?7#alG|w zJYOG8e**kOa{&B-rowbF2ch>T(E6uC&qLQAimrbJ_hQZD+tu7+Zsq-AxA84D^Z9zJ z{r57W_xDnbznALzy;RrlrCNS3)$c>}`);P2Q|7E^`Z()5>!Xp6MzfF5?8lEXOfee& zjV5$%a&9sQI5#_ggMZk0%xvyFjwKMPC9sKF0vlrqynv0d1bd(-_P{5mNNs@i)dq0Y z2G|rEpf_#V2TNd6EP+8-1)I5pp_^kBc~9Wsf9oD%x~Ns)$nJ&d z&+f$q&}z4ud@gh^G&`wPuoG6n#e`piZQx=X%rO1jOWjKexePm@A9lh#!mq_z@URxH zC*%gKg$>kNaMfCf)LIy%)XT!A{t^!A=kh!No!_XzC7jLO<+;fRKcj zFdMKRgF&q}gUc>VXTnRc93m`-GBp0~UU&0*uZM>=%s$Pora!jCZ{WvytY)G>E7vPQ|}CH zi~t+sa_V^nmd3tnX;flqEFk1|?{-2KHrgA7Irc`O+8Z0Gy|Izn8yjM8yhHx)dheM+ z?|tum>iL294ZK(&{nY{~!~${9wq4&f8~7g9NEddP3ecg&8X3}HjTHOECedJxh#j&C zcE})8>Tl|AMoh6rwpVMUr&=T1VT}wm-TYzLB&7}3h}a=TId;hQSRl-~{upeJ?bY^h z{PJe@#)0f(W$cX#cC*Ht?bPbn1gnGf(%%cKqrF-krD}B?u2#oy)#~V=_J*U@MGv(u zdZ=~LL#>M*YF$`=zCYibl4D~ySQmF zt3|OP7RAS$(I@^V*b<-mpPKIeXZ~k|e2#U|9qZyN_^+`s0&I*G@c;Gy3;(VEE&O-> zckti)-;?JL{ttw#^j8uRV~x0KjTERg;;1#Up;{wbt2N@OHR588B(Nev8xg<27NAuZ zVv}s6Hc6y5iGxjoW{EYzd%4vPaoO|hLP%HJm5^>&Bb#E4l##Z(?M{f;B!y~|Oj4U< zwAv&`W0MRvN7x})CcDe-AX>86Cx1};w&D0v{q}Ir`YK@FjYh=7yBjeN>8L!qzXSGH;sWsA9t&vV@jdWIPq?1}B zoz)uYq}E7ZwMIIrHPRVt#A1_(H8NJMksZ_;>8sYr-fE2uQ)^^zwMNFOHL`=%pVQZ19=YME@AW0{ny zWzrkVq&-@Ahp;nNL$k%iWdxw3{^)pt=Kr=8Lgssw5ZIu$WRf@4y zMqnX~3`d&H!%^5Rq1r8*sNJ%$+ATfRZYff`Wqq|92N6Kebz2 zwOb;!TLxjb9DyyAu~;gxe8ggLu~<$f?I~C+1!}Q$$gx;FwO9((V%bP7mJQWnDO8K4 zi&`w6S}YM3%hjfTI1jreP`f3ec1y1uyQOE2#p0;N;;O~sgnz?gan)k!kz=v+XkoEz zs}{>(wOBS&i)FA{EahskbW)3DGj`~gai(Ii?4%aUdRQ#3>4u8IE>gsHk?E?|O9|FX z!gR-aDL|_(#D*zQ8>Ry`Ogl7nv0k=}Iz^q#D79hsiAtgpc(G*miMm8x;l-ZuW!K-7 zs#R00R!xcQ`lFY#>rb9y&va0Grn}lRR_z%#$DZksW6!v1&lF(KRGDJznKP;RpRj5M zs#Vilt(s!BYI;WJMeJ^?Rnr@*rW$*LD+bg=?3qotVsNS1PVJfAYR?p_JyWEXOwSxk zrl(pmJ-L#A&51p8BXzzhx|ue)1$(Bu+A~g$JyWRmjHC8Uf!Z^L(Y?{VW>c;?+(#<0 zZ5*|2T(xbS=rL>?S8baO)wXf4ZJshiqo=WOx~YXzC|4&aYkBk$HUBL7-1JmSW-~0A zjm)rujj?A2s6EqH?U^BJ&x}@k##4J{fN@6NiiKkA;l&sI65qm2T6~uhvb4qbw9eNS z2Sv}f>s$0ZTTgkuh5ZZrm(J)?k?+{5!gkoBW4FfR-3og*@_EWgA8S`$*e&xdzOm)E z!=$bcf%3BZ(%&ARcH6FK*6Q=kAERhii?(RlI_oCn*}~lK($X0NXY?9cI-}Qz8$I0n zF9XU;XOzz9-@D(%r86>Tzb3!MOFJy-P*Zeh?zi3DnQ!Te?mL#QNPoNCSGuCxee%tO zwEQhRF5kE4fi?SP;nmNak$4VY6UfKTZ%>SIGajJW>tzkN}k zy}CcI+_vqH?E7r{BjuPJm9NB?e|r3i3|Dwg_FMEo;W@}`ft+Ds{|3j9=UJf;S6DU9dFYx8t=%qYEEu?b~h!D_s9fpY^Dqf7;NF5}z{H@Z0{;bniU!TSa8BS%s$ocv0d{L&+{I&HJ%t_8#|__FZB!ifc6 z@>?X|;uGXsI3!I6w_AT`!M6q97IIMrT%3+m_~C}9Nu2bT@`$bck;VHJf}&fCZiPo zOIE7%IwUJkW_Hrv*PfIdr3dB9{L84|%N&`RC1s4HOKmvzKqhwPH$9%@tQa>f$8Cd@ zr{!6sH8&3P?}=IiOGd9O^1{aZ2f1$-=rM2W+d?RH&TewN-3@vq5;U=m{G7oT+HN7}!cem6CN*?mn z`kcc*W-kq6Cd#R4x(%hyv*^1UiPO+>#Y_2W-$`x_t@);o5=J~D1{o{-usASIkT6y3 zwRPmadZFXl6)K9^xo6jQoQBjX<*orj*p-7`1^p+x@{YZPr;^BlJLM%jNyu`Z^^*|7 z{jqo|b-8aO$^9ZpcCD7jsUYCKbXQ8F+za5&jBET^q?fQNQcQsxOxTBbS90w;aUH3u zxIgH+IOSYVu9C}ma*=pLh$nC9a-Dz2HSS{0z$2IPhVUueE^=L5MXD<5S;y7*hVrSM z{3Fc13gn$#UM4TCxo4gRQT?loB^%Doi0h+kNb^%jwj_f=TJtRr19-j z@f7=PJSFi1h^d|Lx7WJs8EdW*r;0dL#Hk`q6>&PoNBN`Tdd}j7Xyf>5%6ixwNX=>* z&b*S4zf$u3>C(yPEv`gRYv*wHe!lx}NX^To}D}SJ- z;+z^a)(Ad#lJHiK@F?*+_h~Q&V3iI>_}@#`(#@r9a`qpQeH#3 zv{RX}#Ovps$7R0TXs^t82DTGpQ8k@@o6en5)5Al+p=P>?GUL%cPkk0se@8oQ(GS z!2{ZgI;N;wk{Y~4{gTu#*(A1%&P;5T5s58wk~em4-Y3X-ZFB6#nzWjC^O}rnk#`Ye zDLVpQVFbJiaz+CERY`wU(qEPISEVU7=bNG212~i`S3}(=z;oaqfEmzz0la92axdCY z?%Ej29@tQ>HxJcRb4fLqRC7r+msE2}HJ4O#Ni~;Lb4fLqRC7r+msE4PX4p)!?IL>r zAB?Dff+a}IJM`WP8Fwqc3K+3LS4LF(7Gw7n`ZqnZwHU{oUmfRH$NAN9es!jUq?QrV zWc05|4jpNsNiqj;zLPlLNu2K_&UX^$JBjn1#Q9F*d?(5Lz&THnnS=A5#CcDW8J2VB z{s-2UBv*fDa_x7fxf#qiGr1*TI=RktwgIEScHjat)4i8*)3C0%i{olaN^+;kOw$R8 znCH)q>-;%jF1QBp-emt;fL#06gB!t3;AU_OxK(BWb3ynhZSpvHf_CXdn`CFI=NTo8 z2BiB8TJ{V^%o!Q^r$x^|GAofx898UrvS-k;XCS4ONNFWkVQ;6l3&A3A7q}b98Powe ziwD6&fK^g@!hMwAzk|oX)8HB8sTj$d1P%j-gE_QT7pF9?cCG@mK`odAt_FVrbHO!W z9=Hx%4{l(t7zuU&W5L9@I@}TrjjLtujLrs^Gs{cPHRN1F&Nbv*L(VniTtm(^G~InN{KdE`7Vu{X2nmSAW+kKE^x`#f@=r@5!dJw@&* za!-+airiD=o+9@Yxu?iIMee%Nk$Z~VQ{arSw$&VjajvW?oY5BUet)znaKOFR5n>z2Mk*oIMAe3(f=8U=er_yaV3n z96kig!RP${0(=ElfH)o(7~ld6f_Pk_7_Dsr55*Jb8B1&9DiFZ-rB1&9DiHj(45hX6ltc#Sqh>{mk@*+xJ#2r7)SJz|X z*_1q+l4n!$Y)YO@$+IbWcC(UaQ}S#|o=wTKDftFUo=wTKDS0*}&!*(rK>>YQ2w0UV zeKw`fru5mAK09ye^C^8krO&7I`IJ7N(&tn9{AQ)kr}X)hKA+O(Q~G>LpHJ!YDSbYr z&!_bHlwL>ab(Ef>^!b!NpVH@3`g}@X7h|}oR*-irH`gz8Z1?4PiUQ{*VHl~&Q%w&d#KP>`d!aSvbtcjy&xr(J>R zx2|SxdZ=}cET{kT&hYCy1*|&gTl7ZCDF*GByMFA<@(S}++TxITtF>N9(Kab`lN7p1 zN_%DfHPX0l$G%$#7J<9K-QZqO2krw8f``E0z@y;r;4$ztcm_0RY3MQIL{meT8HX-2 z4qav(y39D!pV=s@Zyk#Udk#1koCm5w3M>K-g50sd`YLlCGE#?()FC5v$VeSBQiqJx zAtQCjNF6d#7n~Bm5S$7Ym;;fKI%K2{84)Y3iPn$I)N!xhI$G^@%sfqvo&(t#O?30D zHlLN=y2MH}18Sak3=Lf8Yu+oYd9MOl``(}(W&L{#ybZGJ;1t^KPTKBH+G>2_JLZ`0 z8B5Q^;~7)q!{^|i*ReG|e39Rm;#2|i5cevIb+Im1=zJqWc5r0X&Wwue>MbLpqD>=$ z6+U+)XwNsPwfky(d8@j`8ytHRyanC{qHC;-7ou-0^bK%;3q0Th3j&Zw2l1E1m;1}( z%dHDMkU6{TSvBe;;U)3q;S6v^yfB;@FN~guFK^n`Yf)>_lIo~+9ks5b)^*gnj#}4I z>pE&(N3HA7oa+1>&1o%bT}Q3!wAPz7nT5`0CTME=jcZ~1t?f+oIJ3|bIWy98jkD4? ztkiK>spGIx$6=w4lUWK2wdG88M0&QuVjX7&H>-KFSU zK79_pVNRv?Not>@_DO0lwxZNtE#fBg>=9}=j-&QTGo)GV+tTi9X2m{2d*)iQ+4fh9 zmK}o3s*tb!lR535wR+R-pVao>yv=jVN~{5~0PyDDXa#uiKCmDF?5{DlWf!ugRnWE> zvbxF4cm=cIOt88ca%=9XHr!Edbf5PgejE0B-6!Fn0`GuN!Dj%!nmiS0xaZh-r+`zz zR4@&k4$c5ofHypOe*}L5XMwZ9IpAC{o!wX7M9O`zhC5sh_pZvbaE5zHjco_;-@zTC zhWkSe&#f7r{o)q3_${8aF+7iALh=sDo99jp&tjNpM=%EL5AZq2(-MYzd<;(`7_%+b z<`k^WDOj6Rur{Y)ZBD`3oPxDE#hDAP0rS9h;CgTaVE@H=5CP7mtHg0YJ@WTRH9CkOI7r={P z33v(oi#;W*cly1Cey^e5Yv}hH`n`sJuc6;-==U1>y@r0Tq2Fuh_Zs@WhJLT1-)rdi z8v0$XcBI%(pQqOjhQp6U#&-Z?!36$Kj4SB>3i`i-{!fKFva>V>u#d$!s9_w`gbQ`2 zse-Xk5uFRql`qCa1>>QH@lX@ZB8;7^h@C6OMvAeKVr--s8>#4X!oC35{ATwi-6}NG`Tnc{~xE!!I#6CuyR|BpDv%pn=9Zs(nu*>OP4gLby?ey5~^w{n6t_70! z_234;j;F_tr^k+`cMD+0)4L7K2k6z_0&qK62+*b)_f6JPm$7IJtJGi4Ldwnt==kBe zU^+n056=e|0QCKgZd14$(lw58w#NH=G>jF9F7o#~4B?YdrQkybl2T9Uf!KV@!D;fsX-W%lj0320jO0fG@#U;A`*=_#XVA zV=%=SoXy-bo3WSOYn;G;_8T)-Z+ynE?Wy~Ay7$OfoE>f-Ul5K4JAey0b}3+oD`YRV zac}aHc(&|MMt2Z)H@F9I&4_V0n{hasaX6cCINR*oeC(-~_`f>-^6S>?MoV26<1?#+ zH)^vwR`+v}Iv1&P?*Xi1F6)^44q%;dKLc2*?iWbezTgyaDwqnUfz!bmpbDG`{s{gA zkQfh%@sJn~iSdvauKd+7cIvn`JH`Ki-!G9mdXww-br#Fkwg+XPJLmz9jq9#?fq zE$OkW>#?ls?S=3&z#{m&`K8|WUQh?_0}m4Z2)~blci`XW_d_5n&*%LA0!Z0k@w)=V zaXprIeZZ`S^<9tkU61u$A5brBt$M8PdaUmH#5YL!k%03IInR*u#Qv&}u*{Yni)i znY(M5yK9-dYni)inY(M5yK9@Rr>w)z_f3N`<05$|00lCLv z6EF}A0-J)(z+f;0Y!0>nTs1RXH8aD&R$yze4Hyo#1tS1g+RP}x6?wBgV4t5Iz#?`4 zi`W4yVh6B@9YDFZu4%Vh2cVnt4|BB#*)~*Z{bsoEUv|^q2GT^$M$8NUwDtHaN4w#`?`Ri04XNF_tuVdw} zW96@7<*#GquVdw}W96@7<*#GquVdw}W96@7<*#GquVdw}W96@7<*#GquS5H+WaY2& zhlAYft`qprwO3aBI#&F;pc~in%K$rNK@T+0hHJ8D099xJDKvl-8bAt-v=WW95{cmb3@!zi0rW;RgY>mrbb2&{YP8f!wA4y8ggP{YIy8hjG=w@dgeo+IDl~*D zG=wVgkH)SYwlT7qLN@Wu0_1KkY-40Ig>0sf%@nekLN-&#W(wI%A)6^=GlguXkj)gb znL;*G$R^iK0cVJ8rjX4PvYA3QQ^;lt*-RmuDP%K+Y^IRS6tbB@HdDxE3fW8{n<->7 zg>0sf%@nekLN?i51e<}uUe(yy6Zp@_u?x`^pW^pf@O*5zJHfCkKA4@{!R+J?Mz&MPb_&^+>)En5 zF_`<#suMAC?Zt+>6>xLIh@yXy`4lprLgrJ*eD3J033uZE&fuANaQG}(91rHs2E&~V zMn~CX^iHmOGDoDaiR2o;%oQm{Rt+PohLKgn$f{xPNHKS$m^)JDMz@D4-M}8;*Wfo`0+a3H7v2Z4jZZ^0yR2sjknVao8CRObH?{0W=|&Iadza{*p={PV#1-~zz<<>PV3 zzX<#pTnsJ&Gr*(jPAZR6!6)ET@EQ0Vd;wN~|AKG9ci?;Q1E6mh zWMz0&D&v{uGM-p2!;?}OyOU)+rCi1{%4N0`bOF?hXD7>eaj$;m4yax*psB zZUQ%hTfl9AHo#9t8PAZFMK1#JD7%1pu%3Cao_VmId9a>&u%3Cao_VmId9a>&u%3Ca zo_VmId9a>&u%3Cao_VmId9a>&u%3Cao_VmId9a>&u%3Cao_VmId9a>&u%3Cao_VmI zd9a>&u%3Cao_VmId9a>&5YK6#KiB{a02_jhz{X$`Fc1s^n}W^2U@!!14z>VWf}vm- z*a~b7wgJPzwqOJp3Ah85d9a>&u%3Cao;h!A_H-(l^D3G1Dp}bpS=lRD*(+JuD_Pkq zS=lRD*(=%asb;^Yn*E+?_Is+?@2O_LrGrwuGrwuGrwu?9ww$@PlDkmr^uEij_#Mvw>^@PYzY}2-^sbi*?pdy6?yP6- ztY_}5XYQEJxTK9$ctm0u0e!+i8GA3e-R5A(6Pe5`37eaycMppW@ifSG`OJpW2C zA1na3gN0xbz_Rtx&3tq-AM4w%1NVXZ!2{qy@DTVLco;ka9tD2~kAcU*697HdN00U2 z1L(2-$KVt2DfkSav-)3v72v<%Tkst~XZ1yAWxV)|7t8oyAFtXnCTsypm z7cdI!$bG3ves=-8!LuvDE<+8w3^nX9)L7miV`&r1z1mjpp5T1!gZw@p7ooKjp|y-a zYZ;+;NWH<10(;|Jf3D*Ca}~P{HS9Lbu^+_$V#i^QUB)kx&aOiZyACz%IMlG?P{WQx zO~765feS1MKq4L-oDv^}rE?U!4mIpL)UfMNllYQdh_CdT|A@qQ+=>4^66nQ6XhcQf z(df^|fXRSy5S|Q90jGkg;4CB8g zbDCLJMo#o{&y=#G~nrgyPM}>53nt z7o5TPP44cD67NLLAMs1Hmvc5AlJ|A)!3)u$PM!E4a{eycf zvmD<-*Et{IN$45pEA^z@1Ft`Cx&86+^RYWv{Q9`V)vNL-yebZ7?*{LOe*`X5=xn~mR>$h#f?E+yWbcyQ_JJtY2GyobeKi}whgTKag8 z+J3g5_n6(pZsI*IK3cpd@XNBD_oVn@@tzhhEMC3%T=AY2pDW&T;&a7&UVN^2i}AK{ zp7#%Yt6b(dPbXjbj`%h4nQ{Wx5Aa`-@C(FeiO)k(czJGzZ<3yV`=C$I z$1lMP$Vq;wc>eH*iO&yzYw`KvZzDcG{88fV!yhevKKwD_;lnQ%4|cO~j063dc*2V|UhF@L?~1Ga7sTVU{|0_37W(gs$7lb2@uBB`C?22v zW#aMK|5Uu>`CsF0VzK`Xz9nAtzZb6({z^Paa8Vk+5rx(jFA+8&ULtH1l||^zQIDvn zEs6$218h6-24UNa9|+q){6N@_;`iBh60Z-oR6IW0F5>CIb`y`!woE)e+x5hAgWU+9 z4KwY=;_KOND!!iWVDZpkHy2;eb_?hA{<8}=G6`r=c zicbZ*yZBVFdx*zp`)lzIXZIJM3ibf;4rdP(ZwmGxd8XC=R=g?LN#aex9wHu}?V;QO zxC3_~>53&R`;tX9D&DdxL$zzF{!ExYtZ~~YDP6Q``lffxqDmV+A4bB1Q zg6ZHqZ~>SLt^xDFwct8%J-7kf2yOy5gImC@;5INHq`(5e(*lO41q@FM7@o;7e+4{~ zV|a4F@Z^BG2k`WOsRKMcV0ik*@T`vEDFVY&1cs*w%){Uj@F@5@cnt8&8XmHfh9?S` z`;*N5NyBp!_{mPP0wm2#;9ub1;C=9+NjmL82hb680-Zq#=mNTeZlDZw2R%Sf&t2n}C5}5ZDxK1_py6U~{kq*b)o{!@$;H8!#Mf3r2vE zfIC}wMkMKM4@QHNz{%hga4MkhoYTNGPzBBee*}L5^r=IiI`pYSpE~p@-o2B~`G9_P zs=+Move^-g1xZj2b^<$tT>xoZ;^S#AiJ!eBUiOlB-cGu6z}4U{fbrp80~jB8)l1@m zJL%pCZUQ%hTfnV=ap5v9T*igVxL^+?iGRGLOFy~vk^3L;GFS>;0k47A!5iRB?yY%? z-?zcL;63m@_yBwemVxEqBk(c!1bhj;0$+n~zzXnR@GbZbe9zrQ1~_1Ma3Y|6d73Zj zan2s+>~YQ>=j>esIB)M_a0!?JE(Mo?%fS_3Ca3{d0@~HP3d{zzfcEleFOT-}XfKcU z@@OxQ_VQ>i?|N_ppxr#$&7<8s+RdZgJlf5p-8|Y2pL$6=>LtB}V3A4s5hwudz#ywWvPt|TCGn4x#5+JhmqBW|YJqYciS!P6ua#KY~92>VS{cB)*7}(M90TfboO3 zpCrD1lFoz{~cn9(2DfT0~5cLZa= zSdavHRw|yJk$Zw$U9B4Kw9UU_?aiw6zp`qvQuCBg{?%&|;fHW{_MzY~_``wREnLa( z@4)ZDQ2=>aXRFr6tS+)*aX0uXSFN*&lW*lh6Kd1y)v$88qglDe{eRV+3%pK6_xNXK zKl}1L2MI~#Dcukf@=EucM?x40sdI8mk`Pi!k|aqw4yh0#lF)@D74o`uzv=S!dP}-G zI3$%^^8e24XK%-$-b?@Y_xu0P`K;ONnLTS}@3rT$)~q!%=u8@&Nux7q`c#e1q|uo) zI+I3c(&$VYok^oJX>=xy&ZN=xy&ZN2cpMsL#SO&YyPqc>^vCXL>t(VH}SlSXgS=uH~E zNuxJu^d^noq|uu+I+JGP(&$VYok^oJX>=xy&ZN2cpMsL#SO&YyP zqc>^vCXL>t(VH}SlSXgS=uH~ENuxJu^d^noq|uu+dXq+P(&$YZy-Bl{-snzdO@(IU z(&$ba-ASW6X>=!z?xfM3G`f>Uchcxi8r?~wJ85($jqaq;oiw_WmUjU|fx7{|t>oKE zzAd_wMt9QaP8!`wqdRGICynl;8M$&9xpEn~av8aD8M$&9xpEn~av8aD8M$&9xpEn~ zav8aD)iENCzNOK(H2RiC-_qz?8huNnZ)x-`jlQMPw>0{eM&HutTN-^!qi<>SEsegV z(YG}EmPX&w=vrp<(u`i3(MvOWX+|&2=%pFGG^3Y3V8uQ%Y>e|j;GP_G&-I}$J6L|T73y@ z0KNjg2EGNp1HK0~0)@aPU^B1S=81 zX>96gZ0c!j>S=81X>96gZ0c#V(geGD8oPQLyLuYCdK$ZW8oPQLyLuYCdK$ZW8oPQL zyLuYCdYVyDV_Q#STTf$KPh(q8V_Q#STTf$KPh(q8J68c$1GzvRa1GEA=mc~Ix&U2) z0pvv;MgP?3pBnvBqkn4jPmTVm(LXi%r$+zO=${%}e3}tfqyK62KaKvU6Q=^S5A;8c z{-@FZbb|JfIER(dv;o$i<}$)+Mp(@Vo688R8DTZLphg$e=zeg$>`yMaBxUV!?7oj>hTPh9GSn*yj8R^p%@xaEN(fQkTp7y7bB zU)Jc$8hu$~`#0y_L@Smwdb37v*8YV6y!YX~-;VW~d0eT_=*}A5S))5Me+z5}egt-i zH2wo=bZCtZt9_DqeE+SXpIi7S#z9=G?I%ht@Om?yb?iHM+M(_txm%8r@r?dux0o()dWE z(ZMzArE`&H?CLP28I9jW8a-U&JCQ~g*XZIJU0kD!YjknV+Ui`S8jU`#(Z@CVxJDn> zthdfZs?qpcr17^%<8P71-y)5_MH+vLH2xN8{4LV>Tcpw3HF~?o?;?%gMH>BGqrYqP zca8q8(cd-tyGD1{=sFbFKP-j1DXSu0WE-*Kr284tpV13{C_#aJQBIY z==l%u{G)*ffqY;LPymbt#sLojtmF}_K|`|oe{)9q4W5h95XtJ#%|;)A|H%LToWRO| zc}@UNPI(bwEUCkiIxMNfk~%D@!;(5I+W=Pp zZGm<`d*Di-18@~^HINJB0oMQ>flfeYpbO9yxEAOJTnBUqt_OMmHvm0>8-ZQ`zJ9U~ za1+oM=m+!%ZUzPbw;)~K3fu+^1a1cg0nFsd!Q8(S7y^D5Fce@$56SV+v+kpaXI7ZC zW&hUhMsgNqJO#`Ko(ARsbAfrlGr+UJbHMY!d|(0a0NMCc}TDSjk%Y9ZYg+L}fj~OVAf4h1060JbZ~+hSfdEJXDX|jiG=p@SK|0MK zoo0|uGf1Zyq|*%2X$I*ugLIlfI?W)RhE|OhTw4OI0A`DkPBTcS8Klz;(rE_iG=p@S zK|0MKoo0|uGf1Zyq|*%2X$I*ugLL}uTSw3`@K(>mTRjhN^*p@M^YBK`!y7%1b!d5b zqvzp`o`*Mj9^UAAc%$dxjh=@$dLG{BdCm{OcHl=~2k;Z{Gw=(r2iVJ6NBCl`AEodw zh98Nt*3bBCeBbhrhC^$}X`(;tB&Q!>6=^`+8Kh;t6Ti5;1U}SA$rJ+z$yTZ4(U0A7k?gJSJRQAGf2@Hr07hd5RIUS>sDYJ@B^?N_!0Ptdp`re06Y2p zE3gaL4eSB-0@QP)>I_nK2B|uORGmSpHuHG3+_LO#NgYPA&LCN5kgPMTBFOU#@%7%! zeBBm+vXPJvv@Y%7_fG(2##W}%_;ynle%I1;1oz4R-?BF0yC0kkR0XO5_X%M5Nq9H>_Ga? zAbn?$zB5SQ8KmzF(syY268OR^=J_0eZ+VdQi|>jA9$LZ7s*MKV=ZckfKCv}8{SOlO zp{-%VvcC7UkAtjYWAGbA9!w$&TAzICfATT#nOvU)o&shAPXlv-1*BgDyaZ6+kDj4&FHuggyMW+?+>0-4Q$=*YtYz~m;+57dFRLQU3bAjWsLEZ=4it{SIY@ZI7lBBM zl*kdKL}^h*aGt2(G*MArR1lTKQRH?EJE*0_vEn#UMI6srfhUTS#L47SO;oozR{J+{ zJmSBQXT|?Qo=5%*d7jd#Q_uclXBR>#x^(Jytt{20%Z+_xxh@0h)RiX?){_kgPnS&z z>&raCzsSCX4digbGvoxqhH@U^nR0oT0d?!hj|uC_Lc)6TH^S2uxz(+&s&?&p{dMZB zuDyESs4nW(w^J9@q-XCgJykaw_OxN&UN_&^SKZpXZ`WRGa36lC;r)0vHLBnBy}GG_ ze*NmyRgVzXQ_~1fS91vKtA&JrQOgJ$s5c1DP-_Vrs?Yn~+_|6nzTeG#`l+J+Cbt~} zukG8L`7AcduwR@FF2re~jyPS^x4&x>dekdZt4y8B;VMOQs$0OF=+DGmMqDzA;A-Mp z5SJzmHFh^bdPl*QNEFvWBOwjHs&|)jm)+*D^s?f$x zqJ32tHAF3&#=M6ll?lzeOWLRT3KyWSn_uVJ@M0StZn@dWL|ZHaCN0(&Oj+y_Fvns| zz!Da_6wG`%DVlbyEauRRV!yy&O4PiRQ@ep>A0O$ zDpaX|VgdiNPuzS`sV3)~RIB=&lSWouR&{OlhE{Qdssl}c9>8c|0kE!mLk?zc zSiO7oIn~#l(&&`-HOidb>g)w)uRVLux#Kg>H|}`JkV_U{vi6egP0ndD_0qgc_cSeP zR;5}0X5*VJYO$nct5!j)(Yk8uHkS`?*Q(v%cF(rk(7r3BA0hMmVLVHX4!1{ZTqSfd~luyP@2g8yU7pjDuQ z*1_eR)b(gEA($9U3LZ0O9dpugyP$p0A-F2In$yFka9UO_Cx>+mI^i$LImbaa&I{Yb z$;Lf`8-kv}RD33&bAx%DF*Z7QFvt%I zIALsTFfL%%tl(k%FjoaD-K&hxtb0DE7+&OF%=zk#Im6JLUHBNM2~Owaz$xzIoEi8e zKCe&X{rVJV11@zp7UN-ga+q@Ig-N;6rx~p1C*Rk=q;J+#B6x?rZLH<2mcDbXU2n-8Js(?oFIO zwl;Xn9pc{Q4t4K#hq?EdGZHx=@ji1hqVe4gz7Gn6jlt)^7I(D!pqr1!>+${x=43nn zWWTCk&9CmC;@9j6!*fAmG8;-<%js5ualq4 z^>VxXN$%qq_8e78l~!d`HO|F7UDa2AQ4LgMb%|=Fu2#9~I@L?vriS2y{vaOc538ru z95t77YhO^y)JpZfTBp8Ko785tL+w<*I*yZY$~uQTM>;i~+D?7vOsA#O$?5ELae6wv zoj%S@PG6^=bC)yBxyKpdjCLM$3Y>AyG-tZ=gfqjL<;-#BI`f@ZoL8MC&QfQY^P02V zS?#>zeB%7g`P})!+2DNTeCKR&wj~k?AAj&giI=EzE!|eGc3ZobyKUSn+_r8zw>|Z< zt9z~6&Ara;?p|-}jHxfC-t@tfyRX~N?eE^~4sdUAZ*^~T2fDYrgWNmZ!S0=ZRByuC z;*Q1V`(fkRP5m}?+tl#|?hEch{JCFp7rX5J;J)fEp~ipVe#3c{e^j^EdH?Xf^1k)9 zhP50I?4+ME=Ph#fdl~;QbN0Jm&M)s*@Q?5-`bYYe{G*a9Qx#J6QX^CMr$(jnQ)5!k zrCv!bNi9unN)@HHrnaTFr+(x_m!DF<VwYrWkfmffS&8~qUDlBe)hBKT)&a-s#)+Osaql{>0bzIV48rTZhTQ)Ny+wIFyfeXnPL=|{ z!8;557j^|x{!VNP%IoQ!O?abs4q-3vT*BVod4zqu^9gVAE)Xtfc~196dKbDa!TWnN zyiwl8ZY%Hs-jm*FFXL+PTfAA`gI;5|HTZ4bY;TO$#JwE+c5jY1)@$mv0UzYe^~QP4 z+$+Ebd(U{|z02IT;CFHc=)+zMw;lKp?>X-gucg~wDEA-1-v~bsJ|+Az_>6Evu#WKS z;P1lohI$LV$K08ocDwTHZtq2Jviqdh+PxOO4s&ODm%H7;?s1>;+PIu@LhI>9__Pa` zX)&C9>F?t-M}>%a1o&P~c~t&yNlu;)5}f;}0w-CPP$nx9D$aUzy_dYH?lr7Jc!zu! zc~jhu!P}ftvcc^Xyi1;)gHQO?#oryg$FE=AzJ$BneuTT-{)Btnn|aO=-V5F&cdysZ zrEW0>-9p@OZ@xEy(dY{IR({>n~Y%^V=au<7?cGZYQ_1 z+r^H`W<)k4^L(?$gcT<5n$vdO58Mw~Ve&caOE$2&7!?}{^^kaR=-f96z};QBI}FHwEFh+bBBIlneZ4_R&w6S>*{q* z%XpJH)dc)_my<@`SMPHQ$XaGpOR0~TQ%%uIk0v)IPVfr7A{2}^sg8u5Qv(QZOAR5+ zPd!RFB{hX`dTIvYQ>mv3pG{GAYC&oN;VY?E374f_Bm8UXEy8zGpA&wW`jYUg)K`Sx zq`o2iF}0I$cZxARwJ)^~^@YR03B8SMK@liZs- z?>V0_uAY}@pP1$ru$F0+`zajmL|L4KFC2s@NpW2EcA$&ES?av@lINZ$I*e~)RDqT6?lc{Q|7vf zISj6;@n~1(cM&?4lN!hUw7qVEWBlg+VO;aQE!0^jHHItW1Js;!Pg;8QQ~^9v&@+al z@{Il`>r3CM$ zTe>G~su`AUCaJa}pPQ$jMX8dKP7pQVUjuOtU#|&Yq77PeN8Tsm;TpJ-PYG{Ay9sNp zDeY~W^J<&VJH!+TMk&f?bmAG`C!C1O<%DBQ-IcThYDV!dXxdGoH0@@S zH0@@*q}@=eX*XNLUIdG=NrN;(E7Oc6cT7){{eH|8wUQ6Pg+fw}hg)O0j<&fz2z7zXC!8Q@Rg_>_*jPE%=1SWl zS6UV0Udg&P*`}UkDIc>mQ!LF?OY^v`2h(glsKj%eMZ0Rs%IglIGd)8udY^&6KSszG zvR`|{k`H@jJ%CSbNQL2r%c}H?}P;sIi9?}AbyivZ}O5~5;It*OBYz|uD|ZkU$e(N;Kf{CacEqP&F!c&Q>#P5jZ))^YRhB$9$vvh7 zl`y#~(_Z0ii8iTBPrnoRi5}QaxXFCR0YC`sthq()#2ddl}nnM$|tOadZBVo zRY}6y@;AcjN)Vo+Bw-t+2x}+@s-9@m(>3 z^L$s^`?)sXJd>}w27IIH2p*2_zdt@5G{&pzq1~i<*z#{6=K^&dVZQ1~%ocSc_&C+e zme`wcqUu99R?!FXRs+GutJ}eg)F4W)sqP@Gr3Mq8s_rDLt#0D(X4RLJ`&2)|393Kg zH|l1>uhjt3xat-{JEp6AVr>tJZ?eHk^d<^^^Mv#?Jk`S{g?a?q0qRlkv1$Tk6{?AZ zTMnXp%2Lt;kd7VzN_qg^VJ>(+9?gvJ_%xfZl$FoaGVV-7Gcl=Nv`<(nmd%Rwn5Jgq zGh(>-GGQTpBjy@XYihV_CUlctgJcZ(bn$DO;O9058Co zgfzv+2s}y5cmB-8<4t19T1U7Qj}r6T2aO1LkC>F-+mstE?RUhC!Ry4-xlNXKi=oBq z+0-3ICbiAni+JGBF1$j=w2LwLk5Ja3#(l@*PLV^qA#G{GjrfpIGF~Kb1wRr)O^ful zI<%ym@_3V&(#*L3AM_5+F*euAgoRF;ybBy!BIVN~r1G6(!M8Zafsb=&kEz`bEjBgT zsZIP==QQx~P94gx>C`2x<-Ml;NLi>5`Jy?=$r-p0VBNg7Zc+&Al&4fLAvoyL+~Q!Ov0_< zmv>s&G%dM%h!Gxd8k0jV;YNp+&$F7AzuBSX^OT(omD8D+txi{-sr(_om2K&cZRrke zJT<}TW%Iky=GWWi(Z}XN%gw3g&~kIC99*~9GvAbdx23(y<}=LF-eYNpoATL1pYQC9 zAU+>CwM3iwXQKhDoeigKn|5f^eCKf{Cx<=&u1zA`;ygyoIA=29L(UY!-Og0PiOyX6 z6!XBxvntv==`_L}&UC_`oF@o>bY>9#;>;xFW>!cW4$k6vldO`aH*)AHcy`lM>~!cU zm`g1-qO)S!e2HfXH?eBkl=3`yku#q#`j#Ktm``j>iGIwX_3}QZ^=@)#z2rsP=G{Ig z9OHapXq@%nysH^soDDYqE0YH8)XMyk+=s+uH4%r_PCk1`Gtn{aJl~;(Qwq;RDcfwG zKM*tC*$!UhY$n{|Y$0ZhQ$+aCfg^l^R__%i66SuwB^;Zeou>*CzR4*Oz!TcBdAbCx zft02-~s`nYoZp)Oxkm&Y7{p4YL}}m@~VM`LeOj z`2DkGiR#RkF>9Kgwc^c~#cG7MEf^=5b@6-cpD&?>8+#(};q%>#-*I>F21C%2$1z(m zixpI_h*fBDpP`KuiJek0k6uw$ku_v}c^)(9t(iaX#_ah(IgFWe&Vgk1Wg)hiH?YWj z&YbynxrYhGvg&AN&1sv&RKT(wmlRS(r)4JM|5IrEw7S?0@EsCVoWQLlL-^K8`Z zEJj_-V${bhMxD%J)XOZ!h?K=%h%v^eY#bw87F!f!FU1(+TlVhDG4@J~y&7XnVr*%Q zEsL?&Vr+Sg{WZo`#MsIhTNPugV{A=~y&hw4#MqlL_EwC&9b@mr*t;?IUW~mTV;{uW zhcUJ`#y*NM+IW^PwDTwqs?dI=qIw+*D>}@jC~(t8!dJ~t6&brvqf-_eA7c;4*dsCaXpAwMXDKGe*rXVHEXF3s*pwKX8e@;g*z_2CBF3i0 z*sK_PD#m8S*vuGvGR9`d7$d)Z(mx)v%wBKNh!u}lhqTRH>Ndr4-Q2y*ZGk=cVRx?k z43-&Vf7urKMtJvO4KD2;?H}V;_Urkl)545Zz>Gzn8L@;T^RcVn#jhwnMSMBtaA=G2 zD7BueX_3nP1|Ni@_$8RLEEZ=|2xi9PcDuh_<9BZ9u+XeO)O|BkX!4D7wq7^P9+k&t za155o8CW4_VR4*;b@3T2iO*pdd=VScA}nq5J?t)`yn4=Y56KzrQnTnF=57SLP#Da1!=HYy4Z8bZ5tt;C(sDy@M|#>(Vcnj zsmyGz6`N&39*xDjk!+8Zdyr)H1pD+TxV9Z$0Qf z$3T^cGw->-yhGjPXsHr3#VHQHmz8#6n&PRg98~O1=xr8ppm<8-Qx^R*iGozM|JVNK zEglcy1D)#O%CGM_aHn+(BhwqjyaetO@3tz=J*n6Itw5Fi})WKjd|M>OQbqS1bA!|`^PS8(w$r)T?LVpXC3%& zS{Es+9hj0;`YG(zCI0bdG-*#El-_+75Bq{e;_!c=AK3p*jNhYVcLVd?gs4ea-n$PE zhf#PlJc#GQSiBU*DE&GdAOyq9c_Q5`JJFX{ad$0Njz z))vPz1|5Z+D;^;ZuSzddQH&O&<*o8#`7wKC4r1n}Q0x%D$pFux%J`|(k!RukbAqac zFWCk7HndTB`2O@&gVb<*eD9MTZeKA7n{mFFfW3GgyHzZgQ|YxA;ES{d zZE>Ca7JYG-O5or2Z$1yUrL|%mPgT~b?qj4jM!3*x&A z@CpmlEx?qr&X5m z>LgiPHpD}#IUa!>8Mpc)fsDYiKMAj_XXRo>uXoUyH^|NMXF9bMn)9)$D*9yub)IT0 z+WRMy`!3pAd*)wy(m(upeRd5#V4vb&_`TfbSIcs1R~B2~M%cm_TN-1_Vr+R9GrSBb z3@;-rqFq31iQ*#K1^9!8afZ_o7SS3`M{yDDLRwrD7tt<_X_v<3E{$o~uQf|yT5CwV zG%j~pOuHWUo6I=yL>SlXKF%t*I?mYgGG0voJ~E6?nXJA))&#z>azJoIh%SC-ZfZw*I;4J zrjwx+sw%1me!A!3RoNOJ-EOLn8mNY;(drRAD(9$$Y8ie(Yt`rKd$nEdaXfmkqw%Ax z?KE^Q!po#Dc_<#G1qhiFJu@6WbEI+=N@kt>m8I)^Z!T7ogj; zar5xJ?Tc6Ka5tabk)LqqF~Tf&-(pwe^==`)-@kc*SI(>KRrTt4XL*gh7Wip)#_w@} zH-r&<9OLyY?|JVPZB0v-tY2 z2;K=k#jksF@N-fmQ^^X+W0TdB^^)f#8z);OJ0!a%dnIp84#n$fd~#}XHoN>TNv=tL zkX)DiHn}aiE0suBAvFzOspnIRQ_E9t zq&`S}mfDai#8Y=yj>2!OT+Y!sC*;(?i|VYLi`etGbxwzz&N)4D`sNJG8JaUPry%E% zoXI&)_>9A*R#8tPY(b1IjIpILwk*b$XE9UvLRwS%A}pe%M~&kmT6)xMoT;B7g{h$t z7SS$@Y3WhpyAdrtYBr7@HO3-Zdek^BqNPX8#?hn3SVT*Y8plPn^r&%ML`#pFjiX16 zv51x)HI9pD=}~PQoXXM~ETlD9NNcc=)?gv6!6I7lY%UR>xyG~+pG{mu8}T{ptqgY! z7L{xIlqfDLH{!EN7nK|F*^G@5EhAT!HsZ6n8uwh^w?3k5uZ(5L>tv-6Bp4&eCA$E8}Zr1MYIv0O9EMtn9hP58bB3;ArYkk()!pA8n$8Z6|qk%A)Hh|eZ2qK)`$ z;v(9J&qi*FXd^zGxQI65vx$pnBR(5RE253~Y~mu?h|eZ2qK)`$WV47i;uwh#6`3bpD8sKAX6RHsZ69Por`pKAX6RHsZ61i)eX%+s@%*OdIjp z#6`3bpG{mu8}XT#m^R|GiHm3>KAX6Z7Rqe71`D6rU?HCk7Sb9lvd+KA7T8q-F6 zHgOSc#Ag#1(MEjcIb+(0&n7OSjreThBHD=0yje^e@!7;hv=N_8Ttpl38D7M+5uZ(5 zL>uwh#6`5cyZuIRFQ$$7Y~mu?h|eZ&xqp0CiVd#|vcDH*uS>JnW!Y<(-f-5WH+&7R zVS2;U@OPNr@YDP@+zhW_dc(=^cbMLAG5j5-Hykv-4gbPxnBMR%{2it@d^5id*TQR< z-f%4Z9i}(j3V(;`4X4a+!>8~XrZ+qae~0Nq{wSMD**ulaNx93J;|Zv1)F++|W-XcuGXtqaH+FcDq6&EUdjK9V#;@4Uaxx2*7vDJtKcaA6tZp`KQ)bJ; zn0nACQ{VT`(%6~cGQ>-FGhxCHOo~I^|CQ&!YVTJuDQs9QAJ%i2*`DU28>_(@%T}_3 z>}h?ejyAr}(i3%LDdvX~W^SFi3VibIwUoVX^DAOCDeWIgSjPHGe9bDe3Sx(Ucs5;G z%G_ct7Im0^Yg9}h9n7rGXgsqgvnFz$Sq0#q8kZ7byRvb6DLIVWi*9SMz4j?0EQ*WL z?dAS1zgG4c!fW{3q%gnD{gblq5MKA%-{hOU?)7W%Rww&43DK(I5_Spy6ic(qUQHg= zdB0tj|8RmgHD3a5fQ39K4@xxQu51kX5o1C_7f^GyG55FEt_!R}{WG(r#_M1L{`l{R z@9~&8hqZZ~nTyM3zGpcza+{g$I*Iw6rmCa56`gPv{sQkX%eIYEfGRq*I9aDcqH5wS zw7Tx-bK?_p5-Sp)CAPbz+>_k%yz1y+w|e>5ZB}{Pe9u4DZ|Jx22m9mDtXBCOY~3?+ zriw2!lqVG8FNBg=Lo-7^0WkBa-GS)Ne0yg|_D(pj9MUYXce-Wo)GtPZ2QR;xXYU+c z?9L)^g>~pjQYgx*LD}mmD=IIUZFh^ZE$>GdW++(S1cl?R@K%`FUUwcerqw0TG5N>9vj6xlNw;q{-e-kO{EtVVbUWBPhAWTRGFy4AY?*7a z6bbJ<^KZ*sn2mG28sWb!b6Pgm^D0FDw#-r4c%M~k@xLvzzrAD1oNmf=*SYI#ncK4z z308gaZ_8YtjdSUr?7uDZt!%94PL2L;nb8yate}qnZJCoTg(-6iWlHvD4wy@Yu4 zn|XQndnPTOrv-;Gvx)gwIBKezip?U78&BMF@bC+o?~awieHQv*HidGhvZ6u~N_<5P zjl(+J(fAEXLa932xCCo>`4<-uJCN8GHr8bou>H67q$}|aZM?NKxXq~-&GFJTz3p*$ z6&(q3lsdueoU6KuYRs(MBbu@%?_SYEJ)j;CH?Ri!dC`*o=#3SjD_c2g&}d%xIs0Kho{;T;~pFguK9b zCduZ^Y|odi@KD+*dpdg)fgF>#!aZ6(X3nirU1*1%>dNUxWz@CFGm^d3jmeqG*VT;V zyUA}U*;=y_gRo|`in$0s6Fr1V^pIvmF>NtS)mAu(wu!cqc2g|&0+HYxF8)~|Qarx8 zaG3?N|6)&kM;gmj!i+9lv$;rmBk7o4Y=yz%SlX-eHD%A^-?ZKENfbRh-_xPSm}?ws zW}l_AkX$Sl$9HF*U*gy2(6d-Pd&gnKFmssF8AdK#?jSEp=ZPKI=UDf6&v2HSzyh z>cxHHOI6%up z4m6xNgBUAKu)0c`@rJmDgp&T)gwNUg{lW3z0zzr{2v)#8ujboTu#45p^v^3;3%gpa zVLj{{^w4i33uRZuTKf9Xhm@v7cx%o(WRSVb_$k{Iv?4q@!>@BDafh=~n_AAydq?4^ zYt^-^QodJ>VATibG>S6VH^+#w_@Vwolv7`@H#lctJ8eY+r-Rc~oN04!MD7KmF}?j- z(cbwOU*9V^LGe40>uhv>5j~te&R%gFr5cY7^EE3|!hOzt&PeBeXB6wc&Au7=&KUCG z3GMhKY`)Sywc%PsnPT)EspwO=a+YMVJ4onwl$s}&HV^aEi7cI@$26KsCB989?k8Nl zv)qR*hIf`bA&wgx$30}RaAyp2-|)*k`!Z3JdHpNdb>S*@TgYXXg=^Sdp%YSO7j{j! zmR%CAV{e4(*$v?a=KgPFuY=x5Q#Y}i}-f37B>U#CO)4lra!_dGx!)xfBiJjqW?;P)3q_6Y6 z3%m=xi@l83*lXf7^_qE?VS#ArX|J_+x!1;P=Uw3$-;kQWvpRo$*2g$pl^=Q-|M6;k zX;hD{weHg#f~Xg;UjR3Ydp#ie7fJ? zU&ZXLV)j@mz9)~_UuFN!1HZr1%8=jPpXW~ZfpDi4p3eAUoX^u4&o0M$c6s>CHRDN* zA487qb;=mth{Nddo+drBLgGlqxTT_!_4_)?%Kpc&yTRA&qrRE(?pXSvQlg>RaYdZv z?e+Gues}*HS48W&)V*s<_21{N@i1#ijp>VRYPx@)zncEbND3*&Ez{ym zJBj*{3&H70ijxb7b?7qd1Y{VaBOP(aRMHGpxVw?CuY!^S` zz3~%!4gDf^ieDL5cO&iX6~BpnCQCfo9em?lJPv$3Jd(&7C!%4Vj2}TYRb8EeHL@n2 z9;f0}a2or))K&H3eT2@yi~US>mO7hVV9v#2dA_{;-p^RBaqoq}GqI|jY%yv5!@ zA7at`0E^~w?3$~bHO}kK8=UpJ-{Z0awf$;0*UiK3c!_tZ*W7F6-HhHl(7VIC%X@;^&GVi||9!|G?>~%<@dN)utcxG{AG3E@)9l_|Q|vxm)9v0`2k)b` zn6G}WcmP>aAW5#I&a7rtcMj(UZxof;L1zLpDMtIKiS}`{Xu_Gmm9u(BGdr3zN1OOc zv{2uuZ$xYMTPhNlo3nYvRkqi^+V=W+MvoBPj2uH|m@OX18+5LihBxSQV!A)lA1R*jNBIwk8UBO*gW^fQz%LN9{5Ad>@f23vH^prK zZU1dC$A8a%Pt0Y%wj;zm_G&vyJi`uZt;MtKj+QIto4wG)0`@i=B^F}MeO4^r-wIgg zS|#?hjlO#H&7&_KeedXNN8dX8rOB;|-RTU^QoGO86>fVwZZv~KW{esHFN}xUINsX$ zyw3HWGjGK^6_~f+9o{SUL_N@}|708dqqbvuFWYM=>X@l-!qzuw>svWnm#Wyhbds%0 zC)>JoD*fBJqBdheOK}?g+kK*rznWgIZn5XSfHNWr{Y{(zyu~l_xBA;S1$evvqrb!d z$^Y4$1?=w&gumDSEl6-0und&H%iql|IE(#XeWN|558U^L9d6j)hP`ca+0lmmY!0z6 z&DZ$s9k}a^!cVF8f0KK(RsUb-S~2d76PNhC@kO}F@9X#T`};Th1N>XqIpsFI6K?kh z`FAjjcBenYzsn!$-;KY*J^pb2UVj9<9_in2Ys+ZrOTIsbIy1IdfAgq6!Jp_);{P#! zvOmS2>ObyJ_n#>7YnngHf6AZX&-9JWaQJm|~^Plmb^`G;f_vf?2%nNvLyy!3TU-B3GFZ-|fulh^; zrTBBa<}dgE>aXxuG6%Vu-r;rIs@|eqz2m=2-|+taUfKV||J47R{~7;(_t*LVzz^gL z|4V;EiC^p4&E`A*EB|Z%8;gDKZ-ie>O7QF9gI1;euW?Ln5JmrNH_N05E=|hc-_bIu zf^^b}cC}0<%)XYzcePBq;l7qh?|*b(%g*u6me&QFlD^s9G8u&XTPBmy4wuPP$vrNU zIpHps$x{1wxlEQ0cezZK`MIcY{xY_skxX-Zby! zXfMg+VZj!=N90HU=`NATV-9OE{%DWLu~v%v{e2?KvQy+S@m`Uq+1()5xuBEyYFdN!aq_WM$cY300i!b&H?N+$^`ow!!E zGrseYX4GDs@@F-HgZH|nY{yE_!b;Ey_QxG1s>G#Av^`WIW{t5;#81+c`H?><$Du(O z?Z7=);;>R~6)VjiU#v`18=ARSp|uz*-BV~KA96Q9I&FUg1MLc}X-a@qYl$Of9tl literal 0 HcmV?d00001 diff --git a/crates/ledger-gui/src/app.rs b/crates/ledger-gui/src/app.rs new file mode 100644 index 0000000..90e260a --- /dev/null +++ b/crates/ledger-gui/src/app.rs @@ -0,0 +1,442 @@ +//! The window: sidebar, top bar, and the current page. + +use crate::books::Books; +use crate::data::{Loader, Source, Update}; +use crate::nav::{Nav, Route, Section}; +use crate::pages; +use crate::receipts::Receipts; +use crate::theme::{self, pal}; +use egui::{ + Align, Color32, CornerRadius, Frame, Key, Layout, Margin, RichText, Sense, Stroke, Ui, vec2, +}; +use egui_phosphor::regular as icon; +use std::sync::Arc; + +/// Per-page state that survives navigation. +#[derive(Default)] +pub struct PageState { + pub transactions: pages::transactions::State, + pub reports: pages::reports::State, + pub accounts: pages::accounts::State, + pub documents: pages::documents::State, + pub journal: pages::journal::State, +} + +/// What a page can ask of the shell. +pub struct Shell<'a> { + pub receipts: &'a mut Receipts, + pub state: &'a mut PageState, + pub go: Option, + /// Seconds since the last live update arrived (for "new" highlights). + pub since_update: f64, +} + +impl Shell<'_> { + pub fn go(&mut self, r: Route) { + self.go = Some(r); + } +} + +pub struct App { + loader: Option, + books: Option>, + error: Option, + nav: Nav, + receipts: Receipts, + dark: bool, + state: PageState, + palette: crate::palette::Palette, + updated_at: f64, +} + +impl App { + /// The live app over a books directory. + pub fn new(cc: &eframe::CreationContext<'_>, source: Source) -> Self { + let dark = cc + .storage + .and_then(|s| s.get_string("dark")) + .map(|v| v == "true") + .unwrap_or(cc.egui_ctx.global_style().visuals.dark_mode); + let mut app = Self::bare(&cc.egui_ctx, dark); + app.loader = Some(Loader::spawn(source, cc.egui_ctx.clone())); + app + } + + /// An app showing fixed books (tests and screenshots). + pub fn with_books(ctx: &egui::Context, books: Books, dark: bool, start: Route) -> Self { + let mut app = Self::bare(ctx, dark); + app.books = Some(Arc::new(books)); + app.nav = Nav::new(start); + app + } + + fn bare(ctx: &egui::Context, dark: bool) -> Self { + theme::install_fonts(ctx); + theme::apply(ctx, dark); + egui_extras::install_image_loaders(ctx); + Self { + loader: None, + books: None, + error: None, + nav: Nav::new(Route::Overview), + receipts: Receipts::new(ctx), + dark, + state: PageState::default(), + palette: Default::default(), + updated_at: -1e9, + } + } + + /// Navigate (tests). + pub fn goto(&mut self, r: Route) { + self.nav.go(r); + } + + /// Block until every receipt on screen has rendered (screenshots). + pub fn settle(&mut self, ctx: &egui::Context) { + self.receipts.settle(ctx); + } + + /// Page state (tests). + pub fn state_mut(&mut self) -> &mut PageState { + &mut self.state + } + + fn handle_keys(&mut self, ui: &Ui) { + let (back, fwd, palette) = ui.input(|i| { + ( + (i.modifiers.alt && i.key_pressed(Key::ArrowLeft)) + || i.pointer.button_pressed(egui::PointerButton::Extra1), + (i.modifiers.alt && i.key_pressed(Key::ArrowRight)) + || i.pointer.button_pressed(egui::PointerButton::Extra2), + i.modifiers.command && i.key_pressed(Key::K), + ) + }); + if back { + self.nav.back(); + } + if fwd { + self.nav.forward(); + } + if palette { + self.palette.open(); + } + } + + fn sidebar(&mut self, ui: &mut Ui) { + let p = pal(ui.ctx()); + let books = self.books.clone(); + egui::Panel::left("sidebar") + .exact_size(224.0) + .resizable(false) + .frame( + Frame::new() + .fill(p.sidebar) + .inner_margin(Margin::symmetric(12, 16)), + ) + .show(ui, |ui| { + ui.horizontal(|ui| { + let (r, _) = ui.allocate_exact_size(vec2(28.0, 28.0), Sense::hover()); + ui.painter().rect_filled(r, CornerRadius::same(8), p.accent); + let initial = books + .as_ref() + .and_then(|b| b.company_name().chars().next()) + .unwrap_or('W'); + ui.painter().text( + r.center(), + egui::Align2::CENTER_CENTER, + initial, + theme::bold(15.0), + Color32::WHITE, + ); + ui.vertical(|ui| { + ui.spacing_mut().item_spacing.y = 0.0; + let name = books + .as_ref() + .map(|b| b.company_name().to_string()) + .unwrap_or_else(|| "wanderbooks".into()); + ui.add( + egui::Label::new(RichText::new(name).font(theme::semibold(13.5))) + .truncate(), + ); + ui.label( + RichText::new("Books") + .font(theme::regular(11.5)) + .color(p.muted), + ); + }); + }); + ui.add_space(18.0); + let current = self.nav.current.section(); + let attention = books.as_ref().map(|b| b.attention.len()).unwrap_or(0); + for s in Section::ALL { + let on = s == current; + let (rect, resp) = + ui.allocate_exact_size(vec2(ui.available_width(), 32.0), Sense::click()); + if on { + ui.painter() + .rect_filled(rect, CornerRadius::same(8), p.surface); + ui.painter().rect_stroke( + rect, + CornerRadius::same(8), + Stroke::new(1.0, p.border), + egui::StrokeKind::Inside, + ); + } else if resp.hovered() { + ui.painter() + .rect_filled(rect, CornerRadius::same(8), p.hover); + } + let color = if on { p.text } else { p.muted }; + ui.painter().text( + rect.left_center() + vec2(10.0, 0.0), + egui::Align2::LEFT_CENTER, + s.icon(), + egui::FontId::proportional(16.0), + if on { p.accent } else { p.muted }, + ); + ui.painter().text( + rect.left_center() + vec2(36.0, 0.0), + egui::Align2::LEFT_CENTER, + s.title(), + if on { + theme::semibold(13.5) + } else { + theme::regular(13.5) + }, + color, + ); + if s == Section::Overview && attention > 0 { + let badge = egui::Rect::from_center_size( + rect.right_center() - vec2(18.0, 0.0), + vec2(22.0, 18.0), + ); + ui.painter() + .rect_filled(badge, CornerRadius::same(9), p.warning_soft); + ui.painter().text( + badge.center(), + egui::Align2::CENTER_CENTER, + attention.to_string(), + theme::semibold(11.0), + p.warning, + ); + } + if resp.clicked() { + self.nav.go(s.home()); + } + } + ui.with_layout(Layout::bottom_up(Align::Min), |ui| { + let label = if self.dark { + format!("{} Light mode", icon::SUN) + } else { + format!("{} Dark mode", icon::MOON) + }; + if ui + .add( + egui::Button::new( + RichText::new(label) + .font(theme::regular(12.5)) + .color(p.muted), + ) + .frame(false), + ) + .clicked() + { + self.dark = !self.dark; + theme::apply(ui.ctx(), self.dark); + } + ui.add_space(6.0); + if let Some(b) = &books { + live_status( + ui, + b, + ui.input(|i| i.time) - self.updated_at, + self.loader.is_some(), + ); + } + }); + }); + } + + fn topbar(&mut self, ui: &mut Ui) { + let p = pal(ui.ctx()); + egui::Panel::top("topbar") + .exact_size(52.0) + .frame( + Frame::new() + .fill(p.bg) + .inner_margin(Margin::symmetric(20, 10)) + .stroke(Stroke::new(1.0, p.border)), + ) + .show(ui, |ui| { + ui.horizontal_centered(|ui| { + let nav_btn = |ui: &mut Ui, glyph: &str, enabled: bool, tip: &str| { + ui.add_enabled( + enabled, + egui::Button::new(RichText::new(glyph).size(16.0)) + .frame(false) + .min_size(vec2(28.0, 28.0)), + ) + .on_hover_text(tip) + .clicked() + }; + if nav_btn(ui, icon::ARROW_LEFT, self.nav.can_back(), "Back (Alt+←)") { + self.nav.back(); + } + if nav_btn( + ui, + icon::ARROW_RIGHT, + self.nav.can_forward(), + "Forward (Alt+→)", + ) { + self.nav.forward(); + } + ui.add_space(6.0); + let crumb = self + .books + .as_ref() + .map(|b| crate::palette::describe(b, &self.nav.current)) + .unwrap_or_default(); + ui.label( + RichText::new(self.nav.current.section().title()) + .font(theme::regular(13.5)) + .color(p.muted), + ); + if !crumb.is_empty() { + ui.label(RichText::new(icon::CARET_RIGHT).color(p.faint)); + ui.add( + egui::Label::new(RichText::new(crumb).font(theme::semibold(13.5))) + .truncate(), + ); + } + ui.with_layout(Layout::right_to_left(Align::Center), |ui| { + let search = egui::Button::new( + RichText::new(format!( + "{} Search everything… Ctrl K", + icon::MAGNIFYING_GLASS + )) + .font(theme::regular(13.0)) + .color(p.faint), + ) + .fill(p.surface) + .stroke(Stroke::new(1.0, p.border)) + .corner_radius(CornerRadius::same(8)) + .min_size(vec2(260.0, 30.0)); + if ui.add(search).clicked() { + self.palette.open(); + } + if let Some(b) = &self.books { + ui.label( + RichText::new(format!("Today {}", crate::fmt::date(b.today))) + .font(theme::regular(12.5)) + .color(p.muted), + ); + } + }); + }); + }); + } +} + +fn live_status(ui: &mut Ui, b: &Books, since_update: f64, live: bool) { + let p = pal(ui.ctx()); + Frame::new() + .fill(p.surface) + .stroke(Stroke::new(1.0, p.border)) + .corner_radius(CornerRadius::same(8)) + .inner_margin(Margin::same(10)) + .show(ui, |ui| { + ui.set_width(ui.available_width()); + ui.horizontal(|ui| { + let (r, _) = ui.allocate_exact_size(vec2(8.0, 8.0), Sense::hover()); + let pulse = (since_update < 2.0) as u8 as f32; + let color = if live { p.positive } else { p.faint }; + ui.painter().circle_filled(r.center(), 4.0 + pulse, color); + ui.label( + RichText::new(if live { "Live" } else { "Snapshot" }) + .font(theme::semibold(12.0)), + ); + ui.label( + RichText::new(format!("· event {}", b.seq())) + .font(theme::regular(12.0)) + .color(p.muted), + ); + }); + ui.label( + RichText::new(format!("{} Journal chain verified", icon::SEAL_CHECK)) + .font(theme::regular(11.5)) + .color(p.muted), + ) + .on_hover_text(format!( + "Every journal event's hash chains to the one before it.\nHead: {}\nData: {}", + b.head, + b.data_dir.display() + )); + }); +} + +impl eframe::App for App { + fn ui(&mut self, ui: &mut Ui, _frame: &mut eframe::Frame) { + if let Some(loader) = &self.loader { + match loader.poll() { + Some(Update::Books(b)) => { + if self.books.is_some() { + self.updated_at = ui.input(|i| i.time); + } + self.books = Some(b); + self.error = None; + } + Some(Update::Error(e)) => self.error = Some(e), + None => {} + } + } + self.receipts.pump(ui.ctx()); + self.handle_keys(ui); + self.sidebar(ui); + self.topbar(ui); + let p = pal(ui.ctx()); + let since_update = ui.input(|i| i.time) - self.updated_at; + if since_update < 6.0 { + ui.ctx() + .request_repaint_after(std::time::Duration::from_millis(250)); + } + egui::CentralPanel::no_frame() + .frame(Frame::new().fill(p.bg)) + .show(ui, |ui| { + if let Some(err) = &self.error { + Frame::new() + .fill(p.negative_soft) + .inner_margin(Margin::symmetric(20, 8)) + .show(ui, |ui| { + ui.set_width(ui.available_width()); + ui.label( + RichText::new(format!("{} {err}", icon::WARNING)).color(p.negative), + ); + }); + } + let Some(books) = self.books.clone() else { + ui.centered_and_justified(|ui| { + ui.label(RichText::new("Opening the books…").color(p.muted)); + }); + return; + }; + let mut shell = Shell { + receipts: &mut self.receipts, + state: &mut self.state, + go: None, + since_update, + }; + let route = self.nav.current.clone(); + pages::show(ui, &books, &route, &mut shell); + if let Some(to) = shell.go.take() { + self.nav.go(to); + } + if let Some(to) = self.palette.show(ui.ctx(), &books) { + self.nav.go(to); + } + }); + } + + fn save(&mut self, storage: &mut dyn eframe::Storage) { + storage.set_string("dark", self.dark.to_string()); + } +} diff --git a/crates/ledger-gui/src/attention.rs b/crates/ledger-gui/src/attention.rs new file mode 100644 index 0000000..dda53e2 --- /dev/null +++ b/crates/ledger-gui/src/attention.rs @@ -0,0 +1,265 @@ +//! What the books need: drafts left unposted, missing receipts, schedules +//! and recurring entries due, open past periods, uncategorized tax lines, +//! 1099 vendors without a W-9, overdue bills and invoices, money owed to +//! owners. Each item says what's wrong, where to look, and the prompt that +//! asks the agent to fix it (the GUI never changes the books itself). + +use crate::books::{Attention, Books, Severity}; +use crate::fmt; +use crate::nav::Route; +use chrono::Datelike; +use ledger_core::reports::profit_and_loss_for_period; +use ledger_core::{AccountType, EntryStatus, PeriodStatus, vendor_1099_report}; +use rust_decimal::Decimal; + +pub fn find(b: &Books) -> Vec { + let mut out = Vec::new(); + let today = b.today; + + for e in b.entries.iter().filter(|e| e.status == EntryStatus::Draft) { + out.push(Attention { + severity: Severity::Todo, + title: format!("Draft not posted: {}", e.description), + detail: format!( + "#{} · {} · {}. Drafts appear in no report until posted.", + e.id, + fmt::date(e.date), + fmt::dollars(e.amount) + ), + target: Some(Route::Entry(e.id)), + prompt: format!( + "In wanderbooks, review draft entry {} (\"{}\", {}): attach its receipt if it needs one, preview it, and post it if it's right.", + e.id, + e.description, + fmt::dollars(e.amount) + ), + }); + } + + let missing: Vec<_> = b + .entries + .iter() + .filter(|e| e.status == EntryStatus::Posted && e.missing_receipt) + .collect(); + if missing.len() > 3 { + let total: Decimal = missing.iter().map(|e| e.amount).sum(); + let list: Vec = missing + .iter() + .map(|e| format!("{} ({}, {})", e.id, e.description, e.date)) + .collect(); + out.push(Attention { + severity: Severity::Problem, + title: format!("{} without receipts", fmt::count(missing.len(), "expense", "expenses")), + detail: format!( + "{} of spending over the {} threshold has no receipt attached.", + fmt::dollars(total), + fmt::dollars(b.receipt_threshold) + ), + target: Some(Route::Transactions), + prompt: format!( + "In wanderbooks, these entries have no receipt: {}. Help me find each receipt and attach it with books.attach_receipt.", + list.join("; ") + ), + }); + } + for e in missing.iter().filter(|_| missing.len() <= 3) { + out.push(Attention { + severity: Severity::Problem, + title: format!("No receipt: {}", e.description), + detail: format!( + "#{} · {} · {} is over the {} receipt threshold.", + e.id, + fmt::date(e.date), + fmt::dollars(e.amount), + fmt::dollars(b.receipt_threshold) + ), + target: Some(Route::Entry(e.id)), + prompt: format!( + "In wanderbooks, entry {} (\"{}\", {} on {}) has no receipt. Find it and attach it with books.attach_receipt.", + e.id, + e.description, + fmt::dollars(e.amount), + e.date + ), + }); + } + + for r in b.ledger.recurring_entries() { + let due = r.due(today); + if !due.is_empty() { + out.push(Attention { + severity: Severity::Todo, + title: format!("Recurring \"{}\" is due", r.description), + detail: format!( + "{} since {}.", + fmt::count(due.len(), "occurrence", "occurrences"), + fmt::date(due[0]) + ), + target: Some(Route::Company), + prompt: format!( + "In wanderbooks, run books.run_recurring through {today}, then attach each draft's receipt and post them." + ), + }); + } + } + + for s in b.ledger.schedules() { + let due = s.due(today); + if !due.is_empty() { + let total: Decimal = due.iter().map(|(_, a)| *a).sum(); + out.push(Attention { + severity: Severity::Todo, + title: format!("Amortization due: {}", s.description), + detail: format!( + "{} totaling {} not yet posted.", + fmt::count(due.len(), "month", "months"), + fmt::dollars(total) + ), + target: Some(Route::Company), + prompt: format!( + "In wanderbooks, preview books.run_schedules through {today}, then post it if it's right." + ), + }); + } + } + + for p in b.ledger.list_periods() { + if p.status == PeriodStatus::Open && p.end < today { + out.push(Attention { + severity: Severity::Todo, + title: format!("Period {} ended but is open", p.name), + detail: format!( + "{} – {}. Closing locks it and moves its earnings to equity.", + fmt::date(p.start), + fmt::date(p.end) + ), + target: Some(Route::Company), + prompt: format!( + "In wanderbooks, review period {} and, if everything for it is recorded and reconciled, preview and close it.", + p.name + ), + }); + } + } + + let (fy_start, _) = b.fiscal_ytd(); + if let Ok(pl) = profit_and_loss_for_period(&b.ledger, fy_start, today, None) { + let uncategorized: Vec = pl + .revenue + .iter() + .chain(&pl.expenses) + .filter(|l| { + b.ledger + .chart() + .find_by_code(&l.code) + .is_some_and(|a| a.tax_category.is_none()) + }) + .map(|l| format!("{} {}", l.code, l.name)) + .collect(); + if !uncategorized.is_empty() { + out.push(Attention { + severity: Severity::Info, + title: format!( + "{} without a tax category", + fmt::count(uncategorized.len(), "account", "accounts") + ), + detail: format!( + "{}. The tax summary lists them as uncategorized.", + uncategorized.join(", ") + ), + target: Some(Route::Accounts), + prompt: format!( + "In wanderbooks, propose a tax category for each of these accounts ({}) using books.tax_categories, and set them with books.set_tax_category once I agree.", + uncategorized.join(", ") + ), + }); + } + } + + let mut years = vec![today.year()]; + if today.month() == 1 { + years.insert(0, today.year() - 1); + } + for year in years { + let r = vendor_1099_report(&b.ledger, year, None); + for v in r.vendors.iter().filter(|v| v.reportable && !v.tin_on_file) { + out.push(Attention { + severity: Severity::Problem, + title: format!("{} needs a W-9", v.name), + detail: format!( + "Paid {} in {year}, over the {} 1099 threshold.", + fmt::dollars(v.paid), + fmt::dollars(r.threshold) + ), + target: Some(Route::Company), + prompt: format!( + "Remind me to request a W-9 from {}; once I have it, mark it on file in wanderbooks with books.set_vendor_1099.", + v.name + ), + }); + } + } + + let overdue = |rows: Vec| -> (usize, Decimal) { + let late: Vec = rows + .iter() + .map(|r| r.days_30 + r.days_60 + r.days_90 + r.days_90_plus) + .filter(|d| !d.is_zero()) + .collect(); + (late.len(), late.iter().sum()) + }; + let (n, total) = overdue(b.ledger.ap_aging(today)); + if n > 0 { + out.push(Attention { + severity: Severity::Problem, + title: format!("{} overdue to pay", fmt::dollars(total)), + detail: format!( + "{} with bills past due.", + fmt::count(n, "vendor", "vendors") + ), + target: Some(Route::Reports(crate::nav::ReportKind::ApAging)), + prompt: "In wanderbooks, show me the A/P aging and which bills are past due.".into(), + }); + } + let (n, total) = overdue(b.ledger.ar_aging(today)); + if n > 0 { + out.push(Attention { + severity: Severity::Problem, + title: format!("{} overdue to collect", fmt::dollars(total)), + detail: format!( + "{} with invoices past due.", + fmt::count(n, "customer", "customers") + ), + target: Some(Route::Reports(crate::nav::ReportKind::ArAging)), + prompt: + "In wanderbooks, show me the A/R aging and draft reminders for past-due invoices." + .into(), + }); + } + + for a in b.ledger.chart().all().filter(|a| { + a.account_type == AccountType::Liability && { + let n = a.name.to_lowercase(); + n.contains("due to") || n.contains("owed to") + } + }) { + let bal = b.balance_on(a.id, today); + if bal > Decimal::ZERO { + out.push(Attention { + severity: Severity::Info, + title: format!("{} owed on {}", fmt::dollars(bal), a.name), + detail: "Expenses someone paid personally, not yet reimbursed.".into(), + target: Some(Route::Account(a.id)), + prompt: format!( + "In wanderbooks, list what makes up the {} balance on {} {} and who is owed what.", + fmt::dollars(bal), + a.code, + a.name + ), + }); + } + } + + out.sort_by_key(|a| a.severity); + out +} diff --git a/crates/ledger-gui/src/books.rs b/crates/ledger-gui/src/books.rs new file mode 100644 index 0000000..2f72823 --- /dev/null +++ b/crates/ledger-gui/src/books.rs @@ -0,0 +1,519 @@ +//! The view model: one immutable picture of the books, rebuilt whenever the +//! journal grows. Built off the UI thread from a [`Snapshot`]; the UI only +//! reads it. Every number here comes from `ledger-core`; this module only +//! indexes and arranges. + +use chrono::{Datelike, NaiveDate}; +use ledger_config::BooksSettings; +use ledger_core::analysis::{balance_history, balance_series}; +use ledger_core::reports::{balance_sheet_as_of, profit_and_loss_for_period}; +use ledger_core::{AccountId, AccountType, EntryId, EntryStatus, Ledger, Side}; +use ledger_store::{Attachment, JournalLine, Snapshot}; +use rust_decimal::Decimal; +use serde_json::Value; +use std::collections::{HashMap, HashSet}; +use std::path::PathBuf; + +/// One entry, indexed for listing and detail. +#[derive(Clone, Debug)] +pub struct EntryInfo { + pub id: EntryId, + pub date: NaiveDate, + pub description: String, + pub status: EntryStatus, + /// Total debits. + pub amount: Decimal, + /// Accounts touched, debits first: "6300 Software". + pub accounts: Vec, + /// Indexes into [`Books::attachments`] of linked, current receipts. + pub receipts: Vec, + /// How the entry came to be, in words. + pub origin: &'static str, + /// Indexes into [`Books::journal`] of every event that touched it. + pub events: Vec, + pub vendor: Option, + pub reversal_of: Option, + pub reversed_by: Option, + /// Spending over the receipt threshold with no receipt. + pub missing_receipt: bool, + /// Net effect on cash accounts: positive in, negative out, zero if the + /// entry doesn't touch cash. + pub cash_effect: Decimal, + /// The customer or vendor, from invoices, bills, and vendor tags. + pub party: Option, + /// Lower-cased text for search: description, accounts, vendor, amount. + pub haystack: String, +} + +/// Something the books need, with how to fix it. +#[derive(Clone, Debug)] +pub struct Attention { + pub severity: Severity, + pub title: String, + pub detail: String, + pub target: Option, + /// A prompt to paste into the agent session that fixes it. + pub prompt: String, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +pub enum Severity { + Problem, + Todo, + Info, +} + +/// The whole picture. +pub struct Books { + pub ledger: Ledger, + pub settings: BooksSettings, + pub data_dir: PathBuf, + pub attachments: Vec, + pub journal: Vec, + pub head: String, + pub today: NaiveDate, + pub loaded_at: chrono::DateTime, + /// Newest first (date, then id). + pub entries: Vec, + pub entry_index: HashMap, + pub cash_accounts: Vec, + pub card_accounts: Vec, + /// Entries created or changed by the most recent refresh. + pub fresh: HashSet, + /// Journal seq before the most recent refresh. + pub fresh_from_seq: u64, + pub receipt_threshold: Decimal, + pub attention: Vec, + pub kpis: Kpis, +} + +/// The headline numbers. +#[derive(Clone, Debug, Default)] +pub struct Kpis { + pub cash: Decimal, + pub cash_30d_ago: Decimal, + pub liabilities: Decimal, + pub receivables: Decimal, + pub revenue_mtd: Decimal, + pub expenses_mtd: Decimal, + /// Last month over the same days as this month so far. + pub revenue_prev_month: Decimal, + pub expenses_prev_month: Decimal, + pub net_ytd: Decimal, + /// Average monthly net loss over the last three full months, if losing. + pub monthly_burn: Option, + pub first_entry: Option, +} + +impl Books { + /// Build the picture from a snapshot. `prev` is the previous picture, + /// to mark what's new. + pub fn build( + snap: &Snapshot, + settings: BooksSettings, + today: NaiveDate, + prev_seq: Option, + ) -> Result { + let ledger = snap.ledger().clone(); + let attachments = snap.attachments(None).map_err(|e| e.to_string())?; + let journal = snap.journal().to_vec(); + let receipt_threshold = settings + .receipt_threshold + .as_deref() + .and_then(|t| t.parse().ok()) + .unwrap_or(Decimal::new(25, 0)); + let cash_accounts = cash_accounts(&ledger, &settings); + let card_accounts: Vec = ledger + .chart() + .all() + .filter(|a| { + a.account_type == AccountType::Liability && a.name.to_lowercase().contains("card") + }) + .map(|a| a.id) + .collect(); + + // Journal events per entry. + let mut events: HashMap> = HashMap::new(); + for (i, line) in journal.iter().enumerate() { + for id in entry_refs(line) { + events.entry(id).or_default().push(i); + } + } + let mut receipts: HashMap> = HashMap::new(); + for (i, a) in attachments.iter().enumerate() { + if let (Some(e), None) = (a.entry_id, &a.withdrawn_at) { + receipts.entry(e).or_default().push(i); + } + } + let fresh_from_seq = prev_seq.unwrap_or(journal.len() as u64); + let parties = parties(&ledger, &journal); + let mut fresh = HashSet::new(); + let closings = ledger.closing_entry_ids(); + let mut entries = Vec::new(); + let mut reversed_by: HashMap = HashMap::new(); + for id in 1..ledger.next_entry_id() { + if let Some(e) = ledger.get_entry(id) + && let Some(orig) = e.reversal_of() + { + reversed_by.insert(orig, id); + } + } + for id in 1..ledger.next_entry_id() { + let Some(e) = ledger.get_entry(id) else { + continue; + }; + let evs = events.remove(&id).unwrap_or_default(); + if evs.iter().any(|&i| journal[i].seq > fresh_from_seq) { + fresh.insert(id); + } + let origin = origin(&evs, &journal, closings.contains(&id)); + let mut accounts: Vec = Vec::new(); + for side in [Side::Debit, Side::Credit] { + for l in e.lines().iter().filter(|l| l.side == side) { + if !accounts.contains(&l.account) { + accounts.push(l.account); + } + } + } + let amount: Decimal = e + .lines() + .iter() + .filter(|l| l.side == Side::Debit) + .map(|l| l.amount.amount) + .sum(); + let rec = receipts.remove(&id).unwrap_or_default(); + let vendor = ledger + .entry_vendor(id) + .and_then(|v| ledger.get_vendor(v)) + .map(|v| v.name.clone()); + // Receipts prove spending: hand-made entries (and recurring + // drafts) that debit an expense or buy an asset from outside. + // Invoices, payments, transfers, draws, closes, and schedules + // carry their own evidence. + let spends = e.lines().iter().any(|l| { + l.side == Side::Debit + && ledger.chart().get(l.account).is_some_and(|a| { + a.account_type == AccountType::Expense + || (a.account_type == AccountType::Asset + && !cash_accounts.contains(&a.id) + && !a.name.to_lowercase().contains("receivable")) + }) + }); + let missing_receipt = matches!(origin, "Journal entry" | "Recurring") + && spends + && rec.is_empty() + && amount > receipt_threshold; + let cash_effect: Decimal = e + .lines() + .iter() + .filter(|l| cash_accounts.contains(&l.account)) + .map(|l| match l.side { + Side::Debit => l.amount.amount, + Side::Credit => -l.amount.amount, + }) + .sum(); + let party = vendor.clone().or_else(|| parties.get(&id).cloned()); + let mut haystack = format!( + "{} {} #{} {}", + e.description(), + crate::fmt::money(amount), + id, + amount + ); + for a in &accounts { + if let Some(acct) = ledger.chart().get(*a) { + haystack.push_str(&format!(" {} {}", acct.code, acct.name)); + } + } + if let Some(v) = &party { + haystack.push(' '); + haystack.push_str(v); + } + entries.push(EntryInfo { + id, + date: e.date(), + description: e.description().to_string(), + status: e.status(), + amount, + accounts, + receipts: rec, + origin, + events: evs, + vendor, + reversal_of: e.reversal_of(), + reversed_by: reversed_by.get(&id).copied(), + missing_receipt, + cash_effect, + party, + haystack: haystack.to_lowercase(), + }); + } + entries.sort_by(|a, b| b.date.cmp(&a.date).then(b.id.cmp(&a.id))); + let entry_index = entries.iter().enumerate().map(|(i, e)| (e.id, i)).collect(); + let mut books = Books { + ledger, + settings, + data_dir: snap.data_dir().to_path_buf(), + attachments, + journal, + head: snap.head_hash().to_string(), + today, + loaded_at: chrono::Utc::now(), + entries, + entry_index, + cash_accounts, + card_accounts, + fresh, + fresh_from_seq, + receipt_threshold, + attention: Vec::new(), + kpis: Kpis::default(), + }; + books.kpis = books.compute_kpis(); + books.attention = crate::attention::find(&books); + Ok(books) + } + + pub fn seq(&self) -> u64 { + self.journal.len() as u64 + } + + pub fn entry(&self, id: EntryId) -> Option<&EntryInfo> { + self.entry_index.get(&id).map(|&i| &self.entries[i]) + } + + pub fn account_label(&self, id: AccountId) -> String { + self.ledger + .chart() + .get(id) + .map(|a| format!("{} {}", a.code, a.name)) + .unwrap_or_else(|| format!("account {id}")) + } + + pub fn account_name(&self, id: AccountId) -> String { + self.ledger + .chart() + .get(id) + .map(|a| a.name.clone()) + .unwrap_or_else(|| format!("account {id}")) + } + + pub fn company_name(&self) -> &str { + &self.settings.company.name + } + + /// Cash balance at the end of each day it changed. + pub fn cash_history(&self) -> Vec<(NaiveDate, Decimal)> { + balance_history(&self.ledger, &self.cash_accounts) + } + + /// Normal-side balance of one account at the end of `date`. + pub fn balance_on(&self, account: AccountId, date: NaiveDate) -> Decimal { + balance_series(&self.ledger, &[account], &[date])[0] + } + + /// First day of the current month. + pub fn month_start(&self) -> NaiveDate { + NaiveDate::from_ymd_opt(self.today.year(), self.today.month(), 1).expect("valid") + } + + /// Range of the last `n` months, ending with the current one. + pub fn trailing_months(&self, n: u32) -> (NaiveDate, NaiveDate) { + let start = self.month_start() - chrono::Months::new(n.saturating_sub(1)); + (start, self.today) + } + + /// The fiscal year to date. + pub fn fiscal_ytd(&self) -> (NaiveDate, NaiveDate) { + let (start, _) = self.settings.company.fiscal_year_containing(self.today); + (start, self.today) + } + + fn compute_kpis(&self) -> Kpis { + let l = &self.ledger; + let today = self.today; + let cash = balance_series( + l, + &self.cash_accounts, + &[today - chrono::Days::new(30), today], + ); + let bs = balance_sheet_as_of(l, today).ok(); + let receivables: Decimal = l + .chart() + .all() + .filter(|a| { + a.account_type == AccountType::Asset && a.name.to_lowercase().contains("receivable") + }) + .map(|a| self.balance_on(a.id, today)) + .sum(); + let ms = self.month_start(); + let prev_start = ms - chrono::Months::new(1); + let prev_end = ms - chrono::Days::new(1); + let pl = |s, e| profit_and_loss_for_period(l, s, e, None).ok(); + let mtd = pl(ms, today); + // Same days of last month: a fair comparison mid-month. + let same_day = (prev_start + chrono::Days::new(u64::from(today.day() - 1))).min(prev_end); + let prev = pl(prev_start, same_day); + let (fy_start, _) = self.fiscal_ytd(); + let ytd = pl(fy_start, today); + let three = pl(ms - chrono::Months::new(3), prev_end); + let first_entry = self + .entries + .iter() + .filter(|e| e.status == EntryStatus::Posted) + .map(|e| e.date) + .min(); + let monthly_burn = three.and_then(|p| { + let loss = p.total_expenses - p.total_revenue; + // Only months the books cover count toward the average. + let months = match first_entry { + Some(f) if f > ms - chrono::Months::new(3) => { + let m = (prev_end.year() * 12 + prev_end.month() as i32) + - (f.year() * 12 + f.month() as i32) + + 1; + m.max(0) + } + Some(_) => 3, + None => 0, + }; + (loss > Decimal::ZERO && months > 0).then(|| (loss / Decimal::from(months)).round_dp(2)) + }); + Kpis { + cash: cash[1], + cash_30d_ago: cash[0], + liabilities: bs.as_ref().map(|b| b.total_liabilities).unwrap_or_default(), + receivables, + revenue_mtd: mtd.as_ref().map(|p| p.total_revenue).unwrap_or_default(), + expenses_mtd: mtd.as_ref().map(|p| p.total_expenses).unwrap_or_default(), + revenue_prev_month: prev.as_ref().map(|p| p.total_revenue).unwrap_or_default(), + expenses_prev_month: prev.as_ref().map(|p| p.total_expenses).unwrap_or_default(), + net_ytd: ytd + .map(|p| p.total_revenue - p.total_expenses) + .unwrap_or_default(), + monthly_burn, + first_entry, + } + } + + /// Blob store path for an attachment. + pub fn blob_root(&self) -> PathBuf { + self.data_dir.join("blobs") + } +} + +/// Customer or vendor names for entries created by invoices and bills and +/// their payments, from the journal. +fn parties(ledger: &Ledger, journal: &[JournalLine]) -> HashMap { + let mut out = HashMap::new(); + let customer = |id: Option| { + id.and_then(|c| ledger.get_customer(c)) + .map(|c| c.name.clone()) + }; + let vendor = |id: Option| { + id.and_then(|v| ledger.get_vendor(v)) + .map(|v| v.name.clone()) + }; + let u = |p: &Value, k: &str| p.get(k).and_then(|v| v.as_u64()); + for line in journal { + let p = &line.payload; + let Some(entry) = u(p, "entry_id") else { + continue; + }; + let name = match line.line_type.as_str() { + "invoice.created" => customer(u(p, "customer_id")), + "invoice.payment_received" => customer( + u(p, "invoice_id") + .and_then(|i| ledger.get_invoice(i)) + .map(|i| i.customer_id), + ), + "bill.created" => vendor(u(p, "vendor_id")), + "bill.paid" => vendor( + u(p, "bill_id") + .and_then(|b| ledger.get_bill(b)) + .map(|b| b.vendor_id), + ), + _ => None, + }; + if let Some(n) = name { + out.insert(entry, n); + } + } + out +} + +/// Entry ids a journal line refers to. +pub fn entry_refs(line: &JournalLine) -> Vec { + let p = &line.payload; + let mut out = Vec::new(); + let mut push = |v: Option<&Value>| { + if let Some(id) = v.and_then(|v| v.as_u64()) + && !out.contains(&id) + { + out.push(id); + } + }; + push(p.get("entry_id")); + push(p.get("closing_entry")); + push(p.get("entry").and_then(|e| e.get("id"))); + if line.line_type.starts_with("entry.") { + push(p.get("id")); + } + out +} + +fn origin(events: &[usize], journal: &[JournalLine], closing: bool) -> &'static str { + if closing { + return "Period close"; + } + let has = |t: &str| events.iter().any(|&i| journal[i].line_type == t); + if has("entry.reversed") { + "Reversal" + } else if has("schedule.posted") { + "Amortization" + } else if has("asset.depreciation_posted") { + "Depreciation" + } else if has("asset.disposed") { + "Asset disposal" + } else if has("bill.created") { + "Bill" + } else if has("bill.paid") { + "Bill payment" + } else if has("invoice.created") { + "Invoice" + } else if has("invoice.payment_received") { + "Customer payment" + } else if has("payroll.run") { + "Payroll" + } else if has("payroll.remitted") || has("payroll.taxes_remitted") { + "Payroll taxes" + } else if has("recurring.generated") { + "Recurring" + } else { + "Journal entry" + } +} + +/// Cash accounts: from `[books] cash_accounts`, else asset accounts whose +/// names say they hold cash. +fn cash_accounts(ledger: &Ledger, settings: &BooksSettings) -> Vec { + if !settings.cash_accounts.is_empty() { + return settings + .cash_accounts + .iter() + .filter_map(|c| ledger.chart().find_by_code(c).map(|a| a.id)) + .collect(); + } + ledger + .chart() + .all() + .filter(|a| { + let n = a.name.to_lowercase(); + a.account_type == AccountType::Asset + && !a.placeholder + && ["cash", "bank", "checking", "savings", "money market"] + .iter() + .any(|w| n.contains(w)) + }) + .map(|a| a.id) + .collect() +} diff --git a/crates/ledger-gui/src/charts.rs b/crates/ledger-gui/src/charts.rs new file mode 100644 index 0000000..a81c92a --- /dev/null +++ b/crates/ledger-gui/src/charts.rs @@ -0,0 +1,387 @@ +//! Charts, painted directly: a balance line (step-shaped, because a +//! balance holds until the next transaction), grouped bars, ranked +//! horizontal bars, and sparklines. Every point answers hover with its +//! exact value; bars report clicks so they can drill down. + +use crate::fmt; +use crate::theme::{self, pal}; +use chrono::NaiveDate; +use egui::{ + Align2, Color32, CornerRadius, Painter, Pos2, Rect, Sense, Shape, Stroke, Ui, pos2, vec2, +}; +use rust_decimal::Decimal; + +fn f(d: Decimal) -> f64 { + d.try_into().unwrap_or(0.0) +} + +/// "Nice" axis ticks covering [lo, hi]. +fn ticks(lo: f64, hi: f64, n: usize) -> Vec { + let span = (hi - lo).max(1e-9); + let raw = span / n as f64; + let mag = 10f64.powf(raw.log10().floor()); + let step = [1.0, 2.0, 2.5, 5.0, 10.0] + .iter() + .map(|m| m * mag) + .find(|s| span / s <= n as f64) + .unwrap_or(10.0 * mag); + let start = (lo / step).floor() * step; + let mut v = vec![start]; + // Up to the first tick at or above the top, so the data never pokes + // past the last gridline. + while *v.last().expect("non-empty") < hi - step * 1e-9 { + let next = v.last().expect("non-empty") + step; + v.push(next); + } + v +} + +fn money_label(v: f64) -> String { + fmt::compact(Decimal::from_f64_retain(v).unwrap_or_default()) +} + +/// A balance over time as a step line with a soft fill. `points` are +/// (date, balance at end of day), ascending; the line runs to `until`. +pub fn balance_line(ui: &mut Ui, points: &[(NaiveDate, Decimal)], until: NaiveDate, height: f32) { + let p = pal(ui.ctx()); + let (rect, resp) = ui.allocate_exact_size(vec2(ui.available_width(), height), Sense::hover()); + let painter = ui.painter_at(rect); + if points.is_empty() { + painter.text( + rect.center(), + Align2::CENTER_CENTER, + "No cash activity yet", + theme::regular(12.5), + p.faint, + ); + return; + } + let first = points[0].0; + let last = until.max(points[points.len() - 1].0); + let days = ((last - first).num_days().max(1)) as f64; + let vals: Vec = points.iter().map(|(_, v)| f(*v)).collect(); + let lo = vals.iter().cloned().fold(0.0f64, f64::min); + let hi = vals.iter().cloned().fold(f64::MIN, f64::max).max(lo + 1.0); + let ts = ticks(lo, hi, 4); + let (lo, hi) = (ts[0].min(lo), ts[ts.len() - 1].max(hi)); + let plot = Rect::from_min_max(rect.min + vec2(52.0, 6.0), rect.max - vec2(8.0, 22.0)); + let x = + |d: NaiveDate| plot.left() + ((d - first).num_days() as f64 / days) as f32 * plot.width(); + let y = |v: f64| plot.bottom() - ((v - lo) / (hi - lo)) as f32 * plot.height(); + for t in &ts { + let yy = y(*t); + painter.line_segment( + [pos2(plot.left(), yy), pos2(plot.right(), yy)], + Stroke::new(1.0, p.border), + ); + painter.text( + pos2(plot.left() - 8.0, yy), + Align2::RIGHT_CENTER, + money_label(*t), + theme::regular(11.0), + p.faint, + ); + } + // X labels: first, last, and a few between. + let n_labels = 4; + for i in 0..=n_labels { + let d = first + chrono::Days::new(((days * i as f64) / n_labels as f64).round() as u64); + let align = match i { + 0 => Align2::LEFT_TOP, + i if i == n_labels => Align2::RIGHT_TOP, + _ => Align2::CENTER_TOP, + }; + painter.text( + pos2(x(d), plot.bottom() + 6.0), + align, + fmt::date_short(d), + theme::regular(11.0), + p.faint, + ); + } + // Step path. + let mut line: Vec = Vec::new(); + for (i, (d, v)) in points.iter().enumerate() { + let px = x(*d); + if i > 0 { + line.push(pos2(px, line.last().unwrap().y)); + } + line.push(pos2(px, y(f(*v)))); + } + line.push(pos2(x(last), line.last().unwrap().y)); + let base = y(0.0f64.clamp(lo, hi)); + let mut fill = line.clone(); + fill.push(pos2(x(last), base)); + fill.push(pos2(x(first), base)); + let soft = Color32::from_rgba_unmultiplied(p.accent.r(), p.accent.g(), p.accent.b(), 28); + // Fill: one mesh of strips under each flat step (the outline may be + // non-convex). A mesh has no anti-aliased edges, so strips meet without + // seams. + let mut mesh = egui::Mesh::default(); + for w in line.windows(2) { + if (w[0].y - w[1].y).abs() < 0.01 && w[1].x > w[0].x { + mesh.add_colored_rect( + Rect::from_min_max( + pos2(w[0].x, w[0].y.min(base)), + pos2(w[1].x, w[0].y.max(base)), + ), + soft, + ); + } + } + painter.add(Shape::mesh(mesh)); + let _ = fill; + painter.add(Shape::line(line.clone(), Stroke::new(2.0, p.accent))); + // Hover: the balance on the hovered day. + if let Some(hp) = resp.hover_pos() + && plot.x_range().contains(hp.x) + { + let frac = ((hp.x - plot.left()) / plot.width()) as f64; + let day = first + chrono::Days::new((frac * days).round() as u64); + let bal = points + .iter() + .take_while(|(d, _)| *d <= day) + .last() + .map(|(_, v)| *v); + if let Some(b) = bal { + let hx = x(day); + painter.line_segment( + [pos2(hx, plot.top()), pos2(hx, plot.bottom())], + Stroke::new(1.0, p.faint), + ); + painter.circle_filled(pos2(hx, y(f(b))), 4.0, p.accent); + tooltip( + &painter, + pos2(hx, plot.top()), + &fmt::date(day), + &fmt::dollars(b), + p.surface, + p.border, + p.text, + p.muted, + rect, + ); + } + } +} + +#[allow(clippy::too_many_arguments)] +fn tooltip( + painter: &Painter, + at: Pos2, + title: &str, + value: &str, + bg: Color32, + border: Color32, + fg: Color32, + muted: Color32, + bounds: Rect, +) { + let t1 = painter.layout_no_wrap(title.to_string(), theme::regular(11.5), muted); + let t2 = painter.layout_no_wrap(value.to_string(), theme::semibold(13.0), fg); + let w = t1.size().x.max(t2.size().x) + 16.0; + let h = t1.size().y + t2.size().y + 12.0; + let mut r = Rect::from_min_size(pos2(at.x + 8.0, at.y), vec2(w, h)); + if r.right() > bounds.right() { + r = r.translate(vec2(-w - 16.0, 0.0)); + } + painter.rect( + r, + CornerRadius::same(6), + bg, + Stroke::new(1.0, border), + egui::StrokeKind::Inside, + ); + painter.galley(r.min + vec2(8.0, 6.0), t1.clone(), muted); + painter.galley(r.min + vec2(8.0, 6.0 + t1.size().y), t2, fg); +} + +/// One group of bars on a [`bar_chart`]. +pub struct BarGroup { + pub label: String, + pub values: Vec, +} + +/// Grouped bars (e.g. income and spending per month), with a legend. +/// Returns the clicked group, if any. +pub fn bar_chart( + ui: &mut Ui, + groups: &[BarGroup], + series: &[(&str, Color32)], + height: f32, +) -> Option { + let p = pal(ui.ctx()); + ui.horizontal(|ui| { + for (name, color) in series { + let (r, _) = ui.allocate_exact_size(vec2(10.0, 10.0), Sense::hover()); + ui.painter().rect_filled(r, CornerRadius::same(3), *color); + ui.label( + egui::RichText::new(*name) + .font(theme::regular(12.0)) + .color(p.muted), + ); + ui.add_space(8.0); + } + }); + let (rect, resp) = ui.allocate_exact_size(vec2(ui.available_width(), height), Sense::click()); + let painter = ui.painter_at(rect); + if groups.is_empty() { + return None; + } + let all: Vec = groups + .iter() + .flat_map(|g| g.values.iter().map(|v| f(*v))) + .collect(); + let lo = all.iter().cloned().fold(0.0f64, f64::min); + let hi = all.iter().cloned().fold(0.0f64, f64::max).max(lo + 1.0); + let ts = ticks(lo, hi, 4); + let (lo, hi) = (ts[0].min(lo), ts[ts.len() - 1].max(hi)); + let plot = Rect::from_min_max(rect.min + vec2(52.0, 6.0), rect.max - vec2(4.0, 22.0)); + let y = |v: f64| plot.bottom() - ((v - lo) / (hi - lo)) as f32 * plot.height(); + for t in &ts { + let yy = y(*t); + painter.line_segment( + [pos2(plot.left(), yy), pos2(plot.right(), yy)], + Stroke::new(1.0, p.border), + ); + painter.text( + pos2(plot.left() - 8.0, yy), + Align2::RIGHT_CENTER, + money_label(*t), + theme::regular(11.0), + p.faint, + ); + } + let gw = plot.width() / groups.len() as f32; + let n = series.len().max(1) as f32; + let bw = ((gw * 0.7) / n).min(28.0); + let mut clicked = None; + let hover = resp.hover_pos(); + for (gi, g) in groups.iter().enumerate() { + let gx = plot.left() + gw * gi as f32; + let grect = Rect::from_min_max(pos2(gx, plot.top()), pos2(gx + gw, plot.bottom())); + let hovered = hover.is_some_and(|h| grect.contains(h)); + if hovered { + painter.rect_filled(grect, CornerRadius::same(6), p.hover); + } + let total_w = bw * n + 3.0 * (n - 1.0); + let start = gx + (gw - total_w) / 2.0; + for (si, v) in g.values.iter().enumerate() { + let color = series.get(si).map(|s| s.1).unwrap_or(p.accent); + let x0 = start + si as f32 * (bw + 3.0); + let (y0, y1) = (y(0.0), y(f(*v))); + let r = Rect::from_min_max( + pos2(x0, y0.min(y1)), + pos2(x0 + bw, y0.max(y1).max(y0.min(y1) + 1.0)), + ); + painter.rect_filled( + r, + CornerRadius { + nw: 3, + ne: 3, + sw: 0, + se: 0, + }, + color, + ); + } + painter.text( + pos2(gx + gw / 2.0, plot.bottom() + 6.0), + Align2::CENTER_TOP, + &g.label, + theme::regular(11.0), + p.faint, + ); + if hovered { + let lines: Vec = series + .iter() + .zip(&g.values) + .map(|((name, _), v)| format!("{name}: {}", fmt::dollars(*v))) + .collect(); + tooltip( + &painter, + pos2(gx + gw / 2.0, plot.top()), + &g.label, + &lines.join("\n"), + p.surface, + p.border, + p.text, + p.muted, + rect, + ); + if resp.clicked() { + clicked = Some(gi); + } + ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); + } + } + clicked +} + +/// Ranked horizontal bars with labels and exact amounts. Returns the +/// clicked row. +pub fn hbars(ui: &mut Ui, rows: &[(String, Decimal)], color: Color32) -> Option { + let p = pal(ui.ctx()); + let max = rows + .iter() + .map(|(_, v)| f(*v).abs()) + .fold(0.0, f64::max) + .max(1e-9); + let mut clicked = None; + for (i, (label, v)) in rows.iter().enumerate() { + let (rect, resp) = ui.allocate_exact_size(vec2(ui.available_width(), 30.0), Sense::click()); + let painter = ui.painter_at(rect); + if resp.hovered() { + painter.rect_filled(rect, CornerRadius::same(6), p.hover); + ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); + } + let amount = fmt::dollars(*v); + let ag = painter.layout_no_wrap(amount, theme::regular(13.0), p.text); + let label_w = (rect.width() * 0.38).min(220.0); + let lg = painter.layout(label.clone(), theme::regular(13.0), p.text, label_w); + painter.galley( + pos2(rect.left() + 6.0, rect.center().y - lg.size().y / 2.0), + lg, + p.text, + ); + let bar_left = rect.left() + label_w + 14.0; + let bar_max = rect.right() - ag.size().x - 18.0 - bar_left; + let w = (f(*v).abs() / max) as f32 * bar_max.max(0.0); + let bar = Rect::from_min_size( + pos2(bar_left, rect.center().y - 6.0), + vec2(w.max(2.0), 12.0), + ); + painter.rect_filled(bar, CornerRadius::same(3), color); + painter.galley( + pos2( + rect.right() - ag.size().x - 6.0, + rect.center().y - ag.size().y / 2.0, + ), + ag, + p.text, + ); + if resp.clicked() { + clicked = Some(i); + } + } + clicked +} + +/// A tiny trend line. +pub fn sparkline(painter: &Painter, rect: Rect, values: &[f64], color: Color32) { + let lo = values.iter().cloned().fold(f64::MAX, f64::min); + let hi = values.iter().cloned().fold(f64::MIN, f64::max); + let span = (hi - lo).max(1e-9); + let n = values.len().max(2) - 1; + let pts: Vec = values + .iter() + .enumerate() + .map(|(i, v)| { + pos2( + rect.left() + rect.width() * i as f32 / n as f32, + rect.bottom() - ((v - lo) / span) as f32 * rect.height(), + ) + }) + .collect(); + painter.add(Shape::line(pts, Stroke::new(1.5, color))); +} diff --git a/crates/ledger-gui/src/data.rs b/crates/ledger-gui/src/data.rs new file mode 100644 index 0000000..490b437 --- /dev/null +++ b/crates/ledger-gui/src/data.rs @@ -0,0 +1,158 @@ +//! The live loader. A background thread owns the read-only [`Snapshot`], +//! watches the data directory, and on every change applies the new journal +//! lines and sends a fresh [`Books`] to the UI, then asks for a repaint. +//! A change made by the agent in another window shows up within a frame or +//! two. Filesystem events are the trigger; a slow poll backs them up in case +//! an event is missed (network drives, odd editors). + +use crate::books::Books; +use chrono::NaiveDate; +use ledger_config::BooksSettings; +use ledger_store::Snapshot; +use notify::{RecursiveMode, Watcher}; +use std::path::PathBuf; +use std::sync::Arc; +use std::sync::mpsc::{Receiver, RecvTimeoutError, Sender, channel}; +use std::time::{Duration, SystemTime}; + +/// Where the books come from. +#[derive(Clone, Debug)] +pub struct Source { + /// The `books-data` directory (journal and blobs). + pub data_dir: PathBuf, + /// The company's `wanderbooks.toml`, if any. + pub books_toml: Option, + /// Fix "today" (tests, screenshots); otherwise the local date. + pub today: Option, +} + +pub enum Update { + Books(Arc), + Error(String), +} + +pub struct Loader { + rx: Receiver, +} + +impl Loader { + pub fn spawn(source: Source, ctx: egui::Context) -> Loader { + let (tx, rx) = channel(); + std::thread::Builder::new() + .name("books-loader".into()) + .spawn(move || run(source, ctx, tx)) + .expect("spawn loader"); + Loader { rx } + } + + /// The newest update, if any arrived since the last call. + pub fn poll(&self) -> Option { + let mut last = None; + while let Ok(u) = self.rx.try_recv() { + last = Some(u); + } + last + } + + /// Block until the first update (tests, headless). + pub fn wait(&self, timeout: Duration) -> Option { + self.rx.recv_timeout(timeout).ok() + } +} + +/// Load once, synchronously (tests and one-shot tools). +pub fn load_once(source: &Source) -> Result { + let snap = Snapshot::load(&source.data_dir).map_err(|e| e.to_string())?; + Books::build(&snap, settings(source)?, today(source), None) +} + +fn today(source: &Source) -> NaiveDate { + source + .today + .unwrap_or_else(|| chrono::Local::now().date_naive()) +} + +fn settings(source: &Source) -> Result { + match &source.books_toml { + Some(p) if p.exists() => ledger_config::load(p), + _ => Ok(BooksSettings::default()), + } +} + +fn mtime(p: &Option) -> Option { + p.as_ref() + .and_then(|p| std::fs::metadata(p).ok()) + .and_then(|m| m.modified().ok()) +} + +fn run(source: Source, ctx: egui::Context, tx: Sender) { + let send = |u: Update| { + let _ = tx.send(u); + ctx.request_repaint(); + }; + let mut snap = loop { + match Snapshot::load(&source.data_dir) { + Ok(s) => break s, + Err(e) => { + send(Update::Error(format!( + "Can't read the books in {}: {e}", + source.data_dir.display() + ))); + std::thread::sleep(Duration::from_secs(2)); + } + } + }; + let build = |snap: &Snapshot, prev: Option| -> Update { + match settings(&source).and_then(|s| Books::build(snap, s, today(&source), prev)) { + Ok(b) => Update::Books(Arc::new(b)), + Err(e) => Update::Error(e), + } + }; + send(build(&snap, None)); + + let (ev_tx, ev_rx) = channel(); + let mut watcher = notify::recommended_watcher(move |res: notify::Result| { + if res.is_ok() { + let _ = ev_tx.send(()); + } + }) + .ok(); + if let Some(w) = watcher.as_mut() { + let _ = w.watch(&source.data_dir, RecursiveMode::NonRecursive); + if let Some(t) = &source.books_toml + && let Some(dir) = t.parent() + { + let _ = w.watch(dir, RecursiveMode::NonRecursive); + } + } + let mut toml_mtime = mtime(&source.books_toml); + let mut day = today(&source); + loop { + match ev_rx.recv_timeout(Duration::from_secs(3)) { + Ok(()) => { + // Let a burst of writes settle, then take them all at once. + std::thread::sleep(Duration::from_millis(30)); + while ev_rx.try_recv().is_ok() {} + } + Err(RecvTimeoutError::Timeout) => {} + Err(RecvTimeoutError::Disconnected) => { + std::thread::sleep(Duration::from_secs(3)); + } + } + let before = snap.journal_seq(); + let grew = match snap.refresh() { + Ok(n) => n > 0, + Err(e) => { + send(Update::Error(format!("Reading the journal failed: {e}"))); + continue; + } + }; + let toml_now = mtime(&source.books_toml); + let new_day = today(&source); + if grew || toml_now != toml_mtime || new_day != day { + toml_mtime = toml_now; + day = new_day; + send(build(&snap, grew.then_some(before))); + } + } +} diff --git a/crates/ledger-gui/src/demo.rs b/crates/ledger-gui/src/demo.rs new file mode 100644 index 0000000..c5a1f4b --- /dev/null +++ b/crates/ledger-gui/src/demo.rs @@ -0,0 +1,796 @@ +//! A demo company, built through the real engine: fifteen months of a +//! small design studio (single-member LLC) with client invoices, template +//! sales paid out by a platform, contractors (one without a W-9), rent on a +//! recurring schedule, a credit card, a laptop on depreciation, prepaid +//! insurance, owner draws, a closed year, PDF receipts, and a few loose +//! ends for the "needs attention" list. Deterministic for a given `today`. + +use chrono::{Datelike, Days, Months, NaiveDate}; +use ledger_core::{ + AccountType, CloseTo, Currency, Form1099, Frequency, Money, NewAsset, NewRecurring, + NewSchedule, ScheduleKind, Side, arap::DocumentLine, +}; +use ledger_store::{Store, StoreError}; +use rust_decimal::Decimal; +use std::path::Path; + +/// The demo's `wanderbooks.toml`. +pub const BOOKS_TOML: &str = r#"[company] +name = "Juniper Studio LLC" +entity_type = "LLC, single-member" +tax_classification = "disregarded entity" # Schedule C +fiscal_year_start = "01-01" +formation_state = "OR" +formed = "2025-06-02" +ein = "00-0000000" +address = "1200 NW Everett St, Portland, OR 97209" +owner = "Alex Rivera" + +[books] +accounting_basis = "accrual" +receipt_threshold = "25.00" +close_into = "3000" +close_sweep = ["3100"] +cash_accounts = ["1000", "1010"] +"#; + +struct Rng(u64); + +impl Rng { + fn next(&mut self) -> u64 { + self.0 = self + .0 + .wrapping_mul(6364136223846793005) + .wrapping_add(1442695040888963407); + self.0 >> 33 + } + /// Uniform in [lo, hi] dollars, to the cent. + fn amount(&mut self, lo: u64, hi: u64) -> Decimal { + let cents = lo * 100 + self.next() % ((hi - lo) * 100 + 1); + Decimal::new(cents as i64, 2) + } + fn pick(&mut self, n: u64) -> u64 { + self.next() % n + } +} + +fn usd(d: Decimal) -> Money { + Money::new(d, Currency::USD) +} + +fn dec(n: i64) -> Decimal { + Decimal::from(n) +} + +fn day(month_start: NaiveDate, d: u32) -> NaiveDate { + let last = (month_start + Months::new(1) - Days::new(1)).day(); + NaiveDate::from_ymd_opt(month_start.year(), month_start.month(), d.min(last)).expect("valid") +} + +/// A one-page PDF receipt with the given lines (Helvetica). +pub fn receipt_pdf(title: &str, lines: &[String]) -> Vec { + let esc = |s: &str| { + s.replace('\\', "\\\\") + .replace('(', "\\(") + .replace(')', "\\)") + }; + let mut content = String::new(); + content.push_str("BT /F2 22 Tf 56 760 Td ("); + content.push_str(&esc(title)); + content.push_str(") Tj ET\n"); + content.push_str("0.85 0.85 0.85 RG 56 742 m 556 742 l S\n"); + let mut y = 712; + for l in lines { + let (font, size) = if l.starts_with("TOTAL") { + ("F2", 13) + } else { + ("F1", 11) + }; + content.push_str(&format!( + "BT /{font} {size} Tf 56 {y} Td ({}) Tj ET\n", + esc(l) + )); + y -= 20; + } + let objects = [ + "<< /Type /Catalog /Pages 2 0 R >>".to_string(), + "<< /Type /Pages /Kids [3 0 R] /Count 1 >>".to_string(), + "<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Resources << /Font << /F1 4 0 R /F2 5 0 R >> >> /Contents 6 0 R >>".to_string(), + "<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>".to_string(), + "<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold >>".to_string(), + format!("<< /Length {} >>\nstream\n{content}endstream", content.len()), + ]; + let mut pdf = b"%PDF-1.4\n".to_vec(); + let mut offsets = Vec::new(); + for (i, o) in objects.iter().enumerate() { + offsets.push(pdf.len()); + pdf.extend_from_slice(format!("{} 0 obj\n{o}\nendobj\n", i + 1).as_bytes()); + } + let xref = pdf.len(); + pdf.extend_from_slice( + format!("xref\n0 {}\n0000000000 65535 f \n", objects.len() + 1).as_bytes(), + ); + for off in offsets { + pdf.extend_from_slice(format!("{off:010} 00000 n \n").as_bytes()); + } + pdf.extend_from_slice( + format!( + "trailer\n<< /Size {} /Root 1 0 R >>\nstartxref\n{xref}\n%%EOF\n", + objects.len() + 1 + ) + .as_bytes(), + ); + pdf +} + +fn receipt(vendor: &str, date: NaiveDate, item: &str, amount: Decimal, paid: &str) -> Vec { + receipt_pdf( + vendor, + &[ + format!("Receipt {}", date.format("%B %-d, %Y")), + format!( + "Order {:08}", + (date.num_days_from_ce() as u64 * 7919 + + (amount * dec(100)).try_into().unwrap_or(0u64)) + % 100_000_000 + ), + String::new(), + item.to_string(), + format!("Amount: ${amount}"), + String::new(), + format!("TOTAL ${amount}"), + format!("Paid with {paid}"), + String::new(), + "Thank you for your business.".into(), + ], + ) +} + +/// Build the demo books in `dir` (which must not already hold books): the +/// journal and blobs under `dir/books-data`, the settings in +/// `dir/wanderbooks.toml`. +pub fn build(dir: &Path, today: NaiveDate) -> Result<(), StoreError> { + std::fs::create_dir_all(dir)?; + std::fs::write(dir.join("wanderbooks.toml"), BOOKS_TOML)?; + let mut s = Store::create(&dir.join("books-data"), Currency::USD)?; + let mut rng = Rng(0x5eed_1234); + let start = + NaiveDate::from_ymd_opt(today.year(), today.month(), 1).expect("valid") - Months::new(15); + let this_month = NaiveDate::from_ymd_opt(today.year(), today.month(), 1).expect("valid"); + + let acct = + |s: &mut Store, code: &str, name: &str, t, tax: Option<&str>| -> Result { + let id = s.add_account(code, name, t, None, false)?; + if let Some(c) = tax { + s.set_account_tax(id, Some(c), None)?; + } + Ok(id) + }; + use AccountType::*; + let checking = acct(&mut s, "1000", "Operating Checking", Asset, None)?; + let savings = acct(&mut s, "1010", "Savings", Asset, None)?; + let prepaid = acct(&mut s, "1300", "Prepaid Insurance", Asset, None)?; + let equipment = acct(&mut s, "1500", "Computer Equipment", Asset, None)?; + let accum = acct(&mut s, "1510", "Accumulated Depreciation", Asset, None)?; + let card = acct(&mut s, "2100", "Business Credit Card", Liability, None)?; + let capital = acct(&mut s, "3000", "Owner's Capital", Equity, None)?; + let draws = acct(&mut s, "3100", "Owner's Draws", Equity, None)?; + let _services = acct( + &mut s, + "4000", + "Design Services", + Revenue, + Some("gross_receipts"), + )?; + let templates = acct( + &mut s, + "4100", + "Template Sales", + Revenue, + Some("gross_receipts"), + )?; + let fees = acct( + &mut s, + "6000", + "Platform Fees", + Expense, + Some("commissions_fees"), + )?; + let contract = acct( + &mut s, + "6050", + "Contract Labor", + Expense, + Some("contract_labor"), + )?; + let software = acct( + &mut s, + "6100", + "Software & Subscriptions", + Expense, + Some("office_expense"), + )?; + let rent = acct( + &mut s, + "6200", + "Studio Rent", + Expense, + Some("rent_property"), + )?; + let insurance = acct(&mut s, "6300", "Insurance", Expense, Some("insurance"))?; + let advertising = acct(&mut s, "6400", "Advertising", Expense, Some("advertising"))?; + let meals = acct(&mut s, "6500", "Meals", Expense, Some("meals"))?; + let travel = acct(&mut s, "6600", "Travel", Expense, Some("travel"))?; + let supplies = acct(&mut s, "6700", "Office Supplies", Expense, Some("supplies"))?; + let depreciation = acct( + &mut s, + "6800", + "Depreciation", + Expense, + Some("depreciation"), + )?; + let bank_fees = acct(&mut s, "6900", "Bank Fees", Expense, None)?; + let client_class = s.add_class("Client work")?; + let template_class = s.add_class("Templates")?; + + let sam = s.add_vendor("Sam Okafor")?; + s.set_vendor_1099(sam, Some(Form1099::Nec), true)?; + let riley = s.add_vendor("Riley Chen")?; + s.set_vendor_1099(riley, Some(Form1099::Nec), false)?; + let landlord = s.add_vendor("Everett Lofts LLC")?; + s.set_vendor_1099(landlord, Some(Form1099::Misc), true)?; + let customers: Vec = [ + "Fern & Field Coffee", + "Bramble Outdoor Co.", + "Northwind Clinics", + "Tidepool Records", + "Larkspur Bakery", + ] + .iter() + .map(|n| s.add_customer(n)) + .collect::>()?; + + // Formation documents. + s.file_document( + "formation", + "Articles of Organization.pdf", + "application/pdf", + &receipt_pdf( + "Articles of Organization", + &[ + "Juniper Studio LLC".into(), + "Oregon Secretary of State".into(), + format!("Filed {}", start.format("%B %-d, %Y")), + ], + ), + Some("Filed with the state"), + )?; + s.file_document( + "tax", + "IRS EIN confirmation.pdf", + "application/pdf", + &receipt_pdf( + "EIN Assignment", + &[ + "Juniper Studio LLC".into(), + "Employer Identification Number assigned".into(), + ], + ), + Some("CP 575"), + )?; + + // Helper: post a two-line entry with an optional receipt and vendor. + #[allow(clippy::too_many_arguments)] + fn post( + s: &mut Store, + date: NaiveDate, + desc: &str, + dr: u64, + cr: u64, + amount: Decimal, + receipt: Option<(&str, Vec)>, + vendor: Option, + class: Option, + ) -> Result { + let e = s.create_entry(date, desc)?; + s.add_line(e, dr, Side::Debit, usd(amount))?; + s.add_line(e, cr, Side::Credit, usd(amount))?; + if let Some(c) = class { + s.set_line_class(e, 0, Some(c))?; + s.set_line_class(e, 1, Some(c))?; + } + if let Some((name, bytes)) = receipt { + s.attach_receipt(Some(e), name, "application/pdf", &bytes, None)?; + } + s.post_entry(e)?; + if vendor.is_some() { + s.set_entry_vendor(e, vendor)?; + } + Ok(e) + } + + post( + &mut s, + day(start, 2), + "Owner contribution — startup capital", + checking, + capital, + dec(15000), + Some(( + "bank-transfer.pdf", + receipt( + "Transfer confirmation", + day(start, 2), + "Transfer from Alex Rivera personal checking", + dec(15000), + "ACH", + ), + )), + None, + None, + )?; + + // Rent: a recurring entry, posted every month with its invoice; this + // month's is left as a draft. + s.register_recurring(NewRecurring { + description: "Studio rent — Everett Lofts".into(), + lines: vec![ + (rent, Side::Debit, usd(dec(1800))), + (checking, Side::Credit, usd(dec(1800))), + ], + frequency: Frequency::Monthly, + start: day(start, 1), + end: None, + })?; + + // Laptop and its depreciation. + let laptop_date = day(start + Months::new(1), 9); + let laptop = dec(3199); + post( + &mut s, + laptop_date, + "MacBook Pro 16\" — studio workstation", + equipment, + card, + laptop, + Some(( + "apple-store.pdf", + receipt( + "Apple Store", + laptop_date, + "MacBook Pro 16-inch, M-series", + laptop, + "Visa ending 4242", + ), + )), + None, + None, + )?; + let asset = s.register_asset(NewAsset { + description: "MacBook Pro 16\"".into(), + purchase_date: laptop_date, + cost: usd(laptop), + salvage_value: usd(dec(400)), + useful_life_months: 36, + cost_account: equipment, + accum_depr_account: accum, + expense_account: depreciation, + })?; + + // Prepaid insurance, spread over a year. + let ins_date = day(start + Months::new(2), 15); + post( + &mut s, + ins_date, + "General liability insurance — annual premium", + prepaid, + checking, + dec(1440), + Some(( + "hiscox-policy.pdf", + receipt( + "Hiscox", + ins_date, + "General liability, 12 months", + dec(1440), + "ACH", + ), + )), + None, + None, + )?; + s.register_schedule(NewSchedule { + description: "General liability insurance".into(), + kind: ScheduleKind::PrepaidExpense, + total: usd(dec(1440)), + start: ins_date, + months: 12, + balance_account: prepaid, + pl_account: insurance, + })?; + + let mut open_invoices: Vec<(u64, NaiveDate, Decimal)> = Vec::new(); + let mut card_balance = Decimal::ZERO; + let mut m = start; + let mut month_index = 0; + while m <= this_month { + let current = m == this_month; + let in_range = |d: NaiveDate| d <= today; + // Software on the card. + for (vendor, item, lo, hi, d) in [ + ("Figma", "Figma Professional — monthly", 45, 45, 3), + ("Adobe", "Creative Cloud All Apps", 59, 60, 7), + ("Google Workspace", "Business Starter — 2 users", 28, 28, 11), + ] { + let date = day(m, d); + if !in_range(date) { + continue; + } + let amt = rng.amount(lo, hi); + post( + &mut s, + date, + &format!("{vendor} — {item}"), + software, + card, + amt, + Some(( + &format!("{}-{}.pdf", vendor.to_lowercase().replace(' ', "-"), date), + receipt(vendor, date, item, amt, "Visa ending 4242"), + )), + None, + None, + )?; + card_balance += amt; + } + // Advertising some months. + if month_index % 3 == 1 { + let date = day(m, 14); + if in_range(date) { + let amt = rng.amount(150, 420); + post( + &mut s, + date, + "Instagram ads — portfolio campaign", + advertising, + card, + amt, + Some(( + "meta-ads.pdf", + receipt("Meta Ads", date, "Sponsored posts", amt, "Visa ending 4242"), + )), + None, + None, + )?; + card_balance += amt; + } + } + // Meals and supplies. + let date = day(m, 17); + if in_range(date) { + let amt = rng.amount(28, 96); + let missing = current || month_index == 13; + post( + &mut s, + date, + "Client lunch — project kickoff", + meals, + card, + amt, + (!missing).then(|| { + ( + "lunch.pdf", + receipt( + "Tasty n Alder", + date, + "Lunch for 2", + amt, + "Visa ending 4242", + ), + ) + }), + None, + None, + )?; + card_balance += amt; + } + if month_index % 4 == 2 { + let date = day(m, 21); + if in_range(date) { + let amt = rng.amount(40, 180); + post( + &mut s, + date, + "Paper, ink, and sketchbooks", + supplies, + card, + amt, + Some(( + "blick.pdf", + receipt( + "Blick Art Materials", + date, + "Supplies", + amt, + "Visa ending 4242", + ), + )), + None, + None, + )?; + card_balance += amt; + } + } + if month_index == 7 { + let date = day(m, 9); + if in_range(date) { + let amt = dec(1186) + rng.amount(0, 90); + post( + &mut s, + date, + "Flights and hotel — client workshop, Austin", + travel, + card, + amt, + Some(( + "alaska-air.pdf", + receipt( + "Alaska Airlines", + date, + "PDX-AUS round trip + 2 nights", + amt, + "Visa ending 4242", + ), + )), + None, + None, + )?; + card_balance += amt; + } + } + // Pay the card in full on the 25th. + let date = day(m, 25); + if in_range(date) && card_balance > Decimal::ZERO { + post( + &mut s, + date, + "Credit card payment", + card, + checking, + card_balance, + Some(( + "card-statement.pdf", + receipt( + "Chase Ink", + date, + "Statement balance payment", + card_balance, + "ACH from Operating Checking", + ), + )), + None, + None, + )?; + card_balance = Decimal::ZERO; + } + // Client invoices: two or three a month, net 30. + for k in 0..(2 + rng.pick(2)) { + let date = day(m, 5 + 9 * k as u32); + if !in_range(date) { + continue; + } + let cust = customers[rng.pick(customers.len() as u64) as usize]; + let amt = (rng.amount(1800, 7800) / dec(50)).round() * dec(50); + let inv = s.create_invoice( + cust, + date, + date + Days::new(30), + vec![DocumentLine { + description: [ + "Brand identity", + "Website design", + "Packaging", + "Illustration set", + "Design retainer", + ][rng.pick(5) as usize] + .into(), + amount: amt, + }], + )?; + let entry = s.ledger().get_invoice(inv).map(|i| i.entry_id); + if let Some(e) = entry { + let _ = e; + } + open_invoices.push((inv, date, amt)); + } + // Collect invoices 20-50 days out; leave the latest ones open and one overdue. + let mut still_open = Vec::new(); + for (inv, date, amt) in open_invoices.drain(..) { + let paid_on = (date + Days::new(20 + rng.pick(30))).max(day(m, 2)); + let overdue_one = month_index == 12 && inv % 2 == 0; + if paid_on <= today && paid_on < m + Months::new(1) && !overdue_one { + s.receive_payment(inv, paid_on, amt, checking)?; + } else { + still_open.push((inv, date, amt)); + } + } + open_invoices = still_open; + // Template sales, paid out by the platform on the 1st for last month. + if month_index > 1 { + let date = day(m, 1); + if in_range(date) { + let gross = rng.amount(450, 1600); + let fee = (gross * Decimal::new(10, 2)).round_dp(2) + Decimal::new(30, 2); + let net = gross - fee; + let e = s.create_entry(date, "Gumroad payout — template sales")?; + s.add_line(e, checking, Side::Debit, usd(net))?; + s.add_line(e, fees, Side::Debit, usd(fee))?; + s.add_line(e, templates, Side::Credit, usd(gross))?; + for i in 0..3 { + s.set_line_class(e, i, Some(template_class))?; + } + s.attach_receipt( + Some(e), + "gumroad-payout.pdf", + "application/pdf", + &receipt_pdf( + "Gumroad payout", + &[ + format!("Payout {}", date.format("%B %-d, %Y")), + format!("Gross sales: ${gross}"), + format!("Fees: ${fee}"), + format!("TOTAL ${net}"), + "Deposited to checking ending 0187".into(), + ], + ), + None, + )?; + s.post_entry(e)?; + } + } + // Contractors. + if month_index % 2 == 0 && month_index > 0 { + let date = day(m, 28); + if in_range(date) { + let amt = (rng.amount(900, 2200) / dec(25)).round() * dec(25); + post( + &mut s, + date, + "Sam Okafor — illustration (invoice)", + contract, + checking, + amt, + Some(( + "sam-okafor-invoice.pdf", + receipt( + "Sam Okafor Illustration", + date, + "Illustration for client projects", + amt, + "ACH", + ), + )), + Some(sam), + Some(client_class), + )?; + } + } + if month_index == 11 || month_index == 13 { + let date = day(m, 19); + if in_range(date) { + post( + &mut s, + date, + "Riley Chen — front-end development", + contract, + checking, + dec(1400), + Some(( + "riley-chen.pdf", + receipt( + "Riley Chen", + date, + "Website build, milestone", + dec(1400), + "ACH", + ), + )), + Some(riley), + Some(client_class), + )?; + } + } + // Owner draws and savings. + if month_index >= 3 { + let date = day(m, 28); + if in_range(date) { + post( + &mut s, + date, + "Owner draw", + draws, + checking, + dec(3500), + None, + None, + None, + )?; + } + } + if month_index % 3 == 2 { + let date = day(m, 26); + if in_range(date) { + post( + &mut s, + date, + "Transfer to savings", + savings, + checking, + dec(4000), + None, + None, + None, + )?; + } + } + let date = day(m, 30); + if in_range(date) && month_index % 5 == 4 { + post( + &mut s, + date, + "Wire fee", + bank_fees, + checking, + dec(30), + None, + None, + None, + )?; + } + // Month-end: rent occurrences, depreciation, amortization. + let month_end = m + Months::new(1) - Days::new(1); + let through = if current { today } else { month_end }; + for (_, date, entry) in s.run_recurring(through)? { + if current { + continue; // this month's rent waits as a draft + } + s.attach_receipt( + Some(entry), + &format!("rent-{date}.pdf"), + "application/pdf", + &receipt( + "Everett Lofts LLC", + date, + "Studio 4B rent", + dec(1800), + "ACH", + ), + None, + )?; + s.post_entry(entry)?; + s.set_entry_vendor(entry, Some(landlord))?; + } + if !current { + if m >= laptop_date.with_day(1).expect("valid") { + s.run_depreciation(asset, &m.format("%Y-%m").to_string())?; + } + s.run_schedules(month_end)?; + } + // Close each finished calendar year into capital, draws swept in. + if m.month() == 12 && !current { + let ys = NaiveDate::from_ymd_opt(m.year(), 1, 1).expect("valid"); + let p = s.create_period(&m.year().to_string(), ys.max(start), month_end)?; + s.close_period_to( + p, + &CloseTo::Account { + into: capital, + sweep: vec![draws], + }, + )?; + } + m = m + Months::new(1); + month_index += 1; + } + let _ = (bank_fees, client_class); + Ok(()) +} diff --git a/crates/ledger-gui/src/fmt.rs b/crates/ledger-gui/src/fmt.rs new file mode 100644 index 0000000..1116ba5 --- /dev/null +++ b/crates/ledger-gui/src/fmt.rs @@ -0,0 +1,184 @@ +//! Formatting money, dates, and counts. Amounts are exact decimals in and +//! exact strings out: nothing here rounds except `compact`, which says so. + +use chrono::NaiveDate; +use rust_decimal::Decimal; + +/// Thousands separators, two decimals, a true minus sign: `−1,234.56`. +pub fn money(d: Decimal) -> String { + let neg = d.is_sign_negative() && !d.is_zero(); + let s = group(d.abs().round_dp(2)); + if neg { format!("\u{2212}{s}") } else { s } +} + +/// Accounting style: negatives in parentheses, `(1,234.56)`. +pub fn accounting(d: Decimal) -> String { + if d.is_sign_negative() && !d.is_zero() { + format!("({})", group(d.abs().round_dp(2))) + } else { + group(d.round_dp(2)) + } +} + +/// With the currency sign: `$1,234.56`, `−$12.00`. +pub fn dollars(d: Decimal) -> String { + let neg = d.is_sign_negative() && !d.is_zero(); + let s = format!("${}", group(d.abs().round_dp(2))); + if neg { format!("\u{2212}{s}") } else { s } +} + +/// Rounded for chart axes and tight tiles: `$1.2k`, `$3.4M`, `$950`. +pub fn compact(d: Decimal) -> String { + let f: f64 = d.try_into().unwrap_or(0.0); + let (neg, a) = (f < 0.0, f.abs()); + let s = if a >= 1_000_000.0 { + format!("${:.1}M", a / 1_000_000.0) + } else if a >= 10_000.0 { + format!("${:.0}k", a / 1_000.0) + } else if a >= 1_000.0 { + format!("${:.1}k", a / 1_000.0) + } else { + format!("${a:.0}") + }; + if neg { format!("\u{2212}{s}") } else { s } +} + +fn group(d: Decimal) -> String { + let s = format!("{:.2}", d); + let (int, frac) = s.split_once('.').unwrap_or((&s, "00")); + let mut out = String::new(); + for (i, c) in int.chars().enumerate() { + if i > 0 && (int.len() - i) % 3 == 0 { + out.push(','); + } + out.push(c); + } + format!("{out}.{frac}") +} + +/// A percent change from `prev` to `now`, if `prev` isn't zero. +pub fn pct_change(prev: Decimal, now: Decimal) -> Option { + if prev.is_zero() { + return None; + } + let p: f64 = prev.try_into().ok()?; + let n: f64 = now.try_into().ok()?; + Some((n - p) / p.abs() * 100.0) +} + +/// `Oct 12, 2026`. +pub fn date(d: NaiveDate) -> String { + d.format("%b %-d, %Y").to_string() +} + +/// `Oct 12`. +pub fn date_short(d: NaiveDate) -> String { + d.format("%b %-d").to_string() +} + +/// `Oct 2026`. +pub fn month(d: NaiveDate) -> String { + d.format("%b %Y").to_string() +} + +/// `1 receipt`, `3 receipts`. +pub fn count(n: usize, one: &str, many: &str) -> String { + format!("{n} {}", if n == 1 { one } else { many }) +} + +/// An RFC 3339 timestamp from the journal, shown as local-ish UTC text: +/// `Oct 11, 2026 18:04 UTC`. +pub fn timestamp(ts: &str) -> String { + chrono::DateTime::parse_from_rfc3339(ts) + .map(|t| t.format("%b %-d, %Y %H:%M UTC").to_string()) + .unwrap_or_else(|_| ts.to_string()) +} + +/// Bytes as `12.3 KB`. +pub fn bytes(n: u64) -> String { + let f = n as f64; + if f >= 1_048_576.0 { + format!("{:.1} MB", f / 1_048_576.0) + } else if f >= 1024.0 { + format!("{:.1} KB", f / 1024.0) + } else { + format!("{n} B") + } +} + +/// `snake_case_key` as `Snake case key`, for settings shown as labels, +/// keeping acronyms upper case (`ein` → `EIN`). +pub fn label(key: &str) -> String { + const ACRONYMS: [&str; 9] = [ + "ein", "duns", "irs", "cpa", "llc", "tin", "ssn", "id", "url", + ]; + let words: Vec = key + .split(['_', ' ']) + .filter(|w| !w.is_empty()) + .enumerate() + .map(|(i, w)| { + if ACRONYMS.contains(&w.to_lowercase().as_str()) { + w.to_uppercase() + } else if i == 0 { + let mut c = w.chars(); + c.next() + .map(|f| f.to_uppercase().collect::() + c.as_str()) + .unwrap_or_default() + } else { + w.to_string() + } + }) + .collect(); + words.join(" ") +} + +/// A `CamelCase` enum name as words: `PrepaidExpense` → `Prepaid expense`. +pub fn words(debug: &str) -> String { + let mut out = String::new(); + for (i, c) in debug.chars().enumerate() { + if c.is_uppercase() && i > 0 { + out.push(' '); + out.extend(c.to_lowercase()); + } else { + out.push(c); + } + } + out +} + +/// The tax return a form enum stands for. +pub fn tax_form(f: ledger_core::TaxForm) -> &'static str { + match f { + ledger_core::TaxForm::ScheduleC => "Schedule C (Form 1040)", + ledger_core::TaxForm::Form1065 => "Form 1065 (partnership)", + ledger_core::TaxForm::Form1120S => "Form 1120-S (S corporation)", + ledger_core::TaxForm::Form1120 => "Form 1120 (C corporation)", + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + + fn dec(s: &str) -> Decimal { + Decimal::from_str(s).unwrap() + } + + #[test] + fn money_formats() { + assert_eq!(money(dec("1234567.5")), "1,234,567.50"); + assert_eq!(money(dec("-12")), "\u{2212}12.00"); + assert_eq!(money(dec("0")), "0.00"); + assert_eq!(money(dec("-0.00")), "0.00"); + assert_eq!(accounting(dec("-207.68")), "(207.68)"); + assert_eq!(dollars(dec("999.999")), "$1,000.00"); + assert_eq!(compact(dec("1234")), "$1.2k"); + assert_eq!(compact(dec("-25000")), "\u{2212}$25k"); + assert_eq!(compact(dec("950.4")), "$950"); + assert_eq!(label("state_entity_number"), "State entity number"); + assert_eq!(label("ein"), "EIN"); + assert_eq!(label("irs_name_control"), "IRS name control"); + assert_eq!(words("PrepaidExpense"), "Prepaid expense"); + } +} diff --git a/crates/ledger-gui/src/lib.rs b/crates/ledger-gui/src/lib.rs new file mode 100644 index 0000000..9948e48 --- /dev/null +++ b/crates/ledger-gui/src/lib.rs @@ -0,0 +1,21 @@ +//! `ledger-gui`: a read-only, live view of wanderbooks books for the people +//! who own them and the accountant who checks them. See `plan/gui.md`. + +#![allow(missing_docs)] + +pub mod app; +mod attention; +pub mod books; +mod charts; +pub mod data; +pub mod demo; +mod fmt; +pub mod nav; +mod pages; +mod palette; +mod receipts; +mod theme; +mod widgets; + +pub use app::App; +pub use data::Source; diff --git a/crates/ledger-gui/src/main.rs b/crates/ledger-gui/src/main.rs new file mode 100644 index 0000000..58d750a --- /dev/null +++ b/crates/ledger-gui/src/main.rs @@ -0,0 +1,72 @@ +//! `ledger-gui [--data-dir PATH] [--books-toml PATH] [--today YYYY-MM-DD] [--demo]` +//! +//! Opens the books read-only and follows them live. With no flags it looks +//! for `books-data/` and `wanderbooks.toml` in the current directory. +//! `--demo` builds a demo company in a temp directory and opens that. + +use ledger_gui::{App, Source}; +use std::path::PathBuf; + +fn main() -> eframe::Result<()> { + let mut data_dir: Option = None; + let mut books_toml: Option = None; + let mut today = None; + let mut demo = false; + let mut args = std::env::args().skip(1); + while let Some(a) = args.next() { + match a.as_str() { + "--data-dir" => data_dir = args.next().map(PathBuf::from), + "--books-toml" => books_toml = args.next().map(PathBuf::from), + "--today" => today = args.next().and_then(|d| d.parse().ok()), + "--demo" => demo = true, + "-h" | "--help" => { + println!( + "usage: ledger-gui [--data-dir PATH] [--books-toml PATH] [--today YYYY-MM-DD] [--demo]" + ); + return Ok(()); + } + other => { + eprintln!("unknown argument {other}"); + std::process::exit(2); + } + } + } + if demo { + let d = today.unwrap_or_else(|| chrono::Local::now().date_naive()); + let dir = std::env::temp_dir().join(format!("wanderbooks-demo-{d}")); + let _ = std::fs::remove_dir_all(&dir); + if let Err(e) = ledger_gui::demo::build(&dir, d) { + eprintln!("building the demo books failed: {e}"); + std::process::exit(1); + } + eprintln!("demo books: {}", dir.display()); + data_dir = Some(dir.join("books-data")); + books_toml = Some(dir.join("wanderbooks.toml")); + } + let data_dir = data_dir.unwrap_or_else(|| PathBuf::from("books-data")); + let books_toml = books_toml.or_else(|| { + let guess = data_dir + .parent() + .unwrap_or(&data_dir) + .join("wanderbooks.toml"); + guess.exists().then_some(guess) + }); + let source = Source { + data_dir, + books_toml, + today, + }; + let options = eframe::NativeOptions { + viewport: egui::ViewportBuilder::default() + .with_title("wanderbooks") + .with_app_id("wanderbooks") + .with_inner_size([1440.0, 920.0]) + .with_min_inner_size([900.0, 600.0]), + ..Default::default() + }; + eframe::run_native( + "wanderbooks", + options, + Box::new(move |cc| Ok(Box::new(App::new(cc, source)))), + ) +} diff --git a/crates/ledger-gui/src/nav.rs b/crates/ledger-gui/src/nav.rs new file mode 100644 index 0000000..02b3d34 --- /dev/null +++ b/crates/ledger-gui/src/nav.rs @@ -0,0 +1,195 @@ +//! Where you are and how you got there: a browser-style history. + +use ledger_core::{AccountId, EntryId}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum ReportKind { + ProfitAndLoss, + BalanceSheet, + CashFlow, + TrialBalance, + GeneralLedger, + MembersEquity, + TaxSummary, + ArAging, + ApAging, + Vendor1099, +} + +impl ReportKind { + pub const ALL: [ReportKind; 10] = [ + ReportKind::ProfitAndLoss, + ReportKind::BalanceSheet, + ReportKind::CashFlow, + ReportKind::MembersEquity, + ReportKind::TrialBalance, + ReportKind::GeneralLedger, + ReportKind::TaxSummary, + ReportKind::Vendor1099, + ReportKind::ArAging, + ReportKind::ApAging, + ]; + + pub fn title(self) -> &'static str { + match self { + ReportKind::ProfitAndLoss => "Profit and loss", + ReportKind::BalanceSheet => "Balance sheet", + ReportKind::CashFlow => "Cash flow", + ReportKind::TrialBalance => "Trial balance", + ReportKind::GeneralLedger => "General ledger", + ReportKind::MembersEquity => "Owners' equity", + ReportKind::TaxSummary => "Tax summary", + ReportKind::ArAging => "Receivables aging", + ReportKind::ApAging => "Payables aging", + ReportKind::Vendor1099 => "1099 worksheet", + } + } +} + +#[derive(Clone, Debug, PartialEq)] +pub enum Route { + Overview, + Cash, + Profit, + Transactions, + Entry(EntryId), + Reports(ReportKind), + Accounts, + Account(AccountId), + Documents, + Document(u64), + Company, + Journal, + JournalEvent(u64), +} + +impl Route { + /// The sidebar section this route belongs to. + pub fn section(&self) -> Section { + match self { + Route::Overview => Section::Overview, + Route::Cash => Section::Cash, + Route::Profit => Section::Profit, + Route::Transactions | Route::Entry(_) => Section::Transactions, + Route::Reports(_) => Section::Reports, + Route::Accounts | Route::Account(_) => Section::Accounts, + Route::Documents | Route::Document(_) => Section::Documents, + Route::Company => Section::Company, + Route::Journal | Route::JournalEvent(_) => Section::Journal, + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Section { + Overview, + Cash, + Profit, + Transactions, + Reports, + Accounts, + Documents, + Company, + Journal, +} + +impl Section { + pub const ALL: [Section; 9] = [ + Section::Overview, + Section::Cash, + Section::Profit, + Section::Transactions, + Section::Reports, + Section::Accounts, + Section::Documents, + Section::Company, + Section::Journal, + ]; + + pub fn title(self) -> &'static str { + match self { + Section::Overview => "Overview", + Section::Cash => "Cash", + Section::Profit => "Profit", + Section::Transactions => "Transactions", + Section::Reports => "Reports", + Section::Accounts => "Accounts", + Section::Documents => "Documents", + Section::Company => "Company", + Section::Journal => "Journal", + } + } + + pub fn icon(self) -> &'static str { + use egui_phosphor::regular as i; + match self { + Section::Overview => i::SQUARES_FOUR, + Section::Cash => i::BANK, + Section::Profit => i::TREND_UP, + Section::Transactions => i::LIST_BULLETS, + Section::Reports => i::FILE_TEXT, + Section::Accounts => i::TREE_STRUCTURE, + Section::Documents => i::FILES, + Section::Company => i::BUILDINGS, + Section::Journal => i::SCROLL, + } + } + + pub fn home(self) -> Route { + match self { + Section::Overview => Route::Overview, + Section::Cash => Route::Cash, + Section::Profit => Route::Profit, + Section::Transactions => Route::Transactions, + Section::Reports => Route::Reports(ReportKind::ProfitAndLoss), + Section::Accounts => Route::Accounts, + Section::Documents => Route::Documents, + Section::Company => Route::Company, + Section::Journal => Route::Journal, + } + } +} + +/// Back/forward history. +pub struct Nav { + back: Vec, + forward: Vec, + pub current: Route, +} + +impl Nav { + pub fn new(start: Route) -> Self { + Self { + back: Vec::new(), + forward: Vec::new(), + current: start, + } + } + + pub fn go(&mut self, to: Route) { + if to != self.current { + self.back.push(std::mem::replace(&mut self.current, to)); + self.forward.clear(); + } + } + + pub fn can_back(&self) -> bool { + !self.back.is_empty() + } + + pub fn can_forward(&self) -> bool { + !self.forward.is_empty() + } + + pub fn back(&mut self) { + if let Some(r) = self.back.pop() { + self.forward.push(std::mem::replace(&mut self.current, r)); + } + } + + pub fn forward(&mut self) { + if let Some(r) = self.forward.pop() { + self.back.push(std::mem::replace(&mut self.current, r)); + } + } +} diff --git a/crates/ledger-gui/src/pages/accounts.rs b/crates/ledger-gui/src/pages/accounts.rs new file mode 100644 index 0000000..6ab5a0e --- /dev/null +++ b/crates/ledger-gui/src/pages/accounts.rs @@ -0,0 +1,350 @@ +//! The chart of accounts with balances, and one account's register: every +//! posting with a running balance and the balance over time. + +use super::page; +use crate::app::Shell; +use crate::books::Books; +use crate::fmt; +use crate::nav::Route; +use crate::theme::{self, pal}; +use crate::widgets; +use chrono::NaiveDate; +use egui::{CornerRadius, RichText, Sense, Ui, vec2}; +use egui_phosphor::regular as icon; +use ledger_core::AccountType; +use ledger_core::analysis::balance_history; +use ledger_core::reports::general_ledger; +use rust_decimal::Decimal; + +#[derive(Default)] +pub struct State { + /// Limit the register to these dates (set by drill-downs). + pub range: Option<(NaiveDate, NaiveDate)>, + pub show_empty: bool, +} + +pub fn show_chart(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + page(ui, "accounts", |ui| { + widgets::page_header( + ui, + "Accounts", + "Every account in the chart with today's balance. Click one for its register.", + ); + ui.checkbox( + &mut shell.state.accounts.show_empty, + "Show accounts with no activity", + ); + ui.add_space(10.0); + let used: std::collections::HashSet = b + .entries + .iter() + .flat_map(|e| e.accounts.iter().copied()) + .collect(); + for (t, title) in [ + (AccountType::Asset, "Assets"), + (AccountType::Liability, "Liabilities"), + (AccountType::Equity, "Equity"), + (AccountType::Revenue, "Income"), + (AccountType::Expense, "Expenses"), + ] { + let accounts: Vec<_> = b + .ledger + .chart() + .all() + .filter(|a| { + a.account_type == t && (shell.state.accounts.show_empty || used.contains(&a.id)) + }) + .collect(); + if accounts.is_empty() { + continue; + } + let mut go = None; + widgets::titled_card( + ui, + title, + |_| {}, + |ui| { + for a in &accounts { + let bal = b.balance_on(a.id, b.today); + let (r, resp) = ui + .allocate_exact_size(vec2(ui.available_width(), 34.0), Sense::click()); + if resp.hovered() { + ui.painter().rect_filled(r, CornerRadius::same(6), p.hover); + } + let painter = ui.painter_at(r); + painter.text( + r.left_center() + vec2(8.0, 0.0), + egui::Align2::LEFT_CENTER, + &a.code, + theme::regular(13.0), + p.muted, + ); + painter.text( + r.left_center() + vec2(64.0, 0.0), + egui::Align2::LEFT_CENTER, + &a.name, + theme::regular(13.5), + p.text, + ); + let mut tags = Vec::new(); + if b.cash_accounts.contains(&a.id) { + tags.push("cash".to_string()); + } + if let Some(c) = &a.tax_category { + let pct = a + .deductible_percent + .map(|p| format!(" {}%", p.normalize())) + .unwrap_or_default(); + tags.push(format!("tax: {}{pct}", c.replace('_', " "))); + } else if matches!(t, AccountType::Revenue | AccountType::Expense) { + tags.push("no tax category".into()); + } + if a.placeholder { + tags.push("header".into()); + } + painter.text( + r.left_center() + vec2(340.0, 0.0), + egui::Align2::LEFT_CENTER, + tags.join(" · "), + theme::regular(12.0), + p.faint, + ); + painter.text( + r.right_center() - vec2(8.0, 0.0), + egui::Align2::RIGHT_CENTER, + fmt::accounting(bal), + theme::semibold(13.5), + p.text, + ); + if resp.clicked() { + go = Some(a.id); + } + } + }, + ); + if let Some(id) = go { + shell.state.accounts.range = None; + shell.go(Route::Account(id)); + } + ui.add_space(12.0); + } + }); +} + +pub fn show_account(ui: &mut Ui, b: &Books, id: u64, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let Some(a) = b.ledger.chart().get(id) else { + return; + }; + let first = b.kpis.first_entry.unwrap_or(b.today); + let (s, e) = shell + .state + .accounts + .range + .unwrap_or((first.min(b.today), b.today)); + page(ui, "account", |ui| { + ui.label( + RichText::new(format!("{:?} account · {}", a.account_type, a.code)) + .font(theme::regular(13.0)) + .color(p.muted), + ); + ui.label(RichText::new(&a.name).font(theme::bold(26.0))); + ui.add_space(4.0); + let bal = b.balance_on(id, b.today); + ui.label( + RichText::new(format!("Balance today {}", fmt::dollars(bal))) + .font(theme::regular(15.0)) + .color(p.muted), + ); + ui.add_space(14.0); + let hist = balance_history(&b.ledger, &[id]); + if hist.len() > 1 && a.account_type.is_balance_sheet() { + widgets::titled_card( + ui, + "Balance over time", + |_| {}, + |ui| crate::charts::balance_line(ui, &hist, b.today, 180.0), + ); + ui.add_space(12.0); + } + ui.horizontal(|ui| { + ui.label( + RichText::new(format!( + "{} {} – {}", + icon::CALENDAR_BLANK, + fmt::date(s), + fmt::date(e) + )) + .font(theme::semibold(13.5)), + ); + if shell.state.accounts.range.is_some() && ui.button("Show all dates").clicked() { + shell.state.accounts.range = None; + } + if ui + .button(format!("{} Find in transactions", icon::LIST_BULLETS)) + .clicked() + { + shell.state.transactions.account = Some(id); + shell.go(Route::Transactions); + } + }); + ui.add_space(8.0); + let Ok(gl) = general_ledger(&b.ledger, s, e) else { + return; + }; + let Some(acct) = gl.accounts.iter().find(|x| x.code == a.code) else { + widgets::card(ui, |ui| { + widgets::empty( + ui, + icon::EMPTY, + "No activity", + "Nothing posted to this account in this range.", + ) + }); + return; + }; + let mut go = None; + widgets::card(ui, |ui| { + let w = ui.available_width(); + let amt = 120.0; + let header = |ui: &mut Ui, vals: [&str; 5]| { + let (r, _) = ui.allocate_exact_size(vec2(w, 26.0), Sense::hover()); + ui.painter().text( + r.left_center() + vec2(4.0, 0.0), + egui::Align2::LEFT_CENTER, + vals[0], + theme::semibold(12.0), + p.muted, + ); + ui.painter().text( + r.left_center() + vec2(90.0, 0.0), + egui::Align2::LEFT_CENTER, + vals[1], + theme::semibold(12.0), + p.muted, + ); + for (i, v) in vals[2..].iter().enumerate() { + ui.painter().text( + egui::pos2(r.right() - amt * (2 - i) as f32 - 4.0, r.center().y), + egui::Align2::RIGHT_CENTER, + *v, + theme::semibold(12.0), + p.muted, + ); + } + }; + header(ui, ["Date", "Description", "Debit", "Credit", "Balance"]); + widgets::rule(ui); + let line = |ui: &mut Ui, + date: String, + desc: String, + sub: String, + d: Decimal, + c: Decimal, + bal: Decimal, + strong: bool| + -> egui::Response { + let (r, resp) = ui.allocate_exact_size( + vec2(w, if sub.is_empty() { 30.0 } else { 42.0 }), + Sense::click(), + ); + if resp.hovered() && !strong { + ui.painter().rect_filled(r, CornerRadius::same(6), p.hover); + } + let painter = ui.painter_at(r); + let font = if strong { + theme::semibold(13.0) + } else { + theme::regular(13.0) + }; + let y = if sub.is_empty() { + r.center().y + } else { + r.center().y - 7.0 + }; + painter.text( + egui::pos2(r.left() + 4.0, y), + egui::Align2::LEFT_CENTER, + date, + theme::regular(12.5), + p.muted, + ); + painter.text( + egui::pos2(r.left() + 90.0, y), + egui::Align2::LEFT_CENTER, + desc, + font.clone(), + p.text, + ); + if !sub.is_empty() { + painter.text( + egui::pos2(r.left() + 90.0, r.center().y + 9.0), + egui::Align2::LEFT_CENTER, + sub, + theme::regular(11.5), + p.faint, + ); + } + for (i, v) in [d, c].iter().enumerate() { + if !v.is_zero() { + painter.text( + egui::pos2(r.right() - amt * (2 - i) as f32 - 4.0, y), + egui::Align2::RIGHT_CENTER, + fmt::money(*v), + font.clone(), + p.text, + ); + } + } + painter.text( + egui::pos2(r.right() - 4.0, y), + egui::Align2::RIGHT_CENTER, + fmt::accounting(bal), + font, + p.text, + ); + resp + }; + line( + ui, + fmt::date_short(s), + "Beginning balance".into(), + String::new(), + Decimal::ZERO, + Decimal::ZERO, + acct.beginning_balance, + true, + ); + for post in acct.postings.iter().rev() { + let r = line( + ui, + fmt::date_short(post.date), + post.description.clone(), + format!("#{} · {}", post.entry_id, post.split), + post.debit, + post.credit, + post.balance, + false, + ); + if r.clicked() { + go = Some(post.entry_id); + } + } + widgets::rule(ui); + line( + ui, + fmt::date_short(e), + "Ending balance".into(), + String::new(), + acct.total_debits, + acct.total_credits, + acct.ending_balance, + true, + ); + }); + if let Some(entry) = go { + shell.go(Route::Entry(entry)); + } + }); +} diff --git a/crates/ledger-gui/src/pages/cash.rs b/crates/ledger-gui/src/pages/cash.rs new file mode 100644 index 0000000..ec7988e --- /dev/null +++ b/crates/ledger-gui/src/pages/cash.rs @@ -0,0 +1,457 @@ +//! Cash: what's in the bank, where it's been going, how long it lasts, and +//! what's coming in and out next. + +use super::{columns, page}; +use crate::app::Shell; +use crate::books::Books; +use crate::charts::{self, BarGroup}; +use crate::fmt; +use crate::nav::Route; +use crate::theme::{self, pal}; +use crate::widgets; +use chrono::{Days, NaiveDate}; +use egui::{CornerRadius, RichText, Sense, Ui, vec2}; +use egui_phosphor::regular as icon; +use ledger_core::analysis::{Interval, balance_history, flows_by_interval, interval_start}; +use rust_decimal::Decimal; + +pub fn show(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + page(ui, "cash", |ui| { + let k = &b.kpis; + let since = b.today - Days::new(30); + let flows = flows_by_interval( + &b.ledger, + &b.cash_accounts, + since + Days::new(1), + b.today, + Interval::Year, + ); + let (cin, cout): (Decimal, Decimal) = + flows.iter().fold((Decimal::ZERO, Decimal::ZERO), |a, f| { + (a.0 + f.2, a.1 + f.3) + }); + widgets::page_header( + ui, + "Cash", + &format!( + "{} across {}. In the last 30 days {} came in and {} went out.", + fmt::dollars(k.cash), + fmt::count(b.cash_accounts.len(), "account", "accounts"), + fmt::dollars(cin), + fmt::dollars(cout) + ), + ); + if b.cash_accounts.is_empty() { + widgets::card(ui, |ui| { + widgets::empty( + ui, + icon::BANK, + "No cash accounts found", + "Name an asset account \"checking\", \"savings\", or \"cash\", or set [books] cash_accounts in wanderbooks.toml.", + ) + }); + return; + } + // One tile per cash and card account. + let mut tiles: Vec<(u64, bool)> = b.cash_accounts.iter().map(|a| (*a, false)).collect(); + tiles.extend(b.card_accounts.iter().map(|a| (*a, true))); + let n = tiles.len().clamp(1, 4); + for row in tiles.chunks(n) { + columns(ui, 0.0, &vec![1.0; n], |i, ui| { + let Some((id, is_card)) = row.get(i) else { + return; + }; + let hist = balance_history(&b.ledger, &[*id]); + let spark: Vec = hist + .iter() + .rev() + .take(40) + .rev() + .map(|(_, v)| (*v).try_into().unwrap_or(0.0)) + .collect(); + let bal = b.balance_on(*id, b.today); + let ago = b.balance_on(*id, since); + let delta = bal - ago; + let r = widgets::kpi( + ui, + widgets::Kpi { + label: &b.account_label(*id), + value: fmt::dollars(bal), + sub: Some(( + if *is_card { + "owed on the card".to_string() + } else if delta.is_zero() { + "no change in 30 days".to_string() + } else { + format!( + "{}{} in 30 days", + if delta > Decimal::ZERO { "+" } else { "" }, + fmt::dollars(delta) + ) + }, + if *is_card || delta.is_zero() { + p.muted + } else if delta > Decimal::ZERO { + p.positive + } else { + p.negative + }, + )), + spark: (spark.len() > 1).then_some(&spark[..]), + how: "", + }, + ); + if r.interact(Sense::click()).clicked() { + shell.state.accounts.range = None; + shell.go(Route::Account(*id)); + } + }); + } + let first = k.first_entry.unwrap_or(b.today); + let (start, end) = b.trailing_months(12); + let start = start.max(interval_start(first, Interval::Month)); + columns(ui, 980.0, &[3.0, 2.0], |i, ui| match i { + 0 => { + widgets::titled_card( + ui, + "Cash balance", + |_| {}, + |ui| charts::balance_line(ui, &b.cash_history(), b.today, 240.0), + ); + } + _ => { + let months = + flows_by_interval(&b.ledger, &b.cash_accounts, start, end, Interval::Month); + widgets::titled_card( + ui, + "Money in and out by month", + |_| {}, + |ui| { + let groups: Vec = months + .iter() + .map(|(s, _, i, o)| BarGroup { + label: s.format("%b").to_string(), + values: vec![*i, *o], + }) + .collect(); + charts::bar_chart( + ui, + &groups, + &[("In", p.series[1]), ("Out", p.series[2])], + 210.0, + ); + }, + ); + } + }); + columns(ui, 980.0, &[1.0, 1.0], |i, ui| match i { + 0 => runway(ui, b), + _ => coming_up(ui, b, shell), + }); + biggest_outflows(ui, b, shell); + }); +} + +fn runway(ui: &mut Ui, b: &Books) { + let p = pal(ui.ctx()); + let ms = b.month_start(); + let three = ms - chrono::Months::new(3); + let start = three.max( + b.kpis + .first_entry + .map_or(three, |f| interval_start(f, Interval::Month)), + ); + let months = flows_by_interval( + &b.ledger, + &b.cash_accounts, + start, + ms - Days::new(1), + Interval::Month, + ); + widgets::titled_card( + ui, + "Burn and runway", + |_| {}, + |ui| { + if months.is_empty() { + ui.label(RichText::new("Needs at least one full month of books.").color(p.muted)); + return; + } + let net: Decimal = months.iter().map(|(_, _, i, o)| i - o).sum::() + / Decimal::from(months.len() as u64); + let net = net.round_dp(2); + let big = |ui: &mut Ui, label: &str, value: String, color| { + ui.vertical(|ui| { + ui.label( + RichText::new(label) + .font(theme::regular(12.5)) + .color(p.muted), + ); + ui.label( + RichText::new(value) + .font(theme::semibold(22.0)) + .color(color), + ); + }); + }; + ui.horizontal(|ui| { + big( + ui, + "Average monthly net cash flow", + format!( + "{}{}", + if net > Decimal::ZERO { "+" } else { "" }, + fmt::dollars(net) + ), + if net >= Decimal::ZERO { + p.positive + } else { + p.negative + }, + ); + ui.add_space(32.0); + if net < Decimal::ZERO { + let months_left = (b.kpis.cash / -net).round_dp(1); + let out = b.today + + Days::new((months_left * Decimal::from(30)).try_into().unwrap_or(0u64)); + big(ui, "Runway", format!("{months_left} months"), p.text); + ui.add_space(32.0); + big(ui, "Cash runs out around", fmt::month(out), p.warning); + } else { + big(ui, "Runway", "Cash is growing".into(), p.positive); + } + }); + ui.add_space(8.0); + ui.label( + RichText::new(format!( + "Cash in minus cash out of {}, averaged over the last {} (owner contributions and draws included: this is what the bank sees).", + b.cash_accounts.iter().map(|a| b.account_name(*a)).collect::>().join(" and "), + fmt::count(months.len(), "full month", "full months") + )) + .font(theme::regular(12.0)) + .color(p.faint), + ); + }, + ); +} + +struct Upcoming { + date: NaiveDate, + label: String, + amount: Decimal, + route: Option, +} + +fn coming_up(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let horizon = b.today + Days::new(45); + let mut items: Vec = Vec::new(); + for r in b.ledger.recurring_entries() { + let cash: Decimal = r + .lines + .iter() + .filter(|(a, _, _)| b.cash_accounts.contains(a)) + .map(|(_, s, m)| { + if *s == ledger_core::Side::Debit { + m.amount + } else { + -m.amount + } + }) + .sum(); + for d in r + .due(horizon) + .into_iter() + .filter(|d| *d > b.today - Days::new(1)) + { + items.push(Upcoming { + date: d, + label: format!("{} (recurring)", r.description), + amount: cash, + route: Some(Route::Company), + }); + } + } + for id in 1..b.ledger.next_invoice_id() { + if let Some(inv) = b.ledger.get_invoice(id) + && !inv.balance().is_zero() + { + let who = b + .ledger + .get_customer(inv.customer_id) + .map(|c| c.name.clone()) + .unwrap_or_default(); + let late = inv.due_date < b.today; + items.push(Upcoming { + date: inv.due_date, + label: format!( + "Invoice {id} from {who}{}", + if late { " — overdue" } else { "" } + ), + amount: inv.balance(), + route: Some(Route::Entry(inv.entry_id)), + }); + } + } + for id in 1..b.ledger.next_bill_id() { + if let Some(bill) = b.ledger.get_bill(id) + && !bill.balance().is_zero() + { + let who = b + .ledger + .get_vendor(bill.vendor_id) + .map(|v| v.name.clone()) + .unwrap_or_default(); + items.push(Upcoming { + date: bill.due_date, + label: format!("Bill {id} to {who}"), + amount: -bill.balance(), + route: Some(Route::Entry(bill.entry_id)), + }); + } + } + items.sort_by_key(|i| i.date); + let mut go = None; + widgets::titled_card( + ui, + "Coming up", + |ui| { + ui.label( + RichText::new("open invoices, bills, recurring") + .font(theme::regular(12.0)) + .color(p.muted), + ); + }, + |ui| { + if items.is_empty() { + widgets::empty( + ui, + icon::CALENDAR_CHECK, + "Nothing scheduled", + "No open invoices, bills, or recurring entries due soon.", + ); + return; + } + let (inflow, outflow): (Decimal, Decimal) = + items.iter().fold((Decimal::ZERO, Decimal::ZERO), |a, i| { + if i.amount > Decimal::ZERO { + (a.0 + i.amount, a.1) + } else { + (a.0, a.1 - i.amount) + } + }); + ui.label( + RichText::new(format!( + "Expected in {} · expected out {}", + fmt::dollars(inflow), + fmt::dollars(outflow) + )) + .font(theme::semibold(13.0)), + ); + ui.add_space(6.0); + egui::ScrollArea::vertical() + .id_salt("upcoming") + .max_height(220.0) + .show(ui, |ui| { + for it in &items { + let (r, resp) = ui + .allocate_exact_size(vec2(ui.available_width(), 28.0), Sense::click()); + if resp.hovered() { + ui.painter().rect_filled(r, CornerRadius::same(6), p.hover); + } + let late = it.date < b.today; + ui.painter().text( + r.left_center() + vec2(6.0, 0.0), + egui::Align2::LEFT_CENTER, + fmt::date_short(it.date), + theme::regular(12.5), + if late { p.negative } else { p.muted }, + ); + ui.painter().text( + r.left_center() + vec2(70.0, 0.0), + egui::Align2::LEFT_CENTER, + &it.label, + theme::regular(13.0), + p.text, + ); + let (txt, c) = if it.amount > Decimal::ZERO { + (format!("+{}", fmt::money(it.amount)), p.positive) + } else { + (fmt::money(it.amount), p.text) + }; + ui.painter().text( + r.right_center() - vec2(6.0, 0.0), + egui::Align2::RIGHT_CENTER, + txt, + theme::semibold(13.0), + c, + ); + if resp.clicked() { + go = it.route.clone(); + } + } + }); + }, + ); + if let Some(r) = go { + shell.go(r); + } +} + +fn biggest_outflows(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let since = b.today - Days::new(30); + let mut out: Vec<&crate::books::EntryInfo> = b + .entries + .iter() + .filter(|e| e.date > since && e.cash_effect < Decimal::ZERO) + .collect(); + out.sort_by_key(|e| e.cash_effect); + out.truncate(8); + let mut go = None; + widgets::titled_card( + ui, + "Biggest payments, last 30 days", + |_| {}, + |ui| { + if out.is_empty() { + widgets::empty(ui, icon::ARROW_UP_RIGHT, "No payments", ""); + } + for e in &out { + let (r, resp) = + ui.allocate_exact_size(vec2(ui.available_width(), 30.0), Sense::click()); + if resp.hovered() { + ui.painter().rect_filled(r, CornerRadius::same(6), p.hover); + } + ui.painter().text( + r.left_center() + vec2(6.0, 0.0), + egui::Align2::LEFT_CENTER, + fmt::date_short(e.date), + theme::regular(12.5), + p.muted, + ); + ui.painter().text( + r.left_center() + vec2(70.0, 0.0), + egui::Align2::LEFT_CENTER, + &e.description, + theme::regular(13.0), + p.text, + ); + ui.painter().text( + r.right_center() - vec2(6.0, 0.0), + egui::Align2::RIGHT_CENTER, + fmt::money(e.cash_effect), + theme::semibold(13.0), + p.text, + ); + if resp.clicked() { + go = Some(e.id); + } + } + }, + ); + if let Some(id) = go { + shell.go(Route::Entry(id)); + } +} diff --git a/crates/ledger-gui/src/pages/company.rs b/crates/ledger-gui/src/pages/company.rs new file mode 100644 index 0000000..06571a8 --- /dev/null +++ b/crates/ledger-gui/src/pages/company.rs @@ -0,0 +1,493 @@ +//! The company: who it is, who owns it, and the standing machinery of the +//! books — periods, fixed assets, amortization schedules, recurring +//! entries, vendors and customers. + +use super::{columns, page}; +use crate::app::Shell; +use crate::books::Books; +use crate::fmt; +use crate::nav::Route; +use crate::theme::{self, pal}; +use crate::widgets; +use egui::{CornerRadius, RichText, Sense, Ui, vec2}; +use egui_phosphor::regular as icon; +use ledger_core::assets::{accumulated_depreciation, book_value}; +use ledger_core::{PeriodStatus, vendor_1099_report}; +use rust_decimal::Decimal; + +fn kv(ui: &mut Ui, k: &str, v: &str) { + let p = pal(ui.ctx()); + ui.horizontal(|ui| { + let (r, _) = ui.allocate_exact_size(vec2(180.0, 20.0), Sense::hover()); + ui.painter().text( + r.left_center(), + egui::Align2::LEFT_CENTER, + k, + theme::regular(13.0), + p.muted, + ); + ui.add(egui::Label::new(RichText::new(v).font(theme::regular(13.0))).wrap()); + }); +} + +pub fn show(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + page(ui, "company", |ui| { + let c = &b.settings.company; + widgets::page_header( + ui, + &c.name, + "The company's profile and the standing parts of its books.", + ); + columns(ui, 980.0, &[1.0, 1.0], |i, ui| match i { + 0 => { + widgets::titled_card( + ui, + "Profile", + |_| {}, + |ui| { + if c.profile.is_empty() { + ui.label( + RichText::new("No [company] settings in wanderbooks.toml.") + .color(p.muted), + ); + } + for (k, v) in &c.profile { + kv(ui, &fmt::label(k), v); + } + kv(ui, "Accounting basis", &c.basis); + kv( + ui, + "Tax return", + c.tax_form.map(fmt::tax_form).unwrap_or("not set"), + ); + kv(ui, "Receipt threshold", &fmt::dollars(b.receipt_threshold)); + }, + ); + } + _ => { + widgets::titled_card( + ui, + "Owners", + |_| {}, + |ui| { + if c.members.is_empty() { + // A single owner or a corporation: equity by account. + for a in b + .ledger + .chart() + .all() + .filter(|a| a.account_type == ledger_core::AccountType::Equity) + { + ui.horizontal(|ui| { + ui.label( + RichText::new(format!("{} {}", a.code, a.name)) + .font(theme::regular(13.0)), + ); + ui.with_layout( + egui::Layout::right_to_left(egui::Align::Center), + |ui| { + ui.label( + RichText::new(fmt::accounting( + b.balance_on(a.id, b.today), + )) + .font(theme::semibold(13.0)), + ); + }, + ); + }); + } + } + for m in &c.members { + let cap = b.ledger.chart().find_by_code(&m.capital_account); + let bal = cap.map(|a| b.balance_on(a.id, b.today)).unwrap_or_default(); + ui.horizontal(|ui| { + ui.label(RichText::new(&m.name).font(theme::semibold(13.5))); + widgets::pill( + ui, + &format!("{}%", (m.share * Decimal::from(100)).normalize()), + p.accent, + p.accent_soft, + ); + ui.with_layout( + egui::Layout::right_to_left(egui::Align::Center), + |ui| { + ui.label( + RichText::new(fmt::dollars(bal)) + .font(theme::semibold(13.5)), + ); + }, + ); + }); + if let Some(a) = cap { + ui.label( + RichText::new(format!("Capital account {} {}", a.code, a.name)) + .font(theme::regular(12.0)) + .color(p.muted), + ); + } + ui.add_space(6.0); + } + }, + ); + ui.add_space(12.0); + widgets::titled_card( + ui, + "Periods", + |_| {}, + |ui| { + let periods = b.ledger.list_periods(); + if periods.is_empty() { + ui.label(RichText::new("No periods yet. Closing a period locks it and moves its earnings into equity.").color(p.muted)); + } + for per in periods { + ui.horizontal(|ui| { + let (g, color) = match per.status { + PeriodStatus::Closed => (icon::LOCK, p.muted), + PeriodStatus::Open => (icon::LOCK_OPEN, p.warning), + }; + ui.label(RichText::new(g).color(color)); + ui.label(RichText::new(&per.name).font(theme::semibold(13.0))); + ui.label( + RichText::new(format!( + "{} – {}", + fmt::date(per.start), + fmt::date(per.end) + )) + .color(p.muted), + ); + if let Some(e) = per.closing_entry + && widgets::link( + ui, + RichText::new(format!("closing entry #{e}")) + .color(p.accent), + ) + .clicked() + { + shell.go(Route::Entry(e)); + } + }); + } + }, + ); + } + }); + assets(ui, b, shell); + schedules(ui, b); + recurring(ui, b); + parties(ui, b); + }); +} + +fn assets(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let assets: Vec<_> = b.ledger.registered_assets().collect(); + if assets.is_empty() { + return; + } + let mut go = None; + widgets::titled_card( + ui, + "Fixed assets", + |_| {}, + |ui| { + for a in &assets { + // What has actually been posted, so this ties to the balance + // sheet; the schedule may run ahead of the books. + let acc: Decimal = b + .journal + .iter() + .filter(|l| { + l.line_type == "asset.depreciation_posted" + && l.payload.get("asset_id").and_then(|v| v.as_u64()) == Some(a.id) + }) + .filter_map(|l| { + l.payload + .get("amount") + .and_then(|v| v.as_str()) + .and_then(|s| s.parse::().ok()) + }) + .sum(); + let bv = a.cost.amount - acc; + let scheduled = accumulated_depreciation(a, b.today); + let _ = book_value; + let dep = a.cost.amount - a.salvage_value.amount; + let frac: f32 = if dep.is_zero() { + 1.0 + } else { + (acc / dep).try_into().unwrap_or(0.0) + }; + ui.horizontal(|ui| { + if widgets::link( + ui, + RichText::new(&a.description).font(theme::semibold(13.5)), + ) + .clicked() + { + go = Some(a.cost_account); + } + ui.label( + RichText::new(format!( + "bought {} · {} months · {}", + fmt::date(a.purchase_date), + a.useful_life_months, + fmt::words(&format!("{:?}", a.status)).to_lowercase() + )) + .font(theme::regular(12.0)) + .color(p.muted), + ); + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + ui.label( + RichText::new(format!("book value {}", fmt::dollars(bv))) + .font(theme::semibold(13.0)), + ); + }); + }); + let behind = scheduled - acc; + let note = if behind > Decimal::ZERO { + format!(" · {} more scheduled through today", fmt::dollars(behind)) + } else { + String::new() + }; + progress( + ui, + frac, + &format!( + "{} of {} depreciated{note}", + fmt::dollars(acc), + fmt::dollars(dep) + ), + ); + ui.add_space(8.0); + } + }, + ); + if let Some(id) = go { + shell.go(Route::Account(id)); + } + ui.add_space(16.0); +} + +fn progress(ui: &mut Ui, frac: f32, label: &str) { + let p = pal(ui.ctx()); + let (r, _) = ui.allocate_exact_size(vec2(ui.available_width(), 8.0), Sense::hover()); + ui.painter().rect_filled(r, CornerRadius::same(4), p.hover); + let mut done = r; + done.set_width(r.width() * frac.clamp(0.0, 1.0)); + ui.painter() + .rect_filled(done, CornerRadius::same(4), p.accent); + ui.label( + RichText::new(label) + .font(theme::regular(11.5)) + .color(p.faint), + ); +} + +fn schedules(ui: &mut Ui, b: &Books) { + let p = pal(ui.ctx()); + let list: Vec<_> = b.ledger.schedules().collect(); + if list.is_empty() { + return; + } + widgets::titled_card( + ui, + "Amortization schedules", + |_| {}, + |ui| { + for s in list { + let total = s.total.amount; + let remaining = s.remaining(); + let frac: f32 = if total.is_zero() { + 1.0 + } else { + ((total - remaining) / total).try_into().unwrap_or(0.0) + }; + let due = s.due(b.today); + ui.horizontal(|ui| { + ui.label(RichText::new(&s.description).font(theme::semibold(13.5))); + ui.label( + RichText::new(format!( + "{} · {} months from {}", + fmt::words(&format!("{:?}", s.kind)), + s.months, + fmt::month(s.start) + )) + .font(theme::regular(12.0)) + .color(p.muted), + ); + if !due.is_empty() { + widgets::pill(ui, &format!("{} due", due.len()), p.warning, p.warning_soft); + } + }); + progress( + ui, + frac, + &format!( + "{} of {} recognized · {} left", + fmt::dollars(total - remaining), + fmt::dollars(total), + fmt::dollars(remaining) + ), + ); + ui.add_space(8.0); + } + }, + ); + ui.add_space(16.0); +} + +fn recurring(ui: &mut Ui, b: &Books) { + let p = pal(ui.ctx()); + let list: Vec<_> = b.ledger.recurring_entries().collect(); + if list.is_empty() { + return; + } + widgets::titled_card( + ui, + "Recurring entries", + |_| {}, + |ui| { + for r in list { + let amount: Decimal = r + .lines + .iter() + .filter(|(_, s, _)| *s == ledger_core::Side::Debit) + .map(|(_, _, m)| m.amount) + .sum(); + let next = (0..) + .map_while(|k| { + r.frequency + .nth(r.start, k) + .filter(|d| r.end.is_none_or(|e| *d <= e)) + }) + .find(|d| !r.generated.contains(d)); + ui.horizontal(|ui| { + ui.label(RichText::new(&r.description).font(theme::semibold(13.5))); + ui.label( + RichText::new(format!( + "{} · {}", + fmt::words(&format!("{:?}", r.frequency)), + fmt::dollars(amount) + )) + .font(theme::regular(12.0)) + .color(p.muted), + ); + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + let text = match next { + Some(d) if d <= b.today => format!("due {}", fmt::date(d)), + Some(d) => format!("next {}", fmt::date(d)), + None => "ended".into(), + }; + ui.label(RichText::new(text).font(theme::regular(12.5)).color( + if next.is_some_and(|d| d <= b.today) { + p.warning + } else { + p.muted + }, + )); + }); + }); + ui.label( + RichText::new(format!( + "{} generated so far · drafts only; each one is posted with its receipt", + r.generated.len() + )) + .font(theme::regular(11.5)) + .color(p.faint), + ); + ui.add_space(6.0); + } + }, + ); + ui.add_space(16.0); +} + +fn parties(ui: &mut Ui, b: &Books) { + let p = pal(ui.ctx()); + let year = chrono::Datelike::year(&b.today); + let r1099 = vendor_1099_report(&b.ledger, year, None); + columns(ui, 980.0, &[1.0, 1.0], |i, ui| match i { + 0 => { + widgets::titled_card( + ui, + "Vendors", + |_| {}, + |ui| { + let vendors = b.ledger.list_vendors(); + if vendors.is_empty() { + ui.label(RichText::new("No vendors yet.").color(p.muted)); + } + for v in vendors { + let paid = r1099 + .vendors + .iter() + .find(|x| x.vendor_id == v.id) + .map(|x| x.paid) + .unwrap_or_default(); + ui.horizontal(|ui| { + ui.label(RichText::new(&v.name).font(theme::semibold(13.0))); + if let Some(f) = v.form_1099 { + widgets::pill(ui, f.label(), p.accent, p.accent_soft); + if v.tin_on_file { + widgets::pill(ui, "W-9", p.positive, p.positive_soft); + } else { + widgets::pill(ui, "no W-9", p.negative, p.negative_soft); + } + } + ui.with_layout( + egui::Layout::right_to_left(egui::Align::Center), + |ui| { + if !paid.is_zero() { + ui.label( + RichText::new(format!( + "{} paid in {year}", + fmt::dollars(paid) + )) + .font(theme::regular(12.5)) + .color(p.muted), + ); + } + }, + ); + }); + } + }, + ); + } + _ => { + widgets::titled_card( + ui, + "Customers", + |_| {}, + |ui| { + let customers = b.ledger.list_customers(); + if customers.is_empty() { + ui.label(RichText::new("No customers yet.").color(p.muted)); + } + for c in customers { + let owed: Decimal = (1..b.ledger.next_invoice_id()) + .filter_map(|i| b.ledger.get_invoice(i)) + .filter(|i| i.customer_id == c.id) + .map(|i| i.balance()) + .sum(); + ui.horizontal(|ui| { + ui.label(RichText::new(&c.name).font(theme::semibold(13.0))); + ui.with_layout( + egui::Layout::right_to_left(egui::Align::Center), + |ui| { + if !owed.is_zero() { + ui.label( + RichText::new(format!("owes {}", fmt::dollars(owed))) + .font(theme::regular(12.5)) + .color(p.muted), + ); + } + }, + ); + }); + } + }, + ); + } + }); +} diff --git a/crates/ledger-gui/src/pages/documents.rs b/crates/ledger-gui/src/pages/documents.rs new file mode 100644 index 0000000..e837877 --- /dev/null +++ b/crates/ledger-gui/src/pages/documents.rs @@ -0,0 +1,302 @@ +//! Every receipt and document the books hold, rendered: what it is, what +//! entry it proves, and whether it was withdrawn (and why). + +use super::page; +use crate::app::Shell; +use crate::books::Books; +use crate::fmt; +use crate::nav::Route; +use crate::receipts::State as Render; +use crate::theme::{self, pal}; +use crate::widgets; +use egui::{CornerRadius, RichText, Sense, Stroke, Ui, vec2}; +use egui_phosphor::regular as icon; +use ledger_store::Attachment; + +#[derive(Default)] +pub struct State { + pub category: Option, + pub show_withdrawn: bool, + pub query: String, +} + +pub fn show(ui: &mut Ui, b: &Books, selected: Option, shell: &mut Shell<'_>) { + match selected.and_then(|id| b.attachments.iter().find(|a| a.id == id)) { + Some(a) => super::split( + ui, + "documents", + (ui.available_width() * 0.5).max(460.0), + shell, + |ui, shell| grid(ui, b, Some(a.id), shell), + |ui, shell| detail(ui, b, a, shell), + ), + None => grid(ui, b, None, shell), + } +} + +fn grid(ui: &mut Ui, b: &Books, selected: Option, shell: &mut Shell<'_>) { + page(ui, "documents", |ui| { + let current = b + .attachments + .iter() + .filter(|a| a.withdrawn_at.is_none()) + .count(); + widgets::page_header( + ui, + "Documents", + &format!( + "{} on file: receipts that prove entries, and the company's records. Bytes are content-addressed and verified on every read.", + fmt::count(current, "document", "documents") + ), + ); + let mut cats: Vec = b.attachments.iter().map(|a| a.category.clone()).collect(); + cats.sort(); + cats.dedup(); + let st = &mut shell.state.documents; + ui.horizontal_wrapped(|ui| { + ui.add( + egui::TextEdit::singleline(&mut st.query) + .hint_text(format!("{} Search file names", icon::MAGNIFYING_GLASS)) + .desired_width(260.0), + ); + if ui.selectable_label(st.category.is_none(), "All").clicked() { + st.category = None; + } + for c in &cats { + if ui + .selectable_label(st.category.as_deref() == Some(c.as_str()), fmt::label(c)) + .clicked() + { + st.category = Some(c.clone()); + } + } + ui.checkbox(&mut st.show_withdrawn, "Show withdrawn"); + }); + ui.add_space(12.0); + let q = st.query.to_lowercase(); + let docs: Vec<&Attachment> = b + .attachments + .iter() + .rev() + .filter(|a| st.show_withdrawn || a.withdrawn_at.is_none()) + .filter(|a| st.category.as_ref().is_none_or(|c| &a.category == c)) + .filter(|a| { + q.is_empty() + || a.file_name.to_lowercase().contains(&q) + || a.description + .as_deref() + .unwrap_or("") + .to_lowercase() + .contains(&q) + }) + .collect(); + if docs.is_empty() { + widgets::card(ui, |ui| widgets::empty(ui, icon::FILES, "No documents", "")); + return; + } + let tile_w = 200.0; + let per_row = ((ui.available_width() + 16.0) / (tile_w + 16.0)) + .floor() + .max(1.0) as usize; + let mut go = None; + for row in docs.chunks(per_row) { + ui.horizontal_top(|ui| { + ui.spacing_mut().item_spacing.x = 16.0; + for a in row { + if tile(ui, b, a, tile_w, selected == Some(a.id), shell).clicked() { + go = Some(a.id); + } + } + }); + ui.add_space(16.0); + } + if let Some(id) = go { + shell.go(Route::Document(id)); + } + }); +} + +fn tile( + ui: &mut Ui, + b: &Books, + a: &Attachment, + w: f32, + on: bool, + shell: &mut Shell<'_>, +) -> egui::Response { + let p = pal(ui.ctx()); + let h = 250.0; + let (rect, resp) = ui.allocate_exact_size(vec2(w, h), Sense::click()); + let fill = if on { p.selected } else { p.surface }; + ui.painter().rect( + rect, + CornerRadius::same(10), + fill, + Stroke::new(1.0, if resp.hovered() { p.accent } else { p.border }), + egui::StrokeKind::Inside, + ); + let thumb = egui::Rect::from_min_size(rect.min + vec2(10.0, 10.0), vec2(w - 20.0, 170.0)); + ui.painter() + .rect_filled(thumb, CornerRadius::same(6), p.hover); + match shell.receipts.get(&a.blob_sha, &a.mime_type, b.blob_root()) { + Render::Ready(pages) => { + if let Some(tex) = pages.first() { + // Top of the first page, filling the width. + let size = tex.size_vec2(); + let scale = thumb.width() / size.x; + let visible_h = (thumb.height() / scale).min(size.y); + let uv = egui::Rect::from_min_max( + egui::pos2(0.0, 0.0), + egui::pos2(1.0, visible_h / size.y), + ); + let img_rect = + egui::Rect::from_min_size(thumb.min, vec2(thumb.width(), visible_h * scale)); + ui.painter() + .image(tex.id(), img_rect, uv, egui::Color32::WHITE); + } + } + Render::Loading => { + ui.painter().text( + thumb.center(), + egui::Align2::CENTER_CENTER, + "…", + theme::regular(16.0), + p.faint, + ); + } + Render::Failed(_) => { + ui.painter().text( + thumb.center(), + egui::Align2::CENTER_CENTER, + icon::FILE, + egui::FontId::proportional(28.0), + p.faint, + ); + } + } + // Title: what it proves, else what it is. + let title = a + .entry_id + .and_then(|e| b.entry(e)) + .map(|e| e.description.clone()) + .or_else(|| a.description.clone()) + .unwrap_or_else(|| a.file_name.clone()); + let max_chars = ((w - 20.0) / 7.2) as usize; + let title = if title.chars().count() > max_chars { + title.chars().take(max_chars - 1).collect::() + "…" + } else { + title + }; + ui.painter().text( + egui::pos2(rect.left() + 10.0, thumb.bottom() + 18.0), + egui::Align2::LEFT_CENTER, + title, + theme::semibold(12.5), + p.text, + ); + let sub = match (a.entry_id, &a.withdrawn_at) { + (_, Some(_)) => format!("Withdrawn · {}", a.file_name), + (Some(e), None) => match b.entry(e) { + Some(x) => format!( + "#{e} · {} · {}", + fmt::date_short(x.date), + fmt::dollars(x.amount) + ), + None => format!("#{e}"), + }, + (None, None) => format!("{} · {}", fmt::label(&a.category), a.file_name), + }; + let sub = if sub.chars().count() > max_chars + 4 { + sub.chars().take(max_chars + 3).collect::() + "…" + } else { + sub + }; + ui.painter().text( + egui::pos2(rect.left() + 10.0, thumb.bottom() + 40.0), + egui::Align2::LEFT_CENTER, + sub, + theme::regular(11.5), + if a.withdrawn_at.is_some() { + p.warning + } else { + p.muted + }, + ); + resp +} + +fn detail(ui: &mut Ui, b: &Books, a: &Attachment, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + egui::ScrollArea::vertical() + .id_salt(("doc", a.id)) + .auto_shrink(false) + .show(ui, |ui| { + ui.horizontal(|ui| { + ui.label( + RichText::new(format!("Document {}", a.id)) + .font(theme::regular(12.5)) + .color(p.muted), + ); + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + if ui + .add(egui::Button::new(RichText::new(icon::X).size(15.0)).frame(false)) + .clicked() + { + shell.go(Route::Documents); + } + }); + }); + ui.label(RichText::new(&a.file_name).font(theme::bold(20.0))); + ui.add_space(8.0); + egui::Grid::new(("docfacts", a.id)) + .num_columns(2) + .spacing(vec2(20.0, 6.0)) + .show(ui, |ui| { + let k = |ui: &mut Ui, s: &str| { + ui.label(RichText::new(s).font(theme::regular(12.5)).color(p.muted)) + }; + k(ui, "Category"); + ui.label(fmt::label(&a.category)); + ui.end_row(); + k(ui, "Type"); + ui.label(format!("{} · {}", a.mime_type, fmt::bytes(a.size_bytes))); + ui.end_row(); + k(ui, "Filed"); + ui.label(fmt::timestamp(&a.created_at)); + ui.end_row(); + k(ui, "SHA-256"); + ui.add( + egui::Label::new(RichText::new(&a.blob_sha).monospace().size(11.5)).wrap(), + ); + ui.end_row(); + if let Some(e) = a.entry_id { + k(ui, "Proves"); + let label = b + .entry(e) + .map(|x| { + format!("#{} {} ({})", x.id, x.description, fmt::dollars(x.amount)) + }) + .unwrap_or_else(|| format!("#{e}")); + if widgets::link(ui, RichText::new(label).color(p.accent)).clicked() { + shell.go(Route::Entry(e)); + } + ui.end_row(); + } + }); + ui.add_space(10.0); + super::entry::render(ui, b, a, shell, ui.available_width()); + if let Some(d) = &a.description { + ui.add_space(6.0); + ui.label(RichText::new(d).color(p.muted)); + } + if a.withdrawn_at.is_some() { + ui.add_space(6.0); + widgets::pill( + ui, + &format!("Withdrawn: {}", a.withdrawn_reason.as_deref().unwrap_or("")), + p.warning, + p.warning_soft, + ); + } + }); +} diff --git a/crates/ledger-gui/src/pages/entry.rs b/crates/ledger-gui/src/pages/entry.rs new file mode 100644 index 0000000..e46ef81 --- /dev/null +++ b/crates/ledger-gui/src/pages/entry.rs @@ -0,0 +1,398 @@ +//! One entry, completely: what it is, every line, the receipt itself, and +//! every journal event that touched it. + +use crate::app::Shell; +use crate::books::{Books, EntryInfo}; +use crate::fmt; +use crate::nav::Route; +use crate::receipts::State as Render; +use crate::theme::{self, pal}; +use crate::widgets; +use egui::{CornerRadius, Margin, RichText, Stroke, Ui, vec2}; +use egui_phosphor::regular as icon; +use ledger_core::{EntryStatus, Side}; +use ledger_store::Attachment; +use rust_decimal::Decimal; + +pub fn detail(ui: &mut Ui, b: &Books, e: &EntryInfo, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let Some(entry) = b.ledger.get_entry(e.id) else { + return; + }; + egui::ScrollArea::vertical() + .id_salt(("entry", e.id)) + .auto_shrink(false) + .show(ui, |ui| { + ui.horizontal(|ui| { + ui.label( + RichText::new(format!("Entry #{}", e.id)) + .font(theme::regular(12.5)) + .color(p.muted), + ); + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + if ui + .add(egui::Button::new(RichText::new(icon::X).size(15.0)).frame(false)) + .on_hover_text("Close") + .clicked() + { + shell.go(Route::Transactions); + } + }); + }); + ui.label(RichText::new(&e.description).font(theme::bold(21.0))); + ui.add_space(6.0); + ui.horizontal_wrapped(|ui| { + match e.status { + EntryStatus::Posted => widgets::pill(ui, "Posted", p.positive, p.positive_soft), + EntryStatus::Draft => { + widgets::pill(ui, "Draft — not in any report", p.warning, p.warning_soft) + } + }; + widgets::pill(ui, e.origin, p.muted, p.hover); + if let Some(v) = &e.vendor { + widgets::pill(ui, &format!("{} {v}", icon::STOREFRONT), p.muted, p.hover); + } + if e.missing_receipt { + widgets::pill(ui, "Missing receipt", p.negative, p.negative_soft); + } + }); + if let Some(o) = e.reversal_of { + ui.add_space(4.0); + if widgets::link( + ui, + RichText::new(format!("{} Reverses #{o}", icon::ARROW_COUNTER_CLOCKWISE)) + .color(p.accent), + ) + .clicked() + { + shell.go(Route::Entry(o)); + } + } + if let Some(r) = e.reversed_by { + ui.add_space(4.0); + if widgets::link( + ui, + RichText::new(format!( + "{} Reversed by #{r}", + icon::ARROW_COUNTER_CLOCKWISE + )) + .color(p.accent), + ) + .clicked() + { + shell.go(Route::Entry(r)); + } + } + ui.add_space(16.0); + + // Facts. + let created = e.events.first().map(|&i| fmt::timestamp(&b.journal[i].ts)); + // Posted by entry.posted, or in one step by whatever created it + // (a schedule, a close, a bill). + let posted = e + .events + .iter() + .find(|&&i| b.journal[i].line_type == "entry.posted") + .or_else(|| e.events.first()) + .map(|&i| fmt::timestamp(&b.journal[i].ts)); + egui::Grid::new(("facts", e.id)) + .num_columns(2) + .spacing(vec2(24.0, 6.0)) + .show(ui, |ui| { + let k = |ui: &mut Ui, s: &str| { + ui.label(RichText::new(s).font(theme::regular(12.5)).color(p.muted)) + }; + k(ui, "Date"); + ui.label(fmt::date(e.date)); + ui.end_row(); + k(ui, "Amount"); + ui.label(RichText::new(fmt::dollars(e.amount)).font(theme::semibold(14.0))); + ui.end_row(); + if let Some(c) = &created { + k(ui, "Recorded"); + ui.label(c); + ui.end_row(); + } + if e.status == EntryStatus::Posted + && let Some(t) = &posted + { + k(ui, "Posted"); + ui.label(t); + ui.end_row(); + } + }); + ui.add_space(16.0); + + // Lines. + section(ui, "Lines"); + let total_w = ui.available_width(); + let amt_w = 104.0; + let class_names: std::collections::HashMap = b + .ledger + .list_classes() + .into_iter() + .map(|c| (c.id, c.name.clone())) + .collect(); + egui::Frame::new() + .stroke(Stroke::new(1.0, p.border)) + .corner_radius(CornerRadius::same(10)) + .inner_margin(Margin::symmetric(12, 8)) + .show(ui, |ui| { + ui.set_width(total_w - 26.0); + ui.horizontal(|ui| { + let w = ui.available_width() - amt_w * 2.0 - 16.0; + let (r, _) = ui.allocate_exact_size(vec2(w, 18.0), egui::Sense::hover()); + ui.painter().text( + r.left_center(), + egui::Align2::LEFT_CENTER, + "Account", + theme::regular(12.0), + p.muted, + ); + widgets::amount_cell(ui, "Debit", amt_w, p.muted, false, false); + widgets::amount_cell(ui, "Credit", amt_w, p.muted, false, false); + }); + let (mut dr, mut cr) = (Decimal::ZERO, Decimal::ZERO); + for line in entry.lines() { + ui.horizontal(|ui| { + let w = ui.available_width() - amt_w * 2.0 - 16.0; + ui.allocate_ui(vec2(w, 22.0), |ui| { + ui.set_width(w); + ui.horizontal(|ui| { + let r = widgets::link( + ui, + RichText::new(b.account_label(line.account)) + .font(theme::regular(13.5)), + ); + if r.clicked() { + shell.go(Route::Account(line.account)); + } + if let Some(c) = line.class_id.and_then(|c| class_names.get(&c)) + { + ui.label( + RichText::new(format!("{} {c}", icon::TAG)) + .font(theme::regular(11.5)) + .color(p.muted), + ); + } + if let (Some(cur), Some(fa)) = + (&line.foreign_currency, line.foreign_amount) + { + ui.label( + RichText::new(format!( + "{} {}", + fmt::money(fa), + cur.code() + )) + .font(theme::regular(11.5)) + .color(p.muted), + ); + } + }); + }); + let a = fmt::money(line.amount.amount); + let (d, c) = match line.side { + Side::Debit => { + dr += line.amount.amount; + (a, String::new()) + } + Side::Credit => { + cr += line.amount.amount; + (String::new(), a) + } + }; + widgets::amount_cell(ui, &d, amt_w, p.text, false, false); + widgets::amount_cell(ui, &c, amt_w, p.text, false, false); + }); + } + widgets::rule(ui); + ui.horizontal(|ui| { + let w = ui.available_width() - amt_w * 2.0 - 16.0; + let balanced = dr == cr; + let (r, _) = ui.allocate_exact_size(vec2(w, 22.0), egui::Sense::hover()); + ui.painter().text( + r.left_center(), + egui::Align2::LEFT_CENTER, + if balanced { + format!("{} Balanced", icon::CHECK) + } else { + "Out of balance".into() + }, + theme::regular(12.0), + if balanced { p.positive } else { p.negative }, + ); + widgets::amount_cell(ui, &fmt::money(dr), amt_w, p.text, true, false); + widgets::amount_cell(ui, &fmt::money(cr), amt_w, p.text, true, false); + }); + }); + ui.add_space(18.0); + + // Receipts. + let all_for_entry: Vec<&Attachment> = b + .attachments + .iter() + .filter(|a| a.entry_id == Some(e.id)) + .collect(); + section( + ui, + if all_for_entry.len() == 1 { + "Receipt" + } else { + "Receipts" + }, + ); + if all_for_entry.is_empty() { + let msg = if e.missing_receipt { + format!( + "None attached, and this entry is over the {} receipt threshold.", + fmt::dollars(b.receipt_threshold) + ) + } else { + "None attached.".to_string() + }; + ui.label(RichText::new(msg).color(if e.missing_receipt { + p.negative + } else { + p.muted + })); + } + for a in all_for_entry { + attachment_view(ui, b, a, shell, true); + ui.add_space(12.0); + } + ui.add_space(12.0); + + // History. + section(ui, "History"); + for &i in &e.events { + let line = &b.journal[i]; + let ev = super::journal::describe_any(b, line); + ui.horizontal(|ui| { + ui.label(RichText::new(ev.icon).color(p.muted)); + let r = widgets::link(ui, RichText::new(&ev.text).font(theme::regular(12.5))); + if r.clicked() { + shell.go(Route::JournalEvent(line.seq)); + } + ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { + ui.label( + RichText::new(format!("#{} · {}", line.seq, fmt::timestamp(&line.ts))) + .font(theme::regular(11.5)) + .color(p.faint), + ); + }); + }); + } + }); +} + +pub fn section(ui: &mut Ui, title: &str) { + let p = pal(ui.ctx()); + ui.label( + RichText::new(title.to_uppercase()) + .font(theme::semibold(11.5)) + .color(p.faint), + ); + ui.add_space(6.0); +} + +/// A receipt or document: its name and facts, then the file itself. +pub fn attachment_view( + ui: &mut Ui, + b: &Books, + a: &Attachment, + shell: &mut Shell<'_>, + link_to_doc: bool, +) { + let p = pal(ui.ctx()); + ui.horizontal(|ui| { + ui.label( + RichText::new(if a.mime_type == "application/pdf" { + icon::FILE_PDF + } else { + icon::FILE_IMAGE + }) + .size(18.0) + .color(p.muted), + ); + ui.vertical(|ui| { + ui.spacing_mut().item_spacing.y = 1.0; + let name = RichText::new(&a.file_name).font(theme::semibold(13.0)); + if link_to_doc { + if widgets::link(ui, name).clicked() { + shell.go(Route::Document(a.id)); + } + } else { + ui.label(name); + } + ui.label( + RichText::new(format!( + "{} · {} · filed {}", + fmt::label(&a.category), + fmt::bytes(a.size_bytes), + fmt::timestamp(&a.created_at) + )) + .font(theme::regular(11.5)) + .color(p.muted), + ); + }); + }); + if let Some(when) = &a.withdrawn_at { + widgets::pill( + ui, + &format!( + "Withdrawn {}: {}", + fmt::timestamp(when), + a.withdrawn_reason.as_deref().unwrap_or("") + ), + p.warning, + p.warning_soft, + ); + } + if let Some(d) = &a.description { + ui.label(RichText::new(d).font(theme::regular(12.5)).color(p.muted)); + } + ui.add_space(6.0); + render(ui, b, a, shell, ui.available_width()); +} + +/// The file itself, pages stacked, scaled to `width`. +pub fn render(ui: &mut Ui, b: &Books, a: &Attachment, shell: &mut Shell<'_>, width: f32) { + let p = pal(ui.ctx()); + match shell.receipts.get(&a.blob_sha, &a.mime_type, b.blob_root()) { + Render::Loading => { + ui.horizontal(|ui| { + ui.spinner(); + ui.label(RichText::new("Rendering…").color(p.muted)); + }); + } + Render::Failed(err) => { + ui.label( + RichText::new(format!("{} Can't show this file: {err}", icon::WARNING)) + .color(p.negative), + ); + } + Render::Ready(pages) => { + for (i, tex) in pages.iter().enumerate() { + let size = tex.size_vec2(); + let scale = (width / size.x).min(1.0); + let img = egui::Image::new(tex) + .fit_to_exact_size(size * scale) + .corner_radius(CornerRadius::same(4)); + egui::Frame::new() + .stroke(Stroke::new(1.0, p.border)) + .corner_radius(CornerRadius::same(6)) + .show(ui, |ui| { + ui.add(img); + }); + if pages.len() > 1 { + ui.label( + RichText::new(format!("Page {} of {}", i + 1, pages.len())) + .font(theme::regular(11.0)) + .color(p.faint), + ); + } + ui.add_space(6.0); + } + } + } +} diff --git a/crates/ledger-gui/src/pages/journal.rs b/crates/ledger-gui/src/pages/journal.rs new file mode 100644 index 0000000..5da4534 --- /dev/null +++ b/crates/ledger-gui/src/pages/journal.rs @@ -0,0 +1,482 @@ +//! The journal: every event, in order, as recorded. The audit trail an +//! accountant wants and the raw truth everything else is built from. + +use super::page; +use crate::app::Shell; +use crate::books::{Books, entry_refs}; +use crate::fmt; +use crate::nav::Route; +use crate::theme::{self, pal}; +use crate::widgets; +use egui::{CornerRadius, Margin, RichText, Sense, Ui, vec2}; +use egui_phosphor::regular as icon; +use ledger_store::JournalLine; +use serde_json::Value; + +#[derive(Default)] +pub struct State { + pub query: String, + pub hide_steps: bool, +} + +pub struct Event { + pub icon: &'static str, + pub text: String, + pub route: Option, +} + +fn s<'a>(p: &'a Value, k: &str) -> &'a str { + p.get(k).and_then(|v| v.as_str()).unwrap_or("") +} + +fn amount(p: &Value) -> String { + p.get("amount") + .and_then(|v| v.as_str()) + .and_then(|a| a.parse().ok()) + .map(fmt::dollars) + .unwrap_or_default() +} + +fn entry_text(b: &Books, id: u64) -> String { + b.entry(id) + .map(|e| format!("#{} {} ({})", e.id, e.description, fmt::dollars(e.amount))) + .unwrap_or_else(|| format!("#{id}")) +} + +fn attachment_name(b: &Books, id: u64) -> String { + b.attachments + .iter() + .find(|a| a.id == id) + .map(|a| a.file_name.clone()) + .unwrap_or_else(|| format!("attachment {id}")) +} + +/// A sentence for a meaningful event; `None` for the intermediate steps of +/// building an entry (created, line added), which the posted event covers. +pub fn describe(b: &Books, line: &JournalLine) -> Option { + let p = &line.payload; + let id = p.get("id").and_then(|v| v.as_u64()).unwrap_or(0); + let entry_id = p.get("entry_id").and_then(|v| v.as_u64()); + let att = p.get("attachment_id").and_then(|v| v.as_u64()).unwrap_or(0); + let ev = |icon, text: String, route: Option| Some(Event { icon, text, route }); + match line.line_type.as_str() { + "entry.created" | "entry.line_added" | "entry.line_class_set" => None, + "store.created" => ev(icon::BOOK_OPEN, "Books created".into(), None), + "entry.posted" => ev( + icon::CHECK_CIRCLE, + format!("Posted {}", entry_text(b, id)), + Some(Route::Entry(id)), + ), + "entry.reversed" => ev( + icon::ARROW_COUNTER_CLOCKWISE, + format!( + "Reversed #{} with #{id}", + p.get("reverses").and_then(|v| v.as_u64()).unwrap_or(0) + ), + Some(Route::Entry(id)), + ), + "receipt.attached" => ev( + icon::PAPERCLIP, + match entry_id { + Some(e) => format!("Attached {} to #{e}", s(p, "file_name")), + None => format!("Filed receipt {}", s(p, "file_name")), + }, + Some(Route::Document(att)), + ), + "document.filed" => ev( + icon::FILE_ARROW_UP, + format!( + "Filed {} ({})", + s(p, "file_name"), + fmt::label(s(p, "category")) + ), + Some(Route::Document(att)), + ), + "receipt.linked" => ev( + icon::LINK, + format!( + "Linked {} to #{}", + attachment_name(b, att), + entry_id.unwrap_or(0) + ), + entry_id.map(Route::Entry), + ), + "receipt.unlinked" => ev( + icon::LINK_BREAK, + format!( + "Unlinked {} from #{}: {}", + attachment_name(b, att), + entry_id.unwrap_or(0), + s(p, "reason") + ), + entry_id.map(Route::Entry), + ), + "attachment.withdrawn" => ev( + icon::ARCHIVE, + format!("Withdrew {}: {}", attachment_name(b, att), s(p, "reason")), + Some(Route::Document(att)), + ), + "account.added" => ev( + icon::PLUS_CIRCLE, + format!("Added account {} {}", s(p, "code"), s(p, "name")), + Some(Route::Account(id)), + ), + "account.tax_set" => ev( + icon::TAG, + format!( + "Tax category of {}: {}", + b.account_label(p.get("account_id").and_then(|v| v.as_u64()).unwrap_or(0)), + p.get("tax_category") + .and_then(|v| v.as_str()) + .unwrap_or("none") + ), + p.get("account_id") + .and_then(|v| v.as_u64()) + .map(Route::Account), + ), + "vendor.added" => ev( + icon::STOREFRONT, + format!("Added vendor {}", s(p, "name")), + Some(Route::Company), + ), + "customer.added" => ev( + icon::USER_PLUS, + format!("Added customer {}", s(p, "name")), + Some(Route::Company), + ), + "class.added" => ev(icon::TAG, format!("Added class {}", s(p, "name")), None), + "vendor.1099_set" => ev( + icon::IDENTIFICATION_CARD, + "Updated a vendor's 1099 details".into(), + Some(Route::Company), + ), + "entry.vendor_set" => ev( + icon::STOREFRONT, + format!("Tagged #{} with a vendor", entry_id.unwrap_or(0)), + entry_id.map(Route::Entry), + ), + "invoice.created" => ev( + icon::INVOICE, + format!("Invoice {id} created"), + entry_id.map(Route::Entry), + ), + "bill.created" => ev( + icon::RECEIPT, + format!("Bill {id} recorded"), + entry_id.map(Route::Entry), + ), + "invoice.payment_received" => ev( + icon::HAND_COINS, + format!("Payment received, {}", amount(p)), + entry_id.map(Route::Entry), + ), + "bill.paid" => ev( + icon::MONEY, + format!("Bill paid, {}", amount(p)), + entry_id.map(Route::Entry), + ), + "period.created" => ev( + icon::CALENDAR_PLUS, + format!("Period {} created", s(p, "name")), + Some(Route::Company), + ), + "period.closed" => ev( + icon::LOCK, + "Period closed".into(), + p.get("closing_entry") + .and_then(|v| v.as_u64()) + .map(Route::Entry), + ), + "asset.registered" => ev( + icon::PACKAGE, + format!("Registered asset {}", s(p, "description")), + Some(Route::Company), + ), + "asset.depreciation_posted" => ev( + icon::TREND_DOWN, + "Depreciation posted".into(), + entry_id.map(Route::Entry), + ), + "asset.disposed" => ev( + icon::TRASH, + "Asset disposed".into(), + entry_id.map(Route::Entry), + ), + "schedule.registered" => ev( + icon::CALENDAR, + format!("Schedule: {}", s(p, "description")), + Some(Route::Company), + ), + "schedule.posted" => ev( + icon::CALENDAR_CHECK, + "Amortization posted".into(), + p.get("entry") + .and_then(|e| e.get("id")) + .and_then(|v| v.as_u64()) + .map(Route::Entry), + ), + "recurring.registered" => ev( + icon::REPEAT, + format!("Recurring: {}", s(p, "description")), + Some(Route::Company), + ), + "recurring.generated" => ev( + icon::REPEAT, + "Recurring draft created".into(), + entry_id.map(Route::Entry), + ), + "fx.rate_set" => ev( + icon::CURRENCY_CIRCLE_DOLLAR, + format!("{} rate set", s(p, "currency")), + None, + ), + "payroll.run" => ev( + icon::USERS, + "Payroll run".into(), + entry_id.map(Route::Entry), + ), + "line.cleared" => ev( + icon::CHECK_SQUARE, + format!("Cleared a line of #{}", entry_id.unwrap_or(0)), + entry_id.map(Route::Entry), + ), + other => ev( + icon::DOT, + other.to_string(), + entry_refs(line).first().copied().map(Route::Entry), + ), + } +} + +/// Like [`describe`], but every event gets a sentence. +pub fn describe_any(b: &Books, line: &JournalLine) -> Event { + if let Some(e) = describe(b, line) { + return e; + } + let p = &line.payload; + let id = p + .get("id") + .and_then(|v| v.as_u64()) + .or_else(|| p.get("entry_id").and_then(|v| v.as_u64())) + .unwrap_or(0); + match line.line_type.as_str() { + "entry.created" => Event { + icon: icon::PENCIL_SIMPLE, + text: format!("Drafted #{id} {}", s(p, "description")), + route: Some(Route::Entry(id)), + }, + "entry.line_added" => { + let amount = p + .get("amount") + .and_then(|a| a.get("amount").or(Some(a))) + .and_then(|v| v.as_str()) + .and_then(|v| v.parse().ok()) + .map(fmt::money) + .unwrap_or_default(); + Event { + icon: icon::PLUS, + text: format!( + "Line on #{id}: {} {} {amount}", + s(p, "side"), + b.account_label( + p.get("account_id") + .or_else(|| p.get("account")) + .and_then(|v| v.as_u64()) + .unwrap_or(0) + ), + ), + route: Some(Route::Entry(id)), + } + } + "entry.line_class_set" => { + let class = p + .get("class_id") + .and_then(|v| v.as_u64()) + .and_then(|c| b.ledger.get_class(c as u32)) + .map(|c| c.name.clone()) + .unwrap_or_else(|| "no class".into()); + Event { + icon: icon::TAG, + text: format!( + "Line {} of #{id} tagged {class}", + p.get("line_index") + .and_then(|v| v.as_u64()) + .map_or(0, |i| i + 1) + ), + route: Some(Route::Entry(id)), + } + } + t => Event { + icon: icon::DOT, + text: t.to_string(), + route: None, + }, + } +} + +pub fn show(ui: &mut Ui, b: &Books, selected: Option, shell: &mut Shell<'_>) { + if let Some(seq) = selected + && let Some(line) = b.journal.get(seq.saturating_sub(1) as usize) + { + super::split( + ui, + "journal", + 480.0, + shell, + |ui, shell| list(ui, b, selected, shell), + |ui, shell| detail(ui, b, line, shell), + ); + } else { + list(ui, b, None, shell); + } +} + +fn list(ui: &mut Ui, b: &Books, selected: Option, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + page(ui, "journal", |ui| { + widgets::page_header( + ui, + "Journal", + &format!( + "Every change to the books, in order: {} events, each hash-chained to the one before. Nothing is ever edited or deleted; corrections are new events.", + b.journal.len() + ), + ); + let st = &mut shell.state.journal; + ui.horizontal(|ui| { + ui.add( + egui::TextEdit::singleline(&mut st.query) + .hint_text(format!("{} Filter events", icon::MAGNIFYING_GLASS)) + .desired_width(320.0), + ); + ui.checkbox(&mut st.hide_steps, "Hide entry-building steps"); + }); + ui.add_space(10.0); + let q = st.query.to_lowercase(); + let hide = st.hide_steps; + let rows: Vec<(&JournalLine, Event)> = b + .journal + .iter() + .rev() + .filter(|l| !(hide && describe(b, l).is_none())) + .map(|l| (l, describe_any(b, l))) + .filter(|(l, e)| { + q.is_empty() || e.text.to_lowercase().contains(&q) || l.line_type.contains(&q) + }) + .collect(); + widgets::card(ui, |ui| { + let row_h = 34.0; + egui::ScrollArea::vertical() + .id_salt("journal_rows") + .max_height(ui.available_height().max(400.0)) + .show_rows(ui, row_h, rows.len(), |ui, range| { + for (line, ev) in &rows[range] { + let (rect, resp) = ui + .allocate_exact_size(vec2(ui.available_width(), row_h), Sense::click()); + let on = selected == Some(line.seq); + let fresh = line.seq > b.fresh_from_seq && shell.since_update < 8.0; + if on { + ui.painter() + .rect_filled(rect, CornerRadius::same(6), p.selected); + } else if fresh { + ui.painter() + .rect_filled(rect, CornerRadius::same(6), p.new_highlight); + } else if resp.hovered() { + ui.painter() + .rect_filled(rect, CornerRadius::same(6), p.hover); + } + let painter = ui.painter_at(rect); + let y = rect.center().y; + painter.text( + egui::pos2(rect.left() + 8.0, y), + egui::Align2::LEFT_CENTER, + format!("{}", line.seq), + theme::regular(12.0), + p.faint, + ); + painter.text( + egui::pos2(rect.left() + 56.0, y), + egui::Align2::LEFT_CENTER, + ev.icon, + egui::FontId::proportional(15.0), + p.muted, + ); + painter.text( + egui::pos2(rect.left() + 80.0, y), + egui::Align2::LEFT_CENTER, + &ev.text, + theme::regular(13.0), + p.text, + ); + painter.text( + egui::pos2(rect.right() - 8.0, y), + egui::Align2::RIGHT_CENTER, + fmt::timestamp(&line.ts), + theme::regular(12.0), + p.faint, + ); + if resp.clicked() { + shell.go(Route::JournalEvent(line.seq)); + } + } + }); + }); + }); +} + +fn detail(ui: &mut Ui, b: &Books, line: &JournalLine, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let ev = describe_any(b, line); + egui::ScrollArea::vertical() + .id_salt("event_detail") + .show(ui, |ui| { + ui.label( + RichText::new(format!("Event {}", line.seq)) + .font(theme::regular(12.5)) + .color(p.muted), + ); + ui.label(RichText::new(&ev.text).font(theme::semibold(17.0))); + ui.add_space(10.0); + let fact = |ui: &mut Ui, k: &str, v: &str| { + ui.horizontal(|ui| { + ui.add_sized( + vec2(90.0, 18.0), + egui::Label::new( + RichText::new(k).font(theme::regular(12.5)).color(p.muted), + ), + ); + ui.add(egui::Label::new(RichText::new(v).font(theme::regular(12.5))).wrap()); + }); + }; + fact(ui, "Type", &line.line_type); + fact(ui, "Recorded", &fmt::timestamp(&line.ts)); + fact(ui, "Previous", &line.prev); + let own = ledger_store::journal::sha256_hex(line.to_canonical().as_bytes()); + fact(ui, "This hash", &own); + if let Some(r) = &ev.route { + ui.add_space(6.0); + if ui + .button(format!( + "{} Open {}", + icon::ARROW_SQUARE_OUT, + crate::palette::describe(b, r) + )) + .clicked() + { + shell.go(r.clone()); + } + } + ui.add_space(12.0); + ui.label(RichText::new("Payload").font(theme::semibold(13.0))); + ui.add_space(4.0); + let json = serde_json::to_string_pretty(&line.payload).unwrap_or_default(); + egui::Frame::new() + .fill(p.hover) + .corner_radius(CornerRadius::same(8)) + .inner_margin(Margin::same(10)) + .show(ui, |ui| { + ui.set_width(ui.available_width()); + ui.add(egui::Label::new(RichText::new(json).monospace().size(12.0)).wrap()); + }); + }); +} diff --git a/crates/ledger-gui/src/pages/mod.rs b/crates/ledger-gui/src/pages/mod.rs new file mode 100644 index 0000000..828c6be --- /dev/null +++ b/crates/ledger-gui/src/pages/mod.rs @@ -0,0 +1,156 @@ +//! One module per screen. + +pub mod accounts; +pub mod cash; +pub mod company; +pub mod documents; +pub mod entry; +pub mod journal; +pub mod overview; +pub mod profit; +pub mod reports; +pub mod transactions; + +use crate::app::Shell; +use crate::books::Books; +use crate::nav::Route; +use egui::{Margin, Ui}; + +/// Standard page body: scrollable, padded. +pub fn page(ui: &mut Ui, id: &str, add: impl FnOnce(&mut Ui)) { + egui::ScrollArea::vertical() + .id_salt(id) + .auto_shrink(false) + .show(ui, |ui| { + egui::Frame::new() + .inner_margin(Margin { + left: 32, + right: 32, + top: 24, + bottom: 40, + }) + .show(ui, |ui| { + ui.set_width(ui.available_width()); + add(ui) + }); + }); +} + +pub fn show(ui: &mut Ui, b: &Books, route: &Route, shell: &mut Shell<'_>) { + match route { + Route::Overview => overview::show(ui, b, shell), + Route::Cash => cash::show(ui, b, shell), + Route::Profit => profit::show(ui, b, shell), + Route::Transactions => transactions::show(ui, b, None, shell), + Route::Entry(id) => transactions::show(ui, b, Some(*id), shell), + Route::Reports(kind) => reports::show(ui, b, *kind, shell), + Route::Accounts => accounts::show_chart(ui, b, shell), + Route::Account(id) => accounts::show_account(ui, b, *id, shell), + Route::Documents => documents::show(ui, b, None, shell), + Route::Document(id) => documents::show(ui, b, Some(*id), shell), + Route::Company => company::show(ui, b, shell), + Route::Journal => journal::show(ui, b, None, shell), + Route::JournalEvent(seq) => journal::show(ui, b, Some(*seq), shell), + } +} + +/// Columns sized by `weights` when the page is at least `min_width` +/// wide; stacked otherwise. `add(i, ui)` fills column `i`. +pub fn columns(ui: &mut Ui, min_width: f32, weights: &[f32], mut add: impl FnMut(usize, &mut Ui)) { + let gap = 16.0; + if ui.available_width() < min_width { + for i in 0..weights.len() { + add(i, ui); + ui.add_space(gap); + } + return; + } + let total: f32 = weights.iter().sum(); + let avail = ui.available_width() - gap * (weights.len() as f32 - 1.0); + let top = ui.cursor().min; + let mut x = top.x; + let mut bottom = top.y; + for (i, w) in weights.iter().enumerate() { + let width = avail * w / total; + let rect = + egui::Rect::from_min_size(egui::pos2(x, top.y), egui::vec2(width, f32::INFINITY)); + let mut child = ui.new_child( + egui::UiBuilder::new() + .max_rect(rect) + .layout(egui::Layout::top_down(egui::Align::Min)), + ); + child.set_width(width); + add(i, &mut child); + bottom = bottom.max(child.min_rect().bottom()); + x += width + gap; + } + let used = egui::Rect::from_min_max(top, egui::pos2(top.x + ui.available_width(), bottom)); + ui.advance_cursor_after_rect(used); + ui.add_space(gap); +} + +/// A list on the left and a detail pane on the right, split by a +/// draggable divider. The split is remembered per `id`. +pub fn split( + ui: &mut Ui, + id: &str, + default_detail: f32, + state: &mut T, + left: impl FnOnce(&mut Ui, &mut T), + right: impl FnOnce(&mut Ui, &mut T), +) { + let p = crate::theme::pal(ui.ctx()); + let rect = ui.available_rect_before_wrap(); + let key = egui::Id::new(("split", id)); + let mut detail_w: f32 = ui + .ctx() + .data_mut(|d| d.get_persisted(key)) + .unwrap_or(default_detail); + detail_w = detail_w.clamp(360.0, (rect.width() - 380.0).max(360.0)); + let divider_x = rect.right() - detail_w; + let left_rect = egui::Rect::from_min_max(rect.min, egui::pos2(divider_x, rect.bottom())); + let right_rect = egui::Rect::from_min_max(egui::pos2(divider_x + 1.0, rect.top()), rect.max); + ui.painter().rect_filled(right_rect, 0.0, p.surface); + ui.painter().line_segment( + [ + egui::pos2(divider_x, rect.top()), + egui::pos2(divider_x, rect.bottom()), + ], + egui::Stroke::new(1.0, p.border), + ); + let mut l = ui.new_child( + egui::UiBuilder::new() + .max_rect(left_rect) + .layout(egui::Layout::top_down(egui::Align::Min)), + ); + l.set_clip_rect(left_rect); + left(&mut l, state); + let inner = right_rect.shrink2(egui::vec2(24.0, 20.0)); + let mut r = ui.new_child( + egui::UiBuilder::new() + .max_rect(inner) + .layout(egui::Layout::top_down(egui::Align::Min)), + ); + r.set_clip_rect(right_rect); + right(&mut r, state); + let handle = egui::Rect::from_center_size( + egui::pos2(divider_x, rect.center().y), + egui::vec2(8.0, rect.height()), + ); + let resp = ui.interact(handle, key.with("handle"), egui::Sense::drag()); + if resp.hovered() || resp.dragged() { + ui.ctx().set_cursor_icon(egui::CursorIcon::ResizeHorizontal); + ui.painter().line_segment( + [ + egui::pos2(divider_x, rect.top()), + egui::pos2(divider_x, rect.bottom()), + ], + egui::Stroke::new(2.0, p.accent), + ); + } + if resp.dragged() { + detail_w -= resp.drag_delta().x; + ui.ctx().data_mut(|d| d.insert_persisted(key, detail_w)); + } + ui.allocate_rect(rect, egui::Sense::hover()); +} diff --git a/crates/ledger-gui/src/pages/overview.rs b/crates/ledger-gui/src/pages/overview.rs new file mode 100644 index 0000000..fbf8a91 --- /dev/null +++ b/crates/ledger-gui/src/pages/overview.rs @@ -0,0 +1,481 @@ +//! Home: the state of the business in one sentence, the numbers behind +//! it, what needs doing, and what just happened. + +use super::{columns, page}; +use crate::app::Shell; +use crate::books::{Books, Severity}; +use crate::charts::{self, BarGroup}; +use crate::fmt; +use crate::nav::{ReportKind, Route}; +use crate::theme::{self, pal}; +use crate::widgets::{self, Kpi}; +use egui::{RichText, Ui}; +use egui_phosphor::regular as icon; +use ledger_core::analysis::{Interval, pnl_by_interval}; +use ledger_core::reports::profit_and_loss_for_period; +use rust_decimal::Decimal; + +pub fn show(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + page(ui, "overview", |ui| { + let k = &b.kpis; + widgets::page_header(ui, b.company_name(), &headline(b)); + kpis(ui, b, shell); + let _ = k; + columns(ui, 980.0, &[2.0, 1.0], |i, ui| match i { + 0 => { + let (more, _) = widgets::titled_card( + ui, + "Cash over time", + |ui| { + widgets::link( + ui, + RichText::new("Cash details") + .font(theme::regular(12.5)) + .color(pal(ui.ctx()).accent), + ) + .clicked() + }, + |ui| charts::balance_line(ui, &b.cash_history(), b.today, 230.0), + ); + if more { + shell.go(Route::Cash); + } + } + _ => attention(ui, b, shell), + }); + columns(ui, 980.0, &[1.0, 1.0], |i, ui| match i { + 0 => income_vs_spending(ui, b, shell), + _ => where_it_went(ui, b, shell), + }); + recent(ui, b, shell); + }); +} + +/// The answer, in words. +fn headline(b: &Books) -> String { + let k = &b.kpis; + let Some(first) = k.first_entry else { + return "No transactions yet. Once your agent records some, this page fills in on its own." + .into(); + }; + let mut s = format!( + "You have {} in cash and owe {}.", + fmt::dollars(k.cash), + fmt::dollars(k.liabilities) + ); + if let Some(burn) = k.monthly_burn { + if burn > Decimal::ZERO && k.cash > Decimal::ZERO { + let months = (k.cash / burn).round_dp(1); + s.push_str(&format!( + " Lately you spend {} a month more than you earn: about {} months of runway.", + fmt::dollars(burn), + months + )); + } + } else if k.net_ytd > Decimal::ZERO { + s.push_str(&format!( + " You've earned {} more than you've spent this year.", + fmt::dollars(k.net_ytd) + )); + } else if k.net_ytd < Decimal::ZERO { + s.push_str(&format!( + " You've spent {} more than you've earned this year.", + fmt::dollars(-k.net_ytd) + )); + } + if (b.today - first).num_days() < 60 { + s.push_str(&format!( + " Your books start {}; trends fill in as the months go by.", + fmt::date(first) + )); + } + s +} + +fn change( + now: Decimal, + prev: Decimal, + up_is_good: bool, + what: &str, +) -> Option<(String, egui::Color32)> { + let pct = fmt::pct_change(prev, now)?; + let good = (pct >= 0.0) == up_is_good; + let p = &theme::LIGHT; + let arrow = if pct >= 0.0 { "▲" } else { "▼" }; + Some(( + format!("{arrow} {:.0}% vs {what}", pct.abs()), + if pct.abs() < 0.5 { + p.muted + } else if good { + p.positive + } else { + p.negative + }, + )) +} + +fn kpis(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let k = &b.kpis; + let p = pal(ui.ctx()); + // Last 12 months of month-end cash for the sparkline. + let (start, end) = b.trailing_months(12); + let start = k.first_entry.map_or(start, |f| { + start.max(ledger_core::analysis::interval_start(f, Interval::Month)) + }); + let month_ends: Vec = + ledger_core::analysis::intervals(start, end, Interval::Month) + .into_iter() + .map(|(_, e)| e) + .collect(); + let cash_spark: Vec = + ledger_core::analysis::balance_series(&b.ledger, &b.cash_accounts, &month_ends) + .into_iter() + .map(|d| d.try_into().unwrap_or(0.0)) + .collect(); + let runway = match k.monthly_burn { + Some(burn) if burn > Decimal::ZERO && k.cash > Decimal::ZERO => ( + format!("{} mo", (k.cash / burn).round_dp(1)), + Some((format!("burning {}/mo", fmt::compact(burn)), p.warning)), + ), + _ if k.first_entry.is_none() => ("—".to_string(), None), + _ if k.first_entry.is_some_and(|f| f >= b.month_start()) => ( + "Too early".to_string(), + Some(("needs a full month of books".to_string(), p.muted)), + ), + _ => ( + "Not burning".to_string(), + Some(("earning ≥ spending".to_string(), p.positive)), + ), + }; + let ytd = b.fiscal_ytd(); + let tiles: Vec<(Kpi, Route)> = vec![ + ( + Kpi { + label: "Cash on hand", + value: fmt::dollars(k.cash), + sub: change(k.cash, k.cash_30d_ago, true, "30 days ago") + .map(|(t, c)| (t, color_for(c, p))), + spark: Some(&cash_spark), + how: "The balance of every cash account (bank, savings, cash on hand) at the end of today.", + }, + Route::Cash, + ), + ( + Kpi { + label: "Owed by the business", + value: fmt::dollars(k.liabilities), + sub: Some(("bills, cards, owners, taxes".into(), p.muted)), + spark: None, + how: "Total liabilities on today's balance sheet.", + }, + Route::Reports(ReportKind::BalanceSheet), + ), + ( + Kpi { + label: "Spending this month", + value: fmt::dollars(k.expenses_mtd), + sub: change( + k.expenses_mtd, + k.expenses_prev_month, + false, + "same days last month", + ) + .map(|(t, c)| (t, color_for(c, p))), + spark: None, + how: "Expenses dated this month (accrual basis: when incurred, not when paid).", + }, + Route::Profit, + ), + ( + Kpi { + label: "Revenue this month", + value: fmt::dollars(k.revenue_mtd), + sub: change( + k.revenue_mtd, + k.revenue_prev_month, + true, + "same days last month", + ) + .map(|(t, c)| (t, color_for(c, p))), + spark: None, + how: "Revenue dated this month.", + }, + Route::Profit, + ), + ( + Kpi { + label: "Net income, year to date", + value: fmt::dollars(k.net_ytd), + sub: Some((format!("since {}", fmt::date_short(ytd.0)), p.muted)), + spark: None, + how: "Revenue minus expenses for the fiscal year so far.", + }, + Route::Reports(ReportKind::ProfitAndLoss), + ), + ( + Kpi { + label: "Runway", + value: runway.0, + sub: runway.1, + spark: None, + how: "Cash on hand divided by the average monthly net loss over the last three full months the books cover.", + }, + Route::Cash, + ), + ]; + let n = if ui.available_width() > 1180.0 { 6 } else { 3 }; + for row in tiles.chunks(n) { + let weights = vec![1.0; n]; + columns(ui, 0.0, &weights, |i, ui| { + if let Some((tile, route)) = row.get(i) { + let r = widgets::kpi( + ui, + Kpi { + label: tile.label, + value: tile.value.clone(), + sub: tile.sub.clone(), + spark: tile.spark, + how: tile.how, + }, + ); + if r.interact(egui::Sense::click()).clicked() { + shell.go(route.clone()); + } + } + }); + } +} + +/// `change` picks from the light palette; map to the current one. +fn color_for(c: egui::Color32, p: &theme::Palette) -> egui::Color32 { + let l = &theme::LIGHT; + if c == l.positive { + p.positive + } else if c == l.negative { + p.negative + } else { + p.muted + } +} + +fn attention(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + widgets::titled_card( + ui, + "Needs attention", + |ui| { + if !b.attention.is_empty() { + widgets::pill( + ui, + &b.attention.len().to_string(), + p.warning, + p.warning_soft, + ); + } + }, + |ui| { + if b.attention.is_empty() { + widgets::empty( + ui, + icon::CHECK_CIRCLE, + "All clear", + "Nothing is missing or overdue.", + ); + return; + } + egui::ScrollArea::vertical() + .id_salt("attention") + .max_height(260.0) + .show(ui, |ui| { + for (i, a) in b.attention.iter().enumerate() { + if i > 0 { + ui.add_space(4.0); + widgets::rule(ui); + ui.add_space(4.0); + } + let (glyph, color) = match a.severity { + Severity::Problem => (icon::WARNING_CIRCLE, p.negative), + Severity::Todo => (icon::CIRCLE_DASHED, p.warning), + Severity::Info => (icon::INFO, p.muted), + }; + ui.horizontal_top(|ui| { + ui.label(RichText::new(glyph).size(16.0).color(color)); + ui.vertical(|ui| { + let t = RichText::new(&a.title).font(theme::semibold(13.0)); + let r = widgets::link(ui, t); + if r.clicked() + && let Some(to) = &a.target + { + shell.go(to.clone()); + } + ui.label( + RichText::new(&a.detail) + .font(theme::regular(12.0)) + .color(p.muted), + ); + widgets::copy_prompt(ui, &a.prompt); + }); + }); + } + }); + }, + ); +} + +fn income_vs_spending(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let (start, end) = b.trailing_months(12); + let start = b.kpis.first_entry.map_or(start, |f| { + start.max(ledger_core::analysis::interval_start(f, Interval::Month)) + }); + let months = pnl_by_interval(&b.ledger, start, end, Interval::Month).unwrap_or_default(); + widgets::titled_card( + ui, + "Income and spending by month", + |_| {}, + |ui| { + if months.is_empty() { + widgets::empty(ui, icon::CHART_BAR, "No months yet", ""); + return; + } + let groups: Vec = months + .iter() + .map(|m| BarGroup { + label: m.start.format("%b").to_string(), + values: vec![m.revenue, m.expenses, m.net()], + }) + .collect(); + let clicked = charts::bar_chart( + ui, + &groups, + &[ + ("Income", p.series[1]), + ("Spending", p.series[2]), + ("Net", p.series[0]), + ], + 220.0, + ); + if let Some(i) = clicked { + shell.state.reports.range = + crate::pages::reports::Range::Custom(months[i].start, months[i].end); + shell.go(Route::Reports(ReportKind::ProfitAndLoss)); + } + }, + ); +} + +fn where_it_went(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let (start, end) = b.fiscal_ytd(); + widgets::titled_card( + ui, + "Where the money went, this year", + |ui| { + ui.label( + RichText::new(format!( + "{} – {}", + fmt::date_short(start), + fmt::date_short(end) + )) + .font(theme::regular(12.0)) + .color(p.muted), + ); + }, + |ui| { + let Ok(pl) = profit_and_loss_for_period(&b.ledger, start, end, None) else { + return; + }; + let mut rows: Vec<(String, Decimal, String)> = pl + .expenses + .iter() + .map(|l| (l.name.clone(), l.amount, l.code.clone())) + .collect(); + rows.sort_by_key(|r| std::cmp::Reverse(r.1)); + rows.truncate(8); + if rows.is_empty() { + widgets::empty(ui, icon::CHART_BAR_HORIZONTAL, "No spending yet", ""); + return; + } + let bars: Vec<(String, Decimal)> = rows.iter().map(|r| (r.0.clone(), r.1)).collect(); + if let Some(i) = charts::hbars(ui, &bars, p.series[2]) + && let Some(a) = b.ledger.chart().find_by_code(&rows[i].2) + { + shell.go(Route::Account(a.id)); + } + }, + ); +} + +fn recent(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let since_update = shell.since_update; + let mut go = None; + let (full, _) = widgets::titled_card( + ui, + "Recent activity", + |ui| { + widgets::link( + ui, + RichText::new("Full journal") + .font(theme::regular(12.5)) + .color(p.accent), + ) + .clicked() + }, + |ui| { + let mut shown = 0; + for (i, line) in b.journal.iter().enumerate().rev() { + let Some(ev) = super::journal::describe(b, line) else { + continue; + }; + if shown == 12 { + break; + } + shown += 1; + let fresh = line.seq > b.fresh_from_seq && since_update < 8.0; + let row = egui::Frame::new() + .fill(if fresh { + p.new_highlight + } else { + egui::Color32::TRANSPARENT + }) + .corner_radius(egui::CornerRadius::same(6)) + .inner_margin(egui::Margin::symmetric(6, 3)) + .show(ui, |ui| { + ui.set_width(ui.available_width()); + ui.horizontal(|ui| { + ui.label(RichText::new(ev.icon).size(15.0).color(p.muted)); + let r = widgets::link( + ui, + RichText::new(&ev.text).font(theme::regular(13.0)), + ); + if r.clicked() { + go = + Some(ev.route.clone().unwrap_or(Route::JournalEvent(line.seq))); + } + ui.with_layout( + egui::Layout::right_to_left(egui::Align::Center), + |ui| { + ui.label( + RichText::new(fmt::timestamp(&line.ts)) + .font(theme::regular(11.5)) + .color(p.faint), + ); + }, + ); + }); + }); + let _ = (row, i); + } + if shown == 0 { + widgets::empty(ui, icon::CLOCK, "Nothing yet", ""); + } + }, + ); + if full { + go = Some(Route::Journal); + } + if let Some(r) = go { + shell.go(r); + } +} diff --git a/crates/ledger-gui/src/pages/profit.rs b/crates/ledger-gui/src/pages/profit.rs new file mode 100644 index 0000000..6e5b8c5 --- /dev/null +++ b/crates/ledger-gui/src/pages/profit.rs @@ -0,0 +1,377 @@ +//! Profit: are we making money, how is it trending, and what moved. +//! Spending by category this month against the recent average, income by +//! customer and by class. + +use super::{columns, page}; +use crate::app::Shell; +use crate::books::Books; +use crate::charts::{self, BarGroup}; +use crate::fmt; +use crate::nav::{ReportKind, Route}; +use crate::theme::{self, pal}; +use crate::widgets; +use chrono::{Days, Months}; +use egui::{CornerRadius, RichText, Sense, Ui, vec2}; +use egui_phosphor::regular as icon; +use ledger_core::analysis::{Interval, interval_start, pnl_by_interval}; +use ledger_core::reports::profit_and_loss_for_period; +use rust_decimal::Decimal; +use std::collections::BTreeMap; + +fn pct(part: Decimal, whole: Decimal) -> Option { + (!whole.is_zero()).then(|| (part / whole * Decimal::from(100)).round_dp(1)) +} + +pub fn show(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + page(ui, "profit", |ui| { + let (ys, ye) = b.fiscal_ytd(); + let ytd = profit_and_loss_for_period(&b.ledger, ys, ye, None).ok(); + let (rev, exp) = ytd + .as_ref() + .map(|p| (p.total_revenue, p.total_expenses)) + .unwrap_or_default(); + let net = rev - exp; + let margin = pct(net, rev); + let sentence = match margin { + Some(m) => format!( + "This year: {} of income, {} of spending, {} {} — a {}% margin.", + fmt::dollars(rev), + fmt::dollars(exp), + fmt::dollars(net.abs()), + if net >= Decimal::ZERO { + "profit" + } else { + "loss" + }, + m + ), + None if exp.is_zero() => "No income or spending recorded this year yet.".into(), + None => format!( + "This year: {} of spending and no income yet.", + fmt::dollars(exp) + ), + }; + widgets::page_header(ui, "Profit", &sentence); + + let first = b.kpis.first_entry.unwrap_or(b.today); + let (start, end) = b.trailing_months(12); + let start = start.max(interval_start(first, Interval::Month)); + let months = pnl_by_interval(&b.ledger, start, end, Interval::Month).unwrap_or_default(); + widgets::titled_card( + ui, + "By month", + |_| {}, + |ui| { + if months.is_empty() { + widgets::empty(ui, icon::CHART_BAR, "No months yet", ""); + return; + } + let groups: Vec = months + .iter() + .map(|m| BarGroup { + label: m.start.format("%b").to_string(), + values: vec![m.revenue, m.expenses, m.net()], + }) + .collect(); + if let Some(i) = charts::bar_chart( + ui, + &groups, + &[ + ("Income", p.series[1]), + ("Spending", p.series[2]), + ("Net", p.series[0]), + ], + 230.0, + ) { + shell.state.reports.range = + crate::pages::reports::Range::Custom(months[i].start, months[i].end); + shell.go(Route::Reports(ReportKind::ProfitAndLoss)); + } + ui.add_space(10.0); + // The same numbers as a table, with the margin. + let w = ui.available_width(); + let cw = 130.0; + let header = |ui: &mut Ui, cells: [&str; 5]| { + let (r, _) = ui.allocate_exact_size(vec2(w, 24.0), Sense::hover()); + ui.painter().text( + r.left_center() + vec2(4.0, 0.0), + egui::Align2::LEFT_CENTER, + cells[0], + theme::semibold(12.0), + p.muted, + ); + for (i, c) in cells[1..].iter().enumerate() { + ui.painter().text( + egui::pos2(r.right() - cw * (3 - i) as f32 - 4.0, r.center().y), + egui::Align2::RIGHT_CENTER, + *c, + theme::semibold(12.0), + p.muted, + ); + } + }; + header(ui, ["Month", "Income", "Spending", "Net", "Margin"]); + for m in months.iter().rev() { + let (r, resp) = ui.allocate_exact_size(vec2(w, 26.0), Sense::click()); + if resp.hovered() { + ui.painter().rect_filled(r, CornerRadius::same(4), p.hover); + } + ui.painter().text( + r.left_center() + vec2(4.0, 0.0), + egui::Align2::LEFT_CENTER, + fmt::month(m.start), + theme::regular(13.0), + p.text, + ); + let vals = [ + fmt::money(m.revenue), + fmt::money(m.expenses), + fmt::accounting(m.net()), + pct(m.net(), m.revenue) + .map(|x| format!("{x}%")) + .unwrap_or_else(|| "—".into()), + ]; + for (i, v) in vals.iter().enumerate() { + let color = if i == 2 && m.net() < Decimal::ZERO { + p.negative + } else { + p.text + }; + ui.painter().text( + egui::pos2(r.right() - cw * (3 - i) as f32 - 4.0, r.center().y), + egui::Align2::RIGHT_CENTER, + v, + theme::regular(13.0), + color, + ); + } + if resp.clicked() { + shell.state.reports.range = + crate::pages::reports::Range::Custom(m.start, m.end); + shell.go(Route::Reports(ReportKind::ProfitAndLoss)); + } + } + }, + ); + ui.add_space(16.0); + spending_changes(ui, b, shell); + columns(ui, 980.0, &[1.0, 1.0], |i, ui| match i { + 0 => by_customer(ui, b), + _ => by_class(ui, b), + }); + }); +} + +/// Each expense account: this month so far, last month, the three-month +/// average, and how far this month is running from it. +fn spending_changes(ui: &mut Ui, b: &Books, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let ms = b.month_start(); + let prev = + profit_and_loss_for_period(&b.ledger, ms - Months::new(1), ms - Days::new(1), None).ok(); + let three = + profit_and_loss_for_period(&b.ledger, ms - Months::new(3), ms - Days::new(1), None).ok(); + let now = profit_and_loss_for_period(&b.ledger, ms, b.today, None).ok(); + let mut rows: BTreeMap = BTreeMap::new(); + let mut add = |s: &Option, slot: usize| { + for l in s.iter().flat_map(|s| &s.expenses) { + let e = rows.entry(l.code.clone()).or_insert(( + l.name.clone(), + Decimal::ZERO, + Decimal::ZERO, + Decimal::ZERO, + )); + match slot { + 0 => e.1 = l.amount, + 1 => e.2 = l.amount, + _ => e.3 = l.amount / Decimal::from(3), + } + } + }; + add(&now, 0); + add(&prev, 1); + add(&three, 2); + let mut rows: Vec<_> = rows.into_iter().collect(); + rows.sort_by_key(|r| std::cmp::Reverse(r.1.3.max(r.1.1))); + let mut go = None; + widgets::titled_card( + ui, + "Spending by category", + |ui| { + ui.label( + RichText::new("this month so far vs. the last three months") + .font(theme::regular(12.0)) + .color(p.muted), + ); + }, + |ui| { + if rows.is_empty() { + widgets::empty(ui, icon::RECEIPT, "No spending yet", ""); + return; + } + let w = ui.available_width(); + let cw = 130.0; + let (r, _) = ui.allocate_exact_size(vec2(w, 24.0), Sense::hover()); + for (i, c) in ["This month", "Last month", "3-month avg"] + .iter() + .enumerate() + { + ui.painter().text( + egui::pos2(r.right() - cw * (2 - i) as f32 - 4.0, r.center().y), + egui::Align2::RIGHT_CENTER, + *c, + theme::semibold(12.0), + p.muted, + ); + } + ui.painter().text( + r.left_center() + vec2(4.0, 0.0), + egui::Align2::LEFT_CENTER, + "Account", + theme::semibold(12.0), + p.muted, + ); + for (code, (name, now, last, avg)) in &rows { + let (r, resp) = ui.allocate_exact_size(vec2(w, 28.0), Sense::click()); + if resp.hovered() { + ui.painter().rect_filled(r, CornerRadius::same(4), p.hover); + } + ui.painter().text( + r.left_center() + vec2(4.0, 0.0), + egui::Align2::LEFT_CENTER, + format!("{code} {name}"), + theme::regular(13.0), + p.text, + ); + // Flag a category already running well above its average. + let hot = *avg > Decimal::ZERO && *now > *avg * Decimal::new(125, 2); + let vals = [(*now, hot), (*last, false), (*avg, false)]; + for (i, (v, flag)) in vals.iter().enumerate() { + let x = r.right() - cw * (2 - i) as f32 - 4.0; + ui.painter().text( + egui::pos2(x, r.center().y), + egui::Align2::RIGHT_CENTER, + fmt::money(v.round_dp(2)), + theme::regular(13.0), + if *flag { p.warning } else { p.text }, + ); + if *flag { + ui.painter().text( + egui::pos2(x - 86.0, r.center().y), + egui::Align2::RIGHT_CENTER, + icon::ARROW_UP_RIGHT, + egui::FontId::proportional(13.0), + p.warning, + ); + } + } + if resp.clicked() { + go = b.ledger.chart().find_by_code(code).map(|a| a.id); + } + } + }, + ); + if let Some(id) = go { + shell.state.accounts.range = Some((ms - Months::new(3), b.today)); + shell.go(Route::Account(id)); + } + ui.add_space(16.0); +} + +fn by_customer(ui: &mut Ui, b: &Books) { + let p = pal(ui.ctx()); + let (ys, ye) = b.fiscal_ytd(); + let mut by: BTreeMap = BTreeMap::new(); + for id in 1..b.ledger.next_invoice_id() { + if let Some(inv) = b.ledger.get_invoice(id) + && inv.date >= ys + && inv.date <= ye + { + let who = b + .ledger + .get_customer(inv.customer_id) + .map(|c| c.name.clone()) + .unwrap_or_default(); + *by.entry(who).or_default() += inv.total(); + } + } + let mut rows: Vec<(String, Decimal)> = by.into_iter().collect(); + rows.sort_by_key(|r| std::cmp::Reverse(r.1)); + widgets::titled_card( + ui, + "Invoiced by customer, this year", + |_| {}, + |ui| { + if rows.is_empty() { + widgets::empty( + ui, + icon::USERS, + "No invoices this year", + "Income recorded without invoices doesn't show a customer.", + ); + return; + } + let total: Decimal = rows.iter().map(|r| r.1).sum(); + if let Some((top, v)) = rows.first() { + ui.label( + RichText::new(format!( + "{top} is {}% of invoiced income.", + pct(*v, total).unwrap_or_default() + )) + .font(theme::regular(12.5)) + .color(p.muted), + ); + ui.add_space(4.0); + } + charts::hbars(ui, &rows, p.series[1]); + }, + ); +} + +fn by_class(ui: &mut Ui, b: &Books) { + let p = pal(ui.ctx()); + let (ys, ye) = b.fiscal_ytd(); + let classes = b.ledger.list_classes(); + widgets::titled_card( + ui, + "Net income by class, this year", + |_| {}, + |ui| { + if classes.is_empty() { + widgets::empty( + ui, + icon::TAG, + "No classes", + "Tag lines with classes (departments, products) to see profit by each.", + ); + return; + } + let mut rows: Vec<(String, Decimal)> = classes + .iter() + .filter_map(|c| { + let pl = profit_and_loss_for_period(&b.ledger, ys, ye, Some(c.id)).ok()?; + let net = pl.total_revenue - pl.total_expenses; + (!pl.total_revenue.is_zero() || !pl.total_expenses.is_zero()) + .then(|| (c.name.clone(), net)) + }) + .collect(); + rows.sort_by_key(|r| std::cmp::Reverse(r.1)); + if rows.is_empty() { + widgets::empty( + ui, + icon::TAG, + "No classified income or spending this year", + "", + ); + return; + } + charts::hbars(ui, &rows, p.series[0]); + ui.label( + RichText::new("Only lines tagged with a class count here.") + .font(theme::regular(12.0)) + .color(p.faint), + ); + }, + ); +} diff --git a/crates/ledger-gui/src/pages/reports.rs b/crates/ledger-gui/src/pages/reports.rs new file mode 100644 index 0000000..252e7f0 --- /dev/null +++ b/crates/ledger-gui/src/pages/reports.rs @@ -0,0 +1,1526 @@ +//! Financial statements and the accountant's reports, over any range, +//! split into months, quarters, or years, compared with a prior period. +//! Every amount drills down to the account's transactions for exactly the +//! dates behind it. Statements come from `ledger-core`; this module lays +//! them out. + +use crate::app::Shell; +use crate::books::Books; +use crate::fmt; +use crate::nav::{ReportKind, Route}; +use crate::theme::{self, pal}; +use crate::widgets; +use chrono::{Datelike, Days, Months, NaiveDate}; +use egui::{CornerRadius, RichText, Sense, Stroke, Ui, vec2}; +use egui_phosphor::regular as icon; +use ledger_core::analysis::{Interval, intervals}; +use ledger_core::reports::{ + CashFlowParams, balance_sheet_as_of, cash_flow, general_ledger, members_equity, + profit_and_loss_for_period, trial_balance_as_of, +}; +use ledger_core::{AccountId, AccountType, MemberCapital, tax_summary, vendor_1099_report}; +use rust_decimal::Decimal; +use std::collections::BTreeMap; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum Range { + ThisMonth, + LastMonth, + ThisQuarter, + #[default] + YearToDate, + LastYear, + Last12Months, + AllTime, + Custom(NaiveDate, NaiveDate), +} + +impl Range { + pub fn dates(self, b: &Books) -> (NaiveDate, NaiveDate) { + let t = b.today; + let ms = b.month_start(); + match self { + Range::ThisMonth => (ms, t), + Range::LastMonth => (ms - Months::new(1), ms - Days::new(1)), + Range::ThisQuarter => ( + ledger_core::analysis::interval_start(t, Interval::Quarter), + t, + ), + Range::YearToDate => b.fiscal_ytd(), + Range::LastYear => { + let (s, _) = b.fiscal_ytd(); + (s - Months::new(12), s - Days::new(1)) + } + Range::Last12Months => (ms - Months::new(11), t), + Range::AllTime => (b.kpis.first_entry.unwrap_or(t).min(t), t), + Range::Custom(s, e) => (s, e), + } + } + + fn label(self) -> &'static str { + match self { + Range::ThisMonth => "This month", + Range::LastMonth => "Last month", + Range::ThisQuarter => "This quarter", + Range::YearToDate => "Year to date", + Range::LastYear => "Last year", + Range::Last12Months => "Last 12 months", + Range::AllTime => "All time", + Range::Custom(..) => "Custom", + } + } + + const PRESETS: [Range; 7] = [ + Range::ThisMonth, + Range::LastMonth, + Range::ThisQuarter, + Range::YearToDate, + Range::LastYear, + Range::Last12Months, + Range::AllTime, + ]; +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum Columns { + #[default] + Total, + Month, + Quarter, + Year, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum Compare { + #[default] + None, + PriorPeriod, + PriorYear, +} + +#[derive(Default)] +pub struct State { + pub range: Range, + pub columns: Columns, + pub compare: Compare, +} + +// ---------------------------------------------------------------------- +// The table model every statement renders through. + +#[derive(Clone, Copy, PartialEq, Eq)] +enum Kind { + Section, + Line, + Subtotal, + Grand, + Note, +} + +#[derive(Clone, Copy)] +struct Drill { + account: AccountId, + start: NaiveDate, + end: NaiveDate, +} + +#[derive(Clone)] +struct Cell { + value: Option, + drill: Option, +} + +impl Cell { + fn none() -> Self { + Cell { + value: None, + drill: None, + } + } + fn of(v: Decimal) -> Self { + Cell { + value: Some(v), + drill: None, + } + } +} + +struct Row { + kind: Kind, + label: String, + detail: String, + cells: Vec, +} + +struct Table { + columns: Vec, + rows: Vec, + /// Format cells as percentages from this column index on. + pct_from: Option, +} + +impl Table { + fn new(columns: Vec) -> Self { + Table { + columns, + rows: Vec::new(), + pct_from: None, + } + } + fn section(&mut self, label: &str) { + self.rows.push(Row { + kind: Kind::Section, + label: label.into(), + detail: String::new(), + cells: Vec::new(), + }); + } + fn row(&mut self, kind: Kind, label: impl Into, cells: Vec) { + self.rows.push(Row { + kind, + label: label.into(), + detail: String::new(), + cells, + }); + } + fn note(&mut self, text: impl Into) { + self.rows.push(Row { + kind: Kind::Note, + label: text.into(), + detail: String::new(), + cells: Vec::new(), + }); + } + + /// Add "Change" and "%" columns comparing column 0 to column 1. + fn add_change(&mut self) { + self.columns.push("Change".into()); + self.columns.push("%".into()); + self.pct_from = Some(self.columns.len() - 1); + for r in &mut self.rows { + if r.cells.len() < 2 { + continue; + } + let (a, b) = (r.cells[0].value, r.cells[1].value); + let diff = match (a, b) { + (Some(a), Some(b)) => Some(a - b), + (Some(a), None) => Some(a), + (None, Some(b)) => Some(-b), + _ => None, + }; + let pct = match (diff, b) { + (Some(d), Some(b)) if !b.is_zero() => { + Some((d / b.abs() * Decimal::from(100)).round_dp(1)) + } + _ => None, + }; + r.cells.push(Cell { + value: diff, + drill: None, + }); + r.cells.push(Cell { + value: pct, + drill: None, + }); + } + } + + /// Add a "% of income" column: each line as a share of total income. + fn add_share_of_income(&mut self) { + let income = self + .rows + .iter() + .find(|r| r.kind == Kind::Subtotal && r.label == "Total income") + .and_then(|r| r.cells.first()) + .and_then(|c| c.value) + .unwrap_or_default(); + if income.is_zero() { + return; + } + self.columns.push("% of income".into()); + self.pct_from = Some(self.columns.len() - 1); + for r in &mut self.rows { + if let Some(v) = r.cells.first().and_then(|c| c.value) { + r.cells + .push(Cell::of((v / income * Decimal::from(100)).round_dp(1))); + } + } + } + + fn tsv(&self) -> String { + let mut out = String::from("\t"); + out.push_str(&self.columns.join("\t")); + out.push('\n'); + for r in &self.rows { + out.push_str(&r.label); + for c in &r.cells { + out.push('\t'); + if let Some(v) = c.value { + out.push_str(&v.round_dp(2).to_string()); + } + } + out.push('\n'); + } + out + } +} + +fn col_title(s: NaiveDate, e: NaiveDate, columns: Columns) -> String { + match columns { + Columns::Month => s.format("%b %Y").to_string(), + Columns::Quarter => format!("Q{} {}", (s.month() - 1) / 3 + 1, s.year()), + Columns::Year => s.year().to_string(), + Columns::Total => { + if s.year() == e.year() { + format!("{} – {}", fmt::date_short(s), fmt::date_short(e)) + } else { + format!("{} – {}", fmt::month(s), fmt::month(e)) + } + } + } +} + +/// The column ranges for a range and split (with the prior period second +/// when comparing a single column). +fn column_ranges(st: &State, b: &Books) -> Vec<(NaiveDate, NaiveDate, String)> { + let (s, e) = st.range.dates(b); + let split = match st.columns { + Columns::Total => None, + Columns::Month => Some(Interval::Month), + Columns::Quarter => Some(Interval::Quarter), + Columns::Year => Some(Interval::Year), + }; + match split { + None => { + let mut v = vec![(s, e, col_title(s, e, Columns::Total))]; + if let Some((ps, pe)) = prior(st, s, e) { + v.push((ps, pe, col_title(ps, pe, Columns::Total))); + } + v + } + Some(i) => intervals(s, e, i) + .into_iter() + .map(|(a, z)| (a, z, col_title(a, z, st.columns))) + .collect(), + } +} + +fn prior(st: &State, s: NaiveDate, e: NaiveDate) -> Option<(NaiveDate, NaiveDate)> { + match st.compare { + Compare::None => None, + Compare::PriorYear => Some((s - Months::new(12), e - Months::new(12))), + Compare::PriorPeriod => { + let days = (e - s).num_days() + 1; + let pe = s - Days::new(1); + Some((pe - Days::new(days as u64 - 1), pe)) + } + } +} + +type Cols = [(NaiveDate, NaiveDate, String)]; + +fn to_jiff(d: NaiveDate) -> jiff::civil::Date { + jiff::civil::Date::new(d.year() as i16, d.month() as i8, d.day() as i8).expect("valid date") +} + +fn from_jiff(d: jiff::civil::Date) -> NaiveDate { + NaiveDate::from_ymd_opt(i32::from(d.year()), d.month() as u32, d.day() as u32) + .expect("valid date") +} + +// ---------------------------------------------------------------------- +// Builders. + +fn pnl(b: &Books, cols: &Cols, total: bool) -> Table { + let mut cols = cols.to_vec(); + if total && cols.len() > 1 { + cols.push((cols[0].0, cols[cols.len() - 1].1, "Total".into())); + } + let stmts: Vec<_> = cols + .iter() + .map(|(s, e, _)| profit_and_loss_for_period(&b.ledger, *s, *e, None).ok()) + .collect(); + let mut t = Table::new(cols.iter().map(|c| c.2.clone()).collect()); + let section = |t: &mut Table, + title: &str, + pick: &dyn Fn( + &ledger_core::ProfitAndLossStatement, + ) -> &Vec, + total_label: &str| { + let mut accounts: BTreeMap = BTreeMap::new(); + for s in stmts.iter().flatten() { + for l in pick(s) { + accounts.insert(l.code.clone(), l.name.clone()); + } + } + t.section(title); + let mut totals = vec![Decimal::ZERO; cols.len()]; + for (code, name) in &accounts { + let id = b.ledger.chart().find_by_code(code).map(|a| a.id); + let cells = cols + .iter() + .zip(&stmts) + .enumerate() + .map(|(i, ((s, e, _), st))| { + let v = st + .as_ref() + .and_then(|st| pick(st).iter().find(|l| &l.code == code)) + .map(|l| l.amount) + .unwrap_or_default(); + totals[i] += v; + Cell { + value: Some(v), + drill: id.map(|account| Drill { + account, + start: *s, + end: *e, + }), + } + }) + .collect(); + t.row(Kind::Line, format!("{code} {name}"), cells); + } + t.row( + Kind::Subtotal, + total_label, + totals.iter().map(|v| Cell::of(*v)).collect(), + ); + totals + }; + let rev = section(&mut t, "Income", &|s| &s.revenue, "Total income"); + let exp = section(&mut t, "Expenses", &|s| &s.expenses, "Total expenses"); + t.row( + Kind::Grand, + "Net income", + rev.iter().zip(&exp).map(|(r, e)| Cell::of(r - e)).collect(), + ); + t +} + +fn balance_sheet(b: &Books, dates: &[(NaiveDate, String)]) -> Table { + let stmts: Vec<_> = dates + .iter() + .map(|(d, _)| balance_sheet_as_of(&b.ledger, *d).ok()) + .collect(); + let start = b.kpis.first_entry.unwrap_or(b.today); + let mut t = Table::new(dates.iter().map(|d| d.1.clone()).collect()); + let section = |t: &mut Table, + title: &str, + pick: &dyn Fn( + &ledger_core::BalanceSheetStatement, + ) -> &Vec| { + let mut accounts: BTreeMap = BTreeMap::new(); + for s in stmts.iter().flatten() { + for l in pick(s) { + accounts.insert(l.code.clone(), l.name.clone()); + } + } + t.section(title); + for (code, name) in &accounts { + let id = b.ledger.chart().find_by_code(code).map(|a| a.id); + let cells = dates + .iter() + .zip(&stmts) + .map(|((d, _), st)| Cell { + value: Some( + st.as_ref() + .and_then(|st| pick(st).iter().find(|l| &l.code == code)) + .map(|l| l.amount) + .unwrap_or_default(), + ), + drill: id.map(|account| Drill { + account, + start: start.min(*d), + end: *d, + }), + }) + .collect(); + t.row(Kind::Line, format!("{code} {name}"), cells); + } + }; + let total = |f: &dyn Fn(&ledger_core::BalanceSheetStatement) -> Decimal| -> Vec { + stmts + .iter() + .map(|s| Cell { + value: s.as_ref().map(f), + drill: None, + }) + .collect() + }; + section(&mut t, "Assets", &|s| &s.assets); + t.row(Kind::Subtotal, "Total assets", total(&|s| s.total_assets)); + section(&mut t, "Liabilities", &|s| &s.liabilities); + t.row( + Kind::Subtotal, + "Total liabilities", + total(&|s| s.total_liabilities), + ); + section(&mut t, "Equity", &|s| &s.equity); + t.row( + Kind::Line, + "Net income not yet closed", + total(&|s| s.current_earnings), + ); + t.row(Kind::Subtotal, "Total equity", total(&|s| s.total_equity)); + t.row( + Kind::Grand, + "Total liabilities and equity", + total(&|s| s.total_liabilities + s.total_equity), + ); + if stmts + .iter() + .flatten() + .all(|s| s.total_assets == s.total_liabilities + s.total_equity) + { + t.note(format!( + "{} Assets equal liabilities plus equity in every column.", + icon::CHECK + )); + } + t +} + +fn financing_accounts(b: &Books) -> Vec { + b.ledger + .chart() + .all() + .filter(|a| { + let n = a.name.to_lowercase(); + a.account_type == AccountType::Liability + && (n.contains("loan") + || n.contains("note payable") + || n.contains("line of credit")) + }) + .map(|a| a.id) + .collect() +} + +fn cash_flow_table(b: &Books, cols: &Cols, total: bool) -> Table { + let mut cols = cols.to_vec(); + if total && cols.len() > 1 { + cols.push((cols[0].0, cols[cols.len() - 1].1, "Total".into())); + } + let fin = financing_accounts(b); + let stmts: Vec<_> = cols + .iter() + .map(|(s, e, _)| { + cash_flow( + &b.ledger, + &CashFlowParams { + start: *s, + end: *e, + cash_accounts: b.cash_accounts.clone(), + financing_accounts: fin.clone(), + }, + ) + .ok() + }) + .collect(); + let mut t = Table::new(cols.iter().map(|c| c.2.clone()).collect()); + let val = |f: &dyn Fn(&ledger_core::CashFlowStatement) -> Decimal| -> Vec { + stmts + .iter() + .map(|s| Cell { + value: s.as_ref().map(f), + drill: None, + }) + .collect() + }; + let lines = |t: &mut Table, + pick: &dyn Fn( + &ledger_core::CashFlowStatement, + ) -> &Vec| { + let mut labels: Vec<(String, Option)> = Vec::new(); + for s in stmts.iter().flatten() { + for l in pick(s) { + if !labels.iter().any(|(x, _)| x == &l.label) { + labels.push((l.label.clone(), l.account.clone())); + } + } + } + for (label, account) in labels { + let id = account + .as_deref() + .and_then(|c| b.ledger.chart().find_by_code(c)) + .map(|a| a.id); + let cells = cols + .iter() + .zip(&stmts) + .map(|((s, e, _), st)| Cell { + value: Some( + st.as_ref() + .and_then(|st| pick(st).iter().find(|l| l.label == label)) + .map(|l| l.amount) + .unwrap_or_default(), + ), + drill: id.map(|account| Drill { + account, + start: *s, + end: *e, + }), + }) + .collect(); + t.row(Kind::Line, label, cells); + } + }; + t.section("Operating activities"); + t.row(Kind::Line, "Net income", val(&|s| s.net_income)); + t.row( + Kind::Line, + "Depreciation (non-cash)", + val(&|s| s.depreciation), + ); + lines(&mut t, &|s| &s.working_capital); + t.row( + Kind::Subtotal, + "Cash from operations", + val(&|s| s.cash_from_operations), + ); + t.section("Investing activities"); + lines(&mut t, &|s| &s.investing); + t.row( + Kind::Subtotal, + "Cash from investing", + val(&|s| s.cash_from_investing), + ); + t.section("Financing activities"); + lines(&mut t, &|s| &s.financing); + t.row( + Kind::Subtotal, + "Cash from financing", + val(&|s| s.cash_from_financing), + ); + t.row( + Kind::Grand, + "Net change in cash", + val(&|s| s.net_change_in_cash), + ); + t.row(Kind::Line, "Cash at beginning", val(&|s| s.cash_beginning)); + t.row(Kind::Line, "Cash at end", val(&|s| s.cash_ending)); + let names: Vec = b + .cash_accounts + .iter() + .map(|a| b.account_label(*a)) + .collect(); + t.note(format!("Cash accounts: {}.", names.join(", "))); + t +} + +fn trial_balance(b: &Books, as_of: NaiveDate) -> Table { + let tb = trial_balance_as_of(&b.ledger, as_of); + let start = b.kpis.first_entry.unwrap_or(as_of).min(as_of); + let mut t = Table::new(vec!["Debit".into(), "Credit".into()]); + for l in &tb.lines { + let id = b.ledger.chart().find_by_code(&l.code).map(|a| a.id); + let d = id.map(|account| Drill { + account, + start, + end: as_of, + }); + let cell = |v: Decimal| Cell { + value: (!v.is_zero()).then_some(v), + drill: d, + }; + t.row( + Kind::Line, + format!("{} {}", l.code, l.name), + vec![cell(l.debit), cell(l.credit)], + ); + } + t.row( + Kind::Grand, + "Total", + vec![Cell::of(tb.total_debits), Cell::of(tb.total_credits)], + ); + if tb.total_debits == tb.total_credits { + t.note(format!("{} Debits equal credits.", icon::CHECK)); + } + t +} + +fn owners_equity(b: &Books, s: NaiveDate, e: NaiveDate) -> Table { + let company = &b.settings.company; + let members: Vec = company + .members + .iter() + .filter_map(|m| { + Some(MemberCapital { + name: m.name.clone(), + capital_account: b.ledger.chart().find_by_code(&m.capital_account)?.id, + distribution_account: m + .distribution_account + .as_deref() + .and_then(|c| b.ledger.chart().find_by_code(c)) + .map(|a| a.id), + share: m.share, + }) + }) + .collect(); + if !members.is_empty() + && let Ok(me) = members_equity(&b.ledger, s, e, &members) + { + let mut cols: Vec = me.members.iter().map(|m| m.name.clone()).collect(); + cols.push("Total".into()); + let mut t = Table::new(cols); + let all: Vec<&ledger_core::MemberEquityColumn> = me + .members + .iter() + .chain(std::iter::once(&me.total)) + .collect(); + let row = |t: &mut Table, + kind, + label: &str, + f: &dyn Fn(&ledger_core::MemberEquityColumn) -> Decimal| { + t.row(kind, label, all.iter().map(|m| Cell::of(f(m))).collect()); + }; + row( + &mut t, + Kind::Line, + &format!("Balance, {}", fmt::date(s - Days::new(1))), + &|m| m.beginning, + ); + row(&mut t, Kind::Line, "Contributions", &|m| m.contributions); + row(&mut t, Kind::Line, "Share of net income", &|m| m.net_income); + row(&mut t, Kind::Line, "Distributions", &|m| -m.distributions); + row(&mut t, Kind::Line, "Other", &|m| m.other); + row( + &mut t, + Kind::Grand, + &format!("Balance, {}", fmt::date(e)), + &|m| m.ending, + ); + let shares: Vec = members + .iter() + .map(|m| format!("{} {}%", m.name, (m.share * Decimal::from(100)).normalize())) + .collect(); + t.note(format!("Ownership: {}.", shares.join(", "))); + return t; + } + // Single owner or a corporation: every equity account's movement. + let mut t = Table::new(vec!["Beginning".into(), "Change".into(), "Ending".into()]); + let eq: Vec = + ledger_core::analysis::accounts_of_type(&b.ledger, &[AccountType::Equity]); + let (mut tb, mut te) = (Decimal::ZERO, Decimal::ZERO); + for a in eq { + let begin = b.balance_on(a, s - Days::new(1)); + let end = b.balance_on(a, e); + tb += begin; + te += end; + let d = Some(Drill { + account: a, + start: s, + end: e, + }); + t.row( + Kind::Line, + b.account_label(a), + vec![ + Cell::of(begin), + Cell { + value: Some(end - begin), + drill: d, + }, + Cell::of(end), + ], + ); + } + let ni_begin = balance_sheet_as_of(&b.ledger, s - Days::new(1)) + .map(|bs| bs.current_earnings) + .unwrap_or_default(); + let ni_end = balance_sheet_as_of(&b.ledger, e) + .map(|bs| bs.current_earnings) + .unwrap_or_default(); + t.row( + Kind::Line, + "Net income not yet closed", + vec![ + Cell::of(ni_begin), + Cell::of(ni_end - ni_begin), + Cell::of(ni_end), + ], + ); + t.row( + Kind::Grand, + "Total equity", + vec![ + Cell::of(tb + ni_begin), + Cell::of(te + ni_end - tb - ni_begin), + Cell::of(te + ni_end), + ], + ); + t +} + +fn tax(b: &Books, s: NaiveDate, e: NaiveDate) -> Table { + let mut t = Table::new(vec!["Book".into(), "Tax".into()]); + let Ok(ts) = tax_summary(&b.ledger, s, e, b.settings.company.tax_form) else { + return t; + }; + let sec = |t: &mut Table, title: &str, lines: &[ledger_core::TaxSummaryLine]| { + if lines.is_empty() { + return; + } + t.section(title); + for l in lines { + t.rows.push(Row { + kind: Kind::Line, + label: l.label.clone(), + detail: l.accounts.join(", "), + cells: vec![Cell::of(l.book), Cell::of(l.tax)], + }); + } + }; + sec(&mut t, "Income", &ts.income); + sec(&mut t, "Cost of goods sold", &ts.cost_of_goods); + sec(&mut t, "Deductions", &ts.deductions); + t.row( + Kind::Grand, + "Net", + vec![Cell::of(ts.book_net()), Cell::of(ts.tax_net())], + ); + if !ts.uncategorized.is_empty() { + t.section("Not categorized"); + for u in &ts.uncategorized { + let id = u + .account + .split_whitespace() + .next() + .and_then(|c| b.ledger.chart().find_by_code(c)) + .map(|a| a.id); + t.row( + Kind::Line, + &u.account, + vec![ + Cell { + value: Some(u.book), + drill: id.map(|account| Drill { + account, + start: s, + end: e, + }), + }, + Cell::none(), + ], + ); + } + } + let form = ts.form.map(fmt::tax_form).unwrap_or("not set"); + t.note(format!("Return: {form}. Deductible percentages applied (meals 50%, penalties 0%). A worksheet for the CPA, not a filing.")); + t +} + +fn aging(rows: Vec, as_of: NaiveDate) -> Table { + let mut t = Table::new(vec![ + "Current".into(), + "1–30".into(), + "31–60".into(), + "61–90".into(), + "Over 90".into(), + "Total".into(), + ]); + let mut tot = [Decimal::ZERO; 6]; + for r in &rows { + let v = [ + r.current, + r.days_30, + r.days_60, + r.days_90, + r.days_90_plus, + r.total(), + ]; + for (i, x) in v.iter().enumerate() { + tot[i] += x; + } + t.row( + Kind::Line, + &r.name, + v.iter() + .map(|x| Cell { + value: (!x.is_zero()).then_some(*x), + drill: None, + }) + .collect(), + ); + } + t.row( + Kind::Grand, + "Total", + tot.iter().map(|x| Cell::of(*x)).collect(), + ); + t.note(format!("Days past due as of {}.", fmt::date(as_of))); + t +} + +// ---------------------------------------------------------------------- +// The page. + +pub fn show(ui: &mut Ui, b: &Books, kind: ReportKind, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let rect = ui.available_rect_before_wrap(); + let nav_w = 210.0; + let nav_rect = egui::Rect::from_min_size(rect.min, vec2(nav_w, rect.height())); + ui.painter().line_segment( + [nav_rect.right_top(), nav_rect.right_bottom()], + Stroke::new(1.0, p.border), + ); + let mut nav = ui.new_child(egui::UiBuilder::new().max_rect(nav_rect.shrink2(vec2(12.0, 24.0)))); + nav.label( + RichText::new("REPORTS") + .font(theme::semibold(11.5)) + .color(p.faint), + ); + nav.add_space(4.0); + let groups: [(&str, &[ReportKind]); 3] = [ + ( + "Statements", + &[ + ReportKind::ProfitAndLoss, + ReportKind::BalanceSheet, + ReportKind::CashFlow, + ReportKind::MembersEquity, + ], + ), + ( + "Ledgers", + &[ReportKind::TrialBalance, ReportKind::GeneralLedger], + ), + ( + "Tax and aging", + &[ + ReportKind::TaxSummary, + ReportKind::Vendor1099, + ReportKind::ArAging, + ReportKind::ApAging, + ], + ), + ]; + for (g, kinds) in groups { + nav.add_space(10.0); + nav.label(RichText::new(g).font(theme::regular(12.0)).color(p.muted)); + nav.add_space(2.0); + for k in kinds { + let on = *k == kind; + let (r, resp) = nav.allocate_exact_size(vec2(nav_w - 24.0, 30.0), Sense::click()); + if on { + nav.painter() + .rect_filled(r, CornerRadius::same(7), p.surface); + nav.painter().rect_stroke( + r, + CornerRadius::same(7), + Stroke::new(1.0, p.border), + egui::StrokeKind::Inside, + ); + } else if resp.hovered() { + nav.painter().rect_filled(r, CornerRadius::same(7), p.hover); + } + nav.painter().text( + r.left_center() + vec2(10.0, 0.0), + egui::Align2::LEFT_CENTER, + k.title(), + if on { + theme::semibold(13.0) + } else { + theme::regular(13.0) + }, + if on { p.text } else { p.muted }, + ); + if resp.clicked() { + shell.go(Route::Reports(*k)); + } + } + } + let body = egui::Rect::from_min_max(egui::pos2(nav_rect.right() + 1.0, rect.top()), rect.max); + let mut child = ui.new_child(egui::UiBuilder::new().max_rect(body)); + child.set_clip_rect(body); + super::page(&mut child, "report", |ui| report(ui, b, kind, shell)); + ui.allocate_rect(rect, Sense::hover()); +} + +fn report(ui: &mut Ui, b: &Books, kind: ReportKind, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let point_in_time = matches!( + kind, + ReportKind::TrialBalance | ReportKind::ArAging | ReportKind::ApAging + ) || (kind == ReportKind::BalanceSheet + && shell.state.reports.columns == Columns::Total); + let splittable = matches!( + kind, + ReportKind::ProfitAndLoss | ReportKind::BalanceSheet | ReportKind::CashFlow + ); + let comparable = matches!( + kind, + ReportKind::ProfitAndLoss + | ReportKind::BalanceSheet + | ReportKind::CashFlow + | ReportKind::TaxSummary + ); + let st = &mut shell.state.reports; + + // Controls. + ui.horizontal_wrapped(|ui| { + egui::ComboBox::from_id_salt("range") + .selected_text(RichText::new(format!( + "{} {}", + icon::CALENDAR_BLANK, + st.range.label() + ))) + .width(170.0) + .show_ui(ui, |ui| { + for r in Range::PRESETS { + ui.selectable_value(&mut st.range, r, r.label()); + } + let (s, e) = st.range.dates(b); + if ui + .selectable_label(matches!(st.range, Range::Custom(..)), "Custom…") + .clicked() + { + st.range = Range::Custom(s, e); + } + }); + if let Range::Custom(s, e) = st.range { + let (mut js, mut je) = (to_jiff(s), to_jiff(e)); + ui.add( + egui_extras::DatePickerButton::new(&mut js) + .id_salt("from") + .calendar_week(false), + ); + ui.label(RichText::new("to").color(p.muted)); + ui.add( + egui_extras::DatePickerButton::new(&mut je) + .id_salt("to") + .calendar_week(false), + ); + let (s, e) = (from_jiff(js), from_jiff(je)); + st.range = Range::Custom(s.min(e), e.max(s)); + } + if splittable { + ui.add_space(8.0); + widgets::segmented( + ui, + &mut st.columns, + &[ + (Columns::Total, "Total"), + (Columns::Month, "Months"), + (Columns::Quarter, "Quarters"), + (Columns::Year, "Years"), + ], + ); + } + if comparable && (st.columns == Columns::Total || !splittable) { + ui.add_space(8.0); + egui::ComboBox::from_id_salt("compare") + .selected_text(match st.compare { + Compare::None => "No comparison", + Compare::PriorPeriod => "vs prior period", + Compare::PriorYear => "vs prior year", + }) + .show_ui(ui, |ui| { + ui.selectable_value(&mut st.compare, Compare::None, "No comparison"); + ui.selectable_value(&mut st.compare, Compare::PriorPeriod, "vs prior period"); + ui.selectable_value(&mut st.compare, Compare::PriorYear, "vs prior year"); + }); + } + }); + ui.add_space(18.0); + + let (s, e) = st.range.dates(b); + let state = State { + range: st.range, + columns: if splittable { + st.columns + } else { + Columns::Total + }, + compare: if comparable && (st.columns == Columns::Total || !splittable) { + st.compare + } else { + Compare::None + }, + }; + let cols = column_ranges(&state, b); + let compare = state.compare != Compare::None; + let subtitle = if point_in_time { + format!("As of {}", fmt::date(e)) + } else { + format!("{} – {}", fmt::date(s), fmt::date(e)) + }; + + ui.label(RichText::new(kind.title()).font(theme::bold(26.0))); + ui.label( + RichText::new(format!( + "{} · {} · {} basis", + b.company_name(), + subtitle, + b.settings.company.basis + )) + .font(theme::regular(14.0)) + .color(p.muted), + ); + ui.add_space(14.0); + + let table = match kind { + ReportKind::ProfitAndLoss => { + let mut t = pnl(b, &cols, state.columns != Columns::Total); + if compare { + t.add_change(); + } else if cols.len() == 1 { + t.add_share_of_income(); + } + Some(t) + } + ReportKind::BalanceSheet => { + let dates: Vec<(NaiveDate, String)> = if state.columns == Columns::Total { + cols.iter() + .map(|(_, e, _)| (*e, format!("As of {}", fmt::date_short(*e)))) + .collect() + } else { + cols.iter() + .map(|(_, e, title)| (*e, title.clone())) + .collect() + }; + let mut t = balance_sheet(b, &dates); + if compare { + t.add_change(); + } + Some(t) + } + ReportKind::CashFlow => { + let mut t = cash_flow_table(b, &cols, state.columns != Columns::Total); + if compare { + t.add_change(); + } + Some(t) + } + ReportKind::TrialBalance => Some(trial_balance(b, e)), + ReportKind::MembersEquity => Some(owners_equity(b, s, e)), + ReportKind::TaxSummary => { + let mut t = tax(b, s, e); + if compare && let Some((ps, pe)) = prior(&state, s, e) { + let prev = tax(b, ps, pe); + // Side by side: the tax column now and then. + let mut m = Table::new(vec![ + cols[0].2.clone(), + cols.get(1).map(|c| c.2.clone()).unwrap_or_default(), + ]); + for r in &t.rows { + let other = prev + .rows + .iter() + .find(|x| x.label == r.label && x.kind == r.kind) + .and_then(|x| x.cells.get(1)) + .cloned() + .unwrap_or(Cell::none()); + let cells = if r.cells.is_empty() { + Vec::new() + } else { + vec![r.cells.get(1).cloned().unwrap_or(Cell::none()), other] + }; + m.rows.push(Row { + kind: r.kind, + label: r.label.clone(), + detail: r.detail.clone(), + cells, + }); + } + m.add_change(); + t = m; + } + Some(t) + } + ReportKind::ArAging => Some(aging(b.ledger.ar_aging(e), e)), + ReportKind::ApAging => Some(aging(b.ledger.ap_aging(e), e)), + ReportKind::Vendor1099 => { + vendor_1099(ui, b, e.year(), shell); + None + } + ReportKind::GeneralLedger => { + gl(ui, b, s, e, shell); + None + } + }; + if let Some(t) = table { + render(ui, &t, shell); + } +} + +fn render(ui: &mut Ui, t: &Table, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let tsv = t.tsv(); + let mut go: Option = None; + widgets::card(ui, |ui| { + ui.with_layout(egui::Layout::right_to_left(egui::Align::Min), |ui| { + if ui + .add( + egui::Button::new( + RichText::new(format!("{} Copy for a spreadsheet", icon::COPY)) + .font(theme::regular(12.0)) + .color(p.muted), + ) + .frame(false), + ) + .on_hover_text("Copies the table as tab-separated values") + .clicked() + { + ui.ctx().copy_text(tsv.clone()); + } + }); + let col_w: f32 = if t.columns.len() > 6 { 112.0 } else { 136.0 }; + let cols_w = col_w * t.columns.len() as f32; + egui::ScrollArea::horizontal() + .id_salt("report_table") + .show(ui, |ui| { + // Labels get what's left, but never so much that the eye loses + // the line between a label and its amount. + let label_w = (ui.available_width() - cols_w).clamp(300.0, 480.0); + let width = label_w + cols_w; + ui.set_min_width(width); + let (hr, _) = ui.allocate_exact_size(vec2(width, 30.0), Sense::hover()); + for (i, c) in t.columns.iter().enumerate() { + let x = hr.left() + label_w + col_w * (i as f32 + 1.0) - 4.0; + ui.painter().text( + egui::pos2(x, hr.center().y), + egui::Align2::RIGHT_CENTER, + c, + theme::semibold(12.5), + p.muted, + ); + } + ui.painter().line_segment( + [hr.left_bottom(), hr.right_bottom()], + Stroke::new(1.0, p.border), + ); + for (ri, r) in t.rows.iter().enumerate() { + let h = match r.kind { + Kind::Section => 36.0, + Kind::Grand => 38.0, + Kind::Note => 32.0, + _ => { + if r.detail.is_empty() { + 27.0 + } else { + 40.0 + } + } + }; + let (rr, resp) = ui.allocate_exact_size(vec2(width, h), Sense::hover()); + if matches!(r.kind, Kind::Line) && resp.hovered() { + ui.painter().rect_filled(rr, CornerRadius::same(4), p.hover); + } + let (font, color, indent) = match r.kind { + Kind::Section => (theme::semibold(13.5), p.text, 0.0), + Kind::Line => (theme::regular(13.5), p.text, 18.0), + Kind::Subtotal => (theme::semibold(13.5), p.text, 0.0), + Kind::Grand => (theme::bold(14.5), p.text, 0.0), + Kind::Note => (theme::regular(12.0), p.muted, 0.0), + }; + let y = match r.kind { + Kind::Section => rr.bottom() - 11.0, + _ if !r.detail.is_empty() => rr.center().y - 7.0, + _ => rr.center().y, + }; + let label_g = ui + .painter() + .layout_no_wrap(r.label.clone(), font.clone(), color); + ui.painter().galley( + egui::pos2(rr.left() + indent + 4.0, y - label_g.size().y / 2.0), + label_g, + color, + ); + if !r.detail.is_empty() { + ui.painter().text( + egui::pos2(rr.left() + indent + 4.0, rr.center().y + 9.0), + egui::Align2::LEFT_CENTER, + &r.detail, + theme::regular(11.5), + p.faint, + ); + } + for (i, c) in r.cells.iter().enumerate() { + let Some(v) = c.value else { + continue; + }; + let is_pct = t.pct_from.is_some_and(|f| i >= f); + let text = if is_pct { + format!("{}%", v.normalize()) + } else { + fmt::accounting(v) + }; + let x1 = rr.left() + label_w + col_w * (i as f32 + 1.0) - 4.0; + let cell = egui::Rect::from_min_max( + egui::pos2(x1 - col_w + 8.0, rr.top()), + egui::pos2(x1, rr.bottom()), + ); + let cresp = ui.interact( + cell, + ui.id().with(("cell", ri, i)), + if c.drill.is_some() { + Sense::click() + } else { + Sense::hover() + }, + ); + let hovered = c.drill.is_some() && cresp.hovered(); + let vcolor = if hovered { p.accent } else { color }; + let vfont = if matches!(r.kind, Kind::Line) { + theme::regular(13.5) + } else { + font.clone() + }; + let g = ui.painter().layout_no_wrap(text, vfont, vcolor); + let pos = egui::pos2(x1 - g.size().x, y - g.size().y / 2.0); + if hovered { + ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); + ui.painter().line_segment( + [ + egui::pos2(pos.x, pos.y + g.size().y), + egui::pos2(x1, pos.y + g.size().y), + ], + Stroke::new(1.0, p.accent), + ); + } + ui.painter().galley(pos, g, vcolor); + let rule_x0 = x1 - col_w + 28.0; + if matches!(r.kind, Kind::Subtotal) { + ui.painter().line_segment( + [ + egui::pos2(rule_x0, rr.top() + 1.0), + egui::pos2(x1, rr.top() + 1.0), + ], + Stroke::new(1.0, p.faint), + ); + } + if matches!(r.kind, Kind::Grand) { + let painter = ui.painter(); + painter.line_segment( + [ + egui::pos2(rule_x0, rr.top() + 2.0), + egui::pos2(x1, rr.top() + 2.0), + ], + Stroke::new(1.0, p.text), + ); + let yb = rr.bottom() - 5.0; + painter.line_segment( + [egui::pos2(rule_x0, yb), egui::pos2(x1, yb)], + Stroke::new(1.0, p.text), + ); + painter.line_segment( + [egui::pos2(rule_x0, yb + 2.5), egui::pos2(x1, yb + 2.5)], + Stroke::new(1.0, p.text), + ); + } + if let Some(d) = c.drill { + let cresp = cresp.on_hover_text(format!( + "Show the transactions behind this ({} – {})", + fmt::date(d.start), + fmt::date(d.end) + )); + if cresp.clicked() { + go = Some(d); + } + } + } + } + }); + }); + if let Some(d) = go { + shell.state.accounts.range = Some((d.start, d.end)); + shell.go(Route::Account(d.account)); + } +} + +fn gl(ui: &mut Ui, b: &Books, s: NaiveDate, e: NaiveDate, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let Ok(g) = general_ledger(&b.ledger, s, e) else { + return; + }; + let mut go: Option = None; + for a in g + .accounts + .iter() + .filter(|a| !a.postings.is_empty() || !a.beginning_balance.is_zero()) + { + widgets::card(ui, |ui| { + ui.horizontal(|ui| { + let r = widgets::link( + ui, + RichText::new(format!("{} {}", a.code, a.name)).font(theme::semibold(14.0)), + ); + if r.clicked() + && let Some(acct) = b.ledger.chart().find_by_code(&a.code) + { + go = Some(Route::Account(acct.id)); + } + ui.label( + RichText::new(format!("{:?}", a.account_type)) + .font(theme::regular(12.0)) + .color(p.muted), + ); + }); + ui.add_space(6.0); + let w = ui.available_width(); + let fixed = [86.0, 52.0, 0.0, 110.0, 110.0, 120.0]; + let flex = (w - fixed.iter().sum::()).max(120.0); + let row = |ui: &mut Ui, + vals: [String; 6], + strong: bool, + color: egui::Color32| + -> egui::Response { + let (r, resp) = ui.allocate_exact_size(vec2(w, 24.0), Sense::click()); + if resp.hovered() && !strong { + ui.painter().rect_filled(r, CornerRadius::same(4), p.hover); + } + let painter = ui.painter_at(r); + let mut x = r.left(); + for (i, v) in vals.iter().enumerate() { + let cw = if i == 2 { flex } else { fixed[i] }; + let font = if strong { + theme::semibold(12.5) + } else { + theme::regular(12.5) + }; + if i >= 3 { + painter.text( + egui::pos2(x + cw - 4.0, r.center().y), + egui::Align2::RIGHT_CENTER, + v, + font, + color, + ); + } else { + let max_chars = ((cw - 8.0) / 6.8) as usize; + let shown: String = if v.chars().count() > max_chars { + v.chars() + .take(max_chars.saturating_sub(1)) + .collect::() + + "…" + } else { + v.clone() + }; + painter.text( + egui::pos2(x + 4.0, r.center().y), + egui::Align2::LEFT_CENTER, + shown, + font, + color, + ); + } + x += cw; + } + resp + }; + row( + ui, + [ + "Date".into(), + "#".into(), + "Description".into(), + "Debit".into(), + "Credit".into(), + "Balance".into(), + ], + true, + p.muted, + ); + row( + ui, + [ + String::new(), + String::new(), + "Beginning balance".into(), + String::new(), + String::new(), + fmt::accounting(a.beginning_balance), + ], + false, + p.muted, + ); + for post in &a.postings { + let r = row( + ui, + [ + fmt::date_short(post.date), + post.entry_id.to_string(), + format!("{} · {}", post.description, post.split), + if post.debit.is_zero() { + String::new() + } else { + fmt::money(post.debit) + }, + if post.credit.is_zero() { + String::new() + } else { + fmt::money(post.credit) + }, + fmt::accounting(post.balance), + ], + false, + p.text, + ); + if r.clicked() { + go = Some(Route::Entry(post.entry_id)); + } + } + row( + ui, + [ + String::new(), + String::new(), + "Totals and ending balance".into(), + fmt::money(a.total_debits), + fmt::money(a.total_credits), + fmt::accounting(a.ending_balance), + ], + true, + p.text, + ); + }); + ui.add_space(12.0); + } + if let Some(r) = go { + if let Route::Account(_) = r { + shell.state.accounts.range = Some((s, e)); + } + shell.go(r); + } +} + +fn vendor_1099(ui: &mut Ui, b: &Books, year: i32, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + let r = vendor_1099_report(&b.ledger, year, None); + ui.label( + RichText::new(format!( + "Calendar {year}. Threshold {} ($600 through 2025; $2,000 from 2026, indexed after). Counts cash paid on entries tagged with the vendor; card payments are reported by the card processor (1099-K) and drop out.", + fmt::dollars(r.threshold) + )) + .color(p.muted), + ); + ui.add_space(10.0); + let mut t = Table::new(vec!["Paid".into()]); + for v in &r.vendors { + let form = v.form.map(|f| f.label()).unwrap_or("No 1099"); + let w9 = if v.tin_on_file { + "W-9 on file" + } else { + "no W-9" + }; + let status = if v.reportable { + if v.tin_on_file { + "File a 1099" + } else { + "File a 1099 · get a W-9 first" + } + } else { + "Not reportable" + }; + t.rows.push(Row { + kind: Kind::Line, + label: v.name.clone(), + detail: format!("{form} · {w9} · {status}"), + cells: vec![Cell::of(v.paid)], + }); + } + if r.vendors.is_empty() { + t.note("No vendors marked for a 1099 and none paid this year."); + } + render(ui, &t, shell); +} diff --git a/crates/ledger-gui/src/pages/transactions.rs b/crates/ledger-gui/src/pages/transactions.rs new file mode 100644 index 0000000..eaa595b --- /dev/null +++ b/crates/ledger-gui/src/pages/transactions.rs @@ -0,0 +1,279 @@ +//! Every entry, searchable and filterable, with the selected one open +//! beside the list: its lines, its receipt rendered, its history. + +use super::page; +use crate::app::Shell; +use crate::books::{Books, EntryInfo}; +use crate::fmt; +use crate::nav::Route; +use crate::theme::{self, pal}; +use crate::widgets; +use egui::{CornerRadius, RichText, Sense, Ui, vec2}; +use egui_phosphor::regular as icon; +use ledger_core::{AccountId, EntryStatus}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum Filter { + #[default] + All, + Posted, + Drafts, + NoReceipt, + WithReceipt, +} + +#[derive(Default)] +pub struct State { + pub query: String, + pub filter: Filter, + pub account: Option, +} + +pub fn matches(e: &EntryInfo, st: &State) -> bool { + let f = match st.filter { + Filter::All => true, + Filter::Posted => e.status == EntryStatus::Posted, + Filter::Drafts => e.status == EntryStatus::Draft, + Filter::NoReceipt => e.receipts.is_empty(), + Filter::WithReceipt => !e.receipts.is_empty(), + }; + let a = st.account.is_none_or(|a| e.accounts.contains(&a)); + let q = st.query.trim().to_lowercase(); + let t = q.is_empty() || q.split_whitespace().all(|w| e.haystack.contains(w)); + f && a && t +} + +pub fn show(ui: &mut Ui, b: &Books, selected: Option, shell: &mut Shell<'_>) { + match selected.and_then(|id| b.entry(id)) { + Some(e) => { + let w = (ui.available_width() * 0.5).max(420.0); + super::split( + ui, + "transactions", + w, + shell, + |ui, shell| list(ui, b, selected, shell), + |ui, shell| super::entry::detail(ui, b, e, shell), + ); + } + None => list(ui, b, None, shell), + } +} + +fn list(ui: &mut Ui, b: &Books, selected: Option, shell: &mut Shell<'_>) { + let p = pal(ui.ctx()); + page(ui, "transactions", |ui| { + let total = b.entries.len(); + widgets::page_header( + ui, + "Transactions", + &format!( + "{} recorded, newest first. Click one to see its lines, its receipt, and its history.", + fmt::count(total, "entry", "entries") + ), + ); + let st = &mut shell.state.transactions; + let narrow = ui.available_width() < 720.0; + ui.horizontal(|ui| { + ui.add( + egui::TextEdit::singleline(&mut st.query) + .hint_text(format!( + "{} Search description, account, vendor, amount", + icon::MAGNIFYING_GLASS + )) + .desired_width(if narrow { ui.available_width() } else { 340.0 }), + ); + if !narrow { + filters(ui, b, st); + } + }); + if narrow { + ui.add_space(6.0); + ui.horizontal(|ui| filters(ui, b, st)); + } + ui.add_space(12.0); + let rows: Vec<&EntryInfo> = b.entries.iter().filter(|e| matches(e, st)).collect(); + if rows.is_empty() { + widgets::card(ui, |ui| { + widgets::empty( + ui, + icon::MAGNIFYING_GLASS, + "No matching entries", + "Try a different search or filter.", + ) + }); + return; + } + widgets::card(ui, |ui| { + let mut last_month: Option<(i32, u32)> = None; + for e in rows { + let m = ( + chrono::Datelike::year(&e.date), + chrono::Datelike::month(&e.date), + ); + if last_month != Some(m) { + if last_month.is_some() { + ui.add_space(10.0); + } + last_month = Some(m); + ui.label( + RichText::new(fmt::month(e.date)) + .font(theme::semibold(12.5)) + .color(p.muted), + ); + ui.add_space(2.0); + } + if row(ui, b, e, selected == Some(e.id), shell.since_update).clicked() { + shell.go(Route::Entry(e.id)); + } + } + }); + }); +} + +fn row(ui: &mut Ui, b: &Books, e: &EntryInfo, on: bool, since_update: f64) -> egui::Response { + let p = pal(ui.ctx()); + let (rect, resp) = ui.allocate_exact_size(vec2(ui.available_width(), 50.0), Sense::click()); + let fresh = b.fresh.contains(&e.id) && since_update < 8.0; + if on { + ui.painter() + .rect_filled(rect, CornerRadius::same(8), p.selected); + } else if fresh { + ui.painter() + .rect_filled(rect, CornerRadius::same(8), p.new_highlight); + } else if resp.hovered() { + ui.painter() + .rect_filled(rect, CornerRadius::same(8), p.hover); + } + let painter = ui.painter_at(rect); + let left = rect.left() + 10.0; + // Date block. + painter.text( + egui::pos2(left, rect.center().y - 8.0), + egui::Align2::LEFT_CENTER, + e.date.format("%b").to_string().to_uppercase(), + theme::semibold(10.5), + p.faint, + ); + painter.text( + egui::pos2(left, rect.center().y + 8.0), + egui::Align2::LEFT_CENTER, + e.date.format("%-d").to_string(), + theme::semibold(16.0), + p.text, + ); + // Description and accounts. + let text_left = left + 44.0; + let amount_w = 120.0; + let max_w = (rect.right() - amount_w - 70.0 - text_left).max(60.0); + let desc = painter.layout(e.description.clone(), theme::semibold(13.5), p.text, max_w); + let desc = if desc.rows.len() > 1 { + painter.layout_no_wrap( + truncate(&e.description, (max_w / 7.5) as usize), + theme::semibold(13.5), + p.text, + ) + } else { + desc + }; + painter.galley(egui::pos2(text_left, rect.center().y - 17.0), desc, p.text); + let accounts: Vec = e.accounts.iter().map(|a| b.account_name(*a)).collect(); + let mut sub = format!("#{} · {} · {}", e.id, e.origin, accounts.join(" → ")); + if let Some(v) = &e.party { + sub.push_str(&format!(" · {v}")); + } + let sub = truncate(&sub, (max_w / 6.3) as usize); + painter.text( + egui::pos2(text_left, rect.center().y + 10.0), + egui::Align2::LEFT_CENTER, + sub, + theme::regular(12.0), + p.muted, + ); + // Amount and badges. + let right = rect.right() - 10.0; + // Cash in reads green with a plus, cash out with a minus; entries that + // don't move cash show their size, muted. + let (amount, color) = if e.cash_effect > rust_decimal::Decimal::ZERO { + (format!("+{}", fmt::money(e.cash_effect)), p.positive) + } else if e.cash_effect < rust_decimal::Decimal::ZERO { + (fmt::money(e.cash_effect), p.text) + } else { + (fmt::money(e.amount), p.muted) + }; + painter.text( + egui::pos2(right, rect.center().y - 6.0), + egui::Align2::RIGHT_CENTER, + amount, + theme::semibold(14.0), + color, + ); + let mut badges: Vec<(&str, egui::Color32)> = Vec::new(); + if e.status == EntryStatus::Draft { + badges.push(("DRAFT", p.warning)); + } + if e.reversed_by.is_some() { + badges.push(("REVERSED", p.muted)); + } + if e.reversal_of.is_some() { + badges.push(("REVERSAL", p.muted)); + } + let mut x = right; + for (text, color) in badges { + let g = painter.layout_no_wrap(text.to_string(), theme::semibold(10.0), color); + x -= g.size().x; + painter.galley(egui::pos2(x, rect.center().y + 6.0), g, color); + x -= 8.0; + } + let clip = if !e.receipts.is_empty() { + Some((icon::PAPERCLIP, p.muted)) + } else if e.missing_receipt { + Some((icon::WARNING_CIRCLE, p.negative)) + } else { + None + }; + if let Some((g, c)) = clip { + painter.text( + egui::pos2(rect.right() - amount_w - 24.0, rect.center().y), + egui::Align2::CENTER_CENTER, + g, + egui::FontId::proportional(16.0), + c, + ); + } + resp +} + +fn truncate(s: &str, n: usize) -> String { + if s.chars().count() <= n { + s.to_string() + } else { + let t: String = s.chars().take(n.saturating_sub(1)).collect(); + format!("{t}…") + } +} + +fn filters(ui: &mut Ui, b: &Books, st: &mut State) { + widgets::segmented( + ui, + &mut st.filter, + &[ + (Filter::All, "All"), + (Filter::Posted, "Posted"), + (Filter::Drafts, "Drafts"), + (Filter::WithReceipt, "With receipt"), + (Filter::NoReceipt, "No receipt"), + ], + ); + if let Some(a) = st.account { + ui.add_space(6.0); + let label = format!("{} {} {}", icon::FUNNEL, b.account_label(a), icon::X); + if ui + .button(label) + .on_hover_text("Clear the account filter") + .clicked() + { + st.account = None; + } + } +} diff --git a/crates/ledger-gui/src/palette.rs b/crates/ledger-gui/src/palette.rs new file mode 100644 index 0000000..9a7def7 --- /dev/null +++ b/crates/ledger-gui/src/palette.rs @@ -0,0 +1,305 @@ +//! Ctrl+K: jump to anything. Pages, reports, accounts, entries (by text, +//! amount, or #id), vendors, and documents, ranked by a simple fuzzy match. + +use crate::books::Books; +use crate::fmt; +use crate::nav::{ReportKind, Route, Section}; +use crate::theme::{self, pal}; +use egui::{CornerRadius, Key, Margin, RichText, Sense, Stroke, vec2}; +use egui_phosphor::regular as icon; + +#[derive(Default)] +pub struct Palette { + open: bool, + query: String, + selected: usize, + focus: bool, +} + +struct Item { + icon: &'static str, + title: String, + detail: String, + route: Route, + score: i32, +} + +impl Palette { + pub fn open(&mut self) { + self.open = true; + self.query.clear(); + self.selected = 0; + self.focus = true; + } + + /// Show the palette if open; returns where to go. + pub fn show(&mut self, ctx: &egui::Context, books: &Books) -> Option { + if !self.open { + return None; + } + let p = pal(ctx); + let items = search(books, &self.query); + let mut go = None; + let (up, down, enter, esc) = ctx.input(|i| { + ( + i.key_pressed(Key::ArrowUp), + i.key_pressed(Key::ArrowDown), + i.key_pressed(Key::Enter), + i.key_pressed(Key::Escape), + ) + }); + if down { + self.selected = (self.selected + 1).min(items.len().saturating_sub(1)); + } + if up { + self.selected = self.selected.saturating_sub(1); + } + if esc { + self.open = false; + return None; + } + if enter && let Some(it) = items.get(self.selected) { + self.open = false; + return Some(it.route.clone()); + } + let modal = egui::Modal::new(egui::Id::new("palette")) + .frame( + egui::Frame::new() + .fill(p.surface) + .stroke(Stroke::new(1.0, p.border)) + .corner_radius(CornerRadius::same(14)) + .inner_margin(Margin::same(10)), + ) + .show(ctx, |ui| { + ui.set_width(620.0); + let edit = egui::TextEdit::singleline(&mut self.query) + .hint_text("Search entries, accounts, vendors, documents, reports…") + .font(theme::regular(16.0)) + .frame(egui::Frame::NONE) + .desired_width(f32::INFINITY); + let r = ui.add(edit); + if self.focus { + r.request_focus(); + self.focus = false; + } + if r.changed() { + self.selected = 0; + } + ui.add_space(6.0); + crate::widgets::rule(ui); + ui.add_space(4.0); + egui::ScrollArea::vertical() + .max_height(420.0) + .show(ui, |ui| { + if items.is_empty() { + ui.label(RichText::new("Nothing matches.").color(p.muted)); + } + for (i, it) in items.iter().enumerate() { + let (rect, resp) = ui.allocate_exact_size( + vec2(ui.available_width(), 40.0), + Sense::click(), + ); + if i == self.selected || resp.hovered() { + ui.painter() + .rect_filled(rect, CornerRadius::same(8), p.hover); + } + if i == self.selected { + ui.scroll_to_rect(rect, None); + } + let painter = ui.painter_at(rect); + painter.text( + rect.left_center() + vec2(12.0, 0.0), + egui::Align2::LEFT_CENTER, + it.icon, + egui::FontId::proportional(16.0), + p.muted, + ); + painter.text( + rect.left_center() + vec2(38.0, -7.0), + egui::Align2::LEFT_CENTER, + &it.title, + theme::regular(14.0), + p.text, + ); + painter.text( + rect.left_center() + vec2(38.0, 9.0), + egui::Align2::LEFT_CENTER, + &it.detail, + theme::regular(11.5), + p.faint, + ); + if resp.clicked() { + go = Some(it.route.clone()); + } + } + }); + }); + if modal.should_close() { + self.open = false; + } + if go.is_some() { + self.open = false; + } + go + } +} + +/// Subsequence match: every query character in order, rewarding +/// contiguous runs and word starts. None if no match. +fn fuzzy(hay: &str, query: &str) -> Option { + if query.is_empty() { + return Some(0); + } + let hay: Vec = hay.to_lowercase().chars().collect(); + let mut score = 0; + let mut hi = 0; + let mut prev_match = false; + for qc in query.to_lowercase().chars() { + if qc == ' ' { + prev_match = false; + continue; + } + let mut found = false; + while hi < hay.len() { + let c = hay[hi]; + hi += 1; + if c == qc { + score += if prev_match { 6 } else { 1 }; + if hi == 1 || !hay[hi - 2].is_alphanumeric() { + score += 4; + } + prev_match = true; + found = true; + break; + } + prev_match = false; + } + if !found { + return None; + } + } + Some(score) +} + +fn search(b: &Books, query: &str) -> Vec { + let q = query.trim(); + let mut out: Vec = Vec::new(); + let mut add = |icon: &'static str, title: String, detail: String, route: Route, hay: &str| { + if let Some(score) = fuzzy(hay, q) { + out.push(Item { + icon, + title, + detail, + route, + score, + }); + } + }; + for s in Section::ALL { + add( + s.icon(), + s.title().into(), + "Page".into(), + s.home(), + s.title(), + ); + } + for r in ReportKind::ALL { + add( + icon::FILE_TEXT, + r.title().into(), + "Report".into(), + Route::Reports(r), + &format!("report {}", r.title()), + ); + } + if !q.is_empty() { + for a in b.ledger.chart().all() { + add( + icon::TREE_STRUCTURE, + format!("{} {}", a.code, a.name), + format!("{:?} account", a.account_type), + Route::Account(a.id), + &format!("{} {}", a.code, a.name), + ); + } + let id_query = q.strip_prefix('#').and_then(|s| s.parse::().ok()); + for e in &b.entries { + let exact = id_query == Some(e.id); + let hay = &e.haystack; + let score = if exact { + Some(1000) + } else { + fuzzy(hay, q).filter(|_| q.len() >= 2) + }; + if let Some(score) = score { + // Prefer substring hits for entries: fuzzy over long text is noisy. + let bonus = if hay.contains(&q.to_lowercase()) { + 50 + } else { + 0 + }; + if bonus == 0 && !exact && q.len() < 4 { + continue; + } + out.push(Item { + icon: icon::RECEIPT, + title: format!("#{} {}", e.id, e.description), + detail: format!("{} · {}", fmt::date(e.date), fmt::dollars(e.amount)), + route: Route::Entry(e.id), + score: score + bonus, + }); + } + } + for v in b.ledger.list_vendors() { + if let Some(score) = fuzzy(&v.name, q) { + out.push(Item { + icon: icon::STOREFRONT, + title: v.name.clone(), + detail: "Vendor".into(), + route: Route::Company, + score, + }); + } + } + for a in &b.attachments { + let hay = format!("{} {}", a.file_name, a.description.as_deref().unwrap_or("")); + if let Some(score) = fuzzy(&hay, q) { + out.push(Item { + icon: icon::FILE, + title: a.file_name.clone(), + detail: format!( + "{} · {}", + fmt::label(&a.category), + a.description.as_deref().unwrap_or("") + ), + route: Route::Document(a.id), + score, + }); + } + } + } + out.sort_by_key(|i| std::cmp::Reverse(i.score)); + out.truncate(40); + out +} + +/// A short description of a route for the breadcrumb. +pub fn describe(b: &Books, r: &Route) -> String { + match r { + Route::Entry(id) => b + .entry(*id) + .map(|e| format!("#{} {}", e.id, e.description)) + .unwrap_or_default(), + Route::Reports(k) => k.title().into(), + Route::Account(id) => b.account_label(*id), + Route::Document(id) => b + .attachments + .iter() + .find(|a| a.id == *id) + .map(|a| a.file_name.clone()) + .unwrap_or_default(), + Route::JournalEvent(seq) => format!("Event {seq}"), + _ => String::new(), + } +} diff --git a/crates/ledger-gui/src/receipts.rs b/crates/ledger-gui/src/receipts.rs new file mode 100644 index 0000000..5597fbd --- /dev/null +++ b/crates/ledger-gui/src/receipts.rs @@ -0,0 +1,177 @@ +//! Rendering receipts and documents to textures, off the UI thread. +//! +//! PDFs are rasterized with `hayro` (pure Rust), images decoded with +//! `image`. Results are cached by blob hash: the same bytes never render +//! twice, and a hash is the content, so the cache never goes stale. Bytes +//! are read through the verifying blob store: a corrupt blob shows as an +//! error, never as a picture. + +use egui::{ColorImage, Context, TextureHandle, TextureOptions}; +use ledger_store::BlobStore; +use std::collections::HashMap; +use std::path::PathBuf; +use std::sync::mpsc::{Receiver, Sender, channel}; + +pub enum State { + Loading, + Ready(Vec), + Failed(String), +} + +struct Job { + sha: String, + mime: String, + root: PathBuf, +} + +struct Done { + sha: String, + result: Result, String>, +} + +pub struct Receipts { + cache: HashMap, + jobs: Sender, + done: Receiver, +} + +impl Receipts { + pub fn new(ctx: &Context) -> Self { + let (jobs, job_rx) = channel::(); + let (done_tx, done) = channel(); + let job_rx = std::sync::Arc::new(std::sync::Mutex::new(job_rx)); + let workers = std::thread::available_parallelism().map_or(2, |n| n.get().clamp(2, 4)); + for i in 0..workers { + let ctx = ctx.clone(); + let job_rx = job_rx.clone(); + let done_tx = done_tx.clone(); + std::thread::Builder::new() + .name(format!("receipt-render-{i}")) + .spawn(move || { + loop { + let job = match job_rx.lock() { + Ok(rx) => rx.recv(), + Err(_) => return, + }; + let Ok(job) = job else { + return; + }; + let result = render(&job); + let _ = done_tx.send(Done { + sha: job.sha, + result, + }); + ctx.request_repaint(); + } + }) + .expect("spawn renderer"); + } + Self { + cache: HashMap::new(), + jobs, + done, + } + } + + /// The rendering of a blob, starting it if needed. + pub fn get(&mut self, sha: &str, mime: &str, root: PathBuf) -> &State { + if !self.cache.contains_key(sha) { + self.cache.insert(sha.to_string(), State::Loading); + let _ = self.jobs.send(Job { + sha: sha.to_string(), + mime: mime.to_string(), + root, + }); + } + &self.cache[sha] + } + + /// Turn finished renders into textures. Call once per frame. + pub fn pump(&mut self, ctx: &Context) { + while let Ok(done) = self.done.try_recv() { + self.accept(ctx, done); + } + } + + fn accept(&mut self, ctx: &Context, done: Done) { + let state = match done.result { + Ok(images) => State::Ready( + images + .into_iter() + .enumerate() + .map(|(i, img)| { + ctx.load_texture( + format!("blob-{}-{i}", done.sha), + img, + TextureOptions::LINEAR, + ) + }) + .collect(), + ), + Err(e) => State::Failed(e), + }; + self.cache.insert(done.sha, state); + } + + /// Wait until nothing is rendering (tests and screenshots). + pub fn settle(&mut self, ctx: &Context) { + let deadline = std::time::Instant::now() + std::time::Duration::from_secs(20); + while self.cache.values().any(|s| matches!(s, State::Loading)) + && std::time::Instant::now() < deadline + { + if let Ok(done) = self + .done + .recv_timeout(std::time::Duration::from_millis(100)) + { + self.accept(ctx, done); + } + } + } +} + +fn render(job: &Job) -> Result, String> { + let bytes = BlobStore::open_read_only(&job.root) + .get(&job.sha) + .map_err(|e| e.to_string())?; + let is_pdf = job.mime == "application/pdf" || bytes.starts_with(b"%PDF"); + if is_pdf { + render_pdf(bytes) + } else if job.mime.starts_with("image/") { + let img = image::load_from_memory(&bytes).map_err(|e| e.to_string())?; + Ok(vec![to_color_image(img.to_rgba8())]) + } else { + Err(format!("{} can't be previewed", job.mime)) + } +} + +fn render_pdf(bytes: Vec) -> Result, String> { + use hayro::hayro_interpret::InterpreterSettings; + use hayro::hayro_syntax::Pdf; + use hayro::vello_cpu::color::palette::css::WHITE; + use hayro::{PixmapSettings, RenderCache, RenderSettings, render}; + let pdf = Pdf::new(bytes).map_err(|e| format!("not a readable PDF: {e:?}"))?; + let cache = RenderCache::new(); + let interp = InterpreterSettings::default(); + let settings = RenderSettings::default(); + let px = PixmapSettings { + x_scale: 2.0, + y_scale: 2.0, + bg_color: WHITE, + }; + let mut out = Vec::new(); + for page in pdf.pages().iter().take(30) { + let pixmap = render(page, &cache, &interp, &settings, &px); + let png = pixmap.into_png().map_err(|e| format!("{e:?}"))?; + let img = image::load_from_memory(&png).map_err(|e| e.to_string())?; + out.push(to_color_image(img.to_rgba8())); + } + if out.is_empty() { + return Err("the PDF has no pages".into()); + } + Ok(out) +} + +fn to_color_image(img: image::RgbaImage) -> ColorImage { + let size = [img.width() as usize, img.height() as usize]; + ColorImage::from_rgba_unmultiplied(size, img.as_raw()) +} diff --git a/crates/ledger-gui/src/theme.rs b/crates/ledger-gui/src/theme.rs new file mode 100644 index 0000000..8f07520 --- /dev/null +++ b/crates/ledger-gui/src/theme.rs @@ -0,0 +1,228 @@ +//! Look and feel: one palette per mode, Inter with tabular figures, and +//! the spacing the whole app shares. + +use egui::{ + Color32, Context, CornerRadius, FontData, FontDefinitions, FontFamily, FontId, Margin, Stroke, + TextStyle, Visuals, +}; +use std::sync::Arc; + +/// Colors for one mode. Every color in the app comes from here. +#[derive(Clone, Copy, Debug)] +pub struct Palette { + pub bg: Color32, + pub surface: Color32, + pub sidebar: Color32, + pub hover: Color32, + pub selected: Color32, + pub border: Color32, + pub text: Color32, + pub muted: Color32, + pub faint: Color32, + pub accent: Color32, + pub accent_soft: Color32, + pub positive: Color32, + pub negative: Color32, + pub warning: Color32, + pub warning_soft: Color32, + pub negative_soft: Color32, + pub positive_soft: Color32, + pub new_highlight: Color32, + /// Chart series, in order. + pub series: [Color32; 6], +} + +pub const LIGHT: Palette = Palette { + bg: Color32::from_rgb(0xF6, 0xF6, 0xF4), + surface: Color32::from_rgb(0xFF, 0xFF, 0xFF), + sidebar: Color32::from_rgb(0xEF, 0xEF, 0xEC), + hover: Color32::from_rgb(0xF2, 0xF2, 0xF0), + selected: Color32::from_rgb(0xE8, 0xE9, 0xFB), + border: Color32::from_rgb(0xE4, 0xE4, 0xE0), + text: Color32::from_rgb(0x1B, 0x1B, 0x1F), + muted: Color32::from_rgb(0x67, 0x67, 0x70), + faint: Color32::from_rgb(0x9C, 0x9C, 0xA4), + accent: Color32::from_rgb(0x4F, 0x46, 0xE5), + accent_soft: Color32::from_rgb(0xEE, 0xEE, 0xFD), + positive: Color32::from_rgb(0x15, 0x80, 0x3D), + negative: Color32::from_rgb(0xB9, 0x1C, 0x1C), + warning: Color32::from_rgb(0xB4, 0x53, 0x09), + warning_soft: Color32::from_rgb(0xFE, 0xF3, 0xE2), + negative_soft: Color32::from_rgb(0xFD, 0xEC, 0xEC), + positive_soft: Color32::from_rgb(0xE8, 0xF5, 0xEC), + new_highlight: Color32::from_rgb(0xFF, 0xF7, 0xD6), + series: [ + Color32::from_rgb(0x4F, 0x46, 0xE5), + Color32::from_rgb(0x0D, 0x94, 0x88), + Color32::from_rgb(0xD9, 0x77, 0x06), + Color32::from_rgb(0xDB, 0x27, 0x77), + Color32::from_rgb(0x25, 0x63, 0xEB), + Color32::from_rgb(0x64, 0x74, 0x8B), + ], +}; + +pub const DARK: Palette = Palette { + bg: Color32::from_rgb(0x11, 0x12, 0x14), + surface: Color32::from_rgb(0x19, 0x1A, 0x1D), + sidebar: Color32::from_rgb(0x15, 0x16, 0x18), + hover: Color32::from_rgb(0x22, 0x23, 0x27), + selected: Color32::from_rgb(0x26, 0x27, 0x45), + border: Color32::from_rgb(0x2A, 0x2B, 0x30), + text: Color32::from_rgb(0xEC, 0xEC, 0xEE), + muted: Color32::from_rgb(0xA3, 0xA3, 0xAC), + faint: Color32::from_rgb(0x6E, 0x6E, 0x78), + accent: Color32::from_rgb(0x8B, 0x93, 0xFA), + accent_soft: Color32::from_rgb(0x24, 0x25, 0x45), + positive: Color32::from_rgb(0x4A, 0xDE, 0x80), + negative: Color32::from_rgb(0xF8, 0x71, 0x71), + warning: Color32::from_rgb(0xFB, 0xBF, 0x24), + warning_soft: Color32::from_rgb(0x33, 0x29, 0x16), + negative_soft: Color32::from_rgb(0x3A, 0x1C, 0x1E), + positive_soft: Color32::from_rgb(0x16, 0x30, 0x22), + new_highlight: Color32::from_rgb(0x36, 0x31, 0x18), + series: [ + Color32::from_rgb(0x8B, 0x93, 0xFA), + Color32::from_rgb(0x2D, 0xD4, 0xBF), + Color32::from_rgb(0xFB, 0xBF, 0x24), + Color32::from_rgb(0xF4, 0x72, 0xB6), + Color32::from_rgb(0x60, 0xA5, 0xFA), + Color32::from_rgb(0x94, 0xA3, 0xB8), + ], +}; + +/// The palette for the current mode. +pub fn pal(ctx: &Context) -> &'static Palette { + if ctx.global_style().visuals.dark_mode { + &DARK + } else { + &LIGHT + } +} + +pub const SEMIBOLD: &str = "semibold"; +pub const BOLD: &str = "bold"; + +pub fn regular(size: f32) -> FontId { + FontId::new(size, FontFamily::Proportional) +} + +pub fn semibold(size: f32) -> FontId { + FontId::new(size, FontFamily::Name(SEMIBOLD.into())) +} + +pub fn bold(size: f32) -> FontId { + FontId::new(size, FontFamily::Name(BOLD.into())) +} + +/// Install fonts: Inter with tabular figures frozen in, so every number in +/// the app lines up digit for digit. Phosphor icons ride along as a +/// fallback in every family. +pub fn install_fonts(ctx: &Context) { + let mut fonts = FontDefinitions::default(); + let add = |fonts: &mut FontDefinitions, name: &str, bytes: &'static [u8]| { + fonts + .font_data + .insert(name.to_owned(), Arc::new(FontData::from_static(bytes))); + }; + add( + &mut fonts, + "InterTab-Regular", + include_bytes!("../assets/fonts/InterTab-Regular.ttf"), + ); + add( + &mut fonts, + "InterTab-SemiBold", + include_bytes!("../assets/fonts/InterTab-SemiBold.ttf"), + ); + add( + &mut fonts, + "InterTab-Bold", + include_bytes!("../assets/fonts/InterTab-Bold.ttf"), + ); + egui_phosphor::add_to_fonts(&mut fonts, egui_phosphor::Variant::Regular); + let fallbacks: Vec = fonts + .families + .get(&FontFamily::Proportional) + .cloned() + .unwrap_or_default(); + // Text first, icons as a fallback. The bundled Inter copies have their + // private-use glyphs removed, so Phosphor's icons (which live there) + // are never shadowed. + let family = |primary: &str| { + let mut v = vec![primary.to_owned()]; + v.extend(fallbacks.iter().cloned()); + v + }; + fonts + .families + .insert(FontFamily::Proportional, family("InterTab-Regular")); + fonts.families.insert( + FontFamily::Name(SEMIBOLD.into()), + family("InterTab-SemiBold"), + ); + fonts + .families + .insert(FontFamily::Name(BOLD.into()), family("InterTab-Bold")); + ctx.set_fonts(fonts); +} + +/// Apply the app's style for light or dark mode. +pub fn apply(ctx: &Context, dark: bool) { + let p = if dark { &DARK } else { &LIGHT }; + let mut visuals = if dark { + Visuals::dark() + } else { + Visuals::light() + }; + visuals.panel_fill = p.bg; + visuals.window_fill = p.surface; + visuals.extreme_bg_color = p.surface; + visuals.faint_bg_color = p.hover; + visuals.override_text_color = Some(p.text); + visuals.hyperlink_color = p.accent; + visuals.selection.bg_fill = p.selected; + visuals.selection.stroke = Stroke::new(1.0, p.accent); + visuals.window_stroke = Stroke::new(1.0, p.border); + visuals.window_corner_radius = CornerRadius::same(12); + visuals.menu_corner_radius = CornerRadius::same(10); + for w in [ + &mut visuals.widgets.noninteractive, + &mut visuals.widgets.inactive, + &mut visuals.widgets.hovered, + &mut visuals.widgets.active, + &mut visuals.widgets.open, + ] { + w.corner_radius = CornerRadius::same(8); + } + visuals.widgets.noninteractive.bg_stroke = Stroke::new(1.0, p.border); + visuals.widgets.noninteractive.fg_stroke = Stroke::new(1.0, p.text); + visuals.widgets.inactive.bg_fill = p.surface; + visuals.widgets.inactive.weak_bg_fill = p.surface; + visuals.widgets.inactive.bg_stroke = Stroke::new(1.0, p.border); + visuals.widgets.inactive.fg_stroke = Stroke::new(1.0, p.text); + visuals.widgets.hovered.bg_fill = p.hover; + visuals.widgets.hovered.weak_bg_fill = p.hover; + visuals.widgets.hovered.bg_stroke = Stroke::new(1.0, p.border); + visuals.widgets.hovered.fg_stroke = Stroke::new(1.0, p.text); + visuals.widgets.active.bg_fill = p.selected; + visuals.widgets.active.weak_bg_fill = p.selected; + visuals.widgets.active.fg_stroke = Stroke::new(1.0, p.text); + ctx.set_visuals(visuals); + ctx.all_styles_mut(|style| { + style.text_styles = [ + (TextStyle::Heading, semibold(20.0)), + (TextStyle::Body, regular(14.0)), + (TextStyle::Button, regular(14.0)), + (TextStyle::Small, regular(12.0)), + (TextStyle::Monospace, FontId::monospace(12.5)), + ] + .into(); + style.spacing.item_spacing = egui::vec2(8.0, 6.0); + style.spacing.button_padding = egui::vec2(10.0, 5.0); + style.spacing.interact_size.y = 28.0; + style.spacing.window_margin = Margin::same(16); + style.spacing.scroll.bar_width = 8.0; + style.spacing.scroll.floating = true; + style.interaction.selectable_labels = false; + }); +} diff --git a/crates/ledger-gui/src/widgets.rs b/crates/ledger-gui/src/widgets.rs new file mode 100644 index 0000000..2f28a07 --- /dev/null +++ b/crates/ledger-gui/src/widgets.rs @@ -0,0 +1,291 @@ +//! Small building blocks shared by every screen. + +use crate::theme::{self, pal}; +use egui::{ + Align, Color32, CornerRadius, Frame, Layout, Margin, Response, RichText, Sense, Stroke, Ui, + vec2, +}; + +/// A white (or dark) rounded surface with a hairline border. +pub fn card(ui: &mut Ui, add: impl FnOnce(&mut Ui) -> R) -> R { + let p = pal(ui.ctx()); + Frame::new() + .fill(p.surface) + .stroke(Stroke::new(1.0, p.border)) + .corner_radius(CornerRadius::same(12)) + .inner_margin(Margin::same(16)) + .show(ui, |ui| { + ui.set_width(ui.available_width()); + add(ui) + }) + .inner +} + +/// A card with a title row and a right-aligned extra (a link, a pill). +/// Returns what `extra` and `add` return. +pub fn titled_card( + ui: &mut Ui, + title: &str, + extra: impl FnOnce(&mut Ui) -> E, + add: impl FnOnce(&mut Ui) -> R, +) -> (E, R) { + card(ui, |ui| { + let e = ui + .horizontal(|ui| { + ui.label(RichText::new(title).font(theme::semibold(14.0))); + ui.with_layout(Layout::right_to_left(Align::Center), extra) + .inner + }) + .inner; + ui.add_space(8.0); + (e, add(ui)) + }) +} + +/// Page title and the sentence under it. +pub fn page_header(ui: &mut Ui, title: &str, subtitle: &str) { + let p = pal(ui.ctx()); + ui.label(RichText::new(title).font(theme::bold(26.0))); + if !subtitle.is_empty() { + ui.add_space(2.0); + let w = ui.available_width().min(860.0); + ui.allocate_ui(vec2(w, 0.0), |ui| { + ui.set_max_width(w); + ui.label( + RichText::new(subtitle) + .font(theme::regular(15.0)) + .color(p.muted), + ); + }); + } + ui.add_space(16.0); +} + +/// A rounded tag. +pub fn pill(ui: &mut Ui, text: &str, fg: Color32, bg: Color32) -> Response { + Frame::new() + .fill(bg) + .corner_radius(CornerRadius::same(255)) + .inner_margin(Margin::symmetric(8, 2)) + .show(ui, |ui| { + ui.label(RichText::new(text).font(theme::semibold(11.5)).color(fg)) + }) + .response +} + +/// Text that looks like plain text until you hover it, then like a link. +pub fn link(ui: &mut Ui, text: RichText) -> Response { + let p = pal(ui.ctx()); + let r = ui.add(egui::Label::new(text.clone()).sense(Sense::click())); + if r.hovered() { + ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); + let rect = r.rect; + ui.painter().line_segment( + [ + rect.left_bottom() + vec2(0.0, 1.0), + rect.right_bottom() + vec2(0.0, 1.0), + ], + Stroke::new(1.0, p.accent), + ); + } + r +} + +/// An amount, right-aligned in a fixed-width cell, clickable when `drill`. +pub fn amount_cell( + ui: &mut Ui, + text: &str, + width: f32, + color: Color32, + strong: bool, + drill: bool, +) -> Response { + let font = if strong { + theme::semibold(14.0) + } else { + theme::regular(14.0) + }; + let (rect, resp) = ui.allocate_exact_size( + vec2(width, 22.0), + if drill { + Sense::click() + } else { + Sense::hover() + }, + ); + let p = pal(ui.ctx()); + let hovered = drill && resp.hovered(); + let galley = ui.painter().layout_no_wrap( + text.to_string(), + font, + if hovered { p.accent } else { color }, + ); + let pos = egui::pos2( + rect.right() - galley.size().x, + rect.center().y - galley.size().y / 2.0, + ); + if hovered { + ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); + ui.painter().line_segment( + [ + egui::pos2(pos.x, rect.center().y + galley.size().y / 2.0), + egui::pos2(rect.right(), rect.center().y + galley.size().y / 2.0), + ], + Stroke::new(1.0, p.accent), + ); + } + ui.painter().galley(pos, galley, color); + resp +} + +/// A big number with a label, a change line, and an optional sparkline. +pub struct Kpi<'a> { + pub label: &'a str, + pub value: String, + pub sub: Option<(String, Color32)>, + pub spark: Option<&'a [f64]>, + pub how: &'a str, +} + +pub fn kpi(ui: &mut Ui, k: Kpi<'_>) -> Response { + let p = pal(ui.ctx()); + let resp = Frame::new() + .fill(p.surface) + .stroke(Stroke::new(1.0, p.border)) + .corner_radius(CornerRadius::same(12)) + .inner_margin(Margin::same(14)) + .show(ui, |ui| { + ui.set_width(ui.available_width()); + ui.set_min_height(104.0); + ui.label( + RichText::new(k.label) + .font(theme::regular(12.5)) + .color(p.muted), + ); + ui.add_space(4.0); + ui.label(RichText::new(&k.value).font(theme::semibold(24.0))); + if let Some((text, color)) = &k.sub { + ui.add_space(2.0); + ui.label(RichText::new(text).font(theme::regular(12.0)).color(*color)); + } + if let Some(values) = k.spark + && values.len() > 1 + { + ui.add_space(6.0); + let (rect, _) = + ui.allocate_exact_size(vec2(ui.available_width(), 26.0), Sense::hover()); + crate::charts::sparkline(ui.painter(), rect, values, p.accent); + } + }) + .response; + if !k.how.is_empty() { + resp.on_hover_text(k.how) + } else { + resp + } +} + +/// A friendly placeholder when there's nothing to show yet. +pub fn empty(ui: &mut Ui, icon: &str, title: &str, text: &str) { + let p = pal(ui.ctx()); + ui.vertical_centered(|ui| { + ui.add_space(18.0); + ui.label(RichText::new(icon).size(28.0).color(p.faint)); + ui.add_space(4.0); + ui.label( + RichText::new(title) + .font(theme::semibold(14.0)) + .color(p.muted), + ); + ui.label( + RichText::new(text) + .font(theme::regular(12.5)) + .color(p.faint), + ); + ui.add_space(18.0); + }); +} + +/// "Copy prompt": puts an agent prompt on the clipboard. +pub fn copy_prompt(ui: &mut Ui, prompt: &str) { + let p = pal(ui.ctx()); + let id = ui.id().with(("copied", prompt)); + let copied_at: Option = ui.ctx().data(|d| d.get_temp(id)); + let now = ui.input(|i| i.time); + let recently = copied_at.is_some_and(|t| now - t < 1.5); + let label = if recently { + format!("{} Copied", egui_phosphor::regular::CHECK) + } else { + format!("{} Ask the agent", egui_phosphor::regular::SPARKLE) + }; + let r = ui + .add( + egui::Button::new( + RichText::new(label) + .font(theme::regular(12.0)) + .color(p.accent), + ) + .fill(p.accent_soft) + .stroke(Stroke::NONE) + .corner_radius(CornerRadius::same(6)), + ) + .on_hover_text(format!( + "Copies this prompt for your agent session:\n\n{prompt}" + )); + if r.clicked() { + ui.ctx().copy_text(prompt.to_string()); + ui.ctx().data_mut(|d| d.insert_temp(id, now)); + } + if recently { + ui.ctx() + .request_repaint_after(std::time::Duration::from_millis(300)); + } +} + +/// A horizontal rule in the border color. +pub fn rule(ui: &mut Ui) { + let p = pal(ui.ctx()); + let w = ui.available_width(); + let (rect, _) = ui.allocate_exact_size(vec2(w, 1.0), Sense::hover()); + ui.painter().rect_filled(rect, 0.0, p.border); +} + +/// Selectable segmented control. +pub fn segmented(ui: &mut Ui, value: &mut T, options: &[(T, &str)]) -> bool { + let p = pal(ui.ctx()); + let mut changed = false; + Frame::new() + .fill(p.hover) + .corner_radius(CornerRadius::same(8)) + .inner_margin(Margin::same(2)) + .show(ui, |ui| { + ui.spacing_mut().item_spacing.x = 2.0; + ui.horizontal(|ui| { + for (v, label) in options { + let on = *value == *v; + let b = egui::Button::new( + RichText::new(*label) + .font(if on { + theme::semibold(12.5) + } else { + theme::regular(12.5) + }) + .color(if on { p.text } else { p.muted }), + ) + .fill(if on { p.surface } else { Color32::TRANSPARENT }) + .stroke(if on { + Stroke::new(1.0, p.border) + } else { + Stroke::NONE + }) + .corner_radius(CornerRadius::same(6)) + .min_size(vec2(0.0, 24.0)); + if ui.add(b).clicked() && !on { + *value = *v; + changed = true; + } + } + }); + }); + changed +} diff --git a/crates/ledger-gui/tests/live.rs b/crates/ledger-gui/tests/live.rs new file mode 100644 index 0000000..12f01be --- /dev/null +++ b/crates/ledger-gui/tests/live.rs @@ -0,0 +1,68 @@ +//! Live updates: a change written to the books (by the MCP server, in +//! practice) reaches the GUI's view model on its own, without a restart, +//! and the changed entry is marked fresh. + +use chrono::NaiveDate; +use ledger_core::{AccountType, Currency, Money, Side}; +use ledger_gui::data::{Loader, Source, Update}; +use ledger_store::Store; +use rust_decimal::Decimal; +use std::time::{Duration, Instant}; + +#[test] +fn a_change_in_another_process_shows_up_live() { + let dir = std::env::temp_dir().join(format!("ledger-gui-live-{}", std::process::id())); + let _ = std::fs::remove_dir_all(&dir); + let data = dir.join("books-data"); + let mut store = Store::create(&data, Currency::USD).unwrap(); + let cash = store + .add_account("1000", "Checking", AccountType::Asset, None, false) + .unwrap(); + let equity = store + .add_account("3000", "Capital", AccountType::Equity, None, false) + .unwrap(); + drop(store); + + let ctx = egui::Context::default(); + let loader = Loader::spawn( + Source { + data_dir: data.clone(), + books_toml: None, + today: NaiveDate::from_ymd_opt(2026, 10, 12), + }, + ctx, + ); + let first = match loader.wait(Duration::from_secs(10)) { + Some(Update::Books(b)) => b, + _ => panic!("no initial load"), + }; + assert_eq!(first.kpis.cash, Decimal::ZERO); + + // The writer (the MCP server's store) posts an entry. + let started = Instant::now(); + let mut store = Store::open(&data).unwrap(); + let d = NaiveDate::from_ymd_opt(2026, 10, 12).unwrap(); + let e = store.create_entry(d, "Owner contribution").unwrap(); + let m = Money::new(Decimal::from(2500), Currency::USD); + store.add_line(e, cash, Side::Debit, m).unwrap(); + store.add_line(e, equity, Side::Credit, m).unwrap(); + store.post_entry(e).unwrap(); + drop(store); + + // The GUI sees it, without being asked. + let deadline = Instant::now() + Duration::from_secs(10); + let mut seen = None; + while Instant::now() < deadline { + if let Some(Update::Books(b)) = loader.wait(Duration::from_millis(200)) + && b.kpis.cash == Decimal::from(2500) + { + seen = Some(b); + break; + } + } + let b = seen.expect("the posted entry never reached the GUI"); + assert!(b.fresh.contains(&e), "the new entry is highlighted as new"); + assert!(b.seq() > first.seq()); + eprintln!("live update arrived in {:?}", started.elapsed()); + let _ = std::fs::remove_dir_all(&dir); +} diff --git a/crates/ledger-gui/tests/screens.rs b/crates/ledger-gui/tests/screens.rs new file mode 100644 index 0000000..d7ea3be --- /dev/null +++ b/crates/ledger-gui/tests/screens.rs @@ -0,0 +1,88 @@ +//! Screenshots of every screen, for eyes. Set `SHOT_BOOKS` to a books dir +//! (containing `books-data/` and `wanderbooks.toml`) and `SHOT_DIR` to +//! where the PNGs go; without them this test does nothing. + +use egui_kittest::Harness; +use ledger_gui::nav::{ReportKind, Route}; +use ledger_gui::{App, Source, data}; +use std::path::PathBuf; + +#[test] +fn screenshots() { + let Ok(out) = std::env::var("SHOT_DIR") else { + return; + }; + let fixed_today: Option = std::env::var("SHOT_TODAY") + .ok() + .and_then(|d| d.parse().ok()); + let books = match std::env::var("SHOT_BOOKS") { + Ok(b) => PathBuf::from(b), + Err(_) => { + let d = fixed_today + .unwrap_or_else(|| chrono::NaiveDate::from_ymd_opt(2026, 10, 12).unwrap()); + let dir = + std::env::temp_dir().join(format!("ledger-gui-shots-demo-{}", std::process::id())); + let _ = std::fs::remove_dir_all(&dir); + ledger_gui::demo::build(&dir, d).unwrap(); + dir + } + }; + let out = PathBuf::from(out); + std::fs::create_dir_all(&out).unwrap(); + let source = Source { + data_dir: books.join("books-data"), + books_toml: Some(books.join("wanderbooks.toml")), + today: fixed_today.or_else(|| { + std::env::var("SHOT_BOOKS") + .is_err() + .then(|| chrono::NaiveDate::from_ymd_opt(2026, 10, 12).unwrap()) + }), + }; + let only = std::env::var("SHOT_ONLY").ok(); + let dark = std::env::var("SHOT_DARK").is_ok(); + let first_entry = data::load_once(&source) + .unwrap() + .entries + .last() + .map(|e| e.id) + .unwrap_or(1); + let routes: Vec<(&str, Route)> = vec![ + ("overview", Route::Overview), + ("transactions", Route::Transactions), + ( + "entry", + Route::Entry( + std::env::var("SHOT_ENTRY") + .ok() + .and_then(|e| e.parse().ok()) + .unwrap_or(first_entry), + ), + ), + ("cash", Route::Cash), + ("profit", Route::Profit), + ("pnl", Route::Reports(ReportKind::ProfitAndLoss)), + ("balance", Route::Reports(ReportKind::BalanceSheet)), + ("accounts", Route::Accounts), + ("documents", Route::Documents), + ("company", Route::Company), + ("journal", Route::Journal), + ]; + for (name, route) in routes { + if only + .as_deref() + .is_some_and(|o| !o.split(',').any(|x| x == name)) + { + continue; + } + let books = data::load_once(&source).unwrap(); + let mut harness = Harness::builder() + .with_size(egui::vec2(1440.0, 920.0)) + .build_eframe(|cc| App::with_books(&cc.egui_ctx, books, dark, route.clone())); + harness.run_steps(4); + let ctx = harness.ctx.clone(); + harness.state_mut().settle(&ctx); + harness.run_steps(4); + let img = harness.render().unwrap(); + img.save(out.join(format!("{name}.png"))).unwrap(); + } +} diff --git a/crates/ledger-mcp/Cargo.toml b/crates/ledger-mcp/Cargo.toml index 4bf9a33..352e2ab 100644 --- a/crates/ledger-mcp/Cargo.toml +++ b/crates/ledger-mcp/Cargo.toml @@ -14,6 +14,7 @@ path = "src/main.rs" ledger-core = { path = "../ledger-core" } ledger-store = { path = "../ledger-store" } ledger-import = { path = "../ledger-import" } +ledger-config = { path = "../ledger-config" } base64 = "0.22" mime_guess = "2" rust_decimal = "1" diff --git a/crates/ledger-mcp/src/main.rs b/crates/ledger-mcp/src/main.rs index 0f9033a..1e2e1bb 100644 --- a/crates/ledger-mcp/src/main.rs +++ b/crates/ledger-mcp/src/main.rs @@ -9,7 +9,7 @@ //! receipt threshold) come from the books dir's `wanderbooks.toml`, by //! default the one next to the data dir. -mod company; +use ledger_config as company; mod policy; mod server; mod types; diff --git a/crates/ledger-mcp/src/server.rs b/crates/ledger-mcp/src/server.rs index 0c7aa51..147c653 100644 --- a/crates/ledger-mcp/src/server.rs +++ b/crates/ledger-mcp/src/server.rs @@ -1,10 +1,10 @@ //! The MCP server: narrow typed tools over the store, with the receipt //! policy enforced server-side. -use crate::company::Company; use crate::policy::ReceiptPolicy; use crate::types::*; use chrono::NaiveDate; +use ledger_config::Company; use ledger_core::{ AccountId, AccountType, AssetStatus, Currency, DocumentLine, DocumentStatus, JournalEntry, Ledger, Money, NewAsset, PeriodStatus, Side, accumulated_depreciation, book_value, diff --git a/crates/ledger-store/src/blob.rs b/crates/ledger-store/src/blob.rs index fae1460..41499d9 100644 --- a/crates/ledger-store/src/blob.rs +++ b/crates/ledger-store/src/blob.rs @@ -25,6 +25,14 @@ impl BlobStore { }) } + /// Open an existing blob store for reading, creating nothing. A + /// missing directory just means no blobs yet. + pub fn open_read_only(root: &Path) -> Self { + Self { + root: root.to_path_buf(), + } + } + fn path_for(&self, sha_hex: &str) -> PathBuf { self.root .join(&sha_hex[0..2]) diff --git a/crates/ledger-store/src/lib.rs b/crates/ledger-store/src/lib.rs index 28bfc0d..f95e8df 100644 --- a/crates/ledger-store/src/lib.rs +++ b/crates/ledger-store/src/lib.rs @@ -22,11 +22,13 @@ pub mod blob; pub mod error; pub mod journal; pub mod schema; +pub mod snapshot; pub mod store; pub use blob::BlobStore; pub use error::StoreError; pub use journal::{GENESIS_PREV, JournalLine, JournalWriter}; +pub use snapshot::Snapshot; pub use store::{ Attachment, DB_FILE, DepreciationRun, DisposalPreview, EntryRow, EventRow, JOURNAL_FILE, PayrollLineInput, Store, diff --git a/crates/ledger-store/src/snapshot.rs b/crates/ledger-store/src/snapshot.rs new file mode 100644 index 0000000..7736eb1 --- /dev/null +++ b/crates/ledger-store/src/snapshot.rs @@ -0,0 +1,175 @@ +//! [`Snapshot`]: a read-only view of the books, for viewers. +//! +//! A snapshot never writes to the data directory. It reads the journal, +//! verifies the hash chain, replays it into its own [`Ledger`], and projects +//! it into a private in-memory SQLite database with exactly the code the +//! writer uses, so attachments and events read the same as through +//! [`crate::Store`]. Blobs are read (and verified) straight from the blob +//! store. +//! +//! [`Snapshot::refresh`] follows a live journal: it reads only the bytes +//! appended since the last read, verifies they chain onto what it has, and +//! applies them. A line the writer is still in the middle of appending +//! (no newline yet) is left for the next refresh, never treated as +//! corruption. If the file shrank or no longer chains, the snapshot reloads +//! from scratch. + +use crate::blob::BlobStore; +use crate::error::StoreError; +use crate::journal::{GENESIS_PREV, JournalLine, sha256_hex}; +use crate::store::{ + Attachment, BLOBS_DIR, JOURNAL_FILE, Store, apply_line_to_sqlite, query_attachments, + read_attachment_bytes, replay_line_into_ledger, +}; +use ledger_core::{Currency, EntryId, Ledger}; +use rusqlite::Connection; +use std::io::{Read, Seek, SeekFrom}; +use std::path::{Path, PathBuf}; + +/// A read-only, live-refreshable view of a data directory. +pub struct Snapshot { + data_dir: PathBuf, + conn: Connection, + blobs: BlobStore, + ledger: Ledger, + base_currency: Currency, + lines: Vec, + /// Bytes of the journal consumed (complete lines only). + offset: u64, + /// Hash of the last line read: what the next line must chain onto. + head: String, +} + +impl Snapshot { + /// Load the books in `data_dir`, read-only. + pub fn load(data_dir: &Path) -> Result { + let journal_path = data_dir.join(JOURNAL_FILE); + if !journal_path.exists() { + return Err(StoreError::NotFound(data_dir.display().to_string())); + } + let conn = Connection::open_in_memory()?; + Store::migrate(&conn)?; + let mut snap = Self { + data_dir: data_dir.to_path_buf(), + conn, + blobs: BlobStore::open_read_only(&data_dir.join(BLOBS_DIR)), + ledger: Ledger::new(Currency::USD), + base_currency: Currency::USD, + lines: Vec::new(), + offset: 0, + head: GENESIS_PREV.to_string(), + }; + snap.read_new()?; + Ok(snap) + } + + /// Apply whatever the writer appended since the last read. Returns the + /// number of new journal lines (0 when nothing changed). + pub fn refresh(&mut self) -> Result { + let len = std::fs::metadata(self.data_dir.join(JOURNAL_FILE))?.len(); + if len < self.offset { + // Rewritten underneath us (e.g. restored from a backup). + *self = Self::load(&self.data_dir)?; + return Ok(self.lines.len()); + } + match self.read_new() { + Ok(n) => Ok(n), + Err(StoreError::JournalCorrupt(_)) => { + // No longer chains onto what we have: start over, and let a + // real corruption surface from the full load. + *self = Self::load(&self.data_dir)?; + Ok(self.lines.len()) + } + Err(e) => Err(e), + } + } + + fn read_new(&mut self) -> Result { + let mut file = std::fs::File::open(self.data_dir.join(JOURNAL_FILE))?; + file.seek(SeekFrom::Start(self.offset))?; + let mut buf = Vec::new(); + file.read_to_end(&mut buf)?; + // Complete lines only: a torn tail is a write still in progress. + let Some(last_newline) = buf.iter().rposition(|&b| b == b'\n') else { + return Ok(0); + }; + let complete = &buf[..=last_newline]; + let mut added = 0; + for raw in complete.split(|&b| b == b'\n').filter(|l| !l.is_empty()) { + let line: JournalLine = serde_json::from_slice(raw).map_err(|e| { + StoreError::JournalCorrupt(format!( + "seq {}: unparseable line: {e}", + self.lines.len() + 1 + )) + })?; + let want_seq = self.lines.len() as u64 + 1; + if line.seq != want_seq { + return Err(StoreError::JournalCorrupt(format!( + "seq gap: expected {want_seq}, found {}", + line.seq + ))); + } + if line.prev != self.head { + return Err(StoreError::JournalCorrupt(format!( + "hash chain broken at seq {}", + line.seq + ))); + } + if line.seq == 1 { + let code = line.payload["base_currency"].as_str().unwrap_or("USD"); + self.base_currency = Currency::new(code) + .map_err(|_| StoreError::JournalCorrupt(format!("bad base_currency {code}")))?; + self.ledger = Ledger::new(self.base_currency); + } + replay_line_into_ledger(&mut self.ledger, &line, self.base_currency)?; + apply_line_to_sqlite(&self.conn, &line)?; + self.head = sha256_hex(line.to_canonical().as_bytes()); + self.lines.push(line); + added += 1; + } + self.offset += complete.len() as u64; + Ok(added) + } + + /// The replayed ledger: the source for every report. + pub fn ledger(&self) -> &Ledger { + &self.ledger + } + + /// The books' base currency. + pub fn base_currency(&self) -> Currency { + self.base_currency + } + + /// The data directory. + pub fn data_dir(&self) -> &Path { + &self.data_dir + } + + /// Every journal line read so far, in order: the complete history, + /// with timestamps and hashes. + pub fn journal(&self) -> &[JournalLine] { + &self.lines + } + + /// Sequence number of the last journal line read. + pub fn journal_seq(&self) -> u64 { + self.lines.len() as u64 + } + + /// Hash of the last journal line: the head of the verified chain. + pub fn head_hash(&self) -> &str { + &self.head + } + + /// Attachments (receipts and documents, withdrawn ones included), + /// optionally only one entry's. + pub fn attachments(&self, entry_id: Option) -> Result, StoreError> { + query_attachments(&self.conn, entry_id) + } + + /// An attachment's bytes, verified against its hash. + pub fn attachment_bytes(&self, attachment_id: u64) -> Result, StoreError> { + read_attachment_bytes(&self.conn, &self.blobs, attachment_id) + } +} diff --git a/crates/ledger-store/src/store.rs b/crates/ledger-store/src/store.rs index 8fd5de0..ccc5f9b 100644 --- a/crates/ledger-store/src/store.rs +++ b/crates/ledger-store/src/store.rs @@ -27,7 +27,7 @@ use std::path::{Path, PathBuf}; pub const JOURNAL_FILE: &str = "journal.jsonl"; /// File names inside the data directory. pub const DB_FILE: &str = "wanderbooks.db"; -const BLOBS_DIR: &str = "blobs"; +pub(crate) const BLOBS_DIR: &str = "blobs"; /// One row of an entry listing. #[derive(Clone, Debug)] @@ -283,7 +283,7 @@ impl Store { matches!(check, Ok(s) if s == "ok") } - fn migrate(conn: &Connection) -> Result<(), StoreError> { + pub(crate) fn migrate(conn: &Connection) -> Result<(), StoreError> { let mut v = Self::current_version(conn)?; if v > schema::SCHEMA_VERSION { return Err(StoreError::SchemaTooNew(v, schema::SCHEMA_VERSION)); @@ -2106,36 +2106,12 @@ impl Store { &self, entry_id: Option, ) -> Result, StoreError> { - let mut sql = String::from( - "SELECT a.id, a.blob_sha, a.entry_id, a.category, b.original_name, b.mime_type, \ - b.size_bytes, a.description, a.created_at, a.withdrawn_at, a.withdrawn_reason \ - FROM attachments a \ - JOIN blobs b ON b.sha256 = a.blob_sha", - ); - if entry_id.is_some() { - sql.push_str(" WHERE a.entry_id = ?"); - } - sql.push_str(" ORDER BY a.id"); - let mut stmt = self.conn.prepare(&sql)?; - let rows: Vec = match entry_id { - Some(eid) => stmt - .query_map(params![eid as i64], row_to_attachment)? - .collect::>()?, - None => stmt - .query_map([], row_to_attachment)? - .collect::>()?, - }; - Ok(rows) + query_attachments(&self.conn, entry_id) } /// Read attachment bytes, verifying the SHA-256. pub fn attachment_bytes(&self, attachment_id: u64) -> Result, StoreError> { - let sha: String = self.conn.query_row( - "SELECT blob_sha FROM attachments WHERE id = ?", - params![attachment_id as i64], - |r| r.get(0), - )?; - self.blobs.get(&sha) + read_attachment_bytes(&self.conn, &self.blobs, attachment_id) } // ------------------------------------------------------------------ @@ -2795,7 +2771,7 @@ fn get_str<'a>(p: &'a Value, key: &str) -> Result<&'a str, StoreError> { /// Replay one journal line into a ledger, asserting recorded ids. Used by /// hydration, `verify`, and `rebuild`: the journal is the script, the engine /// is the actor. -fn replay_line_into_ledger( +pub(crate) fn replay_line_into_ledger( ledger: &mut Ledger, line: &JournalLine, base_currency: Currency, @@ -3376,7 +3352,10 @@ fn check_replayed_entry( Ok(()) } -fn apply_line_to_sqlite(conn: &Connection, line: &JournalLine) -> Result<(), StoreError> { +pub(crate) fn apply_line_to_sqlite( + conn: &Connection, + line: &JournalLine, +) -> Result<(), StoreError> { let p = &line.payload; match line.line_type.as_str() { "store.created" => {} @@ -3795,6 +3774,47 @@ fn apply_line_to_sqlite(conn: &Connection, line: &JournalLine) -> Result<(), Sto Ok(()) } +/// Attachments in the projection, optionally only one entry's, by id. +pub(crate) fn query_attachments( + conn: &Connection, + entry_id: Option, +) -> Result, StoreError> { + let mut sql = String::from( + "SELECT a.id, a.blob_sha, a.entry_id, a.category, b.original_name, b.mime_type, \ + b.size_bytes, a.description, a.created_at, a.withdrawn_at, a.withdrawn_reason \ + FROM attachments a \ + JOIN blobs b ON b.sha256 = a.blob_sha", + ); + if entry_id.is_some() { + sql.push_str(" WHERE a.entry_id = ?"); + } + sql.push_str(" ORDER BY a.id"); + let mut stmt = conn.prepare(&sql)?; + let rows: Vec = match entry_id { + Some(eid) => stmt + .query_map(params![eid as i64], row_to_attachment)? + .collect::>()?, + None => stmt + .query_map([], row_to_attachment)? + .collect::>()?, + }; + Ok(rows) +} + +/// An attachment's bytes, verified against its SHA-256. +pub(crate) fn read_attachment_bytes( + conn: &Connection, + blobs: &BlobStore, + attachment_id: u64, +) -> Result, StoreError> { + let sha: String = conn.query_row( + "SELECT blob_sha FROM attachments WHERE id = ?", + params![attachment_id as i64], + |r| r.get(0), + )?; + blobs.get(&sha) +} + fn row_to_attachment(r: &rusqlite::Row) -> rusqlite::Result { Ok(Attachment { id: r.get::<_, i64>(0)? as u64, diff --git a/crates/ledger-store/tests/snapshot.rs b/crates/ledger-store/tests/snapshot.rs new file mode 100644 index 0000000..a09f24e --- /dev/null +++ b/crates/ledger-store/tests/snapshot.rs @@ -0,0 +1,145 @@ +//! Snapshot: a read-only view that follows a live writer. + +use chrono::NaiveDate; +use ledger_core::reports::snapshot; +use ledger_core::{AccountType, Currency, Money, Side}; +use ledger_store::{JOURNAL_FILE, Snapshot, Store}; +use rust_decimal::Decimal; +use std::io::Write; +use std::path::PathBuf; + +fn test_dir(name: &str) -> PathBuf { + let dir = std::env::temp_dir().join(format!("wanderbooks-snap-{name}-{}", std::process::id())); + let _ = std::fs::remove_dir_all(&dir); + std::fs::create_dir_all(&dir).unwrap(); + dir +} + +fn usd(n: i64) -> Money { + Money::new(Decimal::from(n), Currency::USD) +} + +fn post(store: &mut Store, day: u32, dr: u64, cr: u64, amount: i64) -> u64 { + let d = NaiveDate::from_ymd_opt(2026, 10, day).unwrap(); + let e = store.create_entry(d, "x").unwrap(); + store.add_line(e, dr, Side::Debit, usd(amount)).unwrap(); + store.add_line(e, cr, Side::Credit, usd(amount)).unwrap(); + store.post_entry(e).unwrap(); + e +} + +#[test] +fn a_snapshot_follows_the_writer_and_never_writes() { + let dir = test_dir("follow"); + let mut store = Store::create(&dir, Currency::USD).unwrap(); + let cash = store + .add_account("1000", "Cash", AccountType::Asset, None, false) + .unwrap(); + let equity = store + .add_account("3000", "Equity", AccountType::Equity, None, false) + .unwrap(); + let e = post(&mut store, 1, cash, equity, 1000); + store + .attach_receipt(Some(e), "deposit.png", "image/png", b"png-bytes", None) + .unwrap(); + + let listing = |dir: &std::path::Path| { + let mut v: Vec<_> = walk(dir); + v.sort(); + v + }; + let before = listing(&dir); + let mut snap = Snapshot::load(&dir).unwrap(); + assert_eq!(listing(&dir), before, "loading writes nothing"); + assert_eq!(snap.journal_seq(), store.journal_seq()); + assert_eq!( + snapshot(snap.ledger()).unwrap(), + snapshot(store.ledger()).unwrap() + ); + let atts = snap.attachments(Some(e)).unwrap(); + assert_eq!(atts.len(), 1); + assert_eq!(snap.attachment_bytes(atts[0].id).unwrap(), b"png-bytes"); + + // The writer keeps going; refresh picks up exactly the new lines. + assert_eq!(snap.refresh().unwrap(), 0); + let seq = store.journal_seq(); + post(&mut store, 2, cash, equity, 250); + let added = snap.refresh().unwrap(); + assert_eq!(added as u64, store.journal_seq() - seq); + assert_eq!( + snapshot(snap.ledger()).unwrap(), + snapshot(store.ledger()).unwrap() + ); +} + +#[test] +fn a_half_written_line_waits_for_the_next_refresh() { + let dir = test_dir("torn"); + let mut store = Store::create(&dir, Currency::USD).unwrap(); + store + .add_account("1000", "Cash", AccountType::Asset, None, false) + .unwrap(); + drop(store); + let mut snap = Snapshot::load(&dir).unwrap(); + let seq = snap.journal_seq(); + // Simulate the writer mid-append: half a line, no newline yet. + let journal = dir.join(JOURNAL_FILE); + let full = std::fs::read(&journal).unwrap(); + let mut store = Store::open(&dir).unwrap(); + store + .add_account("3000", "Equity", AccountType::Equity, None, false) + .unwrap(); + drop(store); + let grown = std::fs::read(&journal).unwrap(); + let new_line = &grown[full.len()..]; + std::fs::write(&journal, &full).unwrap(); + let mut f = std::fs::OpenOptions::new() + .append(true) + .open(&journal) + .unwrap(); + f.write_all(&new_line[..new_line.len() / 2]).unwrap(); + f.flush().unwrap(); + assert_eq!(snap.refresh().unwrap(), 0, "torn tail is not corruption"); + f.write_all(&new_line[new_line.len() / 2..]).unwrap(); + f.flush().unwrap(); + assert_eq!(snap.refresh().unwrap(), 1); + assert_eq!(snap.journal_seq(), seq + 1); + assert!(snap.ledger().chart().find_by_code("3000").is_some()); +} + +#[test] +fn a_rewritten_journal_reloads() { + let dir = test_dir("rewrite"); + let mut store = Store::create(&dir, Currency::USD).unwrap(); + let cash = store + .add_account("1000", "Cash", AccountType::Asset, None, false) + .unwrap(); + let equity = store + .add_account("3000", "Equity", AccountType::Equity, None, false) + .unwrap(); + let journal = dir.join(JOURNAL_FILE); + let early = std::fs::read(&journal).unwrap(); + post(&mut store, 1, cash, equity, 10); + drop(store); + let mut snap = Snapshot::load(&dir).unwrap(); + let later = snap.journal_seq(); + // Restored from an earlier backup: shorter file. + std::fs::write(&journal, &early).unwrap(); + snap.refresh().unwrap(); + assert!(snap.journal_seq() < later); + assert!(snap.ledger().posted_entries().next().is_none()); +} + +fn walk(dir: &std::path::Path) -> Vec<(String, u64)> { + let mut out = Vec::new(); + for e in std::fs::read_dir(dir).unwrap() { + let e = e.unwrap(); + let m = e.metadata().unwrap(); + if m.is_dir() { + out.extend(walk(&e.path())); + } else { + out.push((e.path().display().to_string(), m.len())); + } + } + out +} diff --git a/docs/architecture.md b/docs/architecture.md index 2e900b9..9eb064e 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -58,7 +58,6 @@ The core is a pure domain library and stays that way. | `ledger-import` | QuickBooks CSV read-only import (bank transactions, chart of accounts) | `ledger-core` | | `ledger-export` | Format renderers: CSV, XLSX, IIF journal entries (QuickBooks Desktop) | `ledger-core` | | `ledger-oracle` | Diff harness: our engine vs GnuCash on fixture books | `ledger-core`, `ledger-import` | -| `books-app` | egui UI (native + WASM), command-driven | `ledger-core`, `ledger-store` | Dependency direction is always inward toward `ledger-core`. Nothing in the core may depend on a future crate. UI concerns (formatting, locale, widgets) @@ -71,3 +70,13 @@ types, and a type system that makes invalid states (mutable posted entries, float money) unrepresentable. The storytold pipeline this project is modeled on is Rust + egui for the same reasons; when the UI crate arrives it will be one codebase compiling to native and WASM. + +## The GUI (`ledger-gui`) + +Read-only by construction: it opens a `ledger_store::Snapshot` (journal +verified and replayed into its own `Ledger`, projected into a private +in-memory SQLite, blobs read through the verifying store) and never writes +to the data directory. A loader thread watches the directory and applies +appended journal lines; the UI renders an immutable view model rebuilt per +change. Statements and series come from `ledger-core` (`reports`, +`analysis`); the GUI only arranges them. See `plan/gui.md`. diff --git a/plan/STATUS.md b/plan/STATUS.md index 905e653..5d191dc 100644 --- a/plan/STATUS.md +++ b/plan/STATUS.md @@ -249,3 +249,21 @@ interface is MCP, not a cloned GUI. The first storage + MCP slice is done Journal events vendor.1099_set and entry.vendor_set. Schema v7. 64 tools. Also: requirements and parity no longer list finished R-FUTURE work as future (only budgets remain, declined). +- 2026-10-12: ledger-gui, the read-only desktop view (egui 0.36, wgpu). + Overview (the answer in a sentence, KPI tiles with honest comparisons, + cash chart, needs-attention with copyable agent prompts, recent + activity), Cash (accounts, in/out, burn and runway, coming up), Profit + (by month with margin, spending vs. its recent average, by customer and + class), Transactions (search, filters, cash direction, detail with + lines, the rendered receipt via hayro, and journal history), Reports + (P&L, balance sheet, cash flow, owners' equity, trial balance, GL, tax + summary, 1099, agings; date presets, month/quarter/year columns, prior + period/year comparison, % of income, drill-down to the account register + for exactly those dates, copy as TSV), Accounts and registers, + Documents, Company, Journal (every event, hash, payload), Ctrl+K + palette, back/forward, light/dark. Live: notify-driven, ~30 ms from + write to screen. Engine additions: ledger-store Snapshot (read-only, + incremental, torn-tail tolerant), ledger-core analysis (intervals, + balance series and history, P&L by interval, flows), ledger-config + (extracted from ledger-mcp; full profile, cash_accounts). Fonts: Inter + with tnum frozen in and private-use glyphs removed (Phosphor icons). diff --git a/plan/gui.md b/plan/gui.md new file mode 100644 index 0000000..2f3956d --- /dev/null +++ b/plan/gui.md @@ -0,0 +1,111 @@ +# ledger-gui — design + +Phase 4 of the roadmap. A desktop app (egui/eframe; web later) for the +people who own the books and the accountant who checks them. Same +audience as QuickBooks, none of its visual language. + +## What it is for + +It answers the questions an owner actually has, then shows the evidence: + +- **How much money do we have, and how long does it last?** Cash today, + the trend, burn, runway, what's coming due. +- **Are we making money?** Revenue, spending, and profit by month; what + changed and why. +- **Where does the money go?** Spending by category and vendor, over time. +- **Who owes whom?** Payables, receivables, cards, money owed to members. +- **Is anything wrong or missing?** Entries without receipts, drafts never + posted, unreconciled accounts, uncategorized tax lines, 1099 vendors with + no W-9, past periods left open, a journal that fails verification. +- **Can I trust this number?** Every number drills down to the lines that + make it, each line to its entry, each entry to its rendered receipt and + its complete journal history (who did what, when, hash-chained). + +An accountant gets the same data at full depth: statements with interval +columns and comparisons, the general ledger, trial balance, the raw +journal with its verification status. + +## Principles + +1. **Answer first.** Every screen leads with the answer in words and one + big number, then the chart, then the table, then the raw data. +2. **Everything drills down.** Any amount is a link. Navigation is a + history stack (back/forward, like a browser) with a breadcrumb. +3. **All the data, nothing hidden.** Withdrawn attachments, reversals, + drafts, every journal event: visible, marked for what they are. +4. **Read-only by construction.** The GUI has no write path: it reads the + hash-chained journal and the blob store and builds its own in-memory + view (`ledger_store::Snapshot`). Changes happen through the agent (MCP). + Where the GUI finds something to fix, it offers a ready-to-paste prompt + for the agent ("Attach the receipt for entry 12 — Anthropic, $5.82"). +5. **Live.** It follows the journal: a change made by the agent appears + within a second, highlighted as new. +6. **Numbers are typography.** Tabular figures everywhere (Inter with + `tnum` frozen in), right-aligned, parentheses for negatives in + statements, a minus sign elsewhere, never a float. +7. **No accounting logic in the GUI.** Statements, balances, and series + come from `ledger-core` (new reports land there, where MCP can use + them too). The GUI arranges and draws. + +## Screens + +- **Overview** — KPI tiles with sparkline and change vs. the prior period + (cash, runway, revenue, spending, net income, owed by / owed to); + cash over time; income vs. spending by month; spending by category; + needs-attention list; recent activity from the journal. +- **Cash** — every cash and card account with balance and trend; inflows + and outflows by month; burn and runway; known upcoming outflows + (recurring entries, bills due, schedules). +- **Profit** — P&L by month as chart and table, spending breakdown with + month-over-month change, by class. +- **Transactions** — the register of every entry: search, filters + (account, vendor, class, date, status, receipt yes/no, amount), and a + detail pane with lines, the rendered receipt (PDF pages, images), + vendor, reversal links, and the entry's journal history. +- **Reports** — P&L, balance sheet, cash flow, trial balance, general + ledger, members' equity, tax summary, A/R and A/P aging, 1099 + worksheet. Date presets, interval columns (total / month / quarter / + year), comparison to the prior period or year. Every amount drills down. +- **Accounts** — the chart with balances and tax categories; an account + opens its register with a running balance and a balance chart. +- **Documents** — every receipt and company document, rendered, with its + category, entry link, and withdrawal status. +- **Company** — profile, members and capital, periods, fixed assets, + amortization schedules, recurring entries, vendors and 1099 status. +- **Journal** — the raw event log, filterable, each event expandable to + its JSON, with the hash-chain verification result. + +Global: command palette (Ctrl+K) to jump to any account, entry, vendor, +document, or report; back/forward (Alt+←/→); light and dark themes. + +## Architecture + +- `ledger-store::Snapshot`: read-only. Verifies the journal chain, + replays it into a `Ledger`, projects it into an in-memory SQLite with + the same code the writer uses, reads blobs. `refresh()` applies only + new journal lines (or reloads if the file was rewritten). +- `ledger-config` (moved out of `ledger-mcp`): `wanderbooks.toml`. +- `ledger-gui`: + - `data` — a loader thread polls the journal and sends new snapshots. + - `model` — view models built from a snapshot (pure, unit-tested). + - `ui/*` — one module per screen; `widgets` (money, tiles, sparkline, + tables, charts); `theme`; `receipts` (PDF via `hayro`, images via + `image`; textures cached by blob hash). + - Tests: model unit tests, `egui_kittest` screenshots of every screen + against a fixture book. +- Web build later: the model is plain data, so a server can ship it. + +## Status (2026-10-12) + +Built: every screen above, the palette, history, themes, live updates +(tested end to end: a store write reaches the view model in ~30 ms), +receipt rendering for PDFs and images, a deterministic demo company +(`ledger-gui --demo`; also the screenshot fixture), and a screenshot test +(`SHOT_DIR=… cargo test -p ledger-gui --test screens`, optionally +`SHOT_BOOKS`, `SHOT_ONLY`, `SHOT_DARK`). + +Next, in rough order: a budget-free cash forecast with a confidence band; +reconciliation view (cleared vs. uncleared per bank account); receipt +zoom and multi-page navigation; keyboard navigation in lists; +virtualized lists for very large books; the web build (ship the view +model from a server). diff --git a/plan/roadmap.md b/plan/roadmap.md index 7f1995e..f0e4845 100644 --- a/plan/roadmap.md +++ b/plan/roadmap.md @@ -31,7 +31,9 @@ The primary interface is MCP, not a cloned GUI (Stephen's call, 2026-10-10). - Done when: a fixture book produces byte-identical snapshots from both engines with zero manual steps. -## Phase 4 — Read-only GUI +## Phase 4 — Read-only GUI (first version done, 2026-10-12) + +`ledger-gui`: see `plan/gui.md` for the design and what's built. - Consumes the `ledger-store` event log: live updates — the answer to "watch its files to update live."